From 50e38cc9f1e6713228a91ad50f426c4f65e65e1a Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Wed, 30 Oct 2024 09:08:55 -0700 Subject: [PATCH 001/220] Bump serve-static to 1.16.2 to fix CVE-2024-43800 (#47289) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47289 Bump serve-static to 1.16.2 to fix CVE-2024-43800 Changelog: [General] [Changed] - Bump serve-static to 1.16.2 to fix CVE-2024-43800 Reviewed By: cipolleschi Differential Revision: D65146027 fbshipit-source-id: 2876a78f195230cc4cdaa14b0076ecbecc1ee6e4 --- packages/dev-middleware/package.json | 2 +- yarn.lock | 34 ++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/packages/dev-middleware/package.json b/packages/dev-middleware/package.json index 52db3ef78fede7..3dfde88432fe5b 100644 --- a/packages/dev-middleware/package.json +++ b/packages/dev-middleware/package.json @@ -31,7 +31,7 @@ "nullthrows": "^1.1.1", "open": "^7.0.3", "selfsigned": "^2.4.1", - "serve-static": "^1.13.1", + "serve-static": "^1.16.2", "ws": "^6.2.3" }, "engines": { diff --git a/yarn.lock b/yarn.lock index 3c84bd281e3c37..9e875d353741ad 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3758,6 +3758,11 @@ encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== +encodeurl@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-2.0.0.tgz#7b8ea898077d7e409d3ac45474ea38eaf0857a58" + integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg== + end-of-stream@^1.1.0, end-of-stream@^1.4.1: version "1.4.4" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" @@ -7779,6 +7784,25 @@ send@0.18.0: range-parser "~1.2.1" statuses "2.0.1" +send@0.19.0: + version "0.19.0" + resolved "https://registry.yarnpkg.com/send/-/send-0.19.0.tgz#bbc5a388c8ea6c048967049dbeac0e4a3f09d7f8" + integrity sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw== + dependencies: + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "2.0.0" + mime "1.6.0" + ms "2.1.3" + on-finished "2.4.1" + range-parser "~1.2.1" + statuses "2.0.1" + serialize-error@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-2.1.0.tgz#50b679d5635cdf84667bdc8e59af4e5b81d5f60a" @@ -7794,6 +7818,16 @@ serve-static@^1.13.1: parseurl "~1.3.3" send "0.18.0" +serve-static@^1.16.2: + version "1.16.2" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.16.2.tgz#b6a5343da47f6bdd2673848bf45754941e803296" + integrity sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw== + dependencies: + encodeurl "~2.0.0" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.19.0" + set-blocking@^2.0.0, set-blocking@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" From ec0dbb729d3774184dee83efbff5f9beebce72ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Kwas=CC=81niewski?= Date: Wed, 30 Oct 2024 11:24:19 -0700 Subject: [PATCH 002/220] feat: introduce RCTArchConfiguratorProtocol (#47306) Summary: This PR introduces `RCTArchConfiguratorProtocol` for better separation of concerns inside of RCTAppDelegate. It's also a prerequisite for https://github.com/facebook/react-native/issues/46298 Discussed with cipolleschi ## Changelog: [IOS] [ADDED] - introduce RCTArchConfiguratorProtocol Pull Request resolved: https://github.com/facebook/react-native/pull/47306 Test Plan: - CI Green - Test if methods can be overriden Reviewed By: realsoelynn Differential Revision: D65212703 Pulled By: cipolleschi fbshipit-source-id: 9850fec31c421f0c6230e7e23d7a208d823d828f --- .../Libraries/AppDelegate/RCTAppDelegate.h | 30 ++++------------- .../AppDelegate/RCTArchConfiguratorProtocol.h | 32 +++++++++++++++++++ 2 files changed, 39 insertions(+), 23 deletions(-) create mode 100644 packages/react-native/Libraries/AppDelegate/RCTArchConfiguratorProtocol.h diff --git a/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.h b/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.h index 7f527665062e00..44af9901ccfc62 100644 --- a/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.h +++ b/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.h @@ -8,6 +8,7 @@ #import #import #import +#import "RCTArchConfiguratorProtocol.h" #import "RCTRootViewFactory.h" #import "RCTUIConfiguratorProtocol.h" @@ -56,8 +57,12 @@ NS_ASSUME_NONNULL_BEGIN (const facebook::react::ObjCTurboModule::InitParams &)params * - (id)getModuleInstanceFromClass:(Class)moduleClass */ -@interface RCTAppDelegate - : UIResponder +@interface RCTAppDelegate : UIResponder < + UIApplicationDelegate, + UISceneDelegate, + RCTBridgeDelegate, + RCTUIConfiguratorProtocol, + RCTArchConfiguratorProtocol> /// The window object, used to render the UViewControllers @property (nonatomic, strong, nonnull) UIWindow *window; @@ -107,27 +112,6 @@ NS_ASSUME_NONNULL_BEGIN /// @return a dictionary that associate a component for the new renderer with his descriptor. - (NSDictionary> *)thirdPartyFabricComponents; -/// This method controls whether the `turboModules` feature of the New Architecture is turned on or off. -/// -/// @note: This is required to be rendering on Fabric (i.e. on the New Architecture). -/// @return: `true` if the Turbo Native Module are enabled. Otherwise, it returns `false`. -- (BOOL)turboModuleEnabled __attribute__((deprecated("Use newArchEnabled instead"))); - -/// This method controls whether the App will use the Fabric renderer of the New Architecture or not. -/// -/// @return: `true` if the Fabric Renderer is enabled. Otherwise, it returns `false`. -- (BOOL)fabricEnabled __attribute__((deprecated("Use newArchEnabled instead"))); - -/// This method controls whether React Native's new initialization layer is enabled. -/// -/// @return: `true` if the new initialization layer is enabled. Otherwise returns `false`. -- (BOOL)bridgelessEnabled __attribute__((deprecated("Use newArchEnabled instead"))); - -/// This method controls whether React Native uses new Architecture. -/// -/// @return: `true` if the new architecture is enabled. Otherwise returns `false`. -- (BOOL)newArchEnabled; - /// Return the bundle URL for the main bundle. - (NSURL *__nullable)bundleURL; diff --git a/packages/react-native/Libraries/AppDelegate/RCTArchConfiguratorProtocol.h b/packages/react-native/Libraries/AppDelegate/RCTArchConfiguratorProtocol.h new file mode 100644 index 00000000000000..ccd3c6b6f6cd53 --- /dev/null +++ b/packages/react-native/Libraries/AppDelegate/RCTArchConfiguratorProtocol.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#import +#import + +@protocol RCTArchConfiguratorProtocol +/// This method controls whether the `turboModules` feature of the New Architecture is turned on or off. +/// +/// @note: This is required to be rendering on Fabric (i.e. on the New Architecture). +/// @return: `true` if the Turbo Native Module are enabled. Otherwise, it returns `false`. +- (BOOL)turboModuleEnabled __attribute__((deprecated("Use newArchEnabled instead"))); + +/// This method controls whether the App will use the Fabric renderer of the New Architecture or not. +/// +/// @return: `true` if the Fabric Renderer is enabled. Otherwise, it returns `false`. +- (BOOL)fabricEnabled __attribute__((deprecated("Use newArchEnabled instead"))); + +/// This method controls whether React Native's new initialization layer is enabled. +/// +/// @return: `true` if the new initialization layer is enabled. Otherwise returns `false`. +- (BOOL)bridgelessEnabled __attribute__((deprecated("Use newArchEnabled instead"))); + +/// This method controls whether React Native uses new Architecture. +/// +/// @return: `true` if the new architecture is enabled. Otherwise returns `false`. +- (BOOL)newArchEnabled; +@end From 2d9933e616c3efe57ed0ca141277638182a69d9c Mon Sep 17 00:00:00 2001 From: zhongwuzw Date: Wed, 30 Oct 2024 12:01:10 -0700 Subject: [PATCH 003/220] automaticallyAdjustKeyboardInsets not shifting scrollview content (#46732) Summary: Fixes https://github.com/facebook/react-native/issues/46595 . It seems https://github.com/facebook/react-native/issues/37766 broke the `automaticallyAdjustKeyboardInsets` when input accessory view become first responder. ## Changelog: [IOS] [FIXED] - automaticallyAdjustKeyboardInsets not shifting scrollview content Pull Request resolved: https://github.com/facebook/react-native/pull/46732 Test Plan: Repro please see in #https://github.com/facebook/react-native/issues/46595 . Reviewed By: cipolleschi Differential Revision: D65072478 Pulled By: javache fbshipit-source-id: 7d5d7566438d4bb0e1d50074a953b18866e324d3 --- .../Text/TextInput/RCTBaseTextInputView.mm | 1 + .../ScrollView/RCTScrollViewComponentView.h | 3 ++ .../ScrollView/RCTScrollViewComponentView.mm | 30 +++++++++++-------- .../TextInput/RCTTextInputComponentView.mm | 1 + .../React/Views/ScrollView/RCTScrollView.h | 2 ++ .../React/Views/ScrollView/RCTScrollView.m | 6 ++++ 6 files changed, 30 insertions(+), 13 deletions(-) diff --git a/packages/react-native/Libraries/Text/TextInput/RCTBaseTextInputView.mm b/packages/react-native/Libraries/Text/TextInput/RCTBaseTextInputView.mm index 349e53cef6f790..b9c699b8daaa58 100644 --- a/packages/react-native/Libraries/Text/TextInput/RCTBaseTextInputView.mm +++ b/packages/react-native/Libraries/Text/TextInput/RCTBaseTextInputView.mm @@ -36,6 +36,7 @@ - (void)reactUpdateResponderOffsetForScrollView:(RCTScrollView *)scrollView { if (![self isDescendantOfView:scrollView]) { // View is outside scroll view + scrollView.firstResponderViewOutsideScrollView = self.backedTextInputView; return; } diff --git a/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.h b/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.h index 12f4209f63a8f8..99b7240b83d7b8 100644 --- a/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.h +++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.h @@ -38,6 +38,9 @@ NS_ASSUME_NONNULL_BEGIN /** Focus area of newly-activated text input relative to the window to compare against UIKeyboardFrameBegin/End */ @property (nonatomic, assign) CGRect firstResponderFocus; +/** newly-activated text input outside of the scroll view */ +@property (nonatomic, weak) UIView *firstResponderViewOutsideScrollView; + /* * Returns the subview of the scroll view that the component uses to mount all subcomponents into. That's useful to * separate component views from auxiliary views to be able to reliably implement pull-to-refresh- and RTL-related diff --git a/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm b/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm index 6e198a0bfa2d41..bb63afb3c3d7f7 100644 --- a/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm +++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm @@ -182,6 +182,7 @@ - (void)_keyboardWillChangeFrame:(NSNotification *)notification UIViewAnimationCurve curve = (UIViewAnimationCurve)[notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] unsignedIntegerValue]; CGRect keyboardEndFrame = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue]; + CGRect keyboardBeginFrame = [notification.userInfo[UIKeyboardFrameBeginUserInfoKey] CGRectValue]; CGPoint absoluteViewOrigin = [self convertPoint:self.bounds.origin toView:nil]; CGFloat scrollViewLowerY = isInverted ? absoluteViewOrigin.y : absoluteViewOrigin.y + self.bounds.size.height; @@ -203,21 +204,24 @@ - (void)_keyboardWillChangeFrame:(NSNotification *)notification from:self forEvent:nil]) { if (CGRectEqualToRect(_firstResponderFocus, CGRectNull)) { - // Text input view is outside of the scroll view. - return; - } - - CGRect viewIntersection = CGRectIntersection(self.firstResponderFocus, keyboardEndFrame); + UIView *inputAccessoryView = _firstResponderViewOutsideScrollView.inputAccessoryView; + if (inputAccessoryView) { + // Text input view is within the inputAccessoryView. + contentDiff = keyboardEndFrame.origin.y - keyboardBeginFrame.origin.y; + } + } else { + CGRect viewIntersection = CGRectIntersection(self.firstResponderFocus, keyboardEndFrame); - if (CGRectIsNull(viewIntersection)) { - return; - } + if (CGRectIsNull(viewIntersection)) { + return; + } - // Inner text field focused - CGFloat focusEnd = CGRectGetMaxY(self.firstResponderFocus); - if (focusEnd > keyboardEndFrame.origin.y) { - // Text field active region is below visible area with keyboard - update diff to bring into view - contentDiff = keyboardEndFrame.origin.y - focusEnd; + // Inner text field focused + CGFloat focusEnd = CGRectGetMaxY(self.firstResponderFocus); + if (focusEnd > keyboardEndFrame.origin.y) { + // Text field active region is below visible area with keyboard - update diff to bring into view + contentDiff = keyboardEndFrame.origin.y - focusEnd; + } } } diff --git a/packages/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm b/packages/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm index 00cf7563d35492..01a066d3c5114f 100644 --- a/packages/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm +++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm @@ -126,6 +126,7 @@ - (void)reactUpdateResponderOffsetForScrollView:(RCTScrollViewComponentView *)sc { if (![self isDescendantOfView:scrollView.scrollView] || !_backedTextInputView.isFirstResponder) { // View is outside scroll view or it's not a first responder. + scrollView.firstResponderViewOutsideScrollView = _backedTextInputView; return; } diff --git a/packages/react-native/React/Views/ScrollView/RCTScrollView.h b/packages/react-native/React/Views/ScrollView/RCTScrollView.h index d57793b65d9fe7..10ef46a513e143 100644 --- a/packages/react-native/React/Views/ScrollView/RCTScrollView.h +++ b/packages/react-native/React/Views/ScrollView/RCTScrollView.h @@ -50,6 +50,8 @@ @property (nonatomic, assign) BOOL inverted; /** Focus area of newly-activated text input relative to the window to compare against UIKeyboardFrameBegin/End */ @property (nonatomic, assign) CGRect firstResponderFocus; +/** newly-activated text input outside of the scroll view */ +@property (nonatomic, weak) UIView *firstResponderViewOutsideScrollView; // NOTE: currently these event props are only declared so we can export the // event names to JS - we don't call the blocks directly because scroll events diff --git a/packages/react-native/React/Views/ScrollView/RCTScrollView.m b/packages/react-native/React/Views/ScrollView/RCTScrollView.m index 31b76146e61436..e83b91de6756fa 100644 --- a/packages/react-native/React/Views/ScrollView/RCTScrollView.m +++ b/packages/react-native/React/Views/ScrollView/RCTScrollView.m @@ -338,6 +338,12 @@ - (void)_keyboardWillChangeFrame:(NSNotification *)notification if (!didFocusExternalTextField && focusEnd > endFrame.origin.y) { // Text field active region is below visible area with keyboard - update diff to bring into view contentDiff = endFrame.origin.y - focusEnd; + } else { + UIView *inputAccessoryView = _firstResponderViewOutsideScrollView.inputAccessoryView; + if (inputAccessoryView) { + // Text input view is within the inputAccessoryView. + contentDiff = endFrame.origin.y - beginFrame.origin.y; + } } } else if (endFrame.origin.y <= beginFrame.origin.y) { // Keyboard opened for other reason From 8bd1f3fbfa20940d5865d541b2288f53ccd829e5 Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Wed, 30 Oct 2024 12:06:27 -0700 Subject: [PATCH 004/220] Back out "surface setup issues in EventBeat and Scheduler" (#47312) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47312 changelog: [internal] Original commit changeset: 5e044e1e6b02 Original Phabricator Diff: D65001802 Reviewed By: rshest Differential Revision: D65210838 fbshipit-source-id: 90d9db256374f32d2efc366fe120bf677639e67e --- .../ReactCommon/react/renderer/core/EventBeat.cpp | 4 ---- .../react/renderer/scheduler/Scheduler.cpp | 13 ++++++------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/packages/react-native/ReactCommon/react/renderer/core/EventBeat.cpp b/packages/react-native/ReactCommon/react/renderer/core/EventBeat.cpp index 82f18533a9d8dd..305c2375224919 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/EventBeat.cpp +++ b/packages/react-native/ReactCommon/react/renderer/core/EventBeat.cpp @@ -7,7 +7,6 @@ #include "EventBeat.h" -#include #include #include @@ -19,9 +18,6 @@ EventBeat::EventBeat( : ownerBox_(std::move(ownerBox)), runtimeScheduler_(runtimeScheduler) {} void EventBeat::request() const { - react_native_assert( - beatCallback_ && - "Unexpected state: EventBeat::setBeatCallback was not called before EventBeat::request."); isRequested_ = true; } diff --git a/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.cpp b/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.cpp index 6950740f71adc0..3519fa025d77cb 100644 --- a/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.cpp +++ b/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.cpp @@ -54,18 +54,17 @@ Scheduler::Scheduler( auto weakRuntimeScheduler = contextContainer_->find>( "RuntimeScheduler"); - react_native_assert( - weakRuntimeScheduler.has_value() && - "Unexpected state: RuntimeScheduler was not provided."); - - auto runtimeScheduler = weakRuntimeScheduler.value().lock(); + auto runtimeScheduler = weakRuntimeScheduler.has_value() + ? weakRuntimeScheduler.value().lock() + : nullptr; - if (ReactNativeFeatureFlags::enableUIConsistency()) { + if (runtimeScheduler && ReactNativeFeatureFlags::enableUIConsistency()) { runtimeScheduler->setShadowTreeRevisionConsistencyManager( uiManager->getShadowTreeRevisionConsistencyManager()); } - if (ReactNativeFeatureFlags::enableReportEventPaintTime()) { + if (runtimeScheduler && + ReactNativeFeatureFlags::enableReportEventPaintTime()) { runtimeScheduler->setEventTimingDelegate(eventPerformanceLogger_.get()); } From d79dc48abd2e65e4d203e488f99eb554c473a1fc Mon Sep 17 00:00:00 2001 From: David Vacca Date: Wed, 30 Oct 2024 13:32:04 -0700 Subject: [PATCH 005/220] Delete RCTConstants.RCTGetMemoryPressureUnloadLevel (#47297) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47297 In this diff I'm proposing to remove configuration for RCTConstants.RCTGetMemoryPressureUnloadLevel API in iOS changelog: [iOS][Breaking] Delete experimental API RCTConstants.RCTGetMemoryPressureUnloadLevel Reviewed By: rubennorte, philIip Differential Revision: D65181556 fbshipit-source-id: c435bec6ed03562b53f1924add7b69ab517b190b --- packages/react-native/React/Base/RCTConstants.h | 6 ------ packages/react-native/React/Base/RCTConstants.m | 16 ---------------- .../react-native/React/CxxBridge/RCTCxxBridge.mm | 3 ++- 3 files changed, 2 insertions(+), 23 deletions(-) diff --git a/packages/react-native/React/Base/RCTConstants.h b/packages/react-native/React/Base/RCTConstants.h index 51a3967d1af17b..72bbb0f7b5cea9 100644 --- a/packages/react-native/React/Base/RCTConstants.h +++ b/packages/react-native/React/Base/RCTConstants.h @@ -50,9 +50,3 @@ RCT_EXTERN NSString *const RCTDidInitializeModuleNotification; */ RCT_EXTERN BOOL RCTGetDispatchW3CPointerEvents(void); RCT_EXTERN void RCTSetDispatchW3CPointerEvents(BOOL value); - -/* - * Memory Pressure Unloading Level - */ -RCT_EXTERN int RCTGetMemoryPressureUnloadLevel(void); -RCT_EXTERN void RCTSetMemoryPressureUnloadLevel(int value); diff --git a/packages/react-native/React/Base/RCTConstants.m b/packages/react-native/React/Base/RCTConstants.m index f348841d6ad451..eb90640789f6cb 100644 --- a/packages/react-native/React/Base/RCTConstants.m +++ b/packages/react-native/React/Base/RCTConstants.m @@ -38,19 +38,3 @@ void RCTSetDispatchW3CPointerEvents(BOOL value) { RCTDispatchW3CPointerEvents = value; } - -/* - * Memory Pressure Unloading Level for experimentation only. - * Default is 15, which is TRIM_MEMORY_RUNNING_CRITICAL. - */ -static int RCTMemoryPressureUnloadLevel = 15; - -int RCTGetMemoryPressureUnloadLevel(void) -{ - return RCTMemoryPressureUnloadLevel; -} - -void RCTSetMemoryPressureUnloadLevel(int value) -{ - RCTMemoryPressureUnloadLevel = value; -} diff --git a/packages/react-native/React/CxxBridge/RCTCxxBridge.mm b/packages/react-native/React/CxxBridge/RCTCxxBridge.mm index 4bf83305b02f82..dc3c753de65da3 100644 --- a/packages/react-native/React/CxxBridge/RCTCxxBridge.mm +++ b/packages/react-native/React/CxxBridge/RCTCxxBridge.mm @@ -371,7 +371,8 @@ - (void)handleMemoryWarning // in case if some other tread resets it. auto reactInstance = _reactInstance; if (reactInstance) { - int unloadLevel = RCTGetMemoryPressureUnloadLevel(); + // Memory Pressure Unloading Level 15 represents TRIM_MEMORY_RUNNING_CRITICAL. + int unloadLevel = 15; reactInstance->handleMemoryPressure(unloadLevel); } } From e3f8c6369895ff2e2c0eb0db3086301b6466ad1c Mon Sep 17 00:00:00 2001 From: Panos Vekris Date: Wed, 30 Oct 2024 14:37:10 -0700 Subject: [PATCH 006/220] Deploy 0.251.1 to xplat (#47317) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47317 Changelog: [Internal] Reviewed By: SamChou19815 Differential Revision: D65233278 fbshipit-source-id: 35057c00f9377b6492f43bb03e5f92572799a50a --- .flowconfig | 2 +- package.json | 2 +- yarn.lock | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.flowconfig b/.flowconfig index 8d32fadef2a123..44a756caaed099 100644 --- a/.flowconfig +++ b/.flowconfig @@ -90,4 +90,4 @@ untyped-import untyped-type-import [version] -^0.251.0 +^0.251.1 diff --git a/package.json b/package.json index 3a39d171c73dab..fa80c94ff1d9e7 100644 --- a/package.json +++ b/package.json @@ -77,7 +77,7 @@ "eslint-plugin-redundant-undefined": "^0.4.0", "eslint-plugin-relay": "^1.8.3", "flow-api-translator": "0.24.0", - "flow-bin": "^0.251.0", + "flow-bin": "^0.251.1", "glob": "^7.1.1", "hermes-eslint": "0.24.0", "hermes-transform": "0.24.0", diff --git a/yarn.lock b/yarn.lock index 9e875d353741ad..41d4b38fa823ca 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4451,10 +4451,10 @@ flow-api-translator@0.24.0: hermes-transform "0.24.0" typescript "5.3.2" -flow-bin@^0.251.0: - version "0.251.0" - resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.251.0.tgz#8050039ae66c7f0b72f5eea9be036df78d644585" - integrity sha512-1ROmUJrBGLa19ufdOrx4Pu5NVeJbIGDEb2uCmjnr3nmBFVUVHfcB+wQ2RjHvDIloW46k7EwgKFOl5PdseRrrcQ== +flow-bin@^0.251.1: + version "0.251.1" + resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.251.1.tgz#d8dc360b865edaa6e76b3b9edd545f5730e1b520" + integrity sha512-zp8NsURU1hY2drz0p5MEVRrUg+0oXNbzD7od3ExOEBqMZsM6oX5ixp8j4U2sv+4v2dJWLgi9wQS4xJ5dnq2Q+Q== flow-enums-runtime@^0.0.6: version "0.0.6" From 3a01a0c9c501d694d912c937fbf2a7b73760368f Mon Sep 17 00:00:00 2001 From: Sam Zhou Date: Wed, 30 Oct 2024 18:15:03 -0700 Subject: [PATCH 007/220] Fix signature of VirtualizedSectionList (#47318) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47318 Changelog: [Internal] Reviewed By: gkz Differential Revision: D65239931 fbshipit-source-id: c09eaad8d63f6c415e5d07a4d00dd0acc636c6b9 --- .../Lists/VirtualizedSectionList.js | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/packages/virtualized-lists/Lists/VirtualizedSectionList.js b/packages/virtualized-lists/Lists/VirtualizedSectionList.js index 0b531b8a7ecf08..f42e2ef95f8818 100644 --- a/packages/virtualized-lists/Lists/VirtualizedSectionList.js +++ b/packages/virtualized-lists/Lists/VirtualizedSectionList.js @@ -146,7 +146,7 @@ class VirtualizedSectionList< this._listRef.scrollToIndex(toIndexParams); } - getListRef(): ?React.ElementRef { + getListRef(): ?VirtualizedList { return this._listRef; } @@ -598,16 +598,12 @@ function ItemWithSeparator(props: ItemWithSeparatorProps): React.Node { ); } -/* $FlowFixMe[class-object-subtyping] added when improving typing for this - * parameters */ -// $FlowFixMe[method-unbinding] module.exports = VirtualizedSectionList as component( ref: React.RefSetter< - $ReadOnly<{ - +getListRef: () => ?React.ElementRef, - +scrollToLocation: (params: ScrollToLocationParamsType) => void, - ... - }>, + interface { + getListRef(): ?VirtualizedList, + scrollToLocation(params: ScrollToLocationParamsType): void, + }, >, - ...React.ElementConfig + ...Props> ); From 13b93cfddaa559697968ac1c19e55f7aaa053070 Mon Sep 17 00:00:00 2001 From: Nolan O'Brien Date: Wed, 30 Oct 2024 21:08:32 -0700 Subject: [PATCH 008/220] Remove implicit "start", then clean up callsites (#47313) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47313 We're going to fix up a bunch of designated initializers. `RCTSurfaceHostingProxyRootView` is particularly problematic because different initializers will do different things even though reading the code it looks like they should be equivalent. Remove the encapsulated "start" to the provided "surface", and require it to be explicit at the callsite. ## Changelog: [iOS][Changed] - `RCTSurfaceHostingProxyRootView` no longer has different behavior (whether it calls `start` on the provided *surface*) depending on which initializer is used. Call `start` yourself on the *surface* instead. Reviewed By: cipolleschi Differential Revision: D65214656 fbshipit-source-id: 179d5220d4f866b4452561e1bb6e2051020c8a11 --- .../react-native/Libraries/AppDelegate/RCTAppSetupUtils.mm | 4 +++- .../Libraries/AppDelegate/RCTRootViewFactory.mm | 5 ++--- .../SurfaceHostingView/RCTSurfaceHostingProxyRootView.mm | 7 ++----- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/packages/react-native/Libraries/AppDelegate/RCTAppSetupUtils.mm b/packages/react-native/Libraries/AppDelegate/RCTAppSetupUtils.mm index d33fd071d896d4..0478efc67001b1 100644 --- a/packages/react-native/Libraries/AppDelegate/RCTAppSetupUtils.mm +++ b/packages/react-native/Libraries/AppDelegate/RCTAppSetupUtils.mm @@ -53,7 +53,9 @@ void RCTAppSetupPrepareApp(UIApplication *application, BOOL turboModuleEnabled) id surface = [[RCTFabricSurface alloc] initWithBridge:bridge moduleName:moduleName initialProperties:initialProperties]; - return [[RCTSurfaceHostingProxyRootView alloc] initWithSurface:surface]; + UIView *rootView = [[RCTSurfaceHostingProxyRootView alloc] initWithSurface:surface]; + [surface start]; + return rootView; } return [[RCTRootView alloc] initWithBridge:bridge moduleName:moduleName initialProperties:initialProperties]; } diff --git a/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.mm b/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.mm index f5490705bed0e9..4b687c5a3e0f92 100644 --- a/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.mm +++ b/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.mm @@ -172,9 +172,8 @@ - (UIView *)viewWithModuleName:(NSString *)moduleName RCTFabricSurface *surface = [self.reactHost createSurfaceWithModuleName:moduleName initialProperties:initProps]; - RCTSurfaceHostingProxyRootView *surfaceHostingProxyRootView = [[RCTSurfaceHostingProxyRootView alloc] - initWithSurface:surface - sizeMeasureMode:RCTSurfaceSizeMeasureModeWidthExact | RCTSurfaceSizeMeasureModeHeightExact]; + RCTSurfaceHostingProxyRootView *surfaceHostingProxyRootView = + [[RCTSurfaceHostingProxyRootView alloc] initWithSurface:surface]; surfaceHostingProxyRootView.backgroundColor = [UIColor systemBackgroundColor]; if (self->_configuration.customizeRootView != nil) { diff --git a/packages/react-native/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingProxyRootView.mm b/packages/react-native/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingProxyRootView.mm index b14e74ea77e046..e157d2fa2ac442 100644 --- a/packages/react-native/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingProxyRootView.mm +++ b/packages/react-native/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingProxyRootView.mm @@ -53,11 +53,8 @@ @implementation RCTSurfaceHostingProxyRootView - (instancetype)initWithSurface:(id)surface { - if (self = [super initWithSurface:surface - sizeMeasureMode:RCTSurfaceSizeMeasureModeWidthExact | RCTSurfaceSizeMeasureModeHeightExact]) { - [surface start]; - } - return self; + return [super initWithSurface:surface + sizeMeasureMode:RCTSurfaceSizeMeasureModeWidthExact | RCTSurfaceSizeMeasureModeHeightExact]; } RCT_NOT_IMPLEMENTED(-(instancetype)initWithFrame : (CGRect)frame) From b98846c2e37c3ec895536ab942978d7701f51a5e Mon Sep 17 00:00:00 2001 From: Nolan O'Brien Date: Wed, 30 Oct 2024 21:08:32 -0700 Subject: [PATCH 009/220] Fix up designated initializers 8/x (#47316) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47316 Pull Request resolved: https://github.com/facebook/react-native/pull/47300 In preparation of enabling `-Wobjc-designated-initializers` error ## Changelog: [iOS][Fixed] - Fix numerous class interfaces having incorrect designated initializer patterns Reviewed By: caodoan Differential Revision: D65180118 fbshipit-source-id: 6f977816ede0397225ec681a5357241c28e83f6c --- .../react-native/React/Base/RCTBridgeProxy.h | 3 + .../react-native/React/Base/RCTBridgeProxy.mm | 10 ++++ .../react-native/React/Base/RCTCallInvoker.mm | 5 ++ .../react-native/React/Base/RCTModuleData.h | 2 +- .../react-native/React/Base/RCTModuleData.mm | 60 +++++++++---------- .../RCTSurfaceHostingProxyRootView.h | 7 +++ .../platform/ios/ReactCommon/RCTHost.h | 3 + 7 files changed, 56 insertions(+), 34 deletions(-) diff --git a/packages/react-native/React/Base/RCTBridgeProxy.h b/packages/react-native/React/Base/RCTBridgeProxy.h index 71bb9cf0831640..ef392aad70a3ba 100644 --- a/packages/react-native/React/Base/RCTBridgeProxy.h +++ b/packages/react-native/React/Base/RCTBridgeProxy.h @@ -18,6 +18,9 @@ NS_ASSUME_NONNULL_BEGIN @interface RCTBridgeProxy : NSProxy +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; + - (instancetype)initWithViewRegistry:(RCTViewRegistry *)viewRegistry moduleRegistry:(RCTModuleRegistry *)moduleRegistry bundleManager:(RCTBundleManager *)bundleManager diff --git a/packages/react-native/React/Base/RCTBridgeProxy.mm b/packages/react-native/React/Base/RCTBridgeProxy.mm index 5b3e0656929ee3..621262e13645a2 100644 --- a/packages/react-native/React/Base/RCTBridgeProxy.mm +++ b/packages/react-native/React/Base/RCTBridgeProxy.mm @@ -41,6 +41,8 @@ @implementation RCTBridgeProxy { void *_runtime; } +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wobjc-designated-initializers" - (instancetype)initWithViewRegistry:(RCTViewRegistry *)viewRegistry moduleRegistry:(RCTModuleRegistry *)moduleRegistry bundleManager:(RCTBundleManager *)bundleManager @@ -61,8 +63,10 @@ - (instancetype)initWithViewRegistry:(RCTViewRegistry *)viewRegistry _runtime = runtime; _launchOptions = [launchOptions copy]; } + return self; } +#pragma clang diagnostic pop - (void)dispatchBlock:(dispatch_block_t)block queue:(dispatch_queue_t)queue { @@ -414,6 +418,10 @@ @implementation RCTUIManagerProxy { RCTViewRegistry *_viewRegistry; NSMutableDictionary *_legacyViewRegistry; } + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wobjc-designated-initializers" + - (instancetype)initWithViewRegistry:(RCTViewRegistry *)viewRegistry { self = [super self]; @@ -424,6 +432,8 @@ - (instancetype)initWithViewRegistry:(RCTViewRegistry *)viewRegistry return self; } +#pragma clang diagnostic pop + /** * RCTViewRegistry */ diff --git a/packages/react-native/React/Base/RCTCallInvoker.mm b/packages/react-native/React/Base/RCTCallInvoker.mm index f2043bd78cb24d..e60bee482c7512 100644 --- a/packages/react-native/React/Base/RCTCallInvoker.mm +++ b/packages/react-native/React/Base/RCTCallInvoker.mm @@ -11,6 +11,11 @@ @implementation RCTCallInvoker { std::shared_ptr _callInvoker; } +- (instancetype)init +{ + return [self initWithCallInvoker:nullptr]; +} + - (instancetype)initWithCallInvoker:(std::shared_ptr)callInvoker { if (self = [super init]) { diff --git a/packages/react-native/React/Base/RCTModuleData.h b/packages/react-native/React/Base/RCTModuleData.h index 801cc4c269746b..e8d6f04617fb8f 100644 --- a/packages/react-native/React/Base/RCTModuleData.h +++ b/packages/react-native/React/Base/RCTModuleData.h @@ -34,7 +34,7 @@ typedef id (^RCTBridgeModuleProvider)(void); moduleRegistry:(RCTModuleRegistry *)moduleRegistry viewRegistry_DEPRECATED:(RCTViewRegistry *)viewRegistry_DEPRECATED bundleManager:(RCTBundleManager *)bundleManager - callableJSModules:(RCTCallableJSModules *)callableJSModules; + callableJSModules:(RCTCallableJSModules *)callableJSModules NS_DESIGNATED_INITIALIZER; - (instancetype)initWithModuleInstance:(id)instance bridge:(RCTBridge *)bridge diff --git a/packages/react-native/React/Base/RCTModuleData.mm b/packages/react-native/React/Base/RCTModuleData.mm index 6855be2368aabe..2b6e15878afec6 100644 --- a/packages/react-native/React/Base/RCTModuleData.mm +++ b/packages/react-native/React/Base/RCTModuleData.mm @@ -53,8 +53,21 @@ @implementation RCTModuleData { @synthesize instance = _instance; @synthesize methodQueue = _methodQueue; -- (void)setUp +- (void)_setUpWithBridge:(RCTBridge *)bridge + moduleRegistry:(RCTModuleRegistry *)moduleRegistry + viewRegistry_DEPRECATED:(RCTViewRegistry *)viewRegistry_DEPRECATED + bundleManager:(RCTBundleManager *)bundleManager + callableJSModules:(RCTCallableJSModules *)callableJSModules { + // start with the ivars + { + _bridge = bridge; + _moduleRegistry = moduleRegistry; + _viewRegistry_DEPRECATED = viewRegistry_DEPRECATED; + _bundleManager = bundleManager; + _callableJSModules = callableJSModules; + } + _implementsBatchDidComplete = [_moduleClass instancesRespondToSelector:@selector(batchDidComplete)]; // If a module overrides `constantsToExport` and doesn't implement `requiresMainQueueSetup`, then we must assume @@ -86,35 +99,17 @@ - (instancetype)initWithModuleClass:(Class)moduleClass viewRegistry_DEPRECATED:(RCTViewRegistry *)viewRegistry_DEPRECATED bundleManager:(RCTBundleManager *)bundleManager callableJSModules:(RCTCallableJSModules *)callableJSModules -{ - return [self _initWithModuleClass:moduleClass - moduleProvider:^id { - return [moduleClass new]; - } - bridge:bridge - moduleRegistry:moduleRegistry - viewRegistry_DEPRECATED:viewRegistry_DEPRECATED - bundleManager:bundleManager - callableJSModules:callableJSModules]; -} - -- (instancetype)_initWithModuleClass:(Class)moduleClass - moduleProvider:(RCTBridgeModuleProvider)moduleProvider - bridge:(RCTBridge *)bridge - moduleRegistry:(RCTModuleRegistry *)moduleRegistry - viewRegistry_DEPRECATED:(RCTViewRegistry *)viewRegistry_DEPRECATED - bundleManager:(RCTBundleManager *)bundleManager - callableJSModules:(RCTCallableJSModules *)callableJSModules { if (self = [super init]) { - _bridge = bridge; _moduleClass = moduleClass; - _moduleProvider = [moduleProvider copy]; - _moduleRegistry = moduleRegistry; - _viewRegistry_DEPRECATED = viewRegistry_DEPRECATED; - _bundleManager = bundleManager; - _callableJSModules = callableJSModules; - [self setUp]; + _moduleProvider = [^id { + return [moduleClass new]; + } copy]; + [self _setUpWithBridge:bridge + moduleRegistry:moduleRegistry + viewRegistry_DEPRECATED:viewRegistry_DEPRECATED + bundleManager:bundleManager + callableJSModules:callableJSModules]; } return self; } @@ -127,14 +122,13 @@ - (instancetype)initWithModuleInstance:(id)instance callableJSModules:(RCTCallableJSModules *)callableJSModules { if (self = [super init]) { - _bridge = bridge; _instance = instance; _moduleClass = [instance class]; - _moduleRegistry = moduleRegistry; - _viewRegistry_DEPRECATED = viewRegistry_DEPRECATED; - _bundleManager = bundleManager; - _callableJSModules = callableJSModules; - [self setUp]; + [self _setUpWithBridge:bridge + moduleRegistry:moduleRegistry + viewRegistry_DEPRECATED:viewRegistry_DEPRECATED + bundleManager:bundleManager + callableJSModules:callableJSModules]; } return self; } diff --git a/packages/react-native/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingProxyRootView.h b/packages/react-native/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingProxyRootView.h index 02092dd0449f44..82f2adbeb7a5c6 100644 --- a/packages/react-native/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingProxyRootView.h +++ b/packages/react-native/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingProxyRootView.h @@ -39,6 +39,13 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, assign) NSTimeInterval loadingViewFadeDuration; @property (nonatomic, assign) CGSize minimumSize; +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; +- (instancetype)initWithFrame:(CGRect)frame NS_UNAVAILABLE; +- (instancetype)initWithCoder:(NSCoder *)aDecoder NS_UNAVAILABLE; +- (instancetype)initWithSurface:(id)surface + sizeMeasureMode:(RCTSurfaceSizeMeasureMode)sizeMeasureMode NS_UNAVAILABLE; + - (instancetype)initWithSurface:(id)surface NS_DESIGNATED_INITIALIZER; - (void)cancelTouches; diff --git a/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost.h b/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost.h index 37bef80f625763..8d8bcd5fcb1a0e 100644 --- a/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost.h +++ b/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost.h @@ -69,6 +69,9 @@ typedef std::shared_ptr (^RCTHostJSEngineProv jsEngineProvider:(RCTHostJSEngineProvider)jsEngineProvider launchOptions:(nullable NSDictionary *)launchOptions __deprecated; +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; + @property (nonatomic, weak, nullable) id runtimeDelegate; @property (nonatomic, readonly) RCTSurfacePresenter *surfacePresenter; From 3a68f14ac2b1c4d0de84c21dbe3f52e0764f29b4 Mon Sep 17 00:00:00 2001 From: Phillip Pan Date: Thu, 31 Oct 2024 00:56:21 -0700 Subject: [PATCH 010/220] cleanup enabled_automatic_interop_android (#47321) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47321 Changelog: [Internal] this seems to be the last callsite where we read the ReactNativeConfig from the contextContainer. i don't think this killswitch should block cleanup of the ReactNativeConfig, so maybe we can just remove this? Reviewed By: cortinico Differential Revision: D65192744 fbshipit-source-id: d8b595edb6fecce05e67abc257d98805daa16a9a --- .../react/config/ReactNativeConfig.cpp | 3 --- .../ComponentDescriptorRegistry.cpp | 23 ++++--------------- 2 files changed, 5 insertions(+), 21 deletions(-) diff --git a/packages/react-native/ReactCommon/react/config/ReactNativeConfig.cpp b/packages/react-native/ReactCommon/react/config/ReactNativeConfig.cpp index dbeae137424e88..7838f19c4c2384 100644 --- a/packages/react-native/ReactCommon/react/config/ReactNativeConfig.cpp +++ b/packages/react-native/ReactCommon/react/config/ReactNativeConfig.cpp @@ -10,9 +10,6 @@ namespace facebook::react { bool EmptyReactNativeConfig::getBool(const std::string& param) const { - if (param == "react_fabric:enabled_automatic_interop_android") { - return true; - } return false; } diff --git a/packages/react-native/ReactCommon/react/renderer/componentregistry/ComponentDescriptorRegistry.cpp b/packages/react-native/ReactCommon/react/renderer/componentregistry/ComponentDescriptorRegistry.cpp index cbf6bcc1bd506f..3c5487b240de68 100644 --- a/packages/react-native/ReactCommon/react/renderer/componentregistry/ComponentDescriptorRegistry.cpp +++ b/packages/react-native/ReactCommon/react/renderer/componentregistry/ComponentDescriptorRegistry.cpp @@ -9,7 +9,6 @@ #include "componentNameByReactViewName.h" -#include #include #include #include @@ -84,23 +83,11 @@ const ComponentDescriptor& ComponentDescriptorRegistry::at( } if (it == _registryByName.end()) { - auto reactNativeConfig_ = - contextContainer_->at>( - "ReactNativeConfig"); - if (reactNativeConfig_->getBool( - "react_fabric:enabled_automatic_interop_android")) { - auto componentDescriptor = std::make_shared< - const UnstableLegacyViewManagerAutomaticComponentDescriptor>( - parameters_, unifiedComponentName); - registerComponentDescriptor(componentDescriptor); - return *_registryByName.find(unifiedComponentName)->second; - } else if (_fallbackComponentDescriptor == nullptr) { - throw std::invalid_argument( - ("Unable to find componentDescriptor for " + unifiedComponentName) - .c_str()); - } else { - return *_fallbackComponentDescriptor.get(); - } + auto componentDescriptor = std::make_shared< + const UnstableLegacyViewManagerAutomaticComponentDescriptor>( + parameters_, unifiedComponentName); + registerComponentDescriptor(componentDescriptor); + return *_registryByName.find(unifiedComponentName)->second; } return *it->second; From 4d90f84869b680d65a40dc52ff3c5c1e30c17fe0 Mon Sep 17 00:00:00 2001 From: Phillip Pan Date: Thu, 31 Oct 2024 00:56:21 -0700 Subject: [PATCH 011/220] clean up unused callsites to contextContainer->at (#47322) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47322 Changelog: [Internal] these callsites were causing crashes in new bridgeless integrations, it appears they are not used, so cleaning up. after this, we can remove all callsites that insert ReactNativeConfig to the contextContainer. Reviewed By: javache Differential Revision: D65191733 fbshipit-source-id: 94e694ef27249773c2a39bd77f316f8f5cc2b1fb --- packages/react-native/React/Fabric/RCTScheduler.mm | 3 --- packages/react-native/React/Fabric/RCTSurfacePresenter.mm | 3 --- .../ReactCommon/react/renderer/scheduler/Scheduler.cpp | 4 ---- .../ReactCommon/react/renderer/scheduler/Scheduler.h | 2 -- 4 files changed, 12 deletions(-) diff --git a/packages/react-native/React/Fabric/RCTScheduler.mm b/packages/react-native/React/Fabric/RCTScheduler.mm index 016af6dd209648..1f09f1a60b77e5 100644 --- a/packages/react-native/React/Fabric/RCTScheduler.mm +++ b/packages/react-native/React/Fabric/RCTScheduler.mm @@ -114,9 +114,6 @@ @implementation RCTScheduler { - (instancetype)initWithToolbox:(SchedulerToolbox)toolbox { if (self = [super init]) { - auto reactNativeConfig = - toolbox.contextContainer->at>("ReactNativeConfig"); - _delegateProxy = std::make_unique((__bridge void *)self); if (ReactNativeFeatureFlags::enableLayoutAnimationsOnIOS()) { diff --git a/packages/react-native/React/Fabric/RCTSurfacePresenter.mm b/packages/react-native/React/Fabric/RCTSurfacePresenter.mm index a99e30be188853..dbea5607fb9874 100644 --- a/packages/react-native/React/Fabric/RCTSurfacePresenter.mm +++ b/packages/react-native/React/Fabric/RCTSurfacePresenter.mm @@ -26,7 +26,6 @@ #import #import -#import #import #import #import @@ -226,8 +225,6 @@ - (BOOL)resume - (RCTScheduler *)_createScheduler { - auto reactNativeConfig = _contextContainer->at>("ReactNativeConfig"); - auto componentRegistryFactory = [factory = wrapManagedObject(_mountingManager.componentViewRegistry.componentViewFactory)]( const EventDispatcher::Weak &eventDispatcher, const ContextContainer::Shared &contextContainer) { diff --git a/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.cpp b/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.cpp index 3519fa025d77cb..58e2805de36d06 100644 --- a/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.cpp +++ b/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.cpp @@ -31,10 +31,6 @@ Scheduler::Scheduler( runtimeExecutor_ = schedulerToolbox.runtimeExecutor; contextContainer_ = schedulerToolbox.contextContainer; - reactNativeConfig_ = - contextContainer_->at>( - "ReactNativeConfig"); - // Creating a container for future `EventDispatcher` instance. eventDispatcher_ = std::make_shared>(); diff --git a/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.h b/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.h index 0fb2394f8e4ff2..c75f98de523346 100644 --- a/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.h +++ b/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.h @@ -11,7 +11,6 @@ #include #include -#include #include #include #include @@ -120,7 +119,6 @@ class Scheduler final : public UIManagerDelegate { SharedComponentDescriptorRegistry componentDescriptorRegistry_; RuntimeExecutor runtimeExecutor_; std::shared_ptr uiManager_; - std::shared_ptr reactNativeConfig_; std::vector> commitHooks_; From 9a3958a619fddb75ed3c6eddebd94f11c0d00e9f Mon Sep 17 00:00:00 2001 From: hexboy Date: Thu, 31 Oct 2024 01:32:39 -0700 Subject: [PATCH 012/220] fix(Android, iOS): Fix AnsiHighlight Style in RTL Layout (#47230) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: This pull request fixes a style bug in the AnsiHighlight component when the application is in Right-To-Left (RTL) mode. The adjustments ensure that text highlighting is visually consistent and functions properly across all layout modes. ### Before | Android RTL | iOS RTL | Android LTR | iOS LTR | |----------|----------|----------|----------| | ![Before-RTL-Android](https://github.com/user-attachments/assets/059e30e7-f6da-4a07-9c91-08d952c6a4b6) | ![Before-RTL-iOS](https://github.com/user-attachments/assets/a325c838-1510-4415-bd1f-c419ce75e7e2) | ![Before-LTR-Android](https://github.com/user-attachments/assets/26494fb1-71dd-4fae-a75c-381eead211de) | ![Before-LTR-iOS](https://github.com/user-attachments/assets/72bba2d8-f70f-4e16-b771-4af995370d26) | ### After | Android RTL | iOS RTL | Android LTR | iOS LTR | |----------|----------|----------|----------| | ![After-RTL-Android](https://github.com/user-attachments/assets/d2f674c2-7aec-454f-903a-33fcd3e93240) | ![After-RTL-iOS](https://github.com/user-attachments/assets/e3735e79-7323-48e8-8213-f0871bec0ca5) | ![After-LTR-Android](https://github.com/user-attachments/assets/18c80754-8743-4282-8f95-1e9772d51a36) | ![After-LTR-iOS](https://github.com/user-attachments/assets/068f4bd8-df4e-420b-8949-c20dff9c2bc8) | ## Changelog: [GENERAL] [Fixed] - AnsiHighlight style in RTL layout [ANDROID] [ADDED] - Trigger Java GC on app reload Pull Request resolved: https://github.com/facebook/react-native/pull/43813 Test Plan: Open an app, create a Java module that holds a few objects, add `finalize()` methods to those objects and log their deletion. Reload the app to see the logs, compare before vs after. Reviewed By: rshest Differential Revision: D65418163 Pulled By: javache fbshipit-source-id: 7597548790577dfc542b57f59578ae48df543b14 --- .../facebook/react/devsupport/DevSupportManagerBase.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerBase.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerBase.java index f91d9add84937c..fe383544cd4860 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerBase.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerBase.java @@ -593,6 +593,14 @@ public void onReactInstanceDestroyed(ReactContext reactContext) { // for this manager resetCurrentContext(null); } + + // If some JNI types (e.g. jni::HybridClass) are used in JSI (e.g. jsi::HostObject), they might + // not be immediately deleted on an app refresh as both Java and JavaScript are + // garbage-collected languages and the memory might float around for a while. For C++ + // developers, this will be hard to debug as destructors might be called at a later point, so in + // this case we trigger a Java GC to maybe eagerly collect such objects when the app + // reloads. + System.gc(); } @Override From 4da586ead99f421be71ca8b89ca891ed6fb90a99 Mon Sep 17 00:00:00 2001 From: Parsa Nasirimehr Date: Mon, 4 Nov 2024 06:57:47 -0800 Subject: [PATCH 034/220] chore(Android): Migrate DebugOverlayTag and ReactDebugOverlayTag to Kotlin (#47362) Summary: I believe these two were the last items under `com.facebook.debug` that were still Java. I thought about making DebugOverlayTag a Data class, but i will leave it up to the reviewer to decide if it would be needed or not. ## Changelog: [INTERNAL] [FIXED] - Migrate DebugOverlayTag and ReactDebugOverlayTag to Kotlin Pull Request resolved: https://github.com/facebook/react-native/pull/47362 Test Plan: `./gradlew test`: Screenshot 2024-11-02 at 18 45 45 Reviewed By: javache Differential Revision: D65417984 Pulled By: cortinico fbshipit-source-id: e39224e40bde281498fdbed1609a03b264967396 --- .../debugoverlay/model/DebugOverlayTag.java | 30 ------------- .../debugoverlay/model/DebugOverlayTag.kt | 21 +++++++++ .../debug/tags/ReactDebugOverlayTags.java | 38 ---------------- .../debug/tags/ReactDebugOverlayTags.kt | 45 +++++++++++++++++++ 4 files changed, 66 insertions(+), 68 deletions(-) delete mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/debug/debugoverlay/model/DebugOverlayTag.java create mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/debug/debugoverlay/model/DebugOverlayTag.kt delete mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/debug/tags/ReactDebugOverlayTags.java create mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/debug/tags/ReactDebugOverlayTags.kt diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/debug/debugoverlay/model/DebugOverlayTag.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/debug/debugoverlay/model/DebugOverlayTag.java deleted file mode 100644 index 4ee3353ffa8bc9..00000000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/debug/debugoverlay/model/DebugOverlayTag.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and 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.debug.debugoverlay.model; - -import javax.annotation.concurrent.Immutable; - -/** Tag for a debug overlay log message. Name must be unique. */ -@Immutable -public class DebugOverlayTag { - - /** Name of tag. */ - public final String name; - - /** Description to display in settings. */ - public final String description; - - /** Color for tag display. */ - public final int color; - - public DebugOverlayTag(String name, String description, int color) { - this.name = name; - this.description = description; - this.color = color; - } -} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/debug/debugoverlay/model/DebugOverlayTag.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/debug/debugoverlay/model/DebugOverlayTag.kt new file mode 100644 index 00000000000000..7aa4c8d645b137 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/debug/debugoverlay/model/DebugOverlayTag.kt @@ -0,0 +1,21 @@ +/* + * Copyright (c) Meta Platforms, Inc. and 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.debug.debugoverlay.model + +/** + * Tag for a debug overlay log message. Name must be unique. + * + * @param name Name of tag. + * @param description Description to display in settings. + * @param color Color for tag display. + */ +public class DebugOverlayTag( + public val name: String, + public val description: String, + public val color: Int, +) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/debug/tags/ReactDebugOverlayTags.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/debug/tags/ReactDebugOverlayTags.java deleted file mode 100644 index 9df0352aa422e4..00000000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/debug/tags/ReactDebugOverlayTags.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and 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.debug.tags; - -import android.graphics.Color; -import com.facebook.debug.debugoverlay.model.DebugOverlayTag; - -/** Category for debug overlays. */ -public class ReactDebugOverlayTags { - - public static final DebugOverlayTag PERFORMANCE = - new DebugOverlayTag("Performance", "Markers for Performance", Color.GREEN); - public static final DebugOverlayTag NAVIGATION = - new DebugOverlayTag("Navigation", "Tag for navigation", Color.rgb(0x9C, 0x27, 0xB0)); - public static final DebugOverlayTag RN_CORE = - new DebugOverlayTag("RN Core", "Tag for React Native Core", Color.BLACK); - public static final DebugOverlayTag BRIDGE_CALLS = - new DebugOverlayTag( - "Bridge Calls", "JS to Java calls (warning: this is spammy)", Color.MAGENTA); - public static final DebugOverlayTag NATIVE_MODULE = - new DebugOverlayTag("Native Module", "Native Module init", Color.rgb(0x80, 0x00, 0x80)); - public static final DebugOverlayTag UI_MANAGER = - new DebugOverlayTag( - "UI Manager", - "UI Manager View Operations (requires restart\nwarning: this is spammy)", - Color.CYAN); - public static final DebugOverlayTag FABRIC_UI_MANAGER = - new DebugOverlayTag("FabricUIManager", "Fabric UI Manager View Operations", Color.CYAN); - public static final DebugOverlayTag FABRIC_RECONCILER = - new DebugOverlayTag("FabricReconciler", "Reconciler for Fabric", Color.CYAN); - public static final DebugOverlayTag RELAY = - new DebugOverlayTag("Relay", "including prefetching", Color.rgb(0xFF, 0x99, 0x00)); -} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/debug/tags/ReactDebugOverlayTags.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/debug/tags/ReactDebugOverlayTags.kt new file mode 100644 index 00000000000000..4a9b33bae4a5e2 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/debug/tags/ReactDebugOverlayTags.kt @@ -0,0 +1,45 @@ +/* + * Copyright (c) Meta Platforms, Inc. and 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.debug.tags + +import android.graphics.Color +import com.facebook.debug.debugoverlay.model.DebugOverlayTag + +/** Category for debug overlays. */ +public object ReactDebugOverlayTags { + @JvmField + public val PERFORMANCE: DebugOverlayTag = + DebugOverlayTag("Performance", "Markers for Performance", Color.GREEN) + @JvmField + public val NAVIGATION: DebugOverlayTag = + DebugOverlayTag("Navigation", "Tag for navigation", Color.rgb(0x9C, 0x27, 0xB0)) + @JvmField + public val RN_CORE: DebugOverlayTag = + DebugOverlayTag("RN Core", "Tag for React Native Core", Color.BLACK) + @JvmField + public val BRIDGE_CALLS: DebugOverlayTag = + DebugOverlayTag("Bridge Calls", "JS to Java calls (warning: this is spammy)", Color.MAGENTA) + @JvmField + public val NATIVE_MODULE: DebugOverlayTag = + DebugOverlayTag("Native Module", "Native Module init", Color.rgb(0x80, 0x00, 0x80)) + @JvmField + public val UI_MANAGER: DebugOverlayTag = + DebugOverlayTag( + "UI Manager", + "UI Manager View Operations (requires restart\nwarning: this is spammy)", + Color.CYAN) + @JvmField + public val FABRIC_UI_MANAGER: DebugOverlayTag = + DebugOverlayTag("FabricUIManager", "Fabric UI Manager View Operations", Color.CYAN) + @JvmField + public val FABRIC_RECONCILER: DebugOverlayTag = + DebugOverlayTag("FabricReconciler", "Reconciler for Fabric", Color.CYAN) + @JvmField + public val RELAY: DebugOverlayTag = + DebugOverlayTag("Relay", "including prefetching", Color.rgb(0xFF, 0x99, 0x00)) +} From 91df5a4a0fec66c4e31441c8e168a204ae9856cb Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Mon, 4 Nov 2024 08:15:12 -0800 Subject: [PATCH 035/220] surface setup issues in EventBeat and Scheduler (#47355) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47355 changelog: [internal] Reviewed By: rshest Differential Revision: D65333695 fbshipit-source-id: 854dbc3ae52db0093961cbeb81f1f96934eca40d --- .../ReactCommon/react/renderer/core/EventBeat.cpp | 4 ++++ .../react/renderer/scheduler/Scheduler.cpp | 13 +++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/packages/react-native/ReactCommon/react/renderer/core/EventBeat.cpp b/packages/react-native/ReactCommon/react/renderer/core/EventBeat.cpp index 305c2375224919..82f18533a9d8dd 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/EventBeat.cpp +++ b/packages/react-native/ReactCommon/react/renderer/core/EventBeat.cpp @@ -7,6 +7,7 @@ #include "EventBeat.h" +#include #include #include @@ -18,6 +19,9 @@ EventBeat::EventBeat( : ownerBox_(std::move(ownerBox)), runtimeScheduler_(runtimeScheduler) {} void EventBeat::request() const { + react_native_assert( + beatCallback_ && + "Unexpected state: EventBeat::setBeatCallback was not called before EventBeat::request."); isRequested_ = true; } diff --git a/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.cpp b/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.cpp index 58e2805de36d06..28998bd034baea 100644 --- a/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.cpp +++ b/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.cpp @@ -50,17 +50,18 @@ Scheduler::Scheduler( auto weakRuntimeScheduler = contextContainer_->find>( "RuntimeScheduler"); - auto runtimeScheduler = weakRuntimeScheduler.has_value() - ? weakRuntimeScheduler.value().lock() - : nullptr; + react_native_assert( + weakRuntimeScheduler.has_value() && + "Unexpected state: RuntimeScheduler was not provided."); + + auto runtimeScheduler = weakRuntimeScheduler.value().lock(); - if (runtimeScheduler && ReactNativeFeatureFlags::enableUIConsistency()) { + if (ReactNativeFeatureFlags::enableUIConsistency()) { runtimeScheduler->setShadowTreeRevisionConsistencyManager( uiManager->getShadowTreeRevisionConsistencyManager()); } - if (runtimeScheduler && - ReactNativeFeatureFlags::enableReportEventPaintTime()) { + if (ReactNativeFeatureFlags::enableReportEventPaintTime()) { runtimeScheduler->setEventTimingDelegate(eventPerformanceLogger_.get()); } From dc9db01665308ac931967326abfc86deb9ae7e2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Guzm=C3=A1n?= Date: Mon, 4 Nov 2024 08:37:59 -0800 Subject: [PATCH 036/220] feat(image): [android] adding `only-if-cached` cache control option (#47348) Summary: Following up from https://github.com/facebook/react-native/issues/47182, as basic caching control is already in place in Android, it can be extended to include the `only-if-cached` option. We check whether the image is in the cache. If it is, we proceed to load it. Otherwise, we do nothing. ## Changelog: [ANDROID] [ADDED] - Image `only-if-cached` cache control option Pull Request resolved: https://github.com/facebook/react-native/pull/47348 Test Plan: In the `rn-tester`, I added a third example for Android where the third image will never be loaded as the cache policy is set to `only-if-cached` and the image has not been loaded before.
Video demonstrating how the `only-if-cached` options behaves https://github.com/user-attachments/assets/45669e81-5414-4103-8931-138bffa81447
Error from image not found in cache example image
Reviewed By: rshest Differential Revision: D65384639 Pulled By: Abbondanzo fbshipit-source-id: f4a72694f45eb3d7097c350f4a4008a0abf0a1ab --- .../Libraries/Image/ImageSource.d.ts | 2 +- .../Libraries/Image/ImageSource.js | 2 +- .../ReactAndroid/api/ReactAndroid.api | 1 + .../react/modules/fresco/ImageCacheControl.kt | 7 +++++++ .../fresco/ReactOkHttpNetworkFetcher.kt | 3 +++ .../react/views/image/ReactImageView.kt | 11 ++++++++++ .../js/examples/Image/ImageExample.js | 21 ++++++++++++++++--- 7 files changed, 42 insertions(+), 5 deletions(-) diff --git a/packages/react-native/Libraries/Image/ImageSource.d.ts b/packages/react-native/Libraries/Image/ImageSource.d.ts index 1b7d51729b5d42..2d47b6ba194b09 100644 --- a/packages/react-native/Libraries/Image/ImageSource.d.ts +++ b/packages/react-native/Libraries/Image/ImageSource.d.ts @@ -51,7 +51,7 @@ export interface ImageURISource { * to a URL load request, no attempt is made to load the data from the originating source, * and the load is considered to have failed. * - * @platform ios (for `force-cache` and `only-if-cached`) + * @platform ios (for `force-cache`) */ cache?: 'default' | 'reload' | 'force-cache' | 'only-if-cached' | undefined; /** diff --git a/packages/react-native/Libraries/Image/ImageSource.js b/packages/react-native/Libraries/Image/ImageSource.js index a489de2ff07409..1698c945b0b8e1 100644 --- a/packages/react-native/Libraries/Image/ImageSource.js +++ b/packages/react-native/Libraries/Image/ImageSource.js @@ -66,7 +66,7 @@ export interface ImageURISource { * to a URL load request, no attempt is made to load the data from the originating source, * and the load is considered to have failed. * - * @platform ios (for `force-cache` and `only-if-cached`) + * @platform ios (for `force-cache`) */ +cache?: ?('default' | 'reload' | 'force-cache' | 'only-if-cached'); diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index e6594e9757936e..9349fd21d89dab 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -3379,6 +3379,7 @@ public final class com/facebook/react/modules/fresco/FrescoModule$Companion { public final class com/facebook/react/modules/fresco/ImageCacheControl : java/lang/Enum { public static final field DEFAULT Lcom/facebook/react/modules/fresco/ImageCacheControl; + public static final field ONLY_IF_CACHED Lcom/facebook/react/modules/fresco/ImageCacheControl; public static final field RELOAD Lcom/facebook/react/modules/fresco/ImageCacheControl; public static fun getEntries ()Lkotlin/enums/EnumEntries; public static fun valueOf (Ljava/lang/String;)Lcom/facebook/react/modules/fresco/ImageCacheControl; diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/fresco/ImageCacheControl.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/fresco/ImageCacheControl.kt index 689edb1d6f013d..acb04ea7beb0a5 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/fresco/ImageCacheControl.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/fresco/ImageCacheControl.kt @@ -15,4 +15,11 @@ public enum class ImageCacheControl { * be used to satisfy a URL load request. */ RELOAD, + /** + * The existing cache data will be used to satisfy a request, regardless of its age or expiration + * date. If there is no existing data in the cache corresponding to a URL load request, no attempt + * is made to load the data from the originating source, and the load is considered to have + * failed. + */ + ONLY_IF_CACHED, } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/fresco/ReactOkHttpNetworkFetcher.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/fresco/ReactOkHttpNetworkFetcher.kt index 49717cfa51ab92..502f220a090695 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/fresco/ReactOkHttpNetworkFetcher.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/fresco/ReactOkHttpNetworkFetcher.kt @@ -43,6 +43,9 @@ internal class ReactOkHttpNetworkFetcher(private val okHttpClient: OkHttpClient) ImageCacheControl.RELOAD -> { cacheControlBuilder.noCache() } + ImageCacheControl.ONLY_IF_CACHED -> { + cacheControlBuilder.onlyIfCached() + } ImageCacheControl.DEFAULT -> { // No-op } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageView.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageView.kt index b384b5e2f2e651..5365d689f5f01b 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageView.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageView.kt @@ -41,6 +41,7 @@ import com.facebook.imagepipeline.image.ImageInfo import com.facebook.imagepipeline.postprocessors.IterativeBoxBlurPostProcessor import com.facebook.imagepipeline.request.BasePostprocessor import com.facebook.imagepipeline.request.ImageRequest +import com.facebook.imagepipeline.request.ImageRequest.RequestLevel import com.facebook.imagepipeline.request.ImageRequestBuilder import com.facebook.imagepipeline.request.Postprocessor import com.facebook.react.bridge.ReactContext @@ -311,10 +312,18 @@ public class ReactImageView( null, "default" -> ImageCacheControl.DEFAULT "reload" -> ImageCacheControl.RELOAD + "only-if-cached" -> ImageCacheControl.ONLY_IF_CACHED else -> ImageCacheControl.DEFAULT } } + private fun computeRequestLevel(cacheControl: ImageCacheControl): RequestLevel { + return when (cacheControl) { + ImageCacheControl.ONLY_IF_CACHED -> RequestLevel.DISK_CACHE + else -> RequestLevel.FULL_FETCH + } + } + public fun setDefaultSource(name: String?) { val newDefaultDrawable = instance.getResourceDrawable(context, name) if (defaultImageDrawable != newDefaultDrawable) { @@ -426,6 +435,7 @@ public class ReactImageView( val imageSource = this.imageSource ?: return val uri = imageSource.uri val cacheControl = imageSource.cacheControl + val requestLevel = computeRequestLevel(cacheControl) val postprocessorList = mutableListOf() iterativeBoxBlurPostProcessor?.let { postprocessorList.add(it) } @@ -445,6 +455,7 @@ public class ReactImageView( .setResizeOptions(resizeOptions) .setAutoRotateEnabled(true) .setProgressiveRenderingEnabled(progressiveRenderingEnabled) + .setLowestPermittedRequestLevel(requestLevel) if (resizeMethod == ImageResizeMethod.NONE) { imageRequestBuilder.setDownsampleOverride(DownsampleMode.NEVER) diff --git a/packages/rn-tester/js/examples/Image/ImageExample.js b/packages/rn-tester/js/examples/Image/ImageExample.js index 814c7312ea775d..81e42ad8adb72e 100644 --- a/packages/rn-tester/js/examples/Image/ImageExample.js +++ b/packages/rn-tester/js/examples/Image/ImageExample.js @@ -659,6 +659,20 @@ function CacheControlAndroidExample(): React.Node { key={reload} /> + + + Only-if-cached + + console.log(e.nativeEvent.error)} + /> + @@ -1091,9 +1105,10 @@ exports.examples = [ }, { title: 'Cache Policy', - description: ('First image will be loaded and will be cached. ' + - 'Second image is the same but will be reloaded if re-rendered ' + - 'as the cache policy is set to reload.': string), + description: `- First image will be loaded and cached. +- Second image is the same but will be reloaded if re-rendered as the cache policy is set to reload. +- Third image will never be loaded as the cache policy is set to only-if-cached and the image has not been loaded before. + `, render: function (): React.Node { return ; }, From cc1d2853fb2b64adfb884cb30c8d22ce0260be15 Mon Sep 17 00:00:00 2001 From: oddlyspaced Date: Mon, 4 Nov 2024 10:06:10 -0800 Subject: [PATCH 037/220] feat(Android): add support for invert colors check on android accessibility (#47341) Summary: This PR provides a fix for the long existing issue of missing check for invert color in accessibility options on Android. Reference Issue : https://github.com/facebook/react-native/issues/30870 ## Changelog: - Added native module code to check for invert color settings value - Updated js module to return a proper promise instead of default false for isInvertColorsEnabled() Pick one each for the category and type tags: [ANDROID] [FIXED] - Missing isInvertColorsEnabled implementation for Android For more details, see: https://reactnative.dev/contributing/changelogs-in-pull-requests Pull Request resolved: https://github.com/facebook/react-native/pull/47341 Test Plan: Tested on OnePlus 12 with Android 14 and Pixel 6 with Android 15. The try catch exists because in some cases if the switch hasn't been toggled before the android system raises the missing settings exception. Reviewed By: cortinico, fabriziocucci Differential Revision: D65419632 Pulled By: javache fbshipit-source-id: ddb103445a9d0f318e52ba9d23750140ce5a7ed0 --- .../AccessibilityInfo/AccessibilityInfo.js | 9 +++++- .../AccessibilityInfoModule.kt | 29 +++++++++++++++++++ .../specs/modules/NativeAccessibilityInfo.js | 3 ++ .../Accessibility/AccessibilityExample.js | 13 +++++---- 4 files changed, 47 insertions(+), 7 deletions(-) diff --git a/packages/react-native/Libraries/Components/AccessibilityInfo/AccessibilityInfo.js b/packages/react-native/Libraries/Components/AccessibilityInfo/AccessibilityInfo.js index 73940778356f57..1e7c70d265a628 100644 --- a/packages/react-native/Libraries/Components/AccessibilityInfo/AccessibilityInfo.js +++ b/packages/react-native/Libraries/Components/AccessibilityInfo/AccessibilityInfo.js @@ -55,6 +55,7 @@ const EventNames: Map< ['highTextContrastChanged', 'highTextContrastDidChange'], ['screenReaderChanged', 'touchExplorationDidChange'], ['accessibilityServiceChanged', 'accessibilityServiceDidChange'], + ['invertColorsChanged', 'invertColorDidChange'], ]) : new Map([ ['announcementFinished', 'announcementFinished'], @@ -138,7 +139,13 @@ const AccessibilityInfo = { */ isInvertColorsEnabled(): Promise { if (Platform.OS === 'android') { - return Promise.resolve(false); + return new Promise((resolve, reject) => { + if (NativeAccessibilityInfoAndroid?.isInvertColorsEnabled != null) { + NativeAccessibilityInfoAndroid.isInvertColorsEnabled(resolve); + } else { + reject(null); + } + }); } else { return new Promise((resolve, reject) => { if (NativeAccessibilityManagerIOS != null) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/accessibilityinfo/AccessibilityInfoModule.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/accessibilityinfo/AccessibilityInfoModule.kt index 6a44b60ed51091..4f8ed62c7cdf51 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/accessibilityinfo/AccessibilityInfoModule.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/accessibilityinfo/AccessibilityInfoModule.kt @@ -86,6 +86,7 @@ internal class AccessibilityInfoModule(context: ReactApplicationContext) : private var touchExplorationEnabled = false private var accessibilityServiceEnabled = false private var recommendedTimeout = 0 + private var invertColorsEnabled = false init { val appContext = context.applicationContext @@ -111,6 +112,17 @@ internal class AccessibilityInfoModule(context: ReactApplicationContext) : return parsedValue == 0f } + @get:TargetApi(Build.VERSION_CODES.LOLLIPOP) + private val isInvertColorsEnabledValue: Boolean + get() { + try { + return Settings.Secure.getInt( + contentResolver, Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED) == 1 + } catch (e: Settings.SettingNotFoundException) { + return false + } + } + @get:TargetApi(Build.VERSION_CODES.LOLLIPOP) private val isHighTextContrastEnabledValue: Boolean get() { @@ -125,6 +137,10 @@ internal class AccessibilityInfoModule(context: ReactApplicationContext) : successCallback.invoke(reduceMotionEnabled) } + override fun isInvertColorsEnabled(successCallback: Callback) { + successCallback.invoke(invertColorsEnabled) + } + override fun isHighTextContrastEnabled(successCallback: Callback) { successCallback.invoke(highTextContrastEnabled) } @@ -148,6 +164,17 @@ internal class AccessibilityInfoModule(context: ReactApplicationContext) : } } + private fun updateAndSendInvertColorsChangeEvent() { + val isInvertColorsEnabled = isInvertColorsEnabledValue + if (invertColorsEnabled != isInvertColorsEnabled) { + invertColorsEnabled = isInvertColorsEnabled + val reactApplicationContext = getReactApplicationContextIfActiveOrWarn() + if (reactApplicationContext != null) { + reactApplicationContext.emitDeviceEvent(INVERT_COLOR_EVENT_NAME, invertColorsEnabled) + } + } + } + private fun updateAndSendHighTextContrastChangeEvent() { val isHighTextContrastEnabled = isHighTextContrastEnabledValue if (highTextContrastEnabled != isHighTextContrastEnabled) { @@ -199,6 +226,7 @@ internal class AccessibilityInfoModule(context: ReactApplicationContext) : updateAndSendAccessibilityServiceChangeEvent(accessibilityManager?.isEnabled == true) updateAndSendReduceMotionChangeEvent() updateAndSendHighTextContrastChangeEvent() + updateAndSendInvertColorsChangeEvent() } @TargetApi(Build.VERSION_CODES.LOLLIPOP) @@ -263,5 +291,6 @@ internal class AccessibilityInfoModule(context: ReactApplicationContext) : private const val ACCESSIBILITY_SERVICE_EVENT_NAME = "accessibilityServiceDidChange" private const val ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED_CONSTANT = "high_text_contrast_enabled" // constant is marked with @hide + private const val INVERT_COLOR_EVENT_NAME = "invertColorDidChange" } } diff --git a/packages/react-native/src/private/specs/modules/NativeAccessibilityInfo.js b/packages/react-native/src/private/specs/modules/NativeAccessibilityInfo.js index dfb0a27952aeb1..07b4b17622abe4 100644 --- a/packages/react-native/src/private/specs/modules/NativeAccessibilityInfo.js +++ b/packages/react-native/src/private/specs/modules/NativeAccessibilityInfo.js @@ -16,6 +16,9 @@ export interface Spec extends TurboModule { +isReduceMotionEnabled: ( onSuccess: (isReduceMotionEnabled: boolean) => void, ) => void; + +isInvertColorsEnabled?: ( + onSuccess: (isInvertColorsEnabled: boolean) => void, + ) => void; +isHighTextContrastEnabled?: ( onSuccess: (isHighTextContrastEnabled: boolean) => void, ) => void; diff --git a/packages/rn-tester/js/examples/Accessibility/AccessibilityExample.js b/packages/rn-tester/js/examples/Accessibility/AccessibilityExample.js index 308ec71e43ba98..7bbe1c5d8c9e86 100644 --- a/packages/rn-tester/js/examples/Accessibility/AccessibilityExample.js +++ b/packages/rn-tester/js/examples/Accessibility/AccessibilityExample.js @@ -1341,12 +1341,6 @@ class EnabledExamples extends React.Component<{}> { eventListener="grayscaleChanged" /> - - - { /> + + + + Date: Mon, 4 Nov 2024 10:26:47 -0800 Subject: [PATCH 038/220] Stable API - Make ReactDevToolsSettingsManagerModule and ReactDevToolsRuntimeSettingsModule internal (#47373) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47373 Users should not depend on `ReactDevToolsSettingsManagerModule` directly hence I'm making it internal. I expect to breakages in OSS as there no usages at all: https://github.com/search?type=code&q=NOT+is%3Afork+NOT+org%3Afacebook+com.facebook.react.modules.reactdevtoolssettings.ReactDevToolsSettingsManagerModule https://github.com/search?type=code&q=NOT+is%3Afork+NOT+org%3Afacebook+com.facebook.react.modules.devtoolsruntimesettings.ReactDevToolsRuntimeSettingsModule Changelog: [Android] [Breaking] - Stable API - Make ReactDevToolsSettingsManagerModule and ReactDevToolsRuntimeSettingsModule internal Reviewed By: javache Differential Revision: D65421030 fbshipit-source-id: e9d701af6cde25133f7b3ff9b07b678a7710852c --- .../ReactAndroid/api/ReactAndroid.api | 22 ------------------- .../ReactDevToolsRuntimeSettingsModule.kt | 6 ++--- .../ReactDevToolsSettingsManagerModule.kt | 10 ++++----- 3 files changed, 8 insertions(+), 30 deletions(-) diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 9349fd21d89dab..428b39a8c741dd 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -3319,17 +3319,6 @@ public final class com/facebook/react/modules/devloading/DevLoadingModule : com/ public final class com/facebook/react/modules/devloading/DevLoadingModule$Companion { } -public final class com/facebook/react/modules/devtoolsruntimesettings/ReactDevToolsRuntimeSettingsModule : com/facebook/fbreact/specs/NativeReactDevToolsRuntimeSettingsModuleSpec { - public static final field Companion Lcom/facebook/react/modules/devtoolsruntimesettings/ReactDevToolsRuntimeSettingsModule$Companion; - public static final field NAME Ljava/lang/String; - public fun (Lcom/facebook/react/bridge/ReactApplicationContext;)V - public fun getReloadAndProfileConfig ()Lcom/facebook/react/bridge/WritableMap; - public fun setReloadAndProfileConfig (Lcom/facebook/react/bridge/ReadableMap;)V -} - -public final class com/facebook/react/modules/devtoolsruntimesettings/ReactDevToolsRuntimeSettingsModule$Companion { -} - public class com/facebook/react/modules/dialog/AlertFragment : androidx/fragment/app/DialogFragment, android/content/DialogInterface$OnClickListener { public fun ()V public fun (Lcom/facebook/react/modules/dialog/DialogModule$AlertFragmentListener;Landroid/os/Bundle;)V @@ -3616,17 +3605,6 @@ public final class com/facebook/react/modules/permissions/PermissionsModule : co public final class com/facebook/react/modules/permissions/PermissionsModule$Companion { } -public final class com/facebook/react/modules/reactdevtoolssettings/ReactDevToolsSettingsManagerModule : com/facebook/fbreact/specs/NativeReactDevToolsSettingsManagerSpec { - public static final field Companion Lcom/facebook/react/modules/reactdevtoolssettings/ReactDevToolsSettingsManagerModule$Companion; - public static final field NAME Ljava/lang/String; - public fun (Lcom/facebook/react/bridge/ReactApplicationContext;)V - public fun getGlobalHookSettings ()Ljava/lang/String; - public fun setGlobalHookSettings (Ljava/lang/String;)V -} - -public final class com/facebook/react/modules/reactdevtoolssettings/ReactDevToolsSettingsManagerModule$Companion { -} - public final class com/facebook/react/modules/share/ShareModule : com/facebook/fbreact/specs/NativeShareModuleSpec { public static final field Companion Lcom/facebook/react/modules/share/ShareModule$Companion; public static final field ERROR_INVALID_CONTENT Ljava/lang/String; diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/devtoolsruntimesettings/ReactDevToolsRuntimeSettingsModule.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/devtoolsruntimesettings/ReactDevToolsRuntimeSettingsModule.kt index 216bbcefb56b61..188fc6d8bd2bdf 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/devtoolsruntimesettings/ReactDevToolsRuntimeSettingsModule.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/devtoolsruntimesettings/ReactDevToolsRuntimeSettingsModule.kt @@ -22,13 +22,13 @@ private class Settings { @DoNotStripAny @ReactModule(name = NativeReactDevToolsRuntimeSettingsModuleSpec.NAME) -public class ReactDevToolsRuntimeSettingsModule(reactContext: ReactApplicationContext?) : +internal class ReactDevToolsRuntimeSettingsModule(reactContext: ReactApplicationContext?) : NativeReactDevToolsRuntimeSettingsModuleSpec(reactContext) { - public companion object { + companion object { // static to persist across Turbo Module reloads private val settings = Settings() - public const val NAME: String = NativeReactDevToolsRuntimeSettingsModuleSpec.NAME + const val NAME: String = NativeReactDevToolsRuntimeSettingsModuleSpec.NAME } override fun setReloadAndProfileConfig(map: ReadableMap) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/reactdevtoolssettings/ReactDevToolsSettingsManagerModule.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/reactdevtoolssettings/ReactDevToolsSettingsManagerModule.kt index 5746061a0f30ab..b2bc47a46457fe 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/reactdevtoolssettings/ReactDevToolsSettingsManagerModule.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/reactdevtoolssettings/ReactDevToolsSettingsManagerModule.kt @@ -14,20 +14,20 @@ import com.facebook.react.bridge.ReactApplicationContext import com.facebook.react.module.annotations.ReactModule @ReactModule(name = NativeReactDevToolsSettingsManagerSpec.NAME) -public class ReactDevToolsSettingsManagerModule(reactContext: ReactApplicationContext) : +internal class ReactDevToolsSettingsManagerModule(reactContext: ReactApplicationContext) : NativeReactDevToolsSettingsManagerSpec(reactContext) { private val sharedPreferences: SharedPreferences = reactContext.getSharedPreferences(SHARED_PREFERENCES_PREFIX, Context.MODE_PRIVATE) - public override fun setGlobalHookSettings(settings: String): Unit = + override fun setGlobalHookSettings(settings: String): Unit = sharedPreferences.edit().putString(KEY_HOOK_SETTINGS, settings).apply() - public override fun getGlobalHookSettings(): String? = + override fun getGlobalHookSettings(): String? = sharedPreferences.getString(KEY_HOOK_SETTINGS, null) - public companion object { - public const val NAME: String = NativeReactDevToolsSettingsManagerSpec.NAME + companion object { + const val NAME: String = NativeReactDevToolsSettingsManagerSpec.NAME private const val SHARED_PREFERENCES_PREFIX = "ReactNative__DevToolsSettings" private const val KEY_HOOK_SETTINGS = "HookSettings" } From 44f2a083716205b7560bef2f09d25830e29cd0c5 Mon Sep 17 00:00:00 2001 From: zhongwuzw Date: Mon, 4 Nov 2024 10:26:55 -0800 Subject: [PATCH 039/220] Add png extension only if file exist when load local image (#46971) Summary: FIxes https://github.com/facebook/react-native/issues/46870. To avoid many breaking changes, I modified the logic to add the PNG extension only if the file exists. ## Changelog: [IOS] [FIXED] - Add png extension only if file exist when load local image Pull Request resolved: https://github.com/facebook/react-native/pull/46971 Test Plan: Demo in https://github.com/facebook/react-native/issues/46870 . Reviewed By: blakef Differential Revision: D65276409 Pulled By: cipolleschi fbshipit-source-id: 9e03a36b229f7c336632b5b76a92d9f749c59835 --- packages/react-native/Libraries/Image/RCTImageLoader.mm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/react-native/Libraries/Image/RCTImageLoader.mm b/packages/react-native/Libraries/Image/RCTImageLoader.mm index 68a12d351227ef..165c711d1c6724 100644 --- a/packages/react-native/Libraries/Image/RCTImageLoader.mm +++ b/packages/react-native/Libraries/Image/RCTImageLoader.mm @@ -477,7 +477,10 @@ - (RCTImageURLLoaderRequest *)_loadImageOrDataWithURLRequest:(NSURLRequest *)req // Add missing png extension if (request.URL.fileURL && request.URL.pathExtension.length == 0) { - mutableRequest.URL = [request.URL URLByAppendingPathExtension:@"png"]; + NSURL *pngRequestURL = [request.URL URLByAppendingPathExtension:@"png"]; + if ([[NSFileManager defaultManager] fileExistsAtPath:pngRequestURL.path]) { + mutableRequest.URL = pngRequestURL; + } } if (_redirectDelegate != nil) { mutableRequest.URL = [_redirectDelegate redirectAssetsURL:mutableRequest.URL]; From cba1d4bae7285ba160b05f31ca18cfa0b91e9ef5 Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Mon, 4 Nov 2024 11:01:46 -0800 Subject: [PATCH 040/220] Stable API - Make InteropModuleRegistry internal (#47374) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47374 I've converted this class to Kotlin + made it `internal` as it should not be exposed publicly. This class is part of the iterop layer for the New Architecture. Marked as breaking but I expect no meaningful breakages here. Changelog: [Android] [Breaking] - Stable API - Make InteropModuleRegistry internal Reviewed By: javache Differential Revision: D65421965 fbshipit-source-id: 207be5379ebe3a31530cfea75b4623787f5ae7cf --- .../ReactAndroid/api/ReactAndroid.api | 7 --- .../facebook/react/bridge/ReactContext.java | 2 + .../bridge/interop/InteropModuleRegistry.java | 57 ------------------- .../bridge/interop/InteropModuleRegistry.kt | 49 ++++++++++++++++ .../interop/InteropModuleRegistryTest.kt | 2 +- 5 files changed, 52 insertions(+), 65 deletions(-) delete mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/interop/InteropModuleRegistry.java create mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/interop/InteropModuleRegistry.kt diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 428b39a8c741dd..e46e38d36f5148 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -1644,13 +1644,6 @@ public final class com/facebook/react/bridge/WritableNativeMap : com/facebook/re public fun putString (Ljava/lang/String;Ljava/lang/String;)V } -public class com/facebook/react/bridge/interop/InteropModuleRegistry { - public fun ()V - public fun getInteropModule (Ljava/lang/Class;)Lcom/facebook/react/bridge/JavaScriptModule; - public fun registerInteropModule (Ljava/lang/Class;Ljava/lang/Object;)V - public fun shouldReturnInteropModule (Ljava/lang/Class;)Z -} - public abstract interface class com/facebook/react/bridge/queue/MessageQueueThread { public abstract fun assertIsOnThread ()V public abstract fun assertIsOnThread (Ljava/lang/String;)V diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactContext.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactContext.java index c67274d3be6f1f..8fd31df9675a8c 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactContext.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactContext.java @@ -63,6 +63,8 @@ public interface RCTDeviceEventEmitter extends JavaScriptModule { private @Nullable JSExceptionHandler mExceptionHandlerWrapper; private @Nullable WeakReference mCurrentActivity; + // NOTE: When converted to Kotlin, this field should be made internal due to + // visibility restriction on InteropModuleRegistry otherwise it will be exposed to the public API. protected @Nullable InteropModuleRegistry mInteropModuleRegistry; private boolean mIsInitialized = false; diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/interop/InteropModuleRegistry.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/interop/InteropModuleRegistry.java deleted file mode 100644 index 344bc7a1451737..00000000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/interop/InteropModuleRegistry.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and 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.bridge.interop; - -import androidx.annotation.Nullable; -import com.facebook.react.bridge.JavaScriptModule; -import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags; -import java.util.HashMap; - -/** - * A utility class that takes care of returning {@link JavaScriptModule} which are used for the - * Fabric Interop Layer. This allows us to override the returned classes once the user is invoking - * `ReactContext.getJsModule()`. - * - *

Currently we only support a `RCTEventEmitter` re-implementation, being `InteropEventEmitter` - * but this class can support other re-implementation in the future. - */ -public class InteropModuleRegistry { - - @SuppressWarnings("rawtypes") - private final HashMap supportedModules; - - public InteropModuleRegistry() { - supportedModules = new HashMap<>(); - } - - public boolean shouldReturnInteropModule(Class requestedModule) { - return checkReactFeatureFlagsConditions() && supportedModules.containsKey(requestedModule); - } - - @Nullable - public T getInteropModule(Class requestedModule) { - if (checkReactFeatureFlagsConditions()) { - //noinspection unchecked - return (T) supportedModules.get(requestedModule); - } else { - return null; - } - } - - public void registerInteropModule( - Class interopModuleInterface, Object interopModule) { - if (checkReactFeatureFlagsConditions()) { - supportedModules.put(interopModuleInterface, interopModule); - } - } - - private boolean checkReactFeatureFlagsConditions() { - return ReactNativeFeatureFlags.enableFabricRenderer() - && ReactNativeFeatureFlags.useFabricInterop(); - } -} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/interop/InteropModuleRegistry.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/interop/InteropModuleRegistry.kt new file mode 100644 index 00000000000000..9805b229b2316f --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/interop/InteropModuleRegistry.kt @@ -0,0 +1,49 @@ +/* + * Copyright (c) Meta Platforms, Inc. and 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.bridge.interop + +import com.facebook.react.bridge.JavaScriptModule +import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags.enableFabricRenderer +import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags.useFabricInterop + +/** + * A utility class that takes care of returning [JavaScriptModule] which are used for the Fabric + * Interop Layer. This allows us to override the returned classes once the user is invoking + * `ReactContext.getJsModule()`. + * + * Currently we only support a `RCTEventEmitter` re-implementation, being `InteropEventEmitter` but + * this class can support other re-implementation in the future. + */ +internal class InteropModuleRegistry { + private val supportedModules = mutableMapOf, Any?>() + + fun shouldReturnInteropModule(requestedModule: Class): Boolean { + return checkReactFeatureFlagsConditions() && supportedModules.containsKey(requestedModule) + } + + fun getInteropModule(requestedModule: Class): T? { + return if (checkReactFeatureFlagsConditions()) { + @Suppress("UNCHECKED_CAST") + supportedModules[requestedModule] as? T? + } else { + null + } + } + + fun registerInteropModule( + interopModuleInterface: Class, + interopModule: Any + ) { + if (checkReactFeatureFlagsConditions()) { + supportedModules[interopModuleInterface] = interopModule + } + } + + private fun checkReactFeatureFlagsConditions(): Boolean = + enableFabricRenderer() && useFabricInterop() +} diff --git a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/bridge/interop/InteropModuleRegistryTest.kt b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/bridge/interop/InteropModuleRegistryTest.kt index 63ef4bef012928..69513d722e7550 100644 --- a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/bridge/interop/InteropModuleRegistryTest.kt +++ b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/bridge/interop/InteropModuleRegistryTest.kt @@ -24,7 +24,7 @@ import org.junit.Test @OptIn(UnstableReactNativeAPI::class) class InteropModuleRegistryTest { - lateinit var underTest: InteropModuleRegistry + private lateinit var underTest: InteropModuleRegistry @Before fun setup() { From 623d4819915e7e6fafb8006c8e3b3b796e394974 Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Mon, 4 Nov 2024 12:20:50 -0800 Subject: [PATCH 041/220] Make ReactDebugOverlayTags, DebugOverlayTags, Printer, PrinterHolder, NoopPrinter internal Summary: Those 2 classes are not supposed to be exposed externally, so I'm making them internal. The were never part of the public API so I'm not marking this commit as [BREAKING] Changelog: [Android] [Changed] - Make ReactDebugOverlayTags, DebugOverlayTags, Printer, PrinterHolder, NoopPrinter internal Reviewed By: fabriziocucci Differential Revision: D65420257 fbshipit-source-id: b870274e84d9c3202b9f21360c29eeb995a8d52b --- .../debugoverlay/model/DebugOverlayTag.kt | 2 +- .../com/facebook/debug/holder/NoopPrinter.kt | 9 ++++----- .../java/com/facebook/debug/holder/Printer.kt | 8 ++++---- .../facebook/debug/holder/PrinterHolder.kt | 4 ++-- .../debug/tags/ReactDebugOverlayTags.kt | 20 +++++++++---------- 5 files changed, 21 insertions(+), 22 deletions(-) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/debug/debugoverlay/model/DebugOverlayTag.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/debug/debugoverlay/model/DebugOverlayTag.kt index 7aa4c8d645b137..758da83b4ec9c7 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/debug/debugoverlay/model/DebugOverlayTag.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/debug/debugoverlay/model/DebugOverlayTag.kt @@ -14,7 +14,7 @@ package com.facebook.debug.debugoverlay.model * @param description Description to display in settings. * @param color Color for tag display. */ -public class DebugOverlayTag( +internal class DebugOverlayTag( public val name: String, public val description: String, public val color: Int, diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/debug/holder/NoopPrinter.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/debug/holder/NoopPrinter.kt index fb3bb08f173880..6dac185a7f44f4 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/debug/holder/NoopPrinter.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/debug/holder/NoopPrinter.kt @@ -10,12 +10,11 @@ package com.facebook.debug.holder import com.facebook.debug.debugoverlay.model.DebugOverlayTag /** No-op implementation of [Printer]. */ -public object NoopPrinter : Printer { +internal object NoopPrinter : Printer { - public override fun logMessage(tag: DebugOverlayTag, message: String, vararg args: Any?): Unit = - Unit + override fun logMessage(tag: DebugOverlayTag, message: String, vararg args: Any?): Unit = Unit - public override fun logMessage(tag: DebugOverlayTag, message: String): Unit = Unit + override fun logMessage(tag: DebugOverlayTag, message: String): Unit = Unit - public override fun shouldDisplayLogMessage(tag: DebugOverlayTag): Boolean = false + override fun shouldDisplayLogMessage(tag: DebugOverlayTag): Boolean = false } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/debug/holder/Printer.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/debug/holder/Printer.kt index 64f783fb94588c..39185fc42fe589 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/debug/holder/Printer.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/debug/holder/Printer.kt @@ -10,11 +10,11 @@ package com.facebook.debug.holder import com.facebook.debug.debugoverlay.model.DebugOverlayTag /** Interface to debugging tool. */ -public interface Printer { +internal interface Printer { - public fun logMessage(tag: DebugOverlayTag, message: String, vararg args: Any?) + fun logMessage(tag: DebugOverlayTag, message: String, vararg args: Any?) - public fun logMessage(tag: DebugOverlayTag, message: String) + fun logMessage(tag: DebugOverlayTag, message: String) - public fun shouldDisplayLogMessage(tag: DebugOverlayTag): Boolean + fun shouldDisplayLogMessage(tag: DebugOverlayTag): Boolean } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/debug/holder/PrinterHolder.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/debug/holder/PrinterHolder.kt index 97a140274a0e8a..166fa6667dd2b5 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/debug/holder/PrinterHolder.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/debug/holder/PrinterHolder.kt @@ -8,6 +8,6 @@ package com.facebook.debug.holder /** Holder for debugging tool instance. */ -public object PrinterHolder { - @JvmStatic public var printer: Printer = NoopPrinter +internal object PrinterHolder { + @JvmStatic var printer: Printer = NoopPrinter } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/debug/tags/ReactDebugOverlayTags.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/debug/tags/ReactDebugOverlayTags.kt index 4a9b33bae4a5e2..49bbc5f8632ae2 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/debug/tags/ReactDebugOverlayTags.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/debug/tags/ReactDebugOverlayTags.kt @@ -11,35 +11,35 @@ import android.graphics.Color import com.facebook.debug.debugoverlay.model.DebugOverlayTag /** Category for debug overlays. */ -public object ReactDebugOverlayTags { +internal object ReactDebugOverlayTags { @JvmField - public val PERFORMANCE: DebugOverlayTag = + val PERFORMANCE: DebugOverlayTag = DebugOverlayTag("Performance", "Markers for Performance", Color.GREEN) @JvmField - public val NAVIGATION: DebugOverlayTag = + val NAVIGATION: DebugOverlayTag = DebugOverlayTag("Navigation", "Tag for navigation", Color.rgb(0x9C, 0x27, 0xB0)) @JvmField - public val RN_CORE: DebugOverlayTag = + val RN_CORE: DebugOverlayTag = DebugOverlayTag("RN Core", "Tag for React Native Core", Color.BLACK) @JvmField - public val BRIDGE_CALLS: DebugOverlayTag = + val BRIDGE_CALLS: DebugOverlayTag = DebugOverlayTag("Bridge Calls", "JS to Java calls (warning: this is spammy)", Color.MAGENTA) @JvmField - public val NATIVE_MODULE: DebugOverlayTag = + val NATIVE_MODULE: DebugOverlayTag = DebugOverlayTag("Native Module", "Native Module init", Color.rgb(0x80, 0x00, 0x80)) @JvmField - public val UI_MANAGER: DebugOverlayTag = + val UI_MANAGER: DebugOverlayTag = DebugOverlayTag( "UI Manager", "UI Manager View Operations (requires restart\nwarning: this is spammy)", Color.CYAN) @JvmField - public val FABRIC_UI_MANAGER: DebugOverlayTag = + val FABRIC_UI_MANAGER: DebugOverlayTag = DebugOverlayTag("FabricUIManager", "Fabric UI Manager View Operations", Color.CYAN) @JvmField - public val FABRIC_RECONCILER: DebugOverlayTag = + val FABRIC_RECONCILER: DebugOverlayTag = DebugOverlayTag("FabricReconciler", "Reconciler for Fabric", Color.CYAN) @JvmField - public val RELAY: DebugOverlayTag = + val RELAY: DebugOverlayTag = DebugOverlayTag("Relay", "including prefetching", Color.rgb(0xFF, 0x99, 0x00)) } From dd472101b76a964b7a64f0bb84d967f702500cad Mon Sep 17 00:00:00 2001 From: Eli White Date: Mon, 4 Nov 2024 12:58:49 -0800 Subject: [PATCH 042/220] Add NumberLiteralTypeAnnotation support (#47323) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47323 This change adds support for number literals as a type. The codegen already has parsing support for these types ``` +passNumber: (arg: number) => void; +passString: (arg: string) => void; +passStringLiteral: (arg: 'A String Literal') => void; ``` This change now also supports ``` +passNumberLiteral: (arg: 4) => void; ``` On the native side this is treated the same as `number`. It could be strengthened in the future. This is a pre-requisite for number literal unions and enums. Changelog: [Added] Codegen: Added support for Number literals in native module specs Reviewed By: makovkastar Differential Revision: D65249334 fbshipit-source-id: 98b051d2a6bd1ad5cc6473ac88acfcbe82bd5c7d --- .../src/CodegenSchema.d.ts | 7 +++++++ .../react-native-codegen/src/CodegenSchema.js | 7 +++++++ .../generators/modules/GenerateModuleCpp.js | 2 ++ .../src/generators/modules/GenerateModuleH.js | 2 ++ .../modules/GenerateModuleJavaSpec.js | 7 +++++++ .../modules/GenerateModuleJniCpp.js | 6 ++++++ .../GenerateModuleObjCpp/StructCollector.js | 2 ++ .../header/serializeConstantsStruct.js | 4 ++++ .../header/serializeRegularStruct.js | 4 ++++ .../serializeEventEmitter.js | 1 + .../GenerateModuleObjCpp/serializeMethod.js | 6 ++++++ .../modules/__test_fixtures__/fixtures.js | 1 + .../module-parser-snapshot-test.js.snap | 20 +++++++++++++++++++ .../src/parsers/flow/modules/index.js | 4 ++++ .../src/parsers/parsers-primitives.js | 12 +++++++++++ .../modules/__test_fixtures__/fixtures.js | 1 + ...script-module-parser-snapshot-test.js.snap | 20 +++++++++++++++++++ .../src/parsers/typescript/modules/index.js | 4 ++++ 18 files changed, 110 insertions(+) diff --git a/packages/react-native-codegen/src/CodegenSchema.d.ts b/packages/react-native-codegen/src/CodegenSchema.d.ts index d16379472faf17..42f1a75143c132 100644 --- a/packages/react-native-codegen/src/CodegenSchema.d.ts +++ b/packages/react-native-codegen/src/CodegenSchema.d.ts @@ -286,6 +286,11 @@ export interface UnsafeAnyTypeAnnotation { readonly type: 'AnyTypeAnnotation', } +export interface NativeModuleNumberLiteralTypeAnnotation { + readonly type: 'NumberLiteralTypeAnnotation'; + readonly value: number; +} + export interface NativeModuleStringTypeAnnotation { readonly type: 'StringTypeAnnotation'; } @@ -380,6 +385,7 @@ export type NativeModuleEventEmitterBaseTypeAnnotation = | NativeModuleFloatTypeAnnotation | NativeModuleInt32TypeAnnotation | NativeModuleNumberTypeAnnotation + | NativeModuleNumberLiteralTypeAnnotation | NativeModuleStringTypeAnnotation | NativeModuleStringLiteralTypeAnnotation | NativeModuleStringLiteralUnionTypeAnnotation @@ -399,6 +405,7 @@ export type NativeModuleBaseTypeAnnotation = | NativeModuleStringLiteralTypeAnnotation | NativeModuleStringLiteralUnionTypeAnnotation | NativeModuleNumberTypeAnnotation + | NativeModuleNumberLiteralTypeAnnotation | NativeModuleInt32TypeAnnotation | NativeModuleDoubleTypeAnnotation | NativeModuleFloatTypeAnnotation diff --git a/packages/react-native-codegen/src/CodegenSchema.js b/packages/react-native-codegen/src/CodegenSchema.js index 6b3097804fa435..505291700feeee 100644 --- a/packages/react-native-codegen/src/CodegenSchema.js +++ b/packages/react-native-codegen/src/CodegenSchema.js @@ -37,6 +37,11 @@ export type Int32TypeAnnotation = $ReadOnly<{ type: 'Int32TypeAnnotation', }>; +export type NumberLiteralTypeAnnotation = $ReadOnly<{ + type: 'NumberLiteralTypeAnnotation', + value: number, +}>; + export type StringTypeAnnotation = $ReadOnly<{ type: 'StringTypeAnnotation', }>; @@ -366,6 +371,7 @@ type NativeModuleEventEmitterBaseTypeAnnotation = | FloatTypeAnnotation | Int32TypeAnnotation | NativeModuleNumberTypeAnnotation + | NumberLiteralTypeAnnotation | StringTypeAnnotation | StringLiteralTypeAnnotation | StringLiteralUnionTypeAnnotation @@ -385,6 +391,7 @@ export type NativeModuleBaseTypeAnnotation = | StringLiteralTypeAnnotation | StringLiteralUnionTypeAnnotation | NativeModuleNumberTypeAnnotation + | NumberLiteralTypeAnnotation | Int32TypeAnnotation | DoubleTypeAnnotation | FloatTypeAnnotation diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleCpp.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleCpp.js index 1aa3c73dbbb96b..3c4e9b4fe9f9ee 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleCpp.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleCpp.js @@ -186,6 +186,8 @@ function serializeArg( return wrap(val => `${val}.asNumber()`); case 'Int32TypeAnnotation': return wrap(val => `${val}.asNumber()`); + case 'NumberLiteralTypeAnnotation': + return wrap(val => `${val}.asNumber()`); case 'ArrayTypeAnnotation': return wrap(val => `${val}.asObject(rt).asArray(rt)`); case 'FunctionTypeAnnotation': diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleH.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleH.js index f7c4d67488128c..691229f689357c 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleH.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleH.js @@ -179,6 +179,8 @@ function translatePrimitiveJSTypeToCpp( return wrapOptional('jsi::String', isRequired); case 'NumberTypeAnnotation': return wrapOptional('double', isRequired); + case 'NumberLiteralTypeAnnotation': + return wrapOptional('double', isRequired); case 'DoubleTypeAnnotation': return wrapOptional('double', isRequired); case 'FloatTypeAnnotation': diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleJavaSpec.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleJavaSpec.js index 779b9ac3f5fb87..8ff63e8c994a82 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleJavaSpec.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleJavaSpec.js @@ -136,6 +136,7 @@ function translateEventEmitterTypeToJavaType( case 'StringLiteralUnionTypeAnnotation': return 'String'; case 'NumberTypeAnnotation': + case 'NumberLiteralTypeAnnotation': case 'FloatTypeAnnotation': case 'DoubleTypeAnnotation': case 'Int32TypeAnnotation': @@ -203,6 +204,8 @@ function translateFunctionParamToJavaType( return wrapOptional('String', isRequired); case 'NumberTypeAnnotation': return wrapOptional('double', isRequired); + case 'NumberLiteralTypeAnnotation': + return wrapOptional('double', isRequired); case 'FloatTypeAnnotation': return wrapOptional('double', isRequired); case 'DoubleTypeAnnotation': @@ -297,6 +300,8 @@ function translateFunctionReturnTypeToJavaType( return wrapOptional('String', isRequired); case 'NumberTypeAnnotation': return wrapOptional('double', isRequired); + case 'NumberLiteralTypeAnnotation': + return wrapOptional('double', isRequired); case 'FloatTypeAnnotation': return wrapOptional('double', isRequired); case 'DoubleTypeAnnotation': @@ -373,6 +378,8 @@ function getFalsyReturnStatementFromReturnType( return ''; case 'NumberTypeAnnotation': return nullable ? 'return null;' : 'return 0;'; + case 'NumberLiteralTypeAnnotation': + return nullable ? 'return null;' : 'return 0;'; case 'FloatTypeAnnotation': return nullable ? 'return null;' : 'return 0.0;'; case 'DoubleTypeAnnotation': diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleJniCpp.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleJniCpp.js index 3beb1c3fa1ead0..7d6de0a4f54e3f 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleJniCpp.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleJniCpp.js @@ -197,6 +197,8 @@ function translateReturnTypeToKind( } case 'NumberTypeAnnotation': return 'NumberKind'; + case 'NumberLiteralTypeAnnotation': + return 'NumberKind'; case 'DoubleTypeAnnotation': return 'NumberKind'; case 'FloatTypeAnnotation': @@ -280,6 +282,8 @@ function translateParamTypeToJniType( } case 'NumberTypeAnnotation': return !isRequired ? 'Ljava/lang/Double;' : 'D'; + case 'NumberLiteralTypeAnnotation': + return !isRequired ? 'Ljava/lang/Double;' : 'D'; case 'DoubleTypeAnnotation': return !isRequired ? 'Ljava/lang/Double;' : 'D'; case 'FloatTypeAnnotation': @@ -360,6 +364,8 @@ function translateReturnTypeToJniType( } case 'NumberTypeAnnotation': return nullable ? 'Ljava/lang/Double;' : 'D'; + case 'NumberLiteralTypeAnnotation': + return nullable ? 'Ljava/lang/Double;' : 'D'; case 'DoubleTypeAnnotation': return nullable ? 'Ljava/lang/Double;' : 'D'; case 'FloatTypeAnnotation': diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/StructCollector.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/StructCollector.js index 295514ca52653f..db243d9f3024a2 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/StructCollector.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/StructCollector.js @@ -23,6 +23,7 @@ import type { NativeModuleObjectTypeAnnotation, NativeModuleTypeAliasTypeAnnotation, Nullable, + NumberLiteralTypeAnnotation, ReservedTypeAnnotation, StringLiteralTypeAnnotation, StringLiteralUnionTypeAnnotation, @@ -63,6 +64,7 @@ export type StructTypeAnnotation = | StringLiteralTypeAnnotation | StringLiteralUnionTypeAnnotation | NativeModuleNumberTypeAnnotation + | NumberLiteralTypeAnnotation | Int32TypeAnnotation | DoubleTypeAnnotation | FloatTypeAnnotation diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/header/serializeConstantsStruct.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/header/serializeConstantsStruct.js index 9fe6e73fc70067..9cee0665e8f396 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/header/serializeConstantsStruct.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/header/serializeConstantsStruct.js @@ -100,6 +100,8 @@ function toObjCType( return 'NSString *'; case 'NumberTypeAnnotation': return wrapCxxOptional('double', isRequired); + case 'NumberLiteralTypeAnnotation': + return wrapCxxOptional('double', isRequired); case 'FloatTypeAnnotation': return wrapCxxOptional('double', isRequired); case 'Int32TypeAnnotation': @@ -183,6 +185,8 @@ function toObjCValue( return value; case 'NumberTypeAnnotation': return wrapPrimitive('double'); + case 'NumberLiteralTypeAnnotation': + return wrapPrimitive('double'); case 'FloatTypeAnnotation': return wrapPrimitive('double'); case 'Int32TypeAnnotation': diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/header/serializeRegularStruct.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/header/serializeRegularStruct.js index dbf0fbefb50fba..9fca06510ad933 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/header/serializeRegularStruct.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/header/serializeRegularStruct.js @@ -91,6 +91,8 @@ function toObjCType( return 'NSString *'; case 'NumberTypeAnnotation': return wrapCxxOptional('double', isRequired); + case 'NumberLiteralTypeAnnotation': + return wrapCxxOptional('double', isRequired); case 'FloatTypeAnnotation': return wrapCxxOptional('double', isRequired); case 'Int32TypeAnnotation': @@ -173,6 +175,8 @@ function toObjCValue( return RCTBridgingTo('String'); case 'NumberTypeAnnotation': return RCTBridgingTo('Double'); + case 'NumberLiteralTypeAnnotation': + return RCTBridgingTo('Double'); case 'FloatTypeAnnotation': return RCTBridgingTo('Double'); case 'Int32TypeAnnotation': diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/serializeEventEmitter.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/serializeEventEmitter.js index ae3ff4e198ee92..fd1afff066fbf7 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/serializeEventEmitter.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/serializeEventEmitter.js @@ -25,6 +25,7 @@ function getEventEmitterTypeObjCType( case 'StringLiteralUnionTypeAnnotation': return 'NSString *_Nonnull'; case 'NumberTypeAnnotation': + case 'NumberLiteralTypeAnnotation': return 'NSNumber *_Nonnull'; case 'BooleanTypeAnnotation': return 'BOOL'; diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/serializeMethod.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/serializeMethod.js index 3c024a65e44f83..8e0a56472ff8b3 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/serializeMethod.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/serializeMethod.js @@ -263,6 +263,8 @@ function getParamObjCType( return notStruct(wrapOptional('NSString *', !nullable)); case 'NumberTypeAnnotation': return notStruct(isRequired ? 'double' : 'NSNumber *'); + case 'NumberLiteralTypeAnnotation': + return notStruct(isRequired ? 'double' : 'NSNumber *'); case 'FloatTypeAnnotation': return notStruct(isRequired ? 'float' : 'NSNumber *'); case 'DoubleTypeAnnotation': @@ -344,6 +346,8 @@ function getReturnObjCType( return wrapOptional('NSString *', isRequired); case 'NumberTypeAnnotation': return wrapOptional('NSNumber *', isRequired); + case 'NumberLiteralTypeAnnotation': + return wrapOptional('NSNumber *', isRequired); case 'FloatTypeAnnotation': return wrapOptional('NSNumber *', isRequired); case 'DoubleTypeAnnotation': @@ -414,6 +418,8 @@ function getReturnJSType( return 'StringKind'; case 'NumberTypeAnnotation': return 'NumberKind'; + case 'NumberLiteralTypeAnnotation': + return 'NumberKind'; case 'FloatTypeAnnotation': return 'NumberKind'; case 'DoubleTypeAnnotation': diff --git a/packages/react-native-codegen/src/parsers/flow/modules/__test_fixtures__/fixtures.js b/packages/react-native-codegen/src/parsers/flow/modules/__test_fixtures__/fixtures.js index 1130a84e9b2f6f..45c9179f5baa07 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/__test_fixtures__/fixtures.js +++ b/packages/react-native-codegen/src/parsers/flow/modules/__test_fixtures__/fixtures.js @@ -126,6 +126,7 @@ import * as TurboModuleRegistry from '../TurboModuleRegistry'; export interface Spec extends TurboModule { +passBool?: (arg: boolean) => void; +passNumber: (arg: number) => void; + +passNumberLiteral: (arg: 4) => void; +passString: (arg: string) => void; +passStringish: (arg: Stringish) => void; +passStringLiteral: (arg: 'A String Literal') => void; diff --git a/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-snapshot-test.js.snap b/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-snapshot-test.js.snap index 0d107690879072..56df331cbeac29 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-snapshot-test.js.snap +++ b/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-snapshot-test.js.snap @@ -978,6 +978,26 @@ exports[`RN Codegen Flow Parser can generate fixture NATIVE_MODULE_WITH_BASIC_PA ] } }, + { + 'name': 'passNumberLiteral', + 'optional': false, + 'typeAnnotation': { + 'type': 'FunctionTypeAnnotation', + 'returnTypeAnnotation': { + 'type': 'VoidTypeAnnotation' + }, + 'params': [ + { + 'name': 'arg', + 'optional': false, + 'typeAnnotation': { + 'type': 'NumberLiteralTypeAnnotation', + 'value': 4 + } + } + ] + } + }, { 'name': 'passString', 'optional': false, diff --git a/packages/react-native-codegen/src/parsers/flow/modules/index.js b/packages/react-native-codegen/src/parsers/flow/modules/index.js index 4c6d2ef20232a2..501264ca3d6f87 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/index.js +++ b/packages/react-native-codegen/src/parsers/flow/modules/index.js @@ -38,6 +38,7 @@ const { emitCommonTypes, emitDictionary, emitFunction, + emitNumberLiteral, emitPromise, emitRootTag, emitUnion, @@ -243,6 +244,9 @@ function translateTypeAnnotation( case 'UnionTypeAnnotation': { return emitUnion(nullable, hasteModuleName, typeAnnotation, parser); } + case 'NumberLiteralTypeAnnotation': { + return emitNumberLiteral(nullable, typeAnnotation.value); + } case 'StringLiteralTypeAnnotation': { return wrapNullable(nullable, { type: 'StringLiteralTypeAnnotation', diff --git a/packages/react-native-codegen/src/parsers/parsers-primitives.js b/packages/react-native-codegen/src/parsers/parsers-primitives.js index 5e366960201d8d..a0fa2c3f0ecf96 100644 --- a/packages/react-native-codegen/src/parsers/parsers-primitives.js +++ b/packages/react-native-codegen/src/parsers/parsers-primitives.js @@ -31,6 +31,7 @@ import type { NativeModuleTypeAnnotation, NativeModuleUnionTypeAnnotation, Nullable, + NumberLiteralTypeAnnotation, ObjectTypeAnnotation, ReservedTypeAnnotation, StringLiteralTypeAnnotation, @@ -170,6 +171,16 @@ function emitMixed( }); } +function emitNumberLiteral( + nullable: boolean, + value: number, +): Nullable { + return wrapNullable(nullable, { + type: 'NumberLiteralTypeAnnotation', + value, + }); +} + function emitString(nullable: boolean): Nullable { return wrapNullable(nullable, { type: 'StringTypeAnnotation', @@ -762,6 +773,7 @@ module.exports = { emitInt32Prop, emitMixedProp, emitNumber, + emitNumberLiteral, emitGenericObject, emitDictionary, emitObject, diff --git a/packages/react-native-codegen/src/parsers/typescript/modules/__test_fixtures__/fixtures.js b/packages/react-native-codegen/src/parsers/typescript/modules/__test_fixtures__/fixtures.js index 6927f6c77c65e8..1dead63de55f18 100644 --- a/packages/react-native-codegen/src/parsers/typescript/modules/__test_fixtures__/fixtures.js +++ b/packages/react-native-codegen/src/parsers/typescript/modules/__test_fixtures__/fixtures.js @@ -113,6 +113,7 @@ import * as TurboModuleRegistry from '../TurboModuleRegistry'; export interface Spec extends TurboModule { readonly passBool?: (arg: boolean) => void; readonly passNumber: (arg: number) => void; + readonly passNumberLiteral: (arg: 4) => void; readonly passString: (arg: string) => void; readonly passStringish: (arg: Stringish) => void; readonly passStringLiteral: (arg: 'A String Literal') => void; diff --git a/packages/react-native-codegen/src/parsers/typescript/modules/__tests__/__snapshots__/typescript-module-parser-snapshot-test.js.snap b/packages/react-native-codegen/src/parsers/typescript/modules/__tests__/__snapshots__/typescript-module-parser-snapshot-test.js.snap index 5ff8fc7f31f00d..7358482aa08e84 100644 --- a/packages/react-native-codegen/src/parsers/typescript/modules/__tests__/__snapshots__/typescript-module-parser-snapshot-test.js.snap +++ b/packages/react-native-codegen/src/parsers/typescript/modules/__tests__/__snapshots__/typescript-module-parser-snapshot-test.js.snap @@ -1123,6 +1123,26 @@ exports[`RN Codegen TypeScript Parser can generate fixture NATIVE_MODULE_WITH_BA ] } }, + { + 'name': 'passNumberLiteral', + 'optional': false, + 'typeAnnotation': { + 'type': 'FunctionTypeAnnotation', + 'returnTypeAnnotation': { + 'type': 'VoidTypeAnnotation' + }, + 'params': [ + { + 'name': 'arg', + 'optional': false, + 'typeAnnotation': { + 'type': 'NumberLiteralTypeAnnotation', + 'value': 4 + } + } + ] + } + }, { 'name': 'passString', 'optional': false, diff --git a/packages/react-native-codegen/src/parsers/typescript/modules/index.js b/packages/react-native-codegen/src/parsers/typescript/modules/index.js index 8c4da2de883dfb..aaab3ddeeae859 100644 --- a/packages/react-native-codegen/src/parsers/typescript/modules/index.js +++ b/packages/react-native-codegen/src/parsers/typescript/modules/index.js @@ -37,6 +37,7 @@ const { emitCommonTypes, emitDictionary, emitFunction, + emitNumberLiteral, emitPromise, emitRootTag, emitStringLiteral, @@ -403,6 +404,9 @@ function translateTypeAnnotation( case 'StringLiteral': { return emitStringLiteral(nullable, literal.value); } + case 'NumericLiteral': { + return emitNumberLiteral(nullable, literal.value); + } default: { throw new UnsupportedTypeAnnotationParserError( hasteModuleName, From 35f0e1cca2299b5816cbc1847410651eb20a3f02 Mon Sep 17 00:00:00 2001 From: Eli White Date: Mon, 4 Nov 2024 12:58:49 -0800 Subject: [PATCH 043/220] Fix CodegenSchema Enum type to not export array (#47324) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47324 I need to reference this type somewhere else, but not an array of the type. Generally we prefer that all exported types are the object itself, and it used as a member type of arrays when used. Changelog: [Internal] Reviewed By: makovkastar Differential Revision: D65259014 fbshipit-source-id: 35fb5fe03a44bed61ad87337d0fc5c198744c0e9 --- packages/react-native-codegen/src/CodegenSchema.d.ts | 6 +++--- packages/react-native-codegen/src/CodegenSchema.js | 12 +++++------- .../src/generators/modules/GenerateModuleH.js | 4 ++-- .../react-native-codegen/src/parsers/flow/parser.js | 6 ++++-- packages/react-native-codegen/src/parsers/parser.js | 6 ++++-- .../react-native-codegen/src/parsers/parserMock.js | 6 ++++-- .../src/parsers/typescript/parser.js | 6 ++++-- 7 files changed, 26 insertions(+), 20 deletions(-) diff --git a/packages/react-native-codegen/src/CodegenSchema.d.ts b/packages/react-native-codegen/src/CodegenSchema.d.ts index 42f1a75143c132..0f1cf9baff3ded 100644 --- a/packages/react-native-codegen/src/CodegenSchema.d.ts +++ b/packages/react-native-codegen/src/CodegenSchema.d.ts @@ -325,10 +325,10 @@ export interface NativeModuleBooleanTypeAnnotation { readonly type: 'BooleanTypeAnnotation'; } -export type NativeModuleEnumMembers = readonly { +export type NativeModuleEnumMember = { readonly name: string; readonly value: string | number; -}[]; +}; export type NativeModuleEnumMemberType = | 'NumberTypeAnnotation' @@ -344,7 +344,7 @@ export interface NativeModuleEnumDeclarationWithMembers { name: string; type: 'EnumDeclarationWithMembers'; memberType: NativeModuleEnumMemberType; - members: NativeModuleEnumMembers; + members: readonly NativeModuleEnumMember[]; } export interface NativeModuleGenericObjectTypeAnnotation { diff --git a/packages/react-native-codegen/src/CodegenSchema.js b/packages/react-native-codegen/src/CodegenSchema.js index 505291700feeee..d8b72e48ffd138 100644 --- a/packages/react-native-codegen/src/CodegenSchema.js +++ b/packages/react-native-codegen/src/CodegenSchema.js @@ -309,12 +309,10 @@ export type NativeModuleNumberTypeAnnotation = $ReadOnly<{ type: 'NumberTypeAnnotation', }>; -export type NativeModuleEnumMembers = $ReadOnlyArray< - $ReadOnly<{ - name: string, - value: string | number, - }>, ->; +export type NativeModuleEnumMember = { + name: string, + value: string | number, +}; export type NativeModuleEnumMemberType = | 'NumberTypeAnnotation' @@ -330,7 +328,7 @@ export type NativeModuleEnumDeclarationWithMembers = { name: string, type: 'EnumDeclarationWithMembers', memberType: NativeModuleEnumMemberType, - members: NativeModuleEnumMembers, + members: $ReadOnlyArray, }; export type NativeModuleGenericObjectTypeAnnotation = $ReadOnly<{ diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleH.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleH.js index 691229f689357c..9be6999ce5dfb2 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleH.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleH.js @@ -16,7 +16,7 @@ import type { import type { NativeModuleAliasMap, NativeModuleEnumMap, - NativeModuleEnumMembers, + NativeModuleEnumMember, NativeModuleEnumMemberType, NativeModuleEventEmitterShape, NativeModuleFunctionTypeAnnotation, @@ -409,7 +409,7 @@ struct Bridging<${enumName}> { function generateEnum( hasteModuleName: string, origEnumName: string, - members: NativeModuleEnumMembers, + members: $ReadOnlyArray, memberType: NativeModuleEnumMemberType, ): string { const enumName = getEnumName(hasteModuleName, origEnumName); diff --git a/packages/react-native-codegen/src/parsers/flow/parser.js b/packages/react-native-codegen/src/parsers/flow/parser.js index 3a435e47ba4bd5..1afcbed0d8a369 100644 --- a/packages/react-native-codegen/src/parsers/flow/parser.js +++ b/packages/react-native-codegen/src/parsers/flow/parser.js @@ -15,7 +15,7 @@ import type { NamedShape, NativeModuleAliasMap, NativeModuleEnumMap, - NativeModuleEnumMembers, + NativeModuleEnumMember, NativeModuleEnumMemberType, NativeModuleParamTypeAnnotation, Nullable, @@ -227,7 +227,9 @@ class FlowParser implements Parser { }); } - parseEnumMembers(typeAnnotation: $FlowFixMe): NativeModuleEnumMembers { + parseEnumMembers( + typeAnnotation: $FlowFixMe, + ): $ReadOnlyArray { return typeAnnotation.members.map(member => ({ name: member.id.name, value: member.init?.value ?? member.id.name, diff --git a/packages/react-native-codegen/src/parsers/parser.js b/packages/react-native-codegen/src/parsers/parser.js index bfb160bc77f427..3e0b74ec6fda43 100644 --- a/packages/react-native-codegen/src/parsers/parser.js +++ b/packages/react-native-codegen/src/parsers/parser.js @@ -15,7 +15,7 @@ import type { NamedShape, NativeModuleAliasMap, NativeModuleEnumMap, - NativeModuleEnumMembers, + NativeModuleEnumMember, NativeModuleEnumMemberType, NativeModuleParamTypeAnnotation, Nullable, @@ -240,7 +240,9 @@ export interface Parser { /** * Calculates enum's members */ - parseEnumMembers(typeAnnotation: $FlowFixMe): NativeModuleEnumMembers; + parseEnumMembers( + typeAnnotation: $FlowFixMe, + ): $ReadOnlyArray; /** * Given a node, it returns true if it is a module interface diff --git a/packages/react-native-codegen/src/parsers/parserMock.js b/packages/react-native-codegen/src/parsers/parserMock.js index 1045acfea12262..78a2a062f8326f 100644 --- a/packages/react-native-codegen/src/parsers/parserMock.js +++ b/packages/react-native-codegen/src/parsers/parserMock.js @@ -15,7 +15,7 @@ import type { NamedShape, NativeModuleAliasMap, NativeModuleEnumMap, - NativeModuleEnumMembers, + NativeModuleEnumMember, NativeModuleEnumMemberType, NativeModuleParamTypeAnnotation, Nullable, @@ -168,7 +168,9 @@ export class MockedParser implements Parser { return; } - parseEnumMembers(typeAnnotation: $FlowFixMe): NativeModuleEnumMembers { + parseEnumMembers( + typeAnnotation: $FlowFixMe, + ): $ReadOnlyArray { return typeAnnotation.type === 'StringTypeAnnotation' ? [ { diff --git a/packages/react-native-codegen/src/parsers/typescript/parser.js b/packages/react-native-codegen/src/parsers/typescript/parser.js index 592929dbd43463..5f97658f3c65e3 100644 --- a/packages/react-native-codegen/src/parsers/typescript/parser.js +++ b/packages/react-native-codegen/src/parsers/typescript/parser.js @@ -15,7 +15,7 @@ import type { NamedShape, NativeModuleAliasMap, NativeModuleEnumMap, - NativeModuleEnumMembers, + NativeModuleEnumMember, NativeModuleEnumMemberType, NativeModuleParamTypeAnnotation, Nullable, @@ -223,7 +223,9 @@ class TypeScriptParser implements Parser { }); } - parseEnumMembers(typeAnnotation: $FlowFixMe): NativeModuleEnumMembers { + parseEnumMembers( + typeAnnotation: $FlowFixMe, + ): $ReadOnlyArray { return typeAnnotation.members.map(member => ({ name: member.id.name, value: member.initializer?.value ?? member.id.name, From 027b8032c20b507c1149f526dc1c864f76ac4f3e Mon Sep 17 00:00:00 2001 From: Joe Vilches Date: Mon, 4 Nov 2024 16:02:37 -0800 Subject: [PATCH 044/220] Modify private apis to set, store, and get intrinsic sizing keywords (#46938) Summary: X-link: https://github.com/facebook/yoga/pull/1721 Pull Request resolved: https://github.com/facebook/react-native/pull/46938 The private internals of how we store styles needed to change a bit to support 3 new keyword values. Right now the only other keyword that can be stored is `auto`. As a result there isn't much fancy logic to support storing this and its just stored as a specific type inside of `StyleValueHandle`. There are only 3 bits for types (8 values), so it is not sustainable to just stuff every keyword in there. So the change writes the keyword as a value with a new `keyword` `Type`. I chose not to put `auto` in there even though it is a keyword since it is a hot path, I did not want to regress perf when I did not need to. I also make a new `StyleSizeValue` class to store size values - so values for `width`, `height`, etc. This way these new keywords are kept specific to sizes and we will not be able to create, for example, a margin: `max-content`. Changelog: [Internal] Reviewed By: NickGerleman Differential Revision: D63927512 fbshipit-source-id: 7285469d37ac4b05226183b56275c77f0c06996c --- .../Text/RCTParagraphComponentViewTests.mm | 24 +-- packages/react-native/React/Views/RCTLayout.m | 3 + .../react-native/React/Views/RCTShadowView.m | 7 + .../main/java/com/facebook/yoga/YogaUnit.java | 8 +- .../view/YogaLayoutableShadowNode.cpp | 14 +- .../renderer/components/view/conversions.h | 101 ++++++++++--- .../components/view/tests/LayoutTest.cpp | 24 +-- .../tests/PointerEventsProcessorTest.cpp | 20 +-- .../ReactCommon/yoga/yoga/YGEnums.cpp | 6 + .../ReactCommon/yoga/yoga/YGEnums.h | 5 +- .../ReactCommon/yoga/yoga/YGNodeStyle.cpp | 34 ++--- .../ReactCommon/yoga/yoga/YGValue.h | 3 + .../yoga/yoga/algorithm/CalculateLayout.cpp | 2 +- .../ReactCommon/yoga/yoga/enums/Unit.h | 5 +- .../ReactCommon/yoga/yoga/node/Node.cpp | 12 +- .../ReactCommon/yoga/yoga/node/Node.h | 8 +- .../ReactCommon/yoga/yoga/style/Style.h | 26 ++-- .../ReactCommon/yoga/yoga/style/StyleLength.h | 21 ++- .../yoga/yoga/style/StyleSizeLength.h | 139 ++++++++++++++++++ .../yoga/yoga/style/StyleValueHandle.h | 8 + .../yoga/yoga/style/StyleValuePool.h | 63 +++++++- 21 files changed, 419 insertions(+), 114 deletions(-) create mode 100644 packages/react-native/ReactCommon/yoga/yoga/style/StyleSizeLength.h diff --git a/packages/react-native/React/Tests/Text/RCTParagraphComponentViewTests.mm b/packages/react-native/React/Tests/Text/RCTParagraphComponentViewTests.mm index d94ca995977e5c..0284859a16e046 100644 --- a/packages/react-native/React/Tests/Text/RCTParagraphComponentViewTests.mm +++ b/packages/react-native/React/Tests/Text/RCTParagraphComponentViewTests.mm @@ -121,8 +121,8 @@ - (void)setUp auto &props = *sharedProps; props.layoutConstraints = LayoutConstraints{{0, 0}, {500, 500}}; auto &yogaStyle = props.yogaStyle; - yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(200)); - yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(200)); + yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleSizeLength::points(200)); + yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleSizeLength::points(200)); return sharedProps; }) .children({ @@ -136,8 +136,8 @@ - (void)setUp yogaStyle.setPositionType(yoga::PositionType::Absolute); yogaStyle.setPosition(yoga::Edge::Left, yoga::StyleLength::points(0)); yogaStyle.setPosition(yoga::Edge::Top, yoga::StyleLength::points(0)); - yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(200)); - yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(200)); + yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleSizeLength::points(200)); + yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleSizeLength::points(200)); return sharedProps; }) .children({ @@ -216,8 +216,8 @@ - (void)setUp yogaStyle.setPositionType(yoga::PositionType::Absolute); yogaStyle.setPosition(yoga::Edge::Left, yoga::StyleLength::points(0)); yogaStyle.setPosition(yoga::Edge::Top, yoga::StyleLength::points(30)); - yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(200)); - yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(50)); + yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleSizeLength::points(200)); + yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleSizeLength::points(50)); return sharedProps; }) .children({ @@ -260,8 +260,8 @@ - (void)setUp yogaStyle.setPositionType(yoga::PositionType::Absolute); yogaStyle.setPosition(yoga::Edge::Left, yoga::StyleLength::points(0)); yogaStyle.setPosition(yoga::Edge::Top, yoga::StyleLength::points(90)); - yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(200)); - yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(50)); + yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleSizeLength::points(200)); + yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleSizeLength::points(50)); return sharedProps; }) .children({ @@ -418,8 +418,8 @@ - (void)testEntireParagraphLink auto &props = *sharedProps; props.layoutConstraints = LayoutConstraints{{0, 0}, {500, 500}}; auto &yogaStyle = props.yogaStyle; - yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(200)); - yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(200)); + yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleSizeLength::points(200)); + yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleSizeLength::points(200)); return sharedProps; }) .children({ @@ -434,8 +434,8 @@ - (void)testEntireParagraphLink yogaStyle.setPositionType(yoga::PositionType::Absolute); yogaStyle.setPosition(yoga::Edge::Left, yoga::StyleLength::points(0)); yogaStyle.setPosition(yoga::Edge::Top, yoga::StyleLength::points(90)); - yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(200)); - yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(20)); + yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleSizeLength::points(200)); + yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleSizeLength::points(20)); return sharedProps; }) .children({ diff --git a/packages/react-native/React/Views/RCTLayout.m b/packages/react-native/React/Views/RCTLayout.m index 85c8994511a032..0d16f955960c6e 100644 --- a/packages/react-native/React/Views/RCTLayout.m +++ b/packages/react-native/React/Views/RCTLayout.m @@ -87,6 +87,9 @@ CGFloat RCTCoreGraphicsFloatFromYogaValue(YGValue value, CGFloat baseFloatValue) return RCTCoreGraphicsFloatFromYogaFloat(value.value) * baseFloatValue; case YGUnitAuto: case YGUnitUndefined: + case YGUnitMaxContent: + case YGUnitFitContent: + case YGUnitStretch: return baseFloatValue; } } diff --git a/packages/react-native/React/Views/RCTShadowView.m b/packages/react-native/React/Views/RCTShadowView.m index b893cfe5c26785..66385dba06ffd4 100644 --- a/packages/react-native/React/Views/RCTShadowView.m +++ b/packages/react-native/React/Views/RCTShadowView.m @@ -63,6 +63,9 @@ + (YGConfigRef)yogaConfig #define RCT_SET_YGVALUE(ygvalue, setter, ...) \ switch (ygvalue.unit) { \ case YGUnitAuto: \ + case YGUnitMaxContent: \ + case YGUnitFitContent: \ + case YGUnitStretch: \ case YGUnitUndefined: \ setter(__VA_ARGS__, YGUndefined); \ break; \ @@ -88,6 +91,10 @@ + (YGConfigRef)yogaConfig case YGUnitPercent: \ setter##Percent(__VA_ARGS__, ygvalue.value); \ break; \ + case YGUnitMaxContent: \ + case YGUnitFitContent: \ + case YGUnitStretch: \ + break; \ } static void RCTProcessMetaPropsPadding(const YGValue metaProps[META_PROP_COUNT], YGNodeRef node) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaUnit.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaUnit.java index 3614ec1059d2a7..5731a040d93d80 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaUnit.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaUnit.java @@ -13,7 +13,10 @@ public enum YogaUnit { UNDEFINED(0), POINT(1), PERCENT(2), - AUTO(3); + AUTO(3), + MAX_CONTENT(4), + FIT_CONTENT(5), + STRETCH(6); private final int mIntValue; @@ -31,6 +34,9 @@ public static YogaUnit fromInt(int value) { case 1: return POINT; case 2: return PERCENT; case 3: return AUTO; + case 4: return MAX_CONTENT; + case 5: return FIT_CONTENT; + case 6: return STRETCH; default: throw new IllegalArgumentException("Unknown enum value: " + value); } } diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp b/packages/react-native/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp index a6c9b8538dd53f..387095cfa2d89f 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp @@ -538,9 +538,9 @@ void YogaLayoutableShadowNode::setSize(Size size) const { auto style = yogaNode_.style(); style.setDimension( - yoga::Dimension::Width, yoga::StyleLength::points(size.width)); + yoga::Dimension::Width, yoga::StyleSizeLength::points(size.width)); style.setDimension( - yoga::Dimension::Height, yoga::StyleLength::points(size.height)); + yoga::Dimension::Height, yoga::StyleSizeLength::points(size.height)); yogaNode_.setStyle(style); yogaNode_.setDirty(true); } @@ -631,16 +631,18 @@ void YogaLayoutableShadowNode::layoutTree( auto ownerHeight = yogaFloatFromFloat(maximumSize.height); yogaStyle.setMaxDimension( - yoga::Dimension::Width, yoga::StyleLength::points(maximumSize.width)); + yoga::Dimension::Width, yoga::StyleSizeLength::points(maximumSize.width)); yogaStyle.setMaxDimension( - yoga::Dimension::Height, yoga::StyleLength::points(maximumSize.height)); + yoga::Dimension::Height, + yoga::StyleSizeLength::points(maximumSize.height)); yogaStyle.setMinDimension( - yoga::Dimension::Width, yoga::StyleLength::points(minimumSize.width)); + yoga::Dimension::Width, yoga::StyleSizeLength::points(minimumSize.width)); yogaStyle.setMinDimension( - yoga::Dimension::Height, yoga::StyleLength::points(minimumSize.height)); + yoga::Dimension::Height, + yoga::StyleSizeLength::points(minimumSize.height)); auto direction = yogaDirectionFromLayoutDirection(layoutConstraints.layoutDirection); diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/conversions.h b/packages/react-native/ReactCommon/react/renderer/components/view/conversions.h index 58e04bba088aae..e18d1d1e5615dd 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/conversions.h +++ b/packages/react-native/ReactCommon/react/renderer/components/view/conversions.h @@ -92,18 +92,15 @@ inline yoga::FloatOptional yogaOptionalFloatFromFloat(Float value) { inline std::optional optionalFloatFromYogaValue( const yoga::Style::Length& length, std::optional base = {}) { - switch (length.unit()) { - case yoga::Unit::Undefined: - return {}; - case yoga::Unit::Point: - return floatFromYogaOptionalFloat(length.value()); - case yoga::Unit::Percent: - return base.has_value() - ? std::optional( - base.value() * floatFromYogaOptionalFloat(length.value())) - : std::optional(); - case yoga::Unit::Auto: - return {}; + if (length.isPoints()) { + return floatFromYogaOptionalFloat(length.value()); + } else if (length.isPercent()) { + return base.has_value() + ? std::optional( + base.value() * floatFromYogaOptionalFloat(length.value())) + : std::optional(); + } else { + return {}; } } @@ -446,6 +443,47 @@ inline void fromRawValue( LOG(ERROR) << "Could not parse yoga::Display: " << stringValue; } +inline void fromRawValue( + const PropsParserContext& /*context*/, + const RawValue& value, + yoga::Style::SizeLength& result) { + if (value.hasType()) { + result = yoga::StyleSizeLength::points((float)value); + return; + } else if (value.hasType()) { + const auto stringValue = (std::string)value; + if (stringValue == "auto") { + result = yoga::StyleSizeLength::ofAuto(); + return; + } else if (stringValue == "max-content") { + result = yoga::StyleSizeLength::ofMaxContent(); + return; + } else if (stringValue == "stretch") { + result = yoga::StyleSizeLength::ofStretch(); + return; + } else if (stringValue == "fit-content") { + result = yoga::StyleSizeLength::ofFitContent(); + return; + } else { + if (stringValue.back() == '%') { + auto tryValue = folly::tryTo( + std::string_view(stringValue).substr(0, stringValue.length() - 1)); + if (tryValue.hasValue()) { + result = yoga::StyleSizeLength::percent(tryValue.value()); + return; + } + } else { + auto tryValue = folly::tryTo(stringValue); + if (tryValue.hasValue()) { + result = yoga::StyleSizeLength::points(tryValue.value()); + return; + } + } + } + } + result = yoga::StyleSizeLength::undefined(); +} + inline void fromRawValue( const PropsParserContext& context, const RawValue& value, @@ -1370,15 +1408,36 @@ inline std::string toString(const yoga::Display& value) { } inline std::string toString(const yoga::Style::Length& length) { - switch (length.unit()) { - case yoga::Unit::Undefined: - return "undefined"; - case yoga::Unit::Point: - return std::to_string(length.value().unwrap()); - case yoga::Unit::Percent: - return std::to_string(length.value().unwrap()) + "%"; - case yoga::Unit::Auto: - return "auto"; + if (length.isUndefined()) { + return "undefined"; + } else if (length.isAuto()) { + return "auto"; + } else if (length.isPoints()) { + return std::to_string(length.value().unwrap()); + } else if (length.isPercent()) { + return std::to_string(length.value().unwrap()) + "%"; + } else { + return "unknown"; + } +} + +inline std::string toString(const yoga::Style::SizeLength& length) { + if (length.isUndefined()) { + return "undefined"; + } else if (length.isAuto()) { + return "auto"; + } else if (length.isPoints()) { + return std::to_string(length.value().unwrap()); + } else if (length.isPercent()) { + return std::to_string(length.value().unwrap()) + "%"; + } else if (length.isMaxContent()) { + return "max-content"; + } else if (length.isFitContent()) { + return "fit-content"; + } else if (length.isStretch()) { + return "stretch"; + } else { + return "unknown"; } } diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/tests/LayoutTest.cpp b/packages/react-native/ReactCommon/react/renderer/components/view/tests/LayoutTest.cpp index 5277a2b153401d..d722f674135494 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/tests/LayoutTest.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/view/tests/LayoutTest.cpp @@ -77,8 +77,8 @@ class LayoutTest : public ::testing::Test { auto &props = *sharedProps; props.layoutConstraints = LayoutConstraints{{0,0}, {500, 500}}; auto &yogaStyle = props.yogaStyle; - yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(200)); - yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(200)); + yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleSizeLength::points(200)); + yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleSizeLength::points(200)); return sharedProps; }) .children({ @@ -90,8 +90,8 @@ class LayoutTest : public ::testing::Test { auto &props = *sharedProps; auto &yogaStyle = props.yogaStyle; yogaStyle.setPositionType(yoga::PositionType::Absolute); - yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(50)); - yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(50)); + yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleSizeLength::points(50)); + yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleSizeLength::points(50)); return sharedProps; }) .children({ @@ -105,8 +105,8 @@ class LayoutTest : public ::testing::Test { yogaStyle.setPositionType(yoga::PositionType::Absolute); yogaStyle.setPosition(yoga::Edge::Left, yoga::StyleLength::points(10)); yogaStyle.setPosition(yoga::Edge::Top, yoga::StyleLength::points(10)); - yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(30)); - yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(90)); + yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleSizeLength::points(30)); + yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleSizeLength::points(90)); if (testCase == TRANSFORM_SCALE) { props.transform = props.transform * Transform::Scale(2, 2, 1); @@ -138,8 +138,8 @@ class LayoutTest : public ::testing::Test { yogaStyle.setPositionType(yoga::PositionType::Absolute); yogaStyle.setPosition(yoga::Edge::Left, yoga::StyleLength::points(10)); yogaStyle.setPosition(yoga::Edge::Top, yoga::StyleLength::points(10)); - yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(110)); - yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(20)); + yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleSizeLength::points(110)); + yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleSizeLength::points(20)); return sharedProps; }) .children({ @@ -153,8 +153,8 @@ class LayoutTest : public ::testing::Test { yogaStyle.setPositionType(yoga::PositionType::Absolute); yogaStyle.setPosition(yoga::Edge::Left, yoga::StyleLength::points(70)); yogaStyle.setPosition(yoga::Edge::Top, yoga::StyleLength::points(-50)); - yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(30)); - yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(60)); + yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleSizeLength::points(30)); + yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleSizeLength::points(60)); return sharedProps; }) }), @@ -168,8 +168,8 @@ class LayoutTest : public ::testing::Test { yogaStyle.setPositionType(yoga::PositionType::Absolute); yogaStyle.setPosition(yoga::Edge::Left, yoga::StyleLength::points(-60)); yogaStyle.setPosition(yoga::Edge::Top, yoga::StyleLength::points(50)); - yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(70)); - yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(20)); + yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleSizeLength::points(70)); + yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleSizeLength::points(20)); return sharedProps; }) }) diff --git a/packages/react-native/ReactCommon/react/renderer/uimanager/tests/PointerEventsProcessorTest.cpp b/packages/react-native/ReactCommon/react/renderer/uimanager/tests/PointerEventsProcessorTest.cpp index d51547f310f073..3f19e4f7934199 100644 --- a/packages/react-native/ReactCommon/react/renderer/uimanager/tests/PointerEventsProcessorTest.cpp +++ b/packages/react-native/ReactCommon/react/renderer/uimanager/tests/PointerEventsProcessorTest.cpp @@ -87,8 +87,8 @@ class PointerEventsProcessorTest : public ::testing::Test { listenToAllPointerEvents(props); props.layoutConstraints = LayoutConstraints{{0,0}, {500, 500}}; auto &yogaStyle = props.yogaStyle; - yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(400)); - yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(400)); + yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleSizeLength::points(400)); + yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleSizeLength::points(400)); yogaStyle.setDisplay(yoga::Display::Flex); yogaStyle.setFlexDirection(yoga::FlexDirection::Row); yogaStyle.setAlignItems(yoga::Align::Center); @@ -109,8 +109,8 @@ class PointerEventsProcessorTest : public ::testing::Test { yogaStyle.setFlexDirection(yoga::FlexDirection::Column); yogaStyle.setAlignItems(yoga::Align::FlexEnd); yogaStyle.setJustifyContent(yoga::Justify::Center); - yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(150)); - yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(300)); + yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleSizeLength::points(150)); + yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleSizeLength::points(300)); return sharedProps; }) .children({ @@ -123,8 +123,8 @@ class PointerEventsProcessorTest : public ::testing::Test { auto &props = *sharedProps; listenToAllPointerEvents(props); auto &yogaStyle = props.yogaStyle; - yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(100)); - yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(200)); + yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleSizeLength::points(100)); + yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleSizeLength::points(200)); return sharedProps; }) }), @@ -141,8 +141,8 @@ class PointerEventsProcessorTest : public ::testing::Test { yogaStyle.setFlexDirection(yoga::FlexDirection::Column); yogaStyle.setAlignItems(yoga::Align::FlexStart); yogaStyle.setJustifyContent(yoga::Justify::Center); - yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(150)); - yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(300)); + yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleSizeLength::points(150)); + yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleSizeLength::points(300)); return sharedProps; }) .children({ @@ -155,8 +155,8 @@ class PointerEventsProcessorTest : public ::testing::Test { auto &props = *sharedProps; listenToAllPointerEvents(props); auto &yogaStyle = props.yogaStyle; - yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(100)); - yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(200)); + yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleSizeLength::points(100)); + yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleSizeLength::points(200)); return sharedProps; }) }) diff --git a/packages/react-native/ReactCommon/yoga/yoga/YGEnums.cpp b/packages/react-native/ReactCommon/yoga/yoga/YGEnums.cpp index cddd5d5849ff83..4bdace6b7a5e90 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/YGEnums.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/YGEnums.cpp @@ -245,6 +245,12 @@ const char* YGUnitToString(const YGUnit value) { return "percent"; case YGUnitAuto: return "auto"; + case YGUnitMaxContent: + return "max-content"; + case YGUnitFitContent: + return "fit-content"; + case YGUnitStretch: + return "stretch"; } return "unknown"; } diff --git a/packages/react-native/ReactCommon/yoga/yoga/YGEnums.h b/packages/react-native/ReactCommon/yoga/yoga/YGEnums.h index 27f0426f450ec4..bb83bcfac949fa 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/YGEnums.h +++ b/packages/react-native/ReactCommon/yoga/yoga/YGEnums.h @@ -131,7 +131,10 @@ YG_ENUM_DECL( YGUnitUndefined, YGUnitPoint, YGUnitPercent, - YGUnitAuto) + YGUnitAuto, + YGUnitMaxContent, + YGUnitFitContent, + YGUnitStretch) YG_ENUM_DECL( YGWrap, diff --git a/packages/react-native/ReactCommon/yoga/yoga/YGNodeStyle.cpp b/packages/react-native/ReactCommon/yoga/yoga/YGNodeStyle.cpp index 8664b53ec81518..1309117af42cbb 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/YGNodeStyle.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/YGNodeStyle.cpp @@ -177,19 +177,19 @@ float YGNodeStyleGetFlexShrink(const YGNodeConstRef nodeRef) { void YGNodeStyleSetFlexBasis(const YGNodeRef node, const float flexBasis) { updateStyle<&Style::flexBasis, &Style::setFlexBasis>( - node, StyleLength::points(flexBasis)); + node, StyleSizeLength::points(flexBasis)); } void YGNodeStyleSetFlexBasisPercent( const YGNodeRef node, const float flexBasisPercent) { updateStyle<&Style::flexBasis, &Style::setFlexBasis>( - node, StyleLength::percent(flexBasisPercent)); + node, StyleSizeLength::percent(flexBasisPercent)); } void YGNodeStyleSetFlexBasisAuto(const YGNodeRef node) { updateStyle<&Style::flexBasis, &Style::setFlexBasis>( - node, StyleLength::ofAuto()); + node, StyleSizeLength::ofAuto()); } YGValue YGNodeStyleGetFlexBasis(const YGNodeConstRef node) { @@ -308,17 +308,17 @@ YGBoxSizing YGNodeStyleGetBoxSizing(const YGNodeConstRef node) { void YGNodeStyleSetWidth(YGNodeRef node, float points) { updateStyle<&Style::dimension, &Style::setDimension>( - node, Dimension::Width, StyleLength::points(points)); + node, Dimension::Width, StyleSizeLength::points(points)); } void YGNodeStyleSetWidthPercent(YGNodeRef node, float percent) { updateStyle<&Style::dimension, &Style::setDimension>( - node, Dimension::Width, StyleLength::percent(percent)); + node, Dimension::Width, StyleSizeLength::percent(percent)); } void YGNodeStyleSetWidthAuto(YGNodeRef node) { updateStyle<&Style::dimension, &Style::setDimension>( - node, Dimension::Width, StyleLength::ofAuto()); + node, Dimension::Width, StyleSizeLength::ofAuto()); } YGValue YGNodeStyleGetWidth(YGNodeConstRef node) { @@ -327,17 +327,17 @@ YGValue YGNodeStyleGetWidth(YGNodeConstRef node) { void YGNodeStyleSetHeight(YGNodeRef node, float points) { updateStyle<&Style::dimension, &Style::setDimension>( - node, Dimension::Height, StyleLength::points(points)); + node, Dimension::Height, StyleSizeLength::points(points)); } void YGNodeStyleSetHeightPercent(YGNodeRef node, float percent) { updateStyle<&Style::dimension, &Style::setDimension>( - node, Dimension::Height, StyleLength::percent(percent)); + node, Dimension::Height, StyleSizeLength::percent(percent)); } void YGNodeStyleSetHeightAuto(YGNodeRef node) { updateStyle<&Style::dimension, &Style::setDimension>( - node, Dimension::Height, StyleLength::ofAuto()); + node, Dimension::Height, StyleSizeLength::ofAuto()); } YGValue YGNodeStyleGetHeight(YGNodeConstRef node) { @@ -346,12 +346,12 @@ YGValue YGNodeStyleGetHeight(YGNodeConstRef node) { void YGNodeStyleSetMinWidth(const YGNodeRef node, const float minWidth) { updateStyle<&Style::minDimension, &Style::setMinDimension>( - node, Dimension::Width, StyleLength::points(minWidth)); + node, Dimension::Width, StyleSizeLength::points(minWidth)); } void YGNodeStyleSetMinWidthPercent(const YGNodeRef node, const float minWidth) { updateStyle<&Style::minDimension, &Style::setMinDimension>( - node, Dimension::Width, StyleLength::percent(minWidth)); + node, Dimension::Width, StyleSizeLength::percent(minWidth)); } YGValue YGNodeStyleGetMinWidth(const YGNodeConstRef node) { @@ -360,14 +360,14 @@ YGValue YGNodeStyleGetMinWidth(const YGNodeConstRef node) { void YGNodeStyleSetMinHeight(const YGNodeRef node, const float minHeight) { updateStyle<&Style::minDimension, &Style::setMinDimension>( - node, Dimension::Height, StyleLength::points(minHeight)); + node, Dimension::Height, StyleSizeLength::points(minHeight)); } void YGNodeStyleSetMinHeightPercent( const YGNodeRef node, const float minHeight) { updateStyle<&Style::minDimension, &Style::setMinDimension>( - node, Dimension::Height, StyleLength::percent(minHeight)); + node, Dimension::Height, StyleSizeLength::percent(minHeight)); } YGValue YGNodeStyleGetMinHeight(const YGNodeConstRef node) { @@ -376,12 +376,12 @@ YGValue YGNodeStyleGetMinHeight(const YGNodeConstRef node) { void YGNodeStyleSetMaxWidth(const YGNodeRef node, const float maxWidth) { updateStyle<&Style::maxDimension, &Style::setMaxDimension>( - node, Dimension::Width, StyleLength::points(maxWidth)); + node, Dimension::Width, StyleSizeLength::points(maxWidth)); } void YGNodeStyleSetMaxWidthPercent(const YGNodeRef node, const float maxWidth) { updateStyle<&Style::maxDimension, &Style::setMaxDimension>( - node, Dimension::Width, StyleLength::percent(maxWidth)); + node, Dimension::Width, StyleSizeLength::percent(maxWidth)); } YGValue YGNodeStyleGetMaxWidth(const YGNodeConstRef node) { @@ -390,14 +390,14 @@ YGValue YGNodeStyleGetMaxWidth(const YGNodeConstRef node) { void YGNodeStyleSetMaxHeight(const YGNodeRef node, const float maxHeight) { updateStyle<&Style::maxDimension, &Style::setMaxDimension>( - node, Dimension::Height, StyleLength::points(maxHeight)); + node, Dimension::Height, StyleSizeLength::points(maxHeight)); } void YGNodeStyleSetMaxHeightPercent( const YGNodeRef node, const float maxHeight) { updateStyle<&Style::maxDimension, &Style::setMaxDimension>( - node, Dimension::Height, StyleLength::percent(maxHeight)); + node, Dimension::Height, StyleSizeLength::percent(maxHeight)); } YGValue YGNodeStyleGetMaxHeight(const YGNodeConstRef node) { diff --git a/packages/react-native/ReactCommon/yoga/yoga/YGValue.h b/packages/react-native/ReactCommon/yoga/yoga/YGValue.h index 7fa6fd918e5dc3..63c82f3da86e0b 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/YGValue.h +++ b/packages/react-native/ReactCommon/yoga/yoga/YGValue.h @@ -65,6 +65,9 @@ inline bool operator==(const YGValue& lhs, const YGValue& rhs) { switch (lhs.unit) { case YGUnitUndefined: case YGUnitAuto: + case YGUnitFitContent: + case YGUnitMaxContent: + case YGUnitStretch: return true; case YGUnitPoint: case YGUnitPercent: diff --git a/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp b/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp index 1932ff5508bebd..d245f255258986 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp @@ -749,7 +749,7 @@ static float distributeFreeSpaceSecondPass( marginCross; const bool isLoosePercentageMeasurement = currentLineChild->getProcessedDimension(dimension(crossAxis)) - .unit() == Unit::Percent && + .isPercent() && sizingModeCrossDim != SizingMode::StretchFit; childCrossSizingMode = yoga::isUndefined(childCrossSize) || isLoosePercentageMeasurement diff --git a/packages/react-native/ReactCommon/yoga/yoga/enums/Unit.h b/packages/react-native/ReactCommon/yoga/yoga/enums/Unit.h index 57bd1969708361..685b1caecee627 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/enums/Unit.h +++ b/packages/react-native/ReactCommon/yoga/yoga/enums/Unit.h @@ -20,11 +20,14 @@ enum class Unit : uint8_t { Point = YGUnitPoint, Percent = YGUnitPercent, Auto = YGUnitAuto, + MaxContent = YGUnitMaxContent, + FitContent = YGUnitFitContent, + Stretch = YGUnitStretch, }; template <> constexpr int32_t ordinalCount() { - return 4; + return 7; } constexpr Unit scopedEnum(YGUnit unscoped) { diff --git a/packages/react-native/ReactCommon/yoga/yoga/node/Node.cpp b/packages/react-native/ReactCommon/yoga/yoga/node/Node.cpp index cf36ab09a49ea3..e647a47b91d260 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/node/Node.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/node/Node.cpp @@ -314,16 +314,16 @@ void Node::setPosition( crossAxisTrailingEdge); } -Style::Length Node::processFlexBasis() const { - Style::Length flexBasis = style_.flexBasis(); - if (flexBasis.unit() != Unit::Auto && flexBasis.unit() != Unit::Undefined) { +Style::SizeLength Node::processFlexBasis() const { + Style::SizeLength flexBasis = style_.flexBasis(); + if (!flexBasis.isAuto() && !flexBasis.isUndefined()) { return flexBasis; } if (style_.flex().isDefined() && style_.flex().unwrap() > 0.0f) { - return config_->useWebDefaults() ? StyleLength::ofAuto() - : StyleLength::points(0); + return config_->useWebDefaults() ? StyleSizeLength::ofAuto() + : StyleSizeLength::points(0); } - return StyleLength::ofAuto(); + return StyleSizeLength::ofAuto(); } FloatOptional Node::resolveFlexBasis( diff --git a/packages/react-native/ReactCommon/yoga/yoga/node/Node.h b/packages/react-native/ReactCommon/yoga/yoga/node/Node.h index d596c564cf26e6..b3444c41180a8a 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/node/Node.h +++ b/packages/react-native/ReactCommon/yoga/yoga/node/Node.h @@ -172,7 +172,7 @@ class YG_EXPORT Node : public ::YGNode { return isDirty_; } - Style::Length getProcessedDimension(Dimension dimension) const { + Style::SizeLength getProcessedDimension(Dimension dimension) const { return processedDimensions_[static_cast(dimension)]; } @@ -268,7 +268,7 @@ class YG_EXPORT Node : public ::YGNode { void setPosition(Direction direction, float ownerWidth, float ownerHeight); // Other methods - Style::Length processFlexBasis() const; + Style::SizeLength processFlexBasis() const; FloatOptional resolveFlexBasis( Direction direction, FlexDirection flexDirection, @@ -322,8 +322,8 @@ class YG_EXPORT Node : public ::YGNode { Node* owner_ = nullptr; std::vector children_; const Config* config_; - std::array processedDimensions_{ - {StyleLength::undefined(), StyleLength::undefined()}}; + std::array processedDimensions_{ + {StyleSizeLength::undefined(), StyleSizeLength::undefined()}}; }; inline Node* resolveRef(const YGNodeRef ref) { diff --git a/packages/react-native/ReactCommon/yoga/yoga/style/Style.h b/packages/react-native/ReactCommon/yoga/yoga/style/Style.h index 73203e6cca3c7c..923b268bf8f27d 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/style/Style.h +++ b/packages/react-native/ReactCommon/yoga/yoga/style/Style.h @@ -30,6 +30,7 @@ #include #include #include +#include #include namespace facebook::yoga { @@ -37,6 +38,7 @@ namespace facebook::yoga { class YG_EXPORT Style { public: using Length = StyleLength; + using SizeLength = StyleSizeLength; static constexpr float DefaultFlexGrow = 0.0f; static constexpr float DefaultFlexShrink = 0.0f; @@ -133,10 +135,10 @@ class YG_EXPORT Style { pool_.store(flexShrink_, value); } - Style::Length flexBasis() const { - return pool_.getLength(flexBasis_); + Style::SizeLength flexBasis() const { + return pool_.getSize(flexBasis_); } - void setFlexBasis(Style::Length value) { + void setFlexBasis(Style::SizeLength value) { pool_.store(flexBasis_, value); } @@ -175,17 +177,17 @@ class YG_EXPORT Style { pool_.store(gap_[yoga::to_underlying(gutter)], value); } - Style::Length dimension(Dimension axis) const { - return pool_.getLength(dimensions_[yoga::to_underlying(axis)]); + Style::SizeLength dimension(Dimension axis) const { + return pool_.getSize(dimensions_[yoga::to_underlying(axis)]); } - void setDimension(Dimension axis, Style::Length value) { + void setDimension(Dimension axis, Style::SizeLength value) { pool_.store(dimensions_[yoga::to_underlying(axis)], value); } - Style::Length minDimension(Dimension axis) const { - return pool_.getLength(minDimensions_[yoga::to_underlying(axis)]); + Style::SizeLength minDimension(Dimension axis) const { + return pool_.getSize(minDimensions_[yoga::to_underlying(axis)]); } - void setMinDimension(Dimension axis, Style::Length value) { + void setMinDimension(Dimension axis, Style::SizeLength value) { pool_.store(minDimensions_[yoga::to_underlying(axis)], value); } @@ -207,10 +209,10 @@ class YG_EXPORT Style { : FloatOptional{0.0}); } - Style::Length maxDimension(Dimension axis) const { - return pool_.getLength(maxDimensions_[yoga::to_underlying(axis)]); + Style::SizeLength maxDimension(Dimension axis) const { + return pool_.getSize(maxDimensions_[yoga::to_underlying(axis)]); } - void setMaxDimension(Dimension axis, Style::Length value) { + void setMaxDimension(Dimension axis, Style::SizeLength value) { pool_.store(maxDimensions_[yoga::to_underlying(axis)], value); } diff --git a/packages/react-native/ReactCommon/yoga/yoga/style/StyleLength.h b/packages/react-native/ReactCommon/yoga/yoga/style/StyleLength.h index 7cc42d9eb5c8d0..01e69718b2bc2c 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/style/StyleLength.h +++ b/packages/react-native/ReactCommon/yoga/yoga/style/StyleLength.h @@ -19,13 +19,11 @@ namespace facebook::yoga { * 3. A CSS value: * a. value (e.g. 10px) * b. value of a reference - * 4. (soon) A math function which returns a value * * References: * 1. https://www.w3.org/TR/css-values-4/#lengths * 2. https://www.w3.org/TR/css-values-4/#percentage-value * 3. https://www.w3.org/TR/css-values-4/#mixed-percentages - * 4. https://www.w3.org/TR/css-values-4/#math */ class StyleLength { public: @@ -59,6 +57,14 @@ class StyleLength { return unit_ == Unit::Undefined; } + constexpr bool isPoints() const { + return unit_ == Unit::Point; + } + + constexpr bool isPercent() const { + return unit_ == Unit::Percent; + } + constexpr bool isDefined() const { return !isUndefined(); } @@ -67,10 +73,6 @@ class StyleLength { return value_; } - constexpr Unit unit() const { - return unit_; - } - constexpr FloatOptional resolve(float referenceLength) { switch (unit_) { case Unit::Point: @@ -90,6 +92,11 @@ class StyleLength { return value_ == rhs.value_ && unit_ == rhs.unit_; } + constexpr bool inexactEquals(const StyleLength& other) const { + return unit_ == other.unit_ && + facebook::yoga::inexactEquals(value_, other.value_); + } + private: // We intentionally do not allow direct construction using value and unit, to // avoid invalid, or redundant combinations. @@ -101,7 +108,7 @@ class StyleLength { }; inline bool inexactEquals(const StyleLength& a, const StyleLength& b) { - return a.unit() == b.unit() && inexactEquals(a.value(), b.value()); + return a.inexactEquals(b); } } // namespace facebook::yoga diff --git a/packages/react-native/ReactCommon/yoga/yoga/style/StyleSizeLength.h b/packages/react-native/ReactCommon/yoga/yoga/style/StyleSizeLength.h new file mode 100644 index 00000000000000..8dc4f2401320ad --- /dev/null +++ b/packages/react-native/ReactCommon/yoga/yoga/style/StyleSizeLength.h @@ -0,0 +1,139 @@ +/* + * Copyright (c) Meta Platforms, Inc. and 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 + +namespace facebook::yoga { + +/** + * This class represents a CSS Value for sizes (e.g. width, height, min-width, + * etc.). It may be one of: + * 1. Undefined + * 2. A keyword (e.g. auto, max-content, stretch, etc.) + * 3. A CSS value: + * a. value (e.g. 10px) + * b. value of a reference + * + * References: + * 1. https://www.w3.org/TR/css-values-4/#lengths + * 2. https://www.w3.org/TR/css-values-4/#percentage-value + * 3. https://www.w3.org/TR/css-values-4/#mixed-percentages + */ +class StyleSizeLength { + public: + constexpr StyleSizeLength() = default; + + constexpr static StyleSizeLength points(float value) { + return yoga::isUndefined(value) || yoga::isinf(value) + ? undefined() + : StyleSizeLength{FloatOptional{value}, Unit::Point}; + } + + constexpr static StyleSizeLength percent(float value) { + return yoga::isUndefined(value) || yoga::isinf(value) + ? undefined() + : StyleSizeLength{FloatOptional{value}, Unit::Percent}; + } + + constexpr static StyleSizeLength ofAuto() { + return StyleSizeLength{{}, Unit::Auto}; + } + + constexpr static StyleSizeLength ofMaxContent() { + return StyleSizeLength{{}, Unit::MaxContent}; + } + + constexpr static StyleSizeLength ofFitContent() { + return StyleSizeLength{{}, Unit::FitContent}; + } + + constexpr static StyleSizeLength ofStretch() { + return StyleSizeLength{{}, Unit::Stretch}; + } + + constexpr static StyleSizeLength undefined() { + return StyleSizeLength{{}, Unit::Undefined}; + } + + constexpr bool isAuto() const { + return unit_ == Unit::Auto; + } + + constexpr bool isMaxContent() const { + return unit_ == Unit::MaxContent; + } + + constexpr bool isFitContent() const { + return unit_ == Unit::FitContent; + } + + constexpr bool isStretch() const { + return unit_ == Unit::Stretch; + } + + constexpr bool isUndefined() const { + return unit_ == Unit::Undefined; + } + + constexpr bool isDefined() const { + return !isUndefined(); + } + + constexpr bool isPoints() const { + return unit_ == Unit::Point; + } + + constexpr bool isPercent() const { + return unit_ == Unit::Percent; + } + + constexpr FloatOptional value() const { + return value_; + } + + constexpr FloatOptional resolve(float referenceLength) { + switch (unit_) { + case Unit::Point: + return value_; + case Unit::Percent: + return FloatOptional{value_.unwrap() * referenceLength * 0.01f}; + default: + return FloatOptional{}; + } + } + + explicit constexpr operator YGValue() const { + return YGValue{value_.unwrap(), unscopedEnum(unit_)}; + } + + constexpr bool operator==(const StyleSizeLength& rhs) const { + return value_ == rhs.value_ && unit_ == rhs.unit_; + } + + constexpr bool inexactEquals(const StyleSizeLength& other) const { + return unit_ == other.unit_ && + facebook::yoga::inexactEquals(value_, other.value_); + } + + private: + // We intentionally do not allow direct construction using value and unit, to + // avoid invalid, or redundant combinations. + constexpr StyleSizeLength(FloatOptional value, Unit unit) + : value_(value), unit_(unit) {} + + FloatOptional value_{}; + Unit unit_{Unit::Undefined}; +}; + +inline bool inexactEquals(const StyleSizeLength& a, const StyleSizeLength& b) { + return a.inexactEquals(b); +} + +} // namespace facebook::yoga diff --git a/packages/react-native/ReactCommon/yoga/yoga/style/StyleValueHandle.h b/packages/react-native/ReactCommon/yoga/yoga/style/StyleValueHandle.h index f4b97f0a9f7d00..d9c6ae05791ee5 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/style/StyleValueHandle.h +++ b/packages/react-native/ReactCommon/yoga/yoga/style/StyleValueHandle.h @@ -62,8 +62,16 @@ class StyleValueHandle { Percent, Number, Auto, + Keyword }; + // Intentionally leaving out auto as a fast path + enum class Keyword : uint8_t { MaxContent, FitContent, Stretch }; + + constexpr bool isKeyword(Keyword keyword) const { + return type() == Type::Keyword && value() == static_cast(keyword); + } + constexpr Type type() const { return static_cast(repr_ & kHandleTypeMask); } diff --git a/packages/react-native/ReactCommon/yoga/yoga/style/StyleValuePool.h b/packages/react-native/ReactCommon/yoga/yoga/style/StyleValuePool.h index 597eae4c4374a9..dfee30ade9f1b0 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/style/StyleValuePool.h +++ b/packages/react-native/ReactCommon/yoga/yoga/style/StyleValuePool.h @@ -13,6 +13,7 @@ #include #include #include +#include #include namespace facebook::yoga { @@ -32,13 +33,30 @@ class StyleValuePool { } else if (length.isAuto()) { handle.setType(StyleValueHandle::Type::Auto); } else { - auto type = length.unit() == Unit::Point - ? StyleValueHandle::Type::Point - : StyleValueHandle::Type::Percent; + auto type = length.isPoints() ? StyleValueHandle::Type::Point + : StyleValueHandle::Type::Percent; storeValue(handle, length.value().unwrap(), type); } } + void store(StyleValueHandle& handle, StyleSizeLength sizeValue) { + if (sizeValue.isUndefined()) { + handle.setType(StyleValueHandle::Type::Undefined); + } else if (sizeValue.isAuto()) { + handle.setType(StyleValueHandle::Type::Auto); + } else if (sizeValue.isMaxContent()) { + storeKeyword(handle, StyleValueHandle::Keyword::MaxContent); + } else if (sizeValue.isStretch()) { + storeKeyword(handle, StyleValueHandle::Keyword::Stretch); + } else if (sizeValue.isFitContent()) { + storeKeyword(handle, StyleValueHandle::Keyword::FitContent); + } else { + auto type = sizeValue.isPoints() ? StyleValueHandle::Type::Point + : StyleValueHandle::Type::Percent; + storeValue(handle, sizeValue.value().unwrap(), type); + } + } + void store(StyleValueHandle& handle, FloatOptional number) { if (number.isUndefined()) { handle.setType(StyleValueHandle::Type::Undefined); @@ -66,6 +84,31 @@ class StyleValuePool { } } + StyleSizeLength getSize(StyleValueHandle handle) const { + if (handle.isUndefined()) { + return StyleSizeLength::undefined(); + } else if (handle.isAuto()) { + return StyleSizeLength::ofAuto(); + } else if (handle.isKeyword(StyleValueHandle::Keyword::MaxContent)) { + return StyleSizeLength::ofMaxContent(); + } else if (handle.isKeyword(StyleValueHandle::Keyword::FitContent)) { + return StyleSizeLength::ofFitContent(); + } else if (handle.isKeyword(StyleValueHandle::Keyword::Stretch)) { + return StyleSizeLength::ofStretch(); + } else { + assert( + handle.type() == StyleValueHandle::Type::Point || + handle.type() == StyleValueHandle::Type::Percent); + float value = (handle.isValueIndexed()) + ? std::bit_cast(buffer_.get32(handle.value())) + : unpackInlineInteger(handle.value()); + + return handle.type() == StyleValueHandle::Type::Point + ? StyleSizeLength::points(value) + : StyleSizeLength::percent(value); + } + } + FloatOptional getNumber(StyleValueHandle handle) const { if (handle.isUndefined()) { return FloatOptional{}; @@ -98,6 +141,20 @@ class StyleValuePool { } } + void storeKeyword( + StyleValueHandle& handle, + StyleValueHandle::Keyword keyword) { + handle.setType(StyleValueHandle::Type::Keyword); + + if (handle.isValueIndexed()) { + auto newIndex = + buffer_.replace(handle.value(), static_cast(keyword)); + handle.setValue(newIndex); + } else { + handle.setValue(static_cast(keyword)); + } + } + static constexpr bool isIntegerPackable(float f) { constexpr uint16_t kMaxInlineAbsValue = (1 << 11) - 1; From c9a96715efba1fcea83f831be030f041e6f74a73 Mon Sep 17 00:00:00 2001 From: Joe Vilches Date: Mon, 4 Nov 2024 16:02:37 -0800 Subject: [PATCH 045/220] Update public API for intrinsic sizing setters (#46939) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/46939 X-link: https://github.com/facebook/yoga/pull/1722 tsia! opted for one function for each keyword just like auto. This is kinda annoying and not the most sustainable, so maybe it makes more sense to make a new enum here and just add one function Changelog: [Internal] Reviewed By: NickGerleman Differential Revision: D64002837 fbshipit-source-id: f15fae9fc0103175e1d85850fc9aa68579989fd3 --- .../react-native/React/Views/RCTShadowView.m | 43 +++++-- .../java/com/facebook/yoga/YogaNative.java | 21 ++++ .../main/java/com/facebook/yoga/YogaNode.java | 42 +++++++ .../com/facebook/yoga/YogaNodeJNIBase.java | 84 ++++++++++++++ .../java/com/facebook/yoga/YogaProps.java | 46 +++++++- .../first-party/yogajni/jni/YGJNIVanilla.cpp | 99 +++++++++++++++-- .../ReactCommon/yoga/yoga/YGNodeStyle.cpp | 105 ++++++++++++++++++ .../ReactCommon/yoga/yoga/YGNodeStyle.h | 21 ++++ 8 files changed, 443 insertions(+), 18 deletions(-) diff --git a/packages/react-native/React/Views/RCTShadowView.m b/packages/react-native/React/Views/RCTShadowView.m index 66385dba06ffd4..53c51d2bbdef1c 100644 --- a/packages/react-native/React/Views/RCTShadowView.m +++ b/packages/react-native/React/Views/RCTShadowView.m @@ -97,6 +97,31 @@ + (YGConfigRef)yogaConfig break; \ } +#define RCT_SET_YGVALUE_AUTO_INTRINSIC(ygvalue, setter, ...) \ + switch (ygvalue.unit) { \ + case YGUnitAuto: \ + setter##Auto(__VA_ARGS__); \ + break; \ + case YGUnitMaxContent: \ + setter##MaxContent(__VA_ARGS__); \ + break; \ + case YGUnitFitContent: \ + setter##FitContent(__VA_ARGS__); \ + break; \ + case YGUnitStretch: \ + setter##Stretch(__VA_ARGS__); \ + break; \ + case YGUnitUndefined: \ + setter(__VA_ARGS__, YGUndefined); \ + break; \ + case YGUnitPoint: \ + setter(__VA_ARGS__, ygvalue.value); \ + break; \ + case YGUnitPercent: \ + setter##Percent(__VA_ARGS__, ygvalue.value); \ + break; \ + } + static void RCTProcessMetaPropsPadding(const YGValue metaProps[META_PROP_COUNT], YGNodeRef node) { if (![[RCTI18nUtil sharedInstance] doLeftAndRightSwapInRTL]) { @@ -490,14 +515,14 @@ -(float)border##prop##Width \ RCT_BORDER_PROPERTY(End, END) // Dimensions -#define RCT_DIMENSION_PROPERTY(setProp, getProp, cssProp) \ - -(void)set##setProp : (YGValue)value \ - { \ - RCT_SET_YGVALUE_AUTO(value, YGNodeStyleSet##cssProp, _yogaNode); \ - } \ - -(YGValue)getProp \ - { \ - return YGNodeStyleGet##cssProp(_yogaNode); \ +#define RCT_DIMENSION_PROPERTY(setProp, getProp, cssProp) \ + -(void)set##setProp : (YGValue)value \ + { \ + RCT_SET_YGVALUE_AUTO_INTRINSIC(value, YGNodeStyleSet##cssProp, _yogaNode); \ + } \ + -(YGValue)getProp \ + { \ + return YGNodeStyleGet##cssProp(_yogaNode); \ } #define RCT_MIN_MAX_DIMENSION_PROPERTY(setProp, getProp, cssProp) \ @@ -641,7 +666,7 @@ - (void)setLocalData:(__unused NSObject *)localData - (void)setFlexBasis:(YGValue)value { - RCT_SET_YGVALUE_AUTO(value, YGNodeStyleSetFlexBasis, _yogaNode); + RCT_SET_YGVALUE_AUTO_INTRINSIC(value, YGNodeStyleSetFlexBasis, _yogaNode); } - (YGValue)flexBasis diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaNative.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaNative.java index 89ef5ef16f536f..582bd1eb19efd7 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaNative.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaNative.java @@ -74,6 +74,9 @@ public class YogaNative { static native void jni_YGNodeStyleSetFlexBasisJNI(long nativePointer, float flexBasis); static native void jni_YGNodeStyleSetFlexBasisPercentJNI(long nativePointer, float percent); static native void jni_YGNodeStyleSetFlexBasisAutoJNI(long nativePointer); + static native void jni_YGNodeStyleSetFlexBasisMaxContentJNI(long nativePointer); + static native void jni_YGNodeStyleSetFlexBasisFitContentJNI(long nativePointer); + static native void jni_YGNodeStyleSetFlexBasisStretchJNI(long nativePointer); static native long jni_YGNodeStyleGetMarginJNI(long nativePointer, int edge); static native void jni_YGNodeStyleSetMarginJNI(long nativePointer, int edge, float margin); static native void jni_YGNodeStyleSetMarginPercentJNI(long nativePointer, int edge, float percent); @@ -91,22 +94,40 @@ public class YogaNative { static native void jni_YGNodeStyleSetWidthJNI(long nativePointer, float width); static native void jni_YGNodeStyleSetWidthPercentJNI(long nativePointer, float percent); static native void jni_YGNodeStyleSetWidthAutoJNI(long nativePointer); + static native void jni_YGNodeStyleSetWidthMaxContentJNI(long nativePointer); + static native void jni_YGNodeStyleSetWidthFitContentJNI(long nativePointer); + static native void jni_YGNodeStyleSetWidthStretchJNI(long nativePointer); static native long jni_YGNodeStyleGetHeightJNI(long nativePointer); static native void jni_YGNodeStyleSetHeightJNI(long nativePointer, float height); static native void jni_YGNodeStyleSetHeightPercentJNI(long nativePointer, float percent); static native void jni_YGNodeStyleSetHeightAutoJNI(long nativePointer); + static native void jni_YGNodeStyleSetHeightMaxContentJNI(long nativePointer); + static native void jni_YGNodeStyleSetHeightFitContentJNI(long nativePointer); + static native void jni_YGNodeStyleSetHeightStretchJNI(long nativePointer); static native long jni_YGNodeStyleGetMinWidthJNI(long nativePointer); static native void jni_YGNodeStyleSetMinWidthJNI(long nativePointer, float minWidth); static native void jni_YGNodeStyleSetMinWidthPercentJNI(long nativePointer, float percent); + static native void jni_YGNodeStyleSetMinWidthMaxContentJNI(long nativePointer); + static native void jni_YGNodeStyleSetMinWidthFitContentJNI(long nativePointer); + static native void jni_YGNodeStyleSetMinWidthStretchJNI(long nativePointer); static native long jni_YGNodeStyleGetMinHeightJNI(long nativePointer); static native void jni_YGNodeStyleSetMinHeightJNI(long nativePointer, float minHeight); static native void jni_YGNodeStyleSetMinHeightPercentJNI(long nativePointer, float percent); + static native void jni_YGNodeStyleSetMinHeightMaxContentJNI(long nativePointer); + static native void jni_YGNodeStyleSetMinHeightFitContentJNI(long nativePointer); + static native void jni_YGNodeStyleSetMinHeightStretchJNI(long nativePointer); static native long jni_YGNodeStyleGetMaxWidthJNI(long nativePointer); static native void jni_YGNodeStyleSetMaxWidthJNI(long nativePointer, float maxWidth); static native void jni_YGNodeStyleSetMaxWidthPercentJNI(long nativePointer, float percent); + static native void jni_YGNodeStyleSetMaxWidthMaxContentJNI(long nativePointer); + static native void jni_YGNodeStyleSetMaxWidthFitContentJNI(long nativePointer); + static native void jni_YGNodeStyleSetMaxWidthStretchJNI(long nativePointer); static native long jni_YGNodeStyleGetMaxHeightJNI(long nativePointer); static native void jni_YGNodeStyleSetMaxHeightJNI(long nativePointer, float maxheight); static native void jni_YGNodeStyleSetMaxHeightPercentJNI(long nativePointer, float percent); + static native void jni_YGNodeStyleSetMaxHeightMaxContentJNI(long nativePointer); + static native void jni_YGNodeStyleSetMaxHeightFitContentJNI(long nativePointer); + static native void jni_YGNodeStyleSetMaxHeightStretchJNI(long nativePointer); static native float jni_YGNodeStyleGetAspectRatioJNI(long nativePointer); static native void jni_YGNodeStyleSetAspectRatioJNI(long nativePointer, float aspectRatio); static native float jni_YGNodeStyleGetGapJNI(long nativePointer, int gutter); diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaNode.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaNode.java index ba076846759607..b683b553ca4e8f 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaNode.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaNode.java @@ -124,6 +124,12 @@ public interface Inputs { public abstract void setFlexBasisAuto(); + public abstract void setFlexBasisMaxContent(); + + public abstract void setFlexBasisFitContent(); + + public abstract void setFlexBasisStretch(); + public abstract YogaValue getMargin(YogaEdge edge); public abstract void setMargin(YogaEdge edge, float margin); @@ -158,6 +164,12 @@ public interface Inputs { public abstract void setWidthAuto(); + public abstract void setWidthMaxContent(); + + public abstract void setWidthFitContent(); + + public abstract void setWidthStretch(); + public abstract YogaValue getHeight(); public abstract void setHeight(float height); @@ -166,30 +178,60 @@ public interface Inputs { public abstract void setHeightAuto(); + public abstract void setHeightMaxContent(); + + public abstract void setHeightFitContent(); + + public abstract void setHeightStretch(); + public abstract YogaValue getMinWidth(); public abstract void setMinWidth(float minWidth); public abstract void setMinWidthPercent(float percent); + public abstract void setMinWidthMaxContent(); + + public abstract void setMinWidthFitContent(); + + public abstract void setMinWidthStretch(); + public abstract YogaValue getMinHeight(); public abstract void setMinHeight(float minHeight); public abstract void setMinHeightPercent(float percent); + public abstract void setMinHeightMaxContent(); + + public abstract void setMinHeightFitContent(); + + public abstract void setMinHeightStretch(); + public abstract YogaValue getMaxWidth(); public abstract void setMaxWidth(float maxWidth); public abstract void setMaxWidthPercent(float percent); + public abstract void setMaxWidthMaxContent(); + + public abstract void setMaxWidthFitContent(); + + public abstract void setMaxWidthStretch(); + public abstract YogaValue getMaxHeight(); public abstract void setMaxHeight(float maxheight); public abstract void setMaxHeightPercent(float percent); + public abstract void setMaxHeightMaxContent(); + + public abstract void setMaxHeightFitContent(); + + public abstract void setMaxHeightStretch(); + public abstract float getAspectRatio(); public abstract void setAspectRatio(float aspectRatio); diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaNodeJNIBase.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaNodeJNIBase.java index a53fe74af00241..e25872545e4913 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaNodeJNIBase.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaNodeJNIBase.java @@ -373,6 +373,18 @@ public void setFlexBasisAuto() { YogaNative.jni_YGNodeStyleSetFlexBasisAutoJNI(mNativePointer); } + public void setFlexBasisMaxContent() { + YogaNative.jni_YGNodeStyleSetFlexBasisMaxContentJNI(mNativePointer); + } + + public void setFlexBasisFitContent() { + YogaNative.jni_YGNodeStyleSetFlexBasisFitContentJNI(mNativePointer); + } + + public void setFlexBasisStretch() { + YogaNative.jni_YGNodeStyleSetFlexBasisStretchJNI(mNativePointer); + } + public YogaValue getMargin(YogaEdge edge) { return valueFromLong(YogaNative.jni_YGNodeStyleGetMarginJNI(mNativePointer, edge.intValue())); } @@ -441,6 +453,18 @@ public void setWidthAuto() { YogaNative.jni_YGNodeStyleSetWidthAutoJNI(mNativePointer); } + public void setWidthMaxContent() { + YogaNative.jni_YGNodeStyleSetWidthMaxContentJNI(mNativePointer); + } + + public void setWidthFitContent() { + YogaNative.jni_YGNodeStyleSetWidthFitContentJNI(mNativePointer); + } + + public void setWidthStretch() { + YogaNative.jni_YGNodeStyleSetWidthStretchJNI(mNativePointer); + } + public YogaValue getHeight() { return valueFromLong(YogaNative.jni_YGNodeStyleGetHeightJNI(mNativePointer)); } @@ -457,6 +481,18 @@ public void setHeightAuto() { YogaNative.jni_YGNodeStyleSetHeightAutoJNI(mNativePointer); } + public void setHeightMaxContent() { + YogaNative.jni_YGNodeStyleSetHeightMaxContentJNI(mNativePointer); + } + + public void setHeightFitContent() { + YogaNative.jni_YGNodeStyleSetHeightFitContentJNI(mNativePointer); + } + + public void setHeightStretch() { + YogaNative.jni_YGNodeStyleSetHeightStretchJNI(mNativePointer); + } + public YogaValue getMinWidth() { return valueFromLong(YogaNative.jni_YGNodeStyleGetMinWidthJNI(mNativePointer)); } @@ -469,6 +505,18 @@ public void setMinWidthPercent(float percent) { YogaNative.jni_YGNodeStyleSetMinWidthPercentJNI(mNativePointer, percent); } + public void setMinWidthMaxContent() { + YogaNative.jni_YGNodeStyleSetMinWidthMaxContentJNI(mNativePointer); + } + + public void setMinWidthFitContent() { + YogaNative.jni_YGNodeStyleSetMinWidthFitContentJNI(mNativePointer); + } + + public void setMinWidthStretch() { + YogaNative.jni_YGNodeStyleSetMinWidthStretchJNI(mNativePointer); + } + public YogaValue getMinHeight() { return valueFromLong(YogaNative.jni_YGNodeStyleGetMinHeightJNI(mNativePointer)); } @@ -481,6 +529,18 @@ public void setMinHeightPercent(float percent) { YogaNative.jni_YGNodeStyleSetMinHeightPercentJNI(mNativePointer, percent); } + public void setMinHeightMaxContent() { + YogaNative.jni_YGNodeStyleSetMinHeightMaxContentJNI(mNativePointer); + } + + public void setMinHeightFitContent() { + YogaNative.jni_YGNodeStyleSetMinHeightFitContentJNI(mNativePointer); + } + + public void setMinHeightStretch() { + YogaNative.jni_YGNodeStyleSetMinHeightStretchJNI(mNativePointer); + } + public YogaValue getMaxWidth() { return valueFromLong(YogaNative.jni_YGNodeStyleGetMaxWidthJNI(mNativePointer)); } @@ -493,6 +553,18 @@ public void setMaxWidthPercent(float percent) { YogaNative.jni_YGNodeStyleSetMaxWidthPercentJNI(mNativePointer, percent); } + public void setMaxWidthMaxContent() { + YogaNative.jni_YGNodeStyleSetMaxWidthMaxContentJNI(mNativePointer); + } + + public void setMaxWidthFitContent() { + YogaNative.jni_YGNodeStyleSetMaxWidthFitContentJNI(mNativePointer); + } + + public void setMaxWidthStretch() { + YogaNative.jni_YGNodeStyleSetMaxWidthStretchJNI(mNativePointer); + } + public YogaValue getMaxHeight() { return valueFromLong(YogaNative.jni_YGNodeStyleGetMaxHeightJNI(mNativePointer)); } @@ -505,6 +577,18 @@ public void setMaxHeightPercent(float percent) { YogaNative.jni_YGNodeStyleSetMaxHeightPercentJNI(mNativePointer, percent); } + public void setMaxHeightMaxContent() { + YogaNative.jni_YGNodeStyleSetMaxHeightMaxContentJNI(mNativePointer); + } + + public void setMaxHeightFitContent() { + YogaNative.jni_YGNodeStyleSetMaxHeightFitContentJNI(mNativePointer); + } + + public void setMaxHeightStretch() { + YogaNative.jni_YGNodeStyleSetMaxHeightStretchJNI(mNativePointer); + } + public float getAspectRatio() { return YogaNative.jni_YGNodeStyleGetAspectRatioJNI(mNativePointer); } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaProps.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaProps.java index c596c6a7c1c817..0cad45fa9cc311 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaProps.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaProps.java @@ -15,15 +15,33 @@ public interface YogaProps { void setWidthPercent(float percent); + void setWidthAuto(); + + void setWidthMaxContent(); + + void setWidthFitContent(); + + void setWidthStretch(); + void setMinWidth(float minWidth); void setMinWidthPercent(float percent); + void setMinWidthMaxContent(); + + void setMinWidthFitContent(); + + void setMinWidthStretch(); + void setMaxWidth(float maxWidth); void setMaxWidthPercent(float percent); - void setWidthAuto(); + void setMaxWidthMaxContent(); + + void setMaxWidthFitContent(); + + void setMaxWidthStretch(); /* Height properties */ @@ -31,15 +49,33 @@ public interface YogaProps { void setHeightPercent(float percent); + void setHeightAuto(); + + void setHeightMaxContent(); + + void setHeightFitContent(); + + void setHeightStretch(); + void setMinHeight(float minHeight); void setMinHeightPercent(float percent); + void setMinHeightMaxContent(); + + void setMinHeightFitContent(); + + void setMinHeightStretch(); + void setMaxHeight(float maxHeight); void setMaxHeightPercent(float percent); - void setHeightAuto(); + void setMaxHeightMaxContent(); + + void setMaxHeightFitContent(); + + void setMaxHeightStretch(); /* Margin properties */ @@ -81,6 +117,12 @@ public interface YogaProps { void setFlexBasis(float flexBasis); + void setFlexBasisMaxContent(); + + void setFlexBasisFitContent(); + + void setFlexBasisStretch(); + void setFlexDirection(YogaFlexDirection direction); void setFlexGrow(float flexGrow); diff --git a/packages/react-native/ReactAndroid/src/main/jni/first-party/yogajni/jni/YGJNIVanilla.cpp b/packages/react-native/ReactAndroid/src/main/jni/first-party/yogajni/jni/YGJNIVanilla.cpp index 6b8ed14bd694f7..95273836c22bd1 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/first-party/yogajni/jni/YGJNIVanilla.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/first-party/yogajni/jni/YGJNIVanilla.cpp @@ -429,6 +429,28 @@ static void jni_YGNodeCopyStyleJNI( YGNodeStyleSet##name##Auto(_jlong2YGNodeRef(nativePointer)); \ } +#define YG_NODE_JNI_STYLE_UNIT_PROP_AUTO_INTRINSIC(name) \ + YG_NODE_JNI_STYLE_UNIT_PROP_AUTO(name) \ + YG_NODE_JNI_STYLE_UNIT_INTRINSIC(name) + +#define YG_NODE_JNI_STYLE_UNIT_PROP_INTRINSIC(name) \ + YG_NODE_JNI_STYLE_UNIT_PROP(name) \ + YG_NODE_JNI_STYLE_UNIT_INTRINSIC(name) + +#define YG_NODE_JNI_STYLE_UNIT_INTRINSIC(name) \ + static void jni_YGNodeStyleSet##name##MaxContentJNI( \ + JNIEnv* /*env*/, jobject /*obj*/, jlong nativePointer) { \ + YGNodeStyleSet##name##MaxContent(_jlong2YGNodeRef(nativePointer)); \ + } \ + static void jni_YGNodeStyleSet##name##FitContentJNI( \ + JNIEnv* /*env*/, jobject /*obj*/, jlong nativePointer) { \ + YGNodeStyleSet##name##FitContent(_jlong2YGNodeRef(nativePointer)); \ + } \ + static void jni_YGNodeStyleSet##name##StretchJNI( \ + JNIEnv* /*env*/, jobject /*obj*/, jlong nativePointer) { \ + YGNodeStyleSet##name##Stretch(_jlong2YGNodeRef(nativePointer)); \ + } + #define YG_NODE_JNI_STYLE_EDGE_UNIT_PROP(name) \ static jlong jni_YGNodeStyleGet##name##JNI( \ JNIEnv* /*env*/, jobject /*obj*/, jlong nativePointer, jint edge) { \ @@ -483,13 +505,13 @@ YG_NODE_JNI_STYLE_PROP(jfloat, float, Flex); YG_NODE_JNI_STYLE_PROP(jfloat, float, FlexGrow); YG_NODE_JNI_STYLE_PROP(jfloat, float, FlexShrink); -YG_NODE_JNI_STYLE_UNIT_PROP_AUTO(FlexBasis); -YG_NODE_JNI_STYLE_UNIT_PROP_AUTO(Width); -YG_NODE_JNI_STYLE_UNIT_PROP(MinWidth); -YG_NODE_JNI_STYLE_UNIT_PROP(MaxWidth); -YG_NODE_JNI_STYLE_UNIT_PROP_AUTO(Height); -YG_NODE_JNI_STYLE_UNIT_PROP(MinHeight); -YG_NODE_JNI_STYLE_UNIT_PROP(MaxHeight); +YG_NODE_JNI_STYLE_UNIT_PROP_AUTO_INTRINSIC(FlexBasis); +YG_NODE_JNI_STYLE_UNIT_PROP_AUTO_INTRINSIC(Width); +YG_NODE_JNI_STYLE_UNIT_PROP_INTRINSIC(MinWidth); +YG_NODE_JNI_STYLE_UNIT_PROP_INTRINSIC(MaxWidth); +YG_NODE_JNI_STYLE_UNIT_PROP_AUTO_INTRINSIC(Height); +YG_NODE_JNI_STYLE_UNIT_PROP_INTRINSIC(MinHeight); +YG_NODE_JNI_STYLE_UNIT_PROP_INTRINSIC(MaxHeight); YG_NODE_JNI_STYLE_EDGE_UNIT_PROP_AUTO(Position); @@ -870,6 +892,15 @@ static JNINativeMethod methods[] = { {"jni_YGNodeStyleSetFlexBasisAutoJNI", "(J)V", (void*)jni_YGNodeStyleSetFlexBasisAutoJNI}, + {"jni_YGNodeStyleSetFlexBasisMaxContentJNI", + "(J)V", + (void*)jni_YGNodeStyleSetFlexBasisMaxContentJNI}, + {"jni_YGNodeStyleSetFlexBasisFitContentJNI", + "(J)V", + (void*)jni_YGNodeStyleSetFlexBasisFitContentJNI}, + {"jni_YGNodeStyleSetFlexBasisStretchJNI", + "(J)V", + (void*)jni_YGNodeStyleSetFlexBasisStretchJNI}, {"jni_YGNodeStyleGetMarginJNI", "(JI)J", (void*)jni_YGNodeStyleGetMarginJNI}, @@ -917,6 +948,15 @@ static JNINativeMethod methods[] = { {"jni_YGNodeStyleSetWidthAutoJNI", "(J)V", (void*)jni_YGNodeStyleSetWidthAutoJNI}, + {"jni_YGNodeStyleSetWidthMaxContentJNI", + "(J)V", + (void*)jni_YGNodeStyleSetWidthMaxContentJNI}, + {"jni_YGNodeStyleSetWidthFitContentJNI", + "(J)V", + (void*)jni_YGNodeStyleSetWidthFitContentJNI}, + {"jni_YGNodeStyleSetWidthStretchJNI", + "(J)V", + (void*)jni_YGNodeStyleSetWidthStretchJNI}, {"jni_YGNodeStyleGetHeightJNI", "(J)J", (void*)jni_YGNodeStyleGetHeightJNI}, {"jni_YGNodeStyleSetHeightJNI", "(JF)V", @@ -927,6 +967,15 @@ static JNINativeMethod methods[] = { {"jni_YGNodeStyleSetHeightAutoJNI", "(J)V", (void*)jni_YGNodeStyleSetHeightAutoJNI}, + {"jni_YGNodeStyleSetHeightMaxContentJNI", + "(J)V", + (void*)jni_YGNodeStyleSetHeightMaxContentJNI}, + {"jni_YGNodeStyleSetHeightFitContentJNI", + "(J)V", + (void*)jni_YGNodeStyleSetHeightFitContentJNI}, + {"jni_YGNodeStyleSetHeightStretchJNI", + "(J)V", + (void*)jni_YGNodeStyleSetHeightStretchJNI}, {"jni_YGNodeStyleGetMinWidthJNI", "(J)J", (void*)jni_YGNodeStyleGetMinWidthJNI}, @@ -936,6 +985,15 @@ static JNINativeMethod methods[] = { {"jni_YGNodeStyleSetMinWidthPercentJNI", "(JF)V", (void*)jni_YGNodeStyleSetMinWidthPercentJNI}, + {"jni_YGNodeStyleSetMinWidthMaxContentJNI", + "(J)V", + (void*)jni_YGNodeStyleSetMinWidthMaxContentJNI}, + {"jni_YGNodeStyleSetMinWidthFitContentJNI", + "(J)V", + (void*)jni_YGNodeStyleSetMinWidthFitContentJNI}, + {"jni_YGNodeStyleSetMinWidthStretchJNI", + "(J)V", + (void*)jni_YGNodeStyleSetMinWidthStretchJNI}, {"jni_YGNodeStyleGetMinHeightJNI", "(J)J", (void*)jni_YGNodeStyleGetMinHeightJNI}, @@ -945,6 +1003,15 @@ static JNINativeMethod methods[] = { {"jni_YGNodeStyleSetMinHeightPercentJNI", "(JF)V", (void*)jni_YGNodeStyleSetMinHeightPercentJNI}, + {"jni_YGNodeStyleSetMinHeightMaxContentJNI", + "(J)V", + (void*)jni_YGNodeStyleSetMinHeightMaxContentJNI}, + {"jni_YGNodeStyleSetMinHeightFitContentJNI", + "(J)V", + (void*)jni_YGNodeStyleSetMinHeightFitContentJNI}, + {"jni_YGNodeStyleSetMinHeightStretchJNI", + "(J)V", + (void*)jni_YGNodeStyleSetMinHeightStretchJNI}, {"jni_YGNodeStyleGetMaxWidthJNI", "(J)J", (void*)jni_YGNodeStyleGetMaxWidthJNI}, @@ -954,6 +1021,15 @@ static JNINativeMethod methods[] = { {"jni_YGNodeStyleSetMaxWidthPercentJNI", "(JF)V", (void*)jni_YGNodeStyleSetMaxWidthPercentJNI}, + {"jni_YGNodeStyleSetMaxWidthMaxContentJNI", + "(J)V", + (void*)jni_YGNodeStyleSetMaxWidthMaxContentJNI}, + {"jni_YGNodeStyleSetMaxWidthFitContentJNI", + "(J)V", + (void*)jni_YGNodeStyleSetMaxWidthFitContentJNI}, + {"jni_YGNodeStyleSetMaxWidthStretchJNI", + "(J)V", + (void*)jni_YGNodeStyleSetMaxWidthStretchJNI}, {"jni_YGNodeStyleGetMaxHeightJNI", "(J)J", (void*)jni_YGNodeStyleGetMaxHeightJNI}, @@ -963,6 +1039,15 @@ static JNINativeMethod methods[] = { {"jni_YGNodeStyleSetMaxHeightPercentJNI", "(JF)V", (void*)jni_YGNodeStyleSetMaxHeightPercentJNI}, + {"jni_YGNodeStyleSetMaxHeightMaxContentJNI", + "(J)V", + (void*)jni_YGNodeStyleSetMaxHeightMaxContentJNI}, + {"jni_YGNodeStyleSetMaxHeightFitContentJNI", + "(J)V", + (void*)jni_YGNodeStyleSetMaxHeightFitContentJNI}, + {"jni_YGNodeStyleSetMaxHeightStretchJNI", + "(J)V", + (void*)jni_YGNodeStyleSetMaxHeightStretchJNI}, {"jni_YGNodeStyleGetAspectRatioJNI", "(J)F", (void*)jni_YGNodeStyleGetAspectRatioJNI}, diff --git a/packages/react-native/ReactCommon/yoga/yoga/YGNodeStyle.cpp b/packages/react-native/ReactCommon/yoga/yoga/YGNodeStyle.cpp index 1309117af42cbb..3f1be42e463075 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/YGNodeStyle.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/YGNodeStyle.cpp @@ -192,6 +192,21 @@ void YGNodeStyleSetFlexBasisAuto(const YGNodeRef node) { node, StyleSizeLength::ofAuto()); } +void YGNodeStyleSetFlexBasisMaxContent(const YGNodeRef node) { + updateStyle<&Style::flexBasis, &Style::setFlexBasis>( + node, StyleSizeLength::ofMaxContent()); +} + +void YGNodeStyleSetFlexBasisFitContent(const YGNodeRef node) { + updateStyle<&Style::flexBasis, &Style::setFlexBasis>( + node, StyleSizeLength::ofFitContent()); +} + +void YGNodeStyleSetFlexBasisStretch(const YGNodeRef node) { + updateStyle<&Style::flexBasis, &Style::setFlexBasis>( + node, StyleSizeLength::ofStretch()); +} + YGValue YGNodeStyleGetFlexBasis(const YGNodeConstRef node) { return (YGValue)resolveRef(node)->style().flexBasis(); } @@ -321,6 +336,21 @@ void YGNodeStyleSetWidthAuto(YGNodeRef node) { node, Dimension::Width, StyleSizeLength::ofAuto()); } +void YGNodeStyleSetWidthMaxContent(YGNodeRef node) { + updateStyle<&Style::dimension, &Style::setDimension>( + node, Dimension::Width, StyleSizeLength::ofMaxContent()); +} + +void YGNodeStyleSetWidthFitContent(YGNodeRef node) { + updateStyle<&Style::dimension, &Style::setDimension>( + node, Dimension::Width, StyleSizeLength::ofFitContent()); +} + +void YGNodeStyleSetWidthStretch(YGNodeRef node) { + updateStyle<&Style::dimension, &Style::setDimension>( + node, Dimension::Width, StyleSizeLength::ofStretch()); +} + YGValue YGNodeStyleGetWidth(YGNodeConstRef node) { return (YGValue)resolveRef(node)->style().dimension(Dimension::Width); } @@ -340,6 +370,21 @@ void YGNodeStyleSetHeightAuto(YGNodeRef node) { node, Dimension::Height, StyleSizeLength::ofAuto()); } +void YGNodeStyleSetHeightMaxContent(YGNodeRef node) { + updateStyle<&Style::dimension, &Style::setDimension>( + node, Dimension::Height, StyleSizeLength::ofMaxContent()); +} + +void YGNodeStyleSetHeightFitContent(YGNodeRef node) { + updateStyle<&Style::dimension, &Style::setDimension>( + node, Dimension::Height, StyleSizeLength::ofFitContent()); +} + +void YGNodeStyleSetHeightStretch(YGNodeRef node) { + updateStyle<&Style::dimension, &Style::setDimension>( + node, Dimension::Height, StyleSizeLength::ofStretch()); +} + YGValue YGNodeStyleGetHeight(YGNodeConstRef node) { return (YGValue)resolveRef(node)->style().dimension(Dimension::Height); } @@ -354,6 +399,21 @@ void YGNodeStyleSetMinWidthPercent(const YGNodeRef node, const float minWidth) { node, Dimension::Width, StyleSizeLength::percent(minWidth)); } +void YGNodeStyleSetMinWidthMaxContent(const YGNodeRef node) { + updateStyle<&Style::minDimension, &Style::setMinDimension>( + node, Dimension::Width, StyleSizeLength::ofMaxContent()); +} + +void YGNodeStyleSetMinWidthFitContent(const YGNodeRef node) { + updateStyle<&Style::minDimension, &Style::setMinDimension>( + node, Dimension::Width, StyleSizeLength::ofFitContent()); +} + +void YGNodeStyleSetMinWidthStretch(const YGNodeRef node) { + updateStyle<&Style::minDimension, &Style::setMinDimension>( + node, Dimension::Width, StyleSizeLength::ofStretch()); +} + YGValue YGNodeStyleGetMinWidth(const YGNodeConstRef node) { return (YGValue)resolveRef(node)->style().minDimension(Dimension::Width); } @@ -370,6 +430,21 @@ void YGNodeStyleSetMinHeightPercent( node, Dimension::Height, StyleSizeLength::percent(minHeight)); } +void YGNodeStyleSetMinHeightMaxContent(const YGNodeRef node) { + updateStyle<&Style::minDimension, &Style::setMinDimension>( + node, Dimension::Height, StyleSizeLength::ofMaxContent()); +} + +void YGNodeStyleSetMinHeightFitContent(const YGNodeRef node) { + updateStyle<&Style::minDimension, &Style::setMinDimension>( + node, Dimension::Height, StyleSizeLength::ofFitContent()); +} + +void YGNodeStyleSetMinHeightStretch(const YGNodeRef node) { + updateStyle<&Style::minDimension, &Style::setMinDimension>( + node, Dimension::Height, StyleSizeLength::ofStretch()); +} + YGValue YGNodeStyleGetMinHeight(const YGNodeConstRef node) { return (YGValue)resolveRef(node)->style().minDimension(Dimension::Height); } @@ -384,6 +459,21 @@ void YGNodeStyleSetMaxWidthPercent(const YGNodeRef node, const float maxWidth) { node, Dimension::Width, StyleSizeLength::percent(maxWidth)); } +void YGNodeStyleSetMaxWidthMaxContent(const YGNodeRef node) { + updateStyle<&Style::maxDimension, &Style::setMaxDimension>( + node, Dimension::Width, StyleSizeLength::ofMaxContent()); +} + +void YGNodeStyleSetMaxWidthFitContent(const YGNodeRef node) { + updateStyle<&Style::maxDimension, &Style::setMaxDimension>( + node, Dimension::Width, StyleSizeLength::ofFitContent()); +} + +void YGNodeStyleSetMaxWidthStretch(const YGNodeRef node) { + updateStyle<&Style::maxDimension, &Style::setMaxDimension>( + node, Dimension::Width, StyleSizeLength::ofStretch()); +} + YGValue YGNodeStyleGetMaxWidth(const YGNodeConstRef node) { return (YGValue)resolveRef(node)->style().maxDimension(Dimension::Width); } @@ -400,6 +490,21 @@ void YGNodeStyleSetMaxHeightPercent( node, Dimension::Height, StyleSizeLength::percent(maxHeight)); } +void YGNodeStyleSetMaxHeightMaxContent(const YGNodeRef node) { + updateStyle<&Style::maxDimension, &Style::setMaxDimension>( + node, Dimension::Height, StyleSizeLength::ofMaxContent()); +} + +void YGNodeStyleSetMaxHeightFitContent(const YGNodeRef node) { + updateStyle<&Style::maxDimension, &Style::setMaxDimension>( + node, Dimension::Height, StyleSizeLength::ofFitContent()); +} + +void YGNodeStyleSetMaxHeightStretch(const YGNodeRef node) { + updateStyle<&Style::maxDimension, &Style::setMaxDimension>( + node, Dimension::Height, StyleSizeLength::ofStretch()); +} + YGValue YGNodeStyleGetMaxHeight(const YGNodeConstRef node) { return (YGValue)resolveRef(node)->style().maxDimension(Dimension::Height); } diff --git a/packages/react-native/ReactCommon/yoga/yoga/YGNodeStyle.h b/packages/react-native/ReactCommon/yoga/yoga/YGNodeStyle.h index 2746a4a00abb98..a971138bb9dc8a 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/YGNodeStyle.h +++ b/packages/react-native/ReactCommon/yoga/yoga/YGNodeStyle.h @@ -64,6 +64,9 @@ YG_EXPORT float YGNodeStyleGetFlexShrink(YGNodeConstRef node); YG_EXPORT void YGNodeStyleSetFlexBasis(YGNodeRef node, float flexBasis); YG_EXPORT void YGNodeStyleSetFlexBasisPercent(YGNodeRef node, float flexBasis); YG_EXPORT void YGNodeStyleSetFlexBasisAuto(YGNodeRef node); +YG_EXPORT void YGNodeStyleSetFlexBasisMaxContent(YGNodeRef node); +YG_EXPORT void YGNodeStyleSetFlexBasisFitContent(YGNodeRef node); +YG_EXPORT void YGNodeStyleSetFlexBasisStretch(YGNodeRef node); YG_EXPORT YGValue YGNodeStyleGetFlexBasis(YGNodeConstRef node); YG_EXPORT void @@ -101,27 +104,45 @@ YG_EXPORT YGBoxSizing YGNodeStyleGetBoxSizing(YGNodeConstRef node); YG_EXPORT void YGNodeStyleSetWidth(YGNodeRef node, float width); YG_EXPORT void YGNodeStyleSetWidthPercent(YGNodeRef node, float width); YG_EXPORT void YGNodeStyleSetWidthAuto(YGNodeRef node); +YG_EXPORT void YGNodeStyleSetWidthMaxContent(YGNodeRef node); +YG_EXPORT void YGNodeStyleSetWidthFitContent(YGNodeRef node); +YG_EXPORT void YGNodeStyleSetWidthStretch(YGNodeRef node); YG_EXPORT YGValue YGNodeStyleGetWidth(YGNodeConstRef node); YG_EXPORT void YGNodeStyleSetHeight(YGNodeRef node, float height); YG_EXPORT void YGNodeStyleSetHeightPercent(YGNodeRef node, float height); YG_EXPORT void YGNodeStyleSetHeightAuto(YGNodeRef node); +YG_EXPORT void YGNodeStyleSetHeightMaxContent(YGNodeRef node); +YG_EXPORT void YGNodeStyleSetHeightFitContent(YGNodeRef node); +YG_EXPORT void YGNodeStyleSetHeightStretch(YGNodeRef node); YG_EXPORT YGValue YGNodeStyleGetHeight(YGNodeConstRef node); YG_EXPORT void YGNodeStyleSetMinWidth(YGNodeRef node, float minWidth); YG_EXPORT void YGNodeStyleSetMinWidthPercent(YGNodeRef node, float minWidth); +YG_EXPORT void YGNodeStyleSetMinWidthMaxContent(YGNodeRef node); +YG_EXPORT void YGNodeStyleSetMinWidthFitContent(YGNodeRef node); +YG_EXPORT void YGNodeStyleSetMinWidthStretch(YGNodeRef node); YG_EXPORT YGValue YGNodeStyleGetMinWidth(YGNodeConstRef node); YG_EXPORT void YGNodeStyleSetMinHeight(YGNodeRef node, float minHeight); YG_EXPORT void YGNodeStyleSetMinHeightPercent(YGNodeRef node, float minHeight); +YG_EXPORT void YGNodeStyleSetMinHeightMaxContent(YGNodeRef node); +YG_EXPORT void YGNodeStyleSetMinHeightFitContent(YGNodeRef node); +YG_EXPORT void YGNodeStyleSetMinHeightStretch(YGNodeRef node); YG_EXPORT YGValue YGNodeStyleGetMinHeight(YGNodeConstRef node); YG_EXPORT void YGNodeStyleSetMaxWidth(YGNodeRef node, float maxWidth); YG_EXPORT void YGNodeStyleSetMaxWidthPercent(YGNodeRef node, float maxWidth); +YG_EXPORT void YGNodeStyleSetMaxWidthMaxContent(YGNodeRef node); +YG_EXPORT void YGNodeStyleSetMaxWidthFitContent(YGNodeRef node); +YG_EXPORT void YGNodeStyleSetMaxWidthStretch(YGNodeRef node); YG_EXPORT YGValue YGNodeStyleGetMaxWidth(YGNodeConstRef node); YG_EXPORT void YGNodeStyleSetMaxHeight(YGNodeRef node, float maxHeight); YG_EXPORT void YGNodeStyleSetMaxHeightPercent(YGNodeRef node, float maxHeight); +YG_EXPORT void YGNodeStyleSetMaxHeightMaxContent(YGNodeRef node); +YG_EXPORT void YGNodeStyleSetMaxHeightFitContent(YGNodeRef node); +YG_EXPORT void YGNodeStyleSetMaxHeightStretch(YGNodeRef node); YG_EXPORT YGValue YGNodeStyleGetMaxHeight(YGNodeConstRef node); YG_EXPORT void YGNodeStyleSetAspectRatio(YGNodeRef node, float aspectRatio); From fe656be26e0d71bf2505032578dbea54af36b2c5 Mon Sep 17 00:00:00 2001 From: David Vacca Date: Mon, 4 Nov 2024 17:46:14 -0800 Subject: [PATCH 046/220] Reduce visibility of ReactUnimplementedViewManager to internal (#47396) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47396 Migrate ReactUnimplementedViewManager to internal visibility verified and there are usages on OSS changelog: [Android][Breaking] Reduce visibility of ReactUnimplementedViewManager to internal Reviewed By: cortinico Differential Revision: D65444514 fbshipit-source-id: 11ff2acc96098bc4e53be7ef3059e4a5c112c43e --- .../ReactAndroid/api/ReactAndroid.api | 24 ------------------- .../ReactAndroid/gradle.properties | 4 +++- .../ReactUnimplementedViewManager.kt | 4 ++-- 3 files changed, 5 insertions(+), 27 deletions(-) diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index e46e38d36f5148..5b63c80f051859 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -8154,30 +8154,6 @@ public abstract interface class com/facebook/react/views/textinput/ScrollWatcher public abstract fun onScrollChanged (IIII)V } -public final class com/facebook/react/views/unimplementedview/ReactUnimplementedView : android/widget/LinearLayout { - public fun (Landroid/content/Context;)V - public final fun setName (Ljava/lang/String;)V -} - -public final class com/facebook/react/views/unimplementedview/ReactUnimplementedViewManager : com/facebook/react/uimanager/ViewGroupManager { - public static final field Companion Lcom/facebook/react/views/unimplementedview/ReactUnimplementedViewManager$Companion; - public static final field REACT_CLASS Ljava/lang/String; - public fun ()V - public synthetic fun createViewInstance (Lcom/facebook/react/uimanager/ThemedReactContext;)Landroid/view/View; - public fun getName ()Ljava/lang/String; - public final fun setName (Lcom/facebook/react/views/unimplementedview/ReactUnimplementedView;Ljava/lang/String;)V -} - -public class com/facebook/react/views/unimplementedview/ReactUnimplementedViewManager$$PropsSetter : com/facebook/react/uimanager/ViewManagerPropertyUpdater$ViewManagerSetter { - public fun ()V - public fun getProperties (Ljava/util/Map;)V - public synthetic fun setProperty (Lcom/facebook/react/uimanager/ViewManager;Landroid/view/View;Ljava/lang/String;Ljava/lang/Object;)V - public fun setProperty (Lcom/facebook/react/views/unimplementedview/ReactUnimplementedViewManager;Lcom/facebook/react/views/unimplementedview/ReactUnimplementedView;Ljava/lang/String;Ljava/lang/Object;)V -} - -public final class com/facebook/react/views/unimplementedview/ReactUnimplementedViewManager$Companion { -} - public final class com/facebook/react/views/view/ColorUtil { public static final field INSTANCE Lcom/facebook/react/views/view/ColorUtil; public static final fun normalize (DDDD)I diff --git a/packages/react-native/ReactAndroid/gradle.properties b/packages/react-native/ReactAndroid/gradle.properties index b7aeccca0577e1..6c3ec6535d733d 100644 --- a/packages/react-native/ReactAndroid/gradle.properties +++ b/packages/react-native/ReactAndroid/gradle.properties @@ -8,7 +8,9 @@ android.useAndroidX=true react.internal.disableJavaVersionAlignment=true # Binary Compatibility Validator properties -binaryCompatibilityValidator.ignoredClasses=com.facebook.react.BuildConfig +binaryCompatibilityValidator.ignoredClasses=com.facebook.react.BuildConfig,\ +com.facebook.react.views.unimplementedview.ReactUnimplementedViewManager$$PropsSetter + binaryCompatibilityValidator.ignoredPackages=com.facebook.debug,\ com.facebook.fbreact,\ com.facebook.hermes,\ diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/unimplementedview/ReactUnimplementedViewManager.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/unimplementedview/ReactUnimplementedViewManager.kt index 55f9548a9821a4..0b886c04f78285 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/unimplementedview/ReactUnimplementedViewManager.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/unimplementedview/ReactUnimplementedViewManager.kt @@ -14,7 +14,7 @@ import com.facebook.react.uimanager.annotations.ReactProp /** ViewManager for [ReactUnimplementedView] to represent a component that is not yet supported. */ @ReactModule(name = ReactUnimplementedViewManager.REACT_CLASS) -public class ReactUnimplementedViewManager : ViewGroupManager() { +internal class ReactUnimplementedViewManager : ViewGroupManager() { protected override fun createViewInstance( reactContext: ThemedReactContext @@ -27,7 +27,7 @@ public class ReactUnimplementedViewManager : ViewGroupManager Date: Mon, 4 Nov 2024 18:46:35 -0800 Subject: [PATCH 047/220] DevSupportManagerBase: Rename getCurrentContext() -> getCurrentReactContext() (#47390) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47390 getCurrentContext() is very ambiguous. Changelog: [Android][Breaking] - Make DevSupportManagerBase.getCurrentReactContext() public Reviewed By: mdvacca Differential Revision: D65433217 fbshipit-source-id: a739d206de8085fc5b47b2a31c7e94fe6e71852f --- .../ReactAndroid/api/ReactAndroid.api | 2 +- .../devsupport/BridgeDevSupportManager.java | 4 +-- .../devsupport/DevSupportManagerBase.java | 36 ++++++++++--------- 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 5b63c80f051859..b901a82ce6604b 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -2161,7 +2161,7 @@ public abstract class com/facebook/react/devsupport/DevSupportManagerBase : com/ public fun fetchSplitBundleAndCreateBundleLoader (Ljava/lang/String;Lcom/facebook/react/devsupport/DevSupportManagerBase$CallbackWithBundleLoader;)V protected fun getApplicationContext ()Landroid/content/Context; public fun getCurrentActivity ()Landroid/app/Activity; - protected fun getCurrentContext ()Lcom/facebook/react/bridge/ReactContext; + protected fun getCurrentReactContext ()Lcom/facebook/react/bridge/ReactContext; public fun getDevLoadingViewManager ()Lcom/facebook/react/devsupport/interfaces/DevLoadingViewManager; public fun getDevServerHelper ()Lcom/facebook/react/devsupport/DevServerHelper; public fun getDevSettings ()Lcom/facebook/react/modules/debug/interfaces/DeveloperSettings; diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/BridgeDevSupportManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/BridgeDevSupportManager.java index 7239dfc8b858f8..e09bb0ddf0d9d1 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/BridgeDevSupportManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/BridgeDevSupportManager.java @@ -97,8 +97,8 @@ public void loadSplitBundleFromServer( new CallbackWithBundleLoader() { @Override public void onSuccess(JSBundleLoader bundleLoader) { - bundleLoader.loadScript(getCurrentContext().getCatalystInstance()); - getCurrentContext() + bundleLoader.loadScript(getCurrentReactContext().getCatalystInstance()); + getCurrentReactContext() .getJSModule(HMRClient.class) .registerBundle(getDevServerHelper().getDevServerSplitBundleURL(bundlePath)); callback.onSuccess(); diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerBase.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerBase.java index fe383544cd4860..71a11477de44fa 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerBase.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerBase.java @@ -107,7 +107,7 @@ public interface CallbackWithBundleLoader { private @Nullable DebugOverlayController mDebugOverlayController; private boolean mDevLoadingViewVisible = false; private int mPendingJSSplitBundleRequests = 0; - private @Nullable ReactContext mCurrentContext; + private @Nullable ReactContext mCurrentReactContext; private final DeveloperSettings mDevSettings; private boolean mIsReceiverRegistered = false; private boolean mIsShakeDetectorStarted = false; @@ -429,11 +429,11 @@ public void onOptionSelected() { () -> { boolean nextEnabled = !mDevSettings.isHotModuleReplacementEnabled(); mDevSettings.setHotModuleReplacementEnabled(nextEnabled); - if (mCurrentContext != null) { + if (mCurrentReactContext != null) { if (nextEnabled) { - mCurrentContext.getJSModule(HMRClient.class).enable(); + mCurrentReactContext.getJSModule(HMRClient.class).enable(); } else { - mCurrentContext.getJSModule(HMRClient.class).disable(); + mCurrentReactContext.getJSModule(HMRClient.class).disable(); } } if (nextEnabled && !mDevSettings.isJSDevModeEnabled()) { @@ -542,8 +542,10 @@ public View getView(int position, @Nullable View convertView, ViewGroup parent) .setOnCancelListener(dialog -> mDevOptionsDialog = null) .create(); mDevOptionsDialog.show(); - if (mCurrentContext != null) { - mCurrentContext.getJSModule(RCTNativeAppEventEmitter.class).emit("RCTDevMenuShown", null); + if (mCurrentReactContext != null) { + mCurrentReactContext + .getJSModule(RCTNativeAppEventEmitter.class) + .emit("RCTDevMenuShown", null); } } @@ -588,7 +590,7 @@ public void onNewReactContextCreated(ReactContext reactContext) { @Override public void onReactInstanceDestroyed(ReactContext reactContext) { - if (reactContext == mCurrentContext) { + if (reactContext == mCurrentReactContext) { // only call reset context when the destroyed context matches the one that is currently set // for this manager resetCurrentContext(null); @@ -664,12 +666,12 @@ public boolean hasUpToDateJSBundleInCache() { } private void resetCurrentContext(@Nullable ReactContext reactContext) { - if (mCurrentContext == reactContext) { + if (mCurrentReactContext == reactContext) { // new context is the same as the old one - do nothing return; } - mCurrentContext = reactContext; + mCurrentReactContext = reactContext; // Recreate debug overlay controller with new CatalystInstance object if (mDebugOverlayController != null) { @@ -679,13 +681,13 @@ private void resetCurrentContext(@Nullable ReactContext reactContext) { mDebugOverlayController = new DebugOverlayController(reactContext); } - if (mCurrentContext != null) { + if (mCurrentReactContext != null) { try { URL sourceUrl = new URL(getSourceUrl()); String path = sourceUrl.getPath().substring(1); // strip initial slash in path String host = sourceUrl.getHost(); int port = sourceUrl.getPort() != -1 ? sourceUrl.getPort() : sourceUrl.getDefaultPort(); - mCurrentContext + mCurrentReactContext .getJSModule(HMRClient.class) .setup("android", path, host, port, mDevSettings.isHotModuleReplacementEnabled()); } catch (MalformedURLException e) { @@ -705,8 +707,8 @@ public void reloadSettings() { } } - protected @Nullable ReactContext getCurrentContext() { - return mCurrentContext; + protected @Nullable ReactContext getCurrentReactContext() { + return mCurrentReactContext; } public @Nullable String getJSAppBundleName() { @@ -783,7 +785,7 @@ public void fetchSplitBundleAndCreateBundleLoader( public void onSuccess() { UiThreadUtil.runOnUiThread(() -> hideSplitBundleDevLoadingView()); - @Nullable ReactContext context = mCurrentContext; + @Nullable ReactContext context = mCurrentReactContext; if (context == null || !context.hasActiveReactInstance()) { return; } @@ -864,10 +866,10 @@ public int getLastErrorCookie() { } private void handleCaptureHeap(final Responder responder) { - if (mCurrentContext == null) { + if (mCurrentReactContext == null) { return; } - JSCHeapCapture heapCapture = mCurrentContext.getNativeModule(JSCHeapCapture.class); + JSCHeapCapture heapCapture = mCurrentReactContext.getNativeModule(JSCHeapCapture.class); if (heapCapture != null) { heapCapture.captureHeap( @@ -1160,7 +1162,7 @@ private void compatRegisterReceiver( @Override public void openDebugger() { mDevServerHelper.openDebugger( - mCurrentContext, mApplicationContext.getString(R.string.catalyst_open_debugger_error)); + mCurrentReactContext, mApplicationContext.getString(R.string.catalyst_open_debugger_error)); } @Override From 0e7ba9094ea573d1512b2dc71e46f55b24201b7a Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Mon, 4 Nov 2024 18:46:35 -0800 Subject: [PATCH 048/220] Make redboxes resilient to react native preloading (#47391) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47391 React Native can preload before the activity is available. Preloading will execute the js bundle. If the js bundle throws an error, it'll try to render a redbox. If the activity isn't available, and hasn't been set on the react instance yet, the redbox will just render nothing. ## Changes In this diff, just re-try displaying the redbox after the application sets the activity on the react instance (i.e: calls onHostResume(activity)). Changelog: [Android][Breaking] - Rename DevSupportManagerBase.getCurrentContext() -> getCurrentReactContext() Reviewed By: mdvacca Differential Revision: D65352596 fbshipit-source-id: 7750f6ca493fc50405119958e0f2908fc24f1cb4 --- .../ReactAndroid/api/ReactAndroid.api | 4 ++- .../devsupport/DevSupportManagerBase.java | 2 +- .../RedBoxDialogSurfaceDelegate.java | 33 +++++++++++++++++-- .../devsupport/ReleaseDevSupportManager.kt | 3 ++ .../interfaces/DevSupportManager.kt | 1 + 5 files changed, 39 insertions(+), 4 deletions(-) diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index b901a82ce6604b..b76548b510bd4a 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -2161,7 +2161,7 @@ public abstract class com/facebook/react/devsupport/DevSupportManagerBase : com/ public fun fetchSplitBundleAndCreateBundleLoader (Ljava/lang/String;Lcom/facebook/react/devsupport/DevSupportManagerBase$CallbackWithBundleLoader;)V protected fun getApplicationContext ()Landroid/content/Context; public fun getCurrentActivity ()Landroid/app/Activity; - protected fun getCurrentReactContext ()Lcom/facebook/react/bridge/ReactContext; + public fun getCurrentReactContext ()Lcom/facebook/react/bridge/ReactContext; public fun getDevLoadingViewManager ()Lcom/facebook/react/devsupport/interfaces/DevLoadingViewManager; public fun getDevServerHelper ()Lcom/facebook/react/devsupport/DevServerHelper; public fun getDevSettings ()Lcom/facebook/react/modules/debug/interfaces/DeveloperSettings; @@ -2334,6 +2334,7 @@ public class com/facebook/react/devsupport/ReleaseDevSupportManager : com/facebo public fun destroyRootView (Landroid/view/View;)V public fun downloadBundleResourceFromUrlSync (Ljava/lang/String;Ljava/io/File;)Ljava/io/File; public fun getCurrentActivity ()Landroid/app/Activity; + public fun getCurrentReactContext ()Lcom/facebook/react/bridge/ReactContext; public fun getDevSettings ()Lcom/facebook/react/modules/debug/interfaces/DeveloperSettings; public fun getDevSupportEnabled ()Z public fun getDownloadedJSBundleFile ()Ljava/lang/String; @@ -2470,6 +2471,7 @@ public abstract interface class com/facebook/react/devsupport/interfaces/DevSupp public abstract fun destroyRootView (Landroid/view/View;)V public abstract fun downloadBundleResourceFromUrlSync (Ljava/lang/String;Ljava/io/File;)Ljava/io/File; public abstract fun getCurrentActivity ()Landroid/app/Activity; + public abstract fun getCurrentReactContext ()Lcom/facebook/react/bridge/ReactContext; public abstract fun getDevSettings ()Lcom/facebook/react/modules/debug/interfaces/DeveloperSettings; public abstract fun getDevSupportEnabled ()Z public abstract fun getDownloadedJSBundleFile ()Ljava/lang/String; diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerBase.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerBase.java index 71a11477de44fa..f630c1b121b842 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerBase.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerBase.java @@ -707,7 +707,7 @@ public void reloadSettings() { } } - protected @Nullable ReactContext getCurrentReactContext() { + public @Nullable ReactContext getCurrentReactContext() { return mCurrentReactContext; } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/RedBoxDialogSurfaceDelegate.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/RedBoxDialogSurfaceDelegate.java index 705be2c8df54c0..39f184e2a52e20 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/RedBoxDialogSurfaceDelegate.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/RedBoxDialogSurfaceDelegate.java @@ -21,6 +21,8 @@ import androidx.core.view.WindowInsetsCompat; import com.facebook.common.logging.FLog; import com.facebook.react.R; +import com.facebook.react.bridge.LifecycleEventListener; +import com.facebook.react.bridge.ReactContext; import com.facebook.react.common.ReactConstants; import com.facebook.react.common.SurfaceDelegate; import com.facebook.react.devsupport.interfaces.DevSupportManager; @@ -55,7 +57,7 @@ public void createContentView(String appKey) { FLog.e( ReactConstants.TAG, "Unable to launch redbox because react activity " - + "is not available, here is the error that redbox would've displayed: " + + "are not available, here is the error that redbox would've displayed: " + (message != null ? message : "N/A")); return; } @@ -82,9 +84,19 @@ public void show() { @Nullable String message = mDevSupportManager.getLastErrorTitle(); Activity context = mDevSupportManager.getCurrentActivity(); if (context == null || context.isFinishing()) { + final @Nullable ReactContext reactContext = mDevSupportManager.getCurrentReactContext(); + if (reactContext != null) { + /** + * If the activity isn't available, try again after the next onHostResume(). onHostResume() + * is when the activity gets attached to the react native. + */ + runAfterHostResume(reactContext, this::show); + return; + } + FLog.e( ReactConstants.TAG, - "Unable to launch redbox because react activity " + "Unable to launch redbox because react activity and react context " + "is not available, here is the error that redbox would've displayed: " + (message != null ? message : "N/A")); return; @@ -140,6 +152,23 @@ protected void onCreate(Bundle savedInstanceState) { mDialog.show(); } + private static void runAfterHostResume(ReactContext reactContext, Runnable runnable) { + reactContext.addLifecycleEventListener( + new LifecycleEventListener() { + @Override + public void onHostResume() { + runnable.run(); + reactContext.removeLifecycleEventListener(this); + } + + @Override + public void onHostPause() {} + + @Override + public void onHostDestroy() {} + }); + } + @Override public void hide() { // dismiss redbox if exists diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/ReleaseDevSupportManager.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/ReleaseDevSupportManager.kt index 02398843112d28..49aad990ff7540 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/ReleaseDevSupportManager.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/ReleaseDevSupportManager.kt @@ -147,6 +147,9 @@ public open class ReleaseDevSupportManager : DevSupportManager { override public val currentActivity: Activity? get() = null + override public val currentReactContext: ReactContext? + get() = null + override public fun createSurfaceDelegate(moduleName: String?): SurfaceDelegate? = null override public fun openDebugger(): Unit = Unit diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/interfaces/DevSupportManager.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/interfaces/DevSupportManager.kt index a778ac54577676..8a5985931f7ec3 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/interfaces/DevSupportManager.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/interfaces/DevSupportManager.kt @@ -35,6 +35,7 @@ public interface DevSupportManager : JSExceptionHandler { public val lastErrorType: ErrorType? public val lastErrorCookie: Int public val currentActivity: Activity? + public val currentReactContext: ReactContext? public var devSupportEnabled: Boolean From d7d5535fe1ff13b92a63f00f74328f6a98fa799e Mon Sep 17 00:00:00 2001 From: Riccardo Cipolleschi Date: Tue, 5 Nov 2024 02:48:49 -0800 Subject: [PATCH 049/220] Suppres CC_MD5 warning (#47378) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47378 The RCTMD5Hash in RCTUtils is using CC_MD5 function which is deprecated. unfortunately we can't really change it or we will break many apps that use it in the AsyncStorage. Those app wlll have to do a migration to use a different function. Meanwhile we are suppressing the warning ## Changelog [Internal] - Suppress CC_MD5 warning Reviewed By: cortinico Differential Revision: D65424309 fbshipit-source-id: e0258ae68482f6c4a3a865bb52920f87bc5ada21 --- packages/react-native/React/Base/RCTUtils.m | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/react-native/React/Base/RCTUtils.m b/packages/react-native/React/Base/RCTUtils.m index 22b55692471488..d95a4ba9426813 100644 --- a/packages/react-native/React/Base/RCTUtils.m +++ b/packages/react-native/React/Base/RCTUtils.m @@ -239,7 +239,10 @@ id RCTJSONClean(id object) { const char *str = string.UTF8String; unsigned char result[CC_MD5_DIGEST_LENGTH]; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" CC_MD5(str, (CC_LONG)strlen(str), result); +#pragma clang diagnostic pop return [NSString stringWithFormat:@"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", result[0], From 83d38501b85882298b457f0185c73fbdf98cff18 Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Tue, 5 Nov 2024 03:19:06 -0800 Subject: [PATCH 050/220] setup-gradle v4 + Remove unnecessary Gradle Wrapper Validation (#47389) Summary: As per: https://github.com/gradle/actions#the-wrapper-validation-action > Starting with v4 the setup-gradle action will [perform wrapper validation](https://github.com/gradle/actions/blob/main/docs/setup-gradle.md#gradle-wrapper-validation) on each execution. If you are using setup-gradle in your workflows, it is unlikely that you will need to use the wrapper-validation action. I'm moving to setup-gradle v4 and remove this unnecessary extra action. ## Changelog: [INTERNAL] - setup-gradle v4 + Remove unnecessary Gradle Wrapper Validation Pull Request resolved: https://github.com/facebook/react-native/pull/47389 Test Plan: CI Reviewed By: blakef Differential Revision: D65435069 Pulled By: cortinico fbshipit-source-id: c28b4d520e91fea9c59a341fb94598db5fc69900 --- .github/actions/setup-gradle/action.yml | 2 +- .github/workflows/gradle-wrapper-validation.yml | 13 ------------- 2 files changed, 1 insertion(+), 14 deletions(-) delete mode 100644 .github/workflows/gradle-wrapper-validation.yml diff --git a/.github/actions/setup-gradle/action.yml b/.github/actions/setup-gradle/action.yml index c146592c1911ec..b815c62839fb9e 100644 --- a/.github/actions/setup-gradle/action.yml +++ b/.github/actions/setup-gradle/action.yml @@ -8,7 +8,7 @@ runs: using: "composite" steps: - name: Setup gradle - uses: gradle/actions/setup-gradle@v3 + uses: gradle/actions/setup-gradle@v4 with: gradle-version: wrapper # We want the Gradle cache to be written only on main/-stable branches run, and only for jobs with `cache-read-only` == false (i.e. `build_android`). diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml deleted file mode 100644 index eb1ab715d172dc..00000000000000 --- a/.github/workflows/gradle-wrapper-validation.yml +++ /dev/null @@ -1,13 +0,0 @@ -name: "Validate Gradle Wrapper" - -on: - push: - pull_request: - -jobs: - validation: - name: "Validation" - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: gradle/actions/wrapper-validation@v3 From 3956955eaa3cd8c50dfe35a68a6cb8fdcac43155 Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Tue, 5 Nov 2024 03:27:59 -0800 Subject: [PATCH 051/220] Use absolute path when compiling appmodules.so sources (#47379) Summary: Fixes https://github.com/facebook/react-native/issues/47352 This fixes a bug when the user is providing its own CMakeLists.txt file say because they want to compile more C++ code than we actually provide. Previously the `*.cpp` will evalute file in the current directory, meaning that the app's default `OnLoad.cpp` file would be ignored. ## Changelog: [ANDROID] [FIXED] - Use absolute path when compiling appmodules.so sources Pull Request resolved: https://github.com/facebook/react-native/pull/47379 Test Plan: Tested against the reproducer provided in: - Use absolute path when compiling appmodules.so sources Reviewed By: cipolleschi Differential Revision: D65428676 Pulled By: cortinico fbshipit-source-id: 7f3e4d470da0fffc5191c1a2c7e8fec517fee496 --- .../ReactAndroid/cmake-utils/ReactNative-application.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-native/ReactAndroid/cmake-utils/ReactNative-application.cmake b/packages/react-native/ReactAndroid/cmake-utils/ReactNative-application.cmake index f7b0fe2205f82f..a5b3a19423b25b 100644 --- a/packages/react-native/ReactAndroid/cmake-utils/ReactNative-application.cmake +++ b/packages/react-native/ReactAndroid/cmake-utils/ReactNative-application.cmake @@ -41,7 +41,7 @@ if (PROJECT_ROOT_DIR) endif () file(GLOB input_SRC CONFIGURE_DEPENDS - *.cpp + ${REACT_ANDROID_DIR}/cmake-utils/default-app-setup/*.cpp ${BUILD_DIR}/generated/autolinking/src/main/jni/*.cpp) add_library(${CMAKE_PROJECT_NAME} SHARED ${input_SRC}) From 1f62529dc4583af88ef06bee04c89ce6c2ef737f Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Tue, 5 Nov 2024 03:32:16 -0800 Subject: [PATCH 052/220] Properly handle paths with spaces in autolinking (#47388) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47388 Fixes https://github.com/facebook/react-native/issues/47364 Fixes https://github.com/facebook/react-native/issues/47377 Fixes https://github.com/facebook/react-native/issues/37124 We're having problems is a path contains a space ' ' because when autolinking, the `add_subdirectory()` function of CMake consider the path with space as 2 parameters. This fixes it by properly quoting the path. Changelog: [Android] [Fixed] - Properly handle paths with spaces in autolinking Reviewed By: cipolleschi Differential Revision: D65434413 fbshipit-source-id: b9147482f98f7e222405cc8d9e6f3c17a5f4ed02 --- ...rateAutolinkingNewArchitecturesFileTask.kt | 11 +++++--- ...AutolinkingNewArchitecturesFileTaskTest.kt | 27 ++++++++++++++++--- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/tasks/GenerateAutolinkingNewArchitecturesFileTask.kt b/packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/tasks/GenerateAutolinkingNewArchitecturesFileTask.kt index 0de22fc0eb5af0..38a31b86ac57b1 100644 --- a/packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/tasks/GenerateAutolinkingNewArchitecturesFileTask.kt +++ b/packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/tasks/GenerateAutolinkingNewArchitecturesFileTask.kt @@ -59,15 +59,15 @@ abstract class GenerateAutolinkingNewArchitecturesFileTask : DefaultTask() { val cxxModuleCMakeListsPath = dep.cxxModuleCMakeListsPath if (libraryName != null && cmakeListsPath != null) { // If user provided a custom cmakeListsPath, let's honor it. - val nativeFolderPath = cmakeListsPath.replace("CMakeLists.txt", "") + val nativeFolderPath = sanitizeCmakeListsPath(cmakeListsPath) addDirectoryString += - "add_subdirectory($nativeFolderPath ${libraryName}_autolinked_build)" + "add_subdirectory(\"$nativeFolderPath\" ${libraryName}_autolinked_build)" } if (cxxModuleCMakeListsPath != null) { // If user provided a custom cxxModuleCMakeListsPath, let's honor it. - val nativeFolderPath = cxxModuleCMakeListsPath.replace("CMakeLists.txt", "") + val nativeFolderPath = sanitizeCmakeListsPath(cxxModuleCMakeListsPath) addDirectoryString += - "\nadd_subdirectory($nativeFolderPath ${libraryName}_cxxmodule_autolinked_build)" + "\nadd_subdirectory(\"$nativeFolderPath\" ${libraryName}_cxxmodule_autolinked_build)" } addDirectoryString } @@ -159,6 +159,9 @@ abstract class GenerateAutolinkingNewArchitecturesFileTask : DefaultTask() { const val COMPONENT_DESCRIPTOR_FILENAME = "ComponentDescriptors.h" const val COMPONENT_INCLUDE_PATH = "react/renderer/components" + internal fun sanitizeCmakeListsPath(cmakeListsPath: String): String = + cmakeListsPath.replace("CMakeLists.txt", "").replace(" ", "\\ ") + // language=cmake val CMAKE_TEMPLATE = """ diff --git a/packages/gradle-plugin/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/tasks/GenerateAutolinkingNewArchitecturesFileTaskTest.kt b/packages/gradle-plugin/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/tasks/GenerateAutolinkingNewArchitecturesFileTaskTest.kt index 7abe10595b2e91..b8d14bf7bfa172 100644 --- a/packages/gradle-plugin/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/tasks/GenerateAutolinkingNewArchitecturesFileTaskTest.kt +++ b/packages/gradle-plugin/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/tasks/GenerateAutolinkingNewArchitecturesFileTaskTest.kt @@ -11,6 +11,7 @@ import com.facebook.react.model.ModelAutolinkingConfigJson import com.facebook.react.model.ModelAutolinkingDependenciesJson import com.facebook.react.model.ModelAutolinkingDependenciesPlatformAndroidJson import com.facebook.react.model.ModelAutolinkingDependenciesPlatformJson +import com.facebook.react.tasks.GenerateAutolinkingNewArchitecturesFileTask.Companion.sanitizeCmakeListsPath import com.facebook.react.tests.createTestTask import org.assertj.core.api.Assertions.assertThat import org.junit.Rule @@ -145,9 +146,9 @@ class GenerateAutolinkingNewArchitecturesFileTaskTest { # or link against a old prefab target (this is needed for React Native 0.76 on). set(REACTNATIVE_MERGED_SO true) - add_subdirectory(./a/directory/ aPackage_autolinked_build) - add_subdirectory(./another/directory/ anotherPackage_autolinked_build) - add_subdirectory(./another/directory/cxx/ anotherPackage_cxxmodule_autolinked_build) + add_subdirectory("./a/directory/" aPackage_autolinked_build) + add_subdirectory("./another/directory/with\ spaces/" anotherPackage_autolinked_build) + add_subdirectory("./another/directory/cxx/" anotherPackage_cxxmodule_autolinked_build) set(AUTOLINKED_LIBRARIES react_codegen_aPackage @@ -258,6 +259,24 @@ class GenerateAutolinkingNewArchitecturesFileTaskTest { .trimIndent()) } + @Test + fun sanitizeCmakeListsPath_withPathEndingWithFileName_removesFilename() { + val input = "./a/directory/CMakeLists.txt" + assertThat(sanitizeCmakeListsPath(input)).isEqualTo("./a/directory/") + } + + @Test + fun sanitizeCmakeListsPath_withSpaces_removesSpaces() { + val input = "./a/dir ectory/with spaces/" + assertThat(sanitizeCmakeListsPath(input)).isEqualTo("./a/dir\\ ectory/with\\ spaces/") + } + + @Test + fun sanitizeCmakeListsPath_withPathEndingWithFileNameAndSpaces_sanitizesIt() { + val input = "./a/dir ectory/CMakeLists.txt" + assertThat(sanitizeCmakeListsPath(input)).isEqualTo("./a/dir\\ ectory/") + } + private val testDependencies = listOf( ModelAutolinkingDependenciesPlatformAndroidJson( @@ -276,7 +295,7 @@ class GenerateAutolinkingNewArchitecturesFileTaskTest { buildTypes = emptyList(), libraryName = "anotherPackage", componentDescriptors = listOf("AnotherPackageComponentDescriptor"), - cmakeListsPath = "./another/directory/CMakeLists.txt", + cmakeListsPath = "./another/directory/with spaces/CMakeLists.txt", cxxModuleCMakeListsPath = "./another/directory/cxx/CMakeLists.txt", cxxModuleHeaderName = "AnotherCxxModule", cxxModuleCMakeListsModuleName = "another_cxxModule", From 287e20033207df5e59d199a347b7ae2b4cd7a59e Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Tue, 5 Nov 2024 04:11:48 -0800 Subject: [PATCH 053/220] Stable API - Convert to Kotlin and make internal `NotThreadSafeViewHierarchyUpdateDebugListener` (#47371) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47371 This interface should have not been exposed in the first place. I'm converting it to Kotlin + making it `internal`. I found no meaningful usage in OSS so I expect no breakages. Changelog: [Android] [Breaking] - Stable API - Convert to Kotlin and make internal `NotThreadSafeViewHierarchyUpdateDebugListener` Reviewed By: javache Differential Revision: D65420912 fbshipit-source-id: 5afdb013f588a5698b4e7467a7f1096c24d1733e --- .../ReactAndroid/api/ReactAndroid.api | 5 ----- .../react/uimanager/UIImplementation.java | 2 ++ .../react/uimanager/UIManagerModule.java | 2 ++ .../react/uimanager/UIViewOperationQueue.java | 2 ++ ...eadSafeViewHierarchyUpdateDebugListener.kt} | 18 +++++++----------- 5 files changed, 13 insertions(+), 16 deletions(-) rename packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/debug/{NotThreadSafeViewHierarchyUpdateDebugListener.java => NotThreadSafeViewHierarchyUpdateDebugListener.kt} (57%) diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index b76548b510bd4a..b238f03c159f29 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -5658,11 +5658,6 @@ public final class com/facebook/react/uimanager/common/ViewUtil { public static final fun isRootTag (I)Z } -public abstract interface class com/facebook/react/uimanager/debug/NotThreadSafeViewHierarchyUpdateDebugListener { - public abstract fun onViewHierarchyUpdateEnqueued ()V - public abstract fun onViewHierarchyUpdateFinished ()V -} - public abstract interface class com/facebook/react/uimanager/events/BatchEventDispatchedListener { public abstract fun onBatchEventDispatched ()V } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIImplementation.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIImplementation.java index 401e8b26a3079c..afa1d3a968d07d 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIImplementation.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIImplementation.java @@ -774,6 +774,8 @@ public void onCatalystInstanceDestroyed() { mViewManagers.invalidate(); } + // NOTE: When converted to Kotlin this method should be `internal` due to + // visibility restriction for `NotThreadSafeViewHierarchyUpdateDebugListener` public void setViewHierarchyUpdateDebugListener( @Nullable NotThreadSafeViewHierarchyUpdateDebugListener listener) { mOperationsQueue.setViewHierarchyUpdateDebugListener(listener); diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java index 9ecad6f5d88f03..7a3cfc55ae68ec 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java @@ -687,6 +687,8 @@ public void onBatchComplete() { } } + // NOTE: When converted to Kotlin this method should be `internal` due to + // visibility restriction for `NotThreadSafeViewHierarchyUpdateDebugListener` public void setViewHierarchyUpdateDebugListener( @Nullable NotThreadSafeViewHierarchyUpdateDebugListener listener) { mUIImplementation.setViewHierarchyUpdateDebugListener(listener); diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIViewOperationQueue.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIViewOperationQueue.java index 383d02d0a70ea6..3e284122ca69bc 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIViewOperationQueue.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIViewOperationQueue.java @@ -609,6 +609,8 @@ public UIViewOperationQueue( return mNativeViewHierarchyManager; } + // NOTE: When converted to Kotlin this method should be `internal` due to + // visibility restriction for `NotThreadSafeViewHierarchyUpdateDebugListener` public void setViewHierarchyUpdateDebugListener( @Nullable NotThreadSafeViewHierarchyUpdateDebugListener listener) { mViewHierarchyUpdateDebugListener = listener; diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/debug/NotThreadSafeViewHierarchyUpdateDebugListener.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/debug/NotThreadSafeViewHierarchyUpdateDebugListener.kt similarity index 57% rename from packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/debug/NotThreadSafeViewHierarchyUpdateDebugListener.java rename to packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/debug/NotThreadSafeViewHierarchyUpdateDebugListener.kt index 9a6b65eba790ae..9027ed465e14df 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/debug/NotThreadSafeViewHierarchyUpdateDebugListener.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/debug/NotThreadSafeViewHierarchyUpdateDebugListener.kt @@ -5,26 +5,22 @@ * LICENSE file in the root directory of this source tree. */ -package com.facebook.react.uimanager.debug; +package com.facebook.react.uimanager.debug -import com.facebook.react.common.annotations.DeprecatedInNewArchitecture; -import com.facebook.react.uimanager.UIManagerModule; +import com.facebook.react.common.annotations.DeprecatedInNewArchitecture /** * A listener that is notified about view hierarchy update events. This listener should only be used * for debug purposes and should not affect application state. * - *

NB: while onViewHierarchyUpdateFinished will always be called from the UI thread, there are no + * NB: while [onViewHierarchyUpdateFinished] will always be called from the UI thread, there are no * guarantees what thread onViewHierarchyUpdateEnqueued is called on. */ @DeprecatedInNewArchitecture -public interface NotThreadSafeViewHierarchyUpdateDebugListener { - - /** - * Called when {@link UIManagerModule} enqueues a UI batch to be dispatched to the main thread. - */ - void onViewHierarchyUpdateEnqueued(); +internal interface NotThreadSafeViewHierarchyUpdateDebugListener { + /** Called when `UIManagerModule` enqueues a UI batch to be dispatched to the main thread. */ + fun onViewHierarchyUpdateEnqueued() /** Called from the main thread after a UI batch has been applied to all root views. */ - void onViewHierarchyUpdateFinished(); + fun onViewHierarchyUpdateFinished() } From 8c50bf0beb17ced7fdafeae7a734edfc03e6e0b2 Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Tue, 5 Nov 2024 07:35:36 -0800 Subject: [PATCH 054/220] Stable API - Make `DevLoadingModule` internal (#47368) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47368 This class should be internal and has no meaningful usages outside of React Native. See https://github.com/search?type=code&q=%22DevLoadingModule%3A%3Aclass%22 So technically breaking but I expect no impact for OSS at all. Changelog: [Android] [Breaking] - Make `DevLoadingModule` internal Reviewed By: javache Differential Revision: D64725164 fbshipit-source-id: 5f39e609c611662c71cc08bffa195f7bea5db5bd --- .../react-native/ReactAndroid/api/ReactAndroid.api | 11 ----------- .../react/modules/devloading/DevLoadingModule.kt | 2 +- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index b238f03c159f29..1c62bbff5711dd 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -3303,17 +3303,6 @@ public final class com/facebook/react/modules/deviceinfo/DeviceInfoModule : com/ public fun onHostResume ()V } -public final class com/facebook/react/modules/devloading/DevLoadingModule : com/facebook/fbreact/specs/NativeDevLoadingViewSpec { - public static final field Companion Lcom/facebook/react/modules/devloading/DevLoadingModule$Companion; - public static final field NAME Ljava/lang/String; - public fun (Lcom/facebook/react/bridge/ReactApplicationContext;)V - public fun hide ()V - public fun showMessage (Ljava/lang/String;Ljava/lang/Double;Ljava/lang/Double;)V -} - -public final class com/facebook/react/modules/devloading/DevLoadingModule$Companion { -} - public class com/facebook/react/modules/dialog/AlertFragment : androidx/fragment/app/DialogFragment, android/content/DialogInterface$OnClickListener { public fun ()V public fun (Lcom/facebook/react/modules/dialog/DialogModule$AlertFragmentListener;Landroid/os/Bundle;)V diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/devloading/DevLoadingModule.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/devloading/DevLoadingModule.kt index 3457b3ae78c66f..6796c8c6a03404 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/devloading/DevLoadingModule.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/devloading/DevLoadingModule.kt @@ -18,7 +18,7 @@ import com.facebook.react.module.annotations.ReactModule /** [NativeModule] that allows JS to show dev loading view. */ @ReactModule(name = NativeDevLoadingViewSpec.NAME) -public class DevLoadingModule(reactContext: ReactApplicationContext) : +internal class DevLoadingModule(reactContext: ReactApplicationContext) : NativeDevLoadingViewSpec(reactContext) { private val jsExceptionHandler: JSExceptionHandler? = reactContext.jsExceptionHandler From f489944051c499920a2b5e695a6f09dc3e0a5d08 Mon Sep 17 00:00:00 2001 From: Luna Wei Date: Tue, 5 Nov 2024 09:30:30 -0800 Subject: [PATCH 055/220] Convert PanResponder example into functional component (#47381) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47381 Convert PanResponder example into functional component Changelog: [Internal] Update PanResponder example to functional component Reviewed By: lyahdav Differential Revision: D65430973 fbshipit-source-id: 0db09ce12a8c59ec74beaf2ee10326c984fa682c --- .../PanResponder/PanResponderExample.js | 155 ++++++------------ 1 file changed, 50 insertions(+), 105 deletions(-) diff --git a/packages/rn-tester/js/examples/PanResponder/PanResponderExample.js b/packages/rn-tester/js/examples/PanResponder/PanResponderExample.js index e91748bc10dae9..f3b8a7371d6249 100644 --- a/packages/rn-tester/js/examples/PanResponder/PanResponderExample.js +++ b/packages/rn-tester/js/examples/PanResponder/PanResponderExample.js @@ -10,125 +10,69 @@ 'use strict'; -import type { - GestureState, - PanResponderInstance, -} from 'react-native/Libraries/Interaction/PanResponder'; -import type {PressEvent} from 'react-native/Libraries/Types/CoreEventTypes'; - -const RNTesterPage = require('../../components/RNTesterPage'); -const React = require('react'); -const {PanResponder, StyleSheet, View} = require('react-native'); +import * as React from 'react'; +import {useMemo, useRef, useState} from 'react'; +import {PanResponder, StyleSheet, View} from 'react-native'; const CIRCLE_SIZE = 80; -type Props = $ReadOnly<{||}>; -type State = {| - left: number, - top: number, - pressed: boolean, -|}; - -class PanResponderExample extends React.Component { - _previousLeft: number = 20; - _previousTop: number = 84; - circle: ?React.ElementRef = null; - - state: State = { - left: 20, - top: 84, - pressed: false, - }; - - _handleStartShouldSetPanResponder = ( - event: PressEvent, - gestureState: GestureState, - ): boolean => { - // Should we become active when the user presses down on the circle? - return true; - }; - - _handleMoveShouldSetPanResponder = ( - event: PressEvent, - gestureState: GestureState, - ): boolean => { - // Should we become active when the user moves a touch over the circle? - return true; - }; - - _handlePanResponderGrant = ( - event: PressEvent, - gestureState: GestureState, - ) => { - this.setState({ - pressed: true, - }); - }; - - _handlePanResponderMove = (event: PressEvent, gestureState: GestureState) => { - this.setState({ - left: this._previousLeft + gestureState.dx, - top: this._previousTop + gestureState.dy, - }); - }; - - _handlePanResponderEnd = (event: PressEvent, gestureState: GestureState) => { - this.setState({ - pressed: false, - }); - this._previousLeft += gestureState.dx; - this._previousTop += gestureState.dy; - }; - - _panResponder: PanResponderInstance = PanResponder.create({ - onStartShouldSetPanResponder: this._handleStartShouldSetPanResponder, - onMoveShouldSetPanResponder: this._handleMoveShouldSetPanResponder, - onPanResponderGrant: this._handlePanResponderGrant, - onPanResponderMove: this._handlePanResponderMove, - onPanResponderRelease: this._handlePanResponderEnd, - onPanResponderTerminate: this._handlePanResponderEnd, - }); - - render(): React.Node { - return ( - - - { - this.circle = circle; - }} - style={[ - styles.circle, - { - transform: [ - {translateX: this.state.left}, - {translateY: this.state.top}, - ], - backgroundColor: this.state.pressed ? 'blue' : 'green', - }, - ]} - {...this._panResponder.panHandlers} - /> - - - ); - } +function PanResponderExample() { + const [position, setPosition] = useState({left: 20, top: 84}); + const [pressed, setPressed] = useState(false); + const circleRef = useRef>(null); + const panResponder = useMemo( + () => + PanResponder.create({ + onStartShouldSetPanResponder: () => true, + onMoveShouldSetPanResponder: () => true, + onPanResponderGrant: () => { + setPressed(true); + }, + onPanResponderMove: (evt, gestureState) => { + setPosition({ + left: position.left + gestureState.dx, + top: position.top + gestureState.dy, + }); + }, + onPanResponderRelease: () => { + setPressed(false); + }, + }), + [position], + ); + return ( + + + + ); } const styles = StyleSheet.create({ + container: { + flex: 1, + height: 500, + }, circle: { width: CIRCLE_SIZE, height: CIRCLE_SIZE, - backgroundColor: 'green', borderRadius: CIRCLE_SIZE / 2, position: 'absolute', left: 0, top: 0, }, - container: { - flex: 1, - height: 500, - }, }); exports.title = 'PanResponder Sample'; @@ -139,6 +83,7 @@ exports.description = exports.examples = [ { title: 'Basic gesture handling', + description: 'Press and drag circle around', render(): React.MixedElement { return ; }, From ba41228a663a42111d73bfbc1592562a0a947647 Mon Sep 17 00:00:00 2001 From: Riccardo Cipolleschi Date: Tue, 5 Nov 2024 10:06:35 -0800 Subject: [PATCH 056/220] Back out "Add png extension only if file exist when load local image" (#47417) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47417 Backing out this change as it was breaking an internal app. I'll reland this next week when I have more time. ## Changelog: [iOS][Changed] - Revert fix that checks whether an image is present on disk. ## Facebook: This is breaking twilight. Differential Revision: D65479912 fbshipit-source-id: dcd5ac5f3d98ba2f10b9519f09d3eb1fd454da61 --- packages/react-native/Libraries/Image/RCTImageLoader.mm | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/react-native/Libraries/Image/RCTImageLoader.mm b/packages/react-native/Libraries/Image/RCTImageLoader.mm index 165c711d1c6724..68a12d351227ef 100644 --- a/packages/react-native/Libraries/Image/RCTImageLoader.mm +++ b/packages/react-native/Libraries/Image/RCTImageLoader.mm @@ -477,10 +477,7 @@ - (RCTImageURLLoaderRequest *)_loadImageOrDataWithURLRequest:(NSURLRequest *)req // Add missing png extension if (request.URL.fileURL && request.URL.pathExtension.length == 0) { - NSURL *pngRequestURL = [request.URL URLByAppendingPathExtension:@"png"]; - if ([[NSFileManager defaultManager] fileExistsAtPath:pngRequestURL.path]) { - mutableRequest.URL = pngRequestURL; - } + mutableRequest.URL = [request.URL URLByAppendingPathExtension:@"png"]; } if (_redirectDelegate != nil) { mutableRequest.URL = [_redirectDelegate redirectAssetsURL:mutableRequest.URL]; From 06071c68d551b1bcdc803ebe3df340a45807ae41 Mon Sep 17 00:00:00 2001 From: Luna Wei Date: Tue, 5 Nov 2024 10:24:13 -0800 Subject: [PATCH 057/220] Remove experimental types (#47405) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47405 Changelog: [Internal] - With New Architecture out, delete experimental type definition and move types back to relevant definition files Reviewed By: cortinico, jorge-cab Differential Revision: D65462903 fbshipit-source-id: bd7fc5bb689eb054b3a30ec7b388e0f455ff1c93 --- .../Components/View/ViewPropTypes.d.ts | 7 +++ .../Libraries/StyleSheet/StyleSheetTypes.d.ts | 6 ++ packages/react-native/types/experimental.d.ts | 59 ------------------- 3 files changed, 13 insertions(+), 59 deletions(-) delete mode 100644 packages/react-native/types/experimental.d.ts diff --git a/packages/react-native/Libraries/Components/View/ViewPropTypes.d.ts b/packages/react-native/Libraries/Components/View/ViewPropTypes.d.ts index a1aa196ccbd6ee..9210d64aa836a8 100644 --- a/packages/react-native/Libraries/Components/View/ViewPropTypes.d.ts +++ b/packages/react-native/Libraries/Components/View/ViewPropTypes.d.ts @@ -211,4 +211,11 @@ export interface ViewProps * Used to reference react managed views from native code. */ nativeID?: string | undefined; + + /** + * Contols whether this view, and its transitive children, are laid in a way + * consistent with web browsers ('strict'), or consistent with existing + * React Native code which may rely on incorrect behavior ('classic'). + */ + experimental_layoutConformance?: 'strict' | 'classic' | undefined; } diff --git a/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.d.ts b/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.d.ts index 19ea741ae11364..a4aa69d027579e 100644 --- a/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.d.ts +++ b/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.d.ts @@ -434,6 +434,12 @@ export interface ViewStyle extends FlexStyle, ShadowStyleIOS, TransformsStyle { cursor?: CursorValue | undefined; boxShadow?: ReadonlyArray | string | undefined; filter?: ReadonlyArray | string | undefined; + + mixBlendMode?: BlendMode | undefined; + experimental_backgroundImage?: + | ReadonlyArray + | string + | undefined; } export type FontVariant = diff --git a/packages/react-native/types/experimental.d.ts b/packages/react-native/types/experimental.d.ts deleted file mode 100644 index 13a929a092abb1..00000000000000 --- a/packages/react-native/types/experimental.d.ts +++ /dev/null @@ -1,59 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @format - */ - -/** - * These are types for things that are present for New Architecture enabled apps - * which is currently considered experimental. - * - * To load the types declared here in an actual project, there are three ways. - * - * 1. If your `tsconfig.json` already has a `"types"` array in the `"compilerOptions"` section, - * is to add `"react-native/types/experimental"` to the `"types"` array. - * - * 2. Alternatively, a specific import syntax can to be used from a typescript file. - * This module does not exist in reality, which is why the {} is important: - * - * ```ts - * import {} from 'react-native/types/experimental' - * ``` - * - * 3. It is also possible to include it through a triple-slash reference: - * - * ```ts - * /// - * ``` - * - * Either the import or the reference only needs to appear once, anywhere in the project. - */ - -import { - GradientValue, - BlendMode, -} from 'react-native/Libraries/StyleSheet/StyleSheetTypes'; - -export {}; - -declare module '.' { - export interface ViewProps { - /** - * Contols whether this view, and its transitive children, are laid in a way - * consistent with web browsers ('strict'), or consistent with existing - * React Native code which may rely on incorrect behavior ('classic'). - */ - experimental_layoutConformance?: 'strict' | 'classic' | undefined; - } - - export interface ViewStyle { - mixBlendMode?: BlendMode | undefined; - experimental_backgroundImage?: - | ReadonlyArray - | string - | undefined; - } -} From 19b0acf75478c961c45cd267ae1c14314b9e66cc Mon Sep 17 00:00:00 2001 From: Nick Gerleman Date: Tue, 5 Nov 2024 11:28:37 -0800 Subject: [PATCH 058/220] Minor display: contents optimizations (#47358) Summary: X-link: https://github.com/facebook/yoga/pull/1736 Pull Request resolved: https://github.com/facebook/react-native/pull/47358 `LayoutableChildren::Iterator` showed up to a surprising extent on a recent trace. Part of this was during pixel grid rounding, which does full tree traversal (we should fix that...), where the iterator is the first thing to read from the node. I ran Yoga microbenchmark with Yoga compiled with `-O2`, where we saw a regression of synthetic performance by ~10%, but it turns out this build also had ASAN and some other heavy bits enabled, so the real impact was quite lower (~6%). I was able to make some optimizations in the meantime against that, which still show some minor wins, reducing that overhead to ~4% in the properly optimized build (and a bit more before that). This is still measurable on the beefy server, and the code is a bit cleaner, so let's commit these! Note that, in real scenarios, measure functions may dominate layout time, so display: contents does not mean end-to-end 4% regression, even after this change. This change makes a few different optimizations 1. Removes redundant copies 2. Removes redundant index keeping 3. Mark which branches are likely vs unlikely 4. Shrink iterator size from 6 pointers to 3 pointers 5. Avoid usage in pixel grid rounding (so we don't need to have cache read for style) In "Huge nested layout" example | Before display: contents support | After display: contents support | After optimizations | | 9.77ms | 10.39ms | 10.17ms | Changelog: [Internal] Reviewed By: rozele Differential Revision: D65336148 fbshipit-source-id: 01c592771ed7accf2d87dddd5a3a9e0225098b56 --- .../yoga/yoga/algorithm/CalculateLayout.cpp | 2 +- .../yoga/yoga/algorithm/FlexLine.cpp | 22 +++++------- .../yoga/yoga/algorithm/FlexLine.h | 3 -- .../yoga/yoga/algorithm/PixelGrid.cpp | 2 +- .../yoga/yoga/node/LayoutableChildren.h | 35 +++++++++---------- 5 files changed, 27 insertions(+), 37 deletions(-) diff --git a/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp b/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp index d245f255258986..b9758d8cfe0ccb 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp @@ -540,7 +540,7 @@ static float computeFlexBasisForChildren( const uint32_t generationCount) { float totalOuterFlexBasis = 0.0f; YGNodeRef singleFlexChild = nullptr; - const auto& children = node->getLayoutChildren(); + auto children = node->getLayoutChildren(); SizingMode sizingModeMainDim = isRow(mainAxis) ? widthSizingMode : heightSizingMode; // If there is only one child with flexGrow + flexShrink it means we can set diff --git a/packages/react-native/ReactCommon/yoga/yoga/algorithm/FlexLine.cpp b/packages/react-native/ReactCommon/yoga/yoga/algorithm/FlexLine.cpp index aac495f47b7ed8..cb5c72891bb7e9 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/algorithm/FlexLine.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/algorithm/FlexLine.cpp @@ -29,8 +29,7 @@ FlexLine calculateFlexLine( float totalFlexGrowFactors = 0.0f; float totalFlexShrinkScaledFactors = 0.0f; size_t numberOfAutoMargins = 0; - size_t endOfLineIndex = iterator.index(); - size_t firstElementInLineIndex = iterator.index(); + yoga::Node* firstElementInLine = nullptr; float sizeConsumedIncludingMinConstraint = 0; const Direction direction = node->resolveDirection(ownerDirection); @@ -40,19 +39,19 @@ FlexLine calculateFlexLine( const float gap = node->style().computeGapForAxis(mainAxis, availableInnerMainDim); + const auto childrenEnd = node->getLayoutChildren().end(); // Add items to the current line until it's full or we run out of items. - for (; iterator != node->getLayoutChildren().end(); - iterator++, endOfLineIndex = iterator.index()) { + for (; iterator != childrenEnd; iterator++) { auto child = *iterator; if (child->style().display() == Display::None || child->style().positionType() == PositionType::Absolute) { - if (firstElementInLineIndex == endOfLineIndex) { - // We haven't found the first contributing element in the line yet. - firstElementInLineIndex++; - } continue; } + if (firstElementInLine == nullptr) { + firstElementInLine = child; + } + if (child->style().flexStartMarginIsAuto(mainAxis, ownerDirection)) { numberOfAutoMargins++; } @@ -60,13 +59,11 @@ FlexLine calculateFlexLine( numberOfAutoMargins++; } - const bool isFirstElementInLine = - (endOfLineIndex - firstElementInLineIndex) == 0; - child->setLineIndex(lineCount); const float childMarginMainAxis = child->style().computeMarginForAxis(mainAxis, availableInnerWidth); - const float childLeadingGapMainAxis = isFirstElementInLine ? 0.0f : gap; + const float childLeadingGapMainAxis = + child == firstElementInLine ? 0.0f : gap; const float flexBasisWithMinAndMaxConstraints = boundAxisWithinMinAndMax( child, @@ -117,7 +114,6 @@ FlexLine calculateFlexLine( return FlexLine{ .itemsInFlow = std::move(itemsInFlow), .sizeConsumed = sizeConsumed, - .endOfLineIndex = endOfLineIndex, .numberOfAutoMargins = numberOfAutoMargins, .layout = FlexLineRunningLayout{ totalFlexGrowFactors, diff --git a/packages/react-native/ReactCommon/yoga/yoga/algorithm/FlexLine.h b/packages/react-native/ReactCommon/yoga/yoga/algorithm/FlexLine.h index 4dcf7a509d0e24..9ec72ea8315abc 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/algorithm/FlexLine.h +++ b/packages/react-native/ReactCommon/yoga/yoga/algorithm/FlexLine.h @@ -49,9 +49,6 @@ struct FlexLine { // the flexible children. const float sizeConsumed{0.0f}; - // The index of the first item beyond the current line. - const size_t endOfLineIndex{0}; - // Number of edges along the line flow with an auto margin. const size_t numberOfAutoMargins{0}; diff --git a/packages/react-native/ReactCommon/yoga/yoga/algorithm/PixelGrid.cpp b/packages/react-native/ReactCommon/yoga/yoga/algorithm/PixelGrid.cpp index 038994d70e2b08..7a694565e9b44e 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/algorithm/PixelGrid.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/algorithm/PixelGrid.cpp @@ -124,7 +124,7 @@ void roundLayoutResultsToPixelGrid( Dimension::Height); } - for (yoga::Node* child : node->getLayoutChildren()) { + for (yoga::Node* child : node->getChildren()) { roundLayoutResultsToPixelGrid(child, absoluteNodeLeft, absoluteNodeTop); } } diff --git a/packages/react-native/ReactCommon/yoga/yoga/node/LayoutableChildren.h b/packages/react-native/ReactCommon/yoga/yoga/node/LayoutableChildren.h index 7d5598fb04f8c8..b158a6a6379d6c 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/node/LayoutableChildren.h +++ b/packages/react-native/ReactCommon/yoga/yoga/node/LayoutableChildren.h @@ -4,10 +4,12 @@ * 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 @@ -18,7 +20,6 @@ class Node; template class LayoutableChildren { public: - using Backtrack = std::vector>; struct Iterator { using iterator_category = std::input_iterator_tag; using difference_type = std::ptrdiff_t; @@ -30,10 +31,6 @@ class LayoutableChildren { Iterator(const T* node, size_t childIndex) : node_(node), childIndex_(childIndex) {} - Iterator(const T* node, size_t childIndex, Backtrack&& backtrack) - : node_(node), - childIndex_(childIndex), - backtrack_(std::move(backtrack)) {} T* operator*() const { return node_->getChild(childIndex_); @@ -41,7 +38,6 @@ class LayoutableChildren { Iterator& operator++() { next(); - currentNodeIndex_++; return *this; } @@ -51,10 +47,6 @@ class LayoutableChildren { return tmp; } - size_t index() const { - return currentNodeIndex_; - } - friend bool operator==(const Iterator& a, const Iterator& b) { return a.node_ == b.node_ && a.childIndex_ == b.childIndex_; } @@ -68,16 +60,16 @@ class LayoutableChildren { if (childIndex_ + 1 >= node_->getChildCount()) { // if the current node has no more children, try to backtrack and // visit its successor - if (backtrack_.empty()) { + if (backtrack_.empty()) [[likely]] { // if there are no nodes to backtrack to, the last node has been // visited *this = Iterator{}; } else { // pop and restore the latest backtrack entry - const auto back = backtrack_.back(); - backtrack_.pop_back(); + const auto& back = backtrack_.front(); node_ = back.first; childIndex_ = back.second; + backtrack_.pop_front(); // go to the next node next(); @@ -87,7 +79,10 @@ class LayoutableChildren { ++childIndex_; // skip all display: contents nodes, possibly going deeper into the // tree - skipContentsNodes(); + if (node_->getChild(childIndex_)->style().display() == + Display::Contents) [[unlikely]] { + skipContentsNodes(); + } } } @@ -99,7 +94,7 @@ class LayoutableChildren { // if it has display: contents set, it shouldn't be returned but its // children should in its place push the current node and child index // so that the current state can be restored when backtracking - backtrack_.push_back({node_, childIndex_}); + backtrack_.push_front({node_, childIndex_}); // traverse the child node_ = currentNode; childIndex_ = 0; @@ -117,8 +112,7 @@ class LayoutableChildren { const T* node_{nullptr}; size_t childIndex_{0}; - size_t currentNodeIndex_{0}; - Backtrack backtrack_; + std::forward_list> backtrack_; friend LayoutableChildren; }; @@ -133,7 +127,10 @@ class LayoutableChildren { Iterator begin() const { if (node_->getChildCount() > 0) { auto result = Iterator(node_, 0); - result.skipContentsNodes(); + if (node_->getChild(0)->style().display() == Display::Contents) + [[unlikely]] { + result.skipContentsNodes(); + } return result; } else { return Iterator{}; From d1fb01cd85391f8f73422d69193f459c0e3f62c6 Mon Sep 17 00:00:00 2001 From: Alan Lee Date: Tue, 5 Nov 2024 11:31:37 -0800 Subject: [PATCH 059/220] Make FrescoBasedReactTextInlineImageViewManager Nullsafe (#47425) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47425 Make FrescoBasedReactTextInlineImageViewManager Nullsafe. Changelog: [Internal] Reviewed By: tdn120 Differential Revision: D65456481 fbshipit-source-id: c841494ba933be149a2124a461d6a5011ce7d993 --- .../FrescoBasedReactTextInlineImageViewManager.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/frescosupport/FrescoBasedReactTextInlineImageViewManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/frescosupport/FrescoBasedReactTextInlineImageViewManager.java index 9e0cc7998c4d9f..5eec2e88828985 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/frescosupport/FrescoBasedReactTextInlineImageViewManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/frescosupport/FrescoBasedReactTextInlineImageViewManager.java @@ -11,6 +11,7 @@ import androidx.annotation.Nullable; import com.facebook.drawee.backends.pipeline.Fresco; import com.facebook.drawee.controller.AbstractDraweeControllerBuilder; +import com.facebook.infer.annotation.Nullsafe; import com.facebook.react.module.annotations.ReactModule; import com.facebook.react.uimanager.BaseViewManager; import com.facebook.react.uimanager.ThemedReactContext; @@ -19,6 +20,7 @@ * Manages Images embedded in Text nodes using Fresco. Since they are used only as a virtual nodes * any type of native view operation will throw an {@link IllegalStateException}. */ +@Nullsafe(Nullsafe.Mode.LOCAL) @ReactModule(name = FrescoBasedReactTextInlineImageViewManager.REACT_CLASS) public class FrescoBasedReactTextInlineImageViewManager extends BaseViewManager { From d7d5de9f9630e7dcd0194830d7ccb32f167b619c Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Tue, 5 Nov 2024 11:35:12 -0800 Subject: [PATCH 060/220] Stable API - Make `NativeModulePerfLogger` internal (#47415) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47415 This class should not be accessed directly, therefore I'm making it internal. Technically breaking but I verified that there are no meaningful usages in OSS: https://github.com/search?type=code&q=NOT+is%3Afork+NOT+org%3Afacebook+com.facebook.react.reactperflogger.NativeModulePerfLogger Changelog: [Android] [Breaking] - Stable API - Make NativeModulePerfLogger internal Reviewed By: mdvacca Differential Revision: D65479550 fbshipit-source-id: 545c33e2c526e396084af65fc19314f59c8a74f8 --- .../ReactAndroid/api/ReactAndroid.api | 16 -------------- .../reactperflogger/NativeModulePerfLogger.kt | 22 +++++++++---------- 2 files changed, 11 insertions(+), 27 deletions(-) diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 1c62bbff5711dd..d8bf1e485e2798 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -3763,22 +3763,6 @@ public abstract interface class com/facebook/react/packagerconnection/Responder public abstract fun respond (Ljava/lang/Object;)V } -public abstract class com/facebook/react/reactperflogger/NativeModulePerfLogger { - protected fun ()V - protected abstract fun initHybrid ()Lcom/facebook/jni/HybridData; - protected final fun maybeLoadOtherSoLibraries ()V - public abstract fun moduleCreateCacheHit (Ljava/lang/String;I)V - public abstract fun moduleCreateConstructEnd (Ljava/lang/String;I)V - public abstract fun moduleCreateConstructStart (Ljava/lang/String;I)V - public abstract fun moduleCreateEnd (Ljava/lang/String;I)V - public abstract fun moduleCreateFail (Ljava/lang/String;I)V - public abstract fun moduleCreateSetUpEnd (Ljava/lang/String;I)V - public abstract fun moduleCreateSetUpStart (Ljava/lang/String;I)V - public abstract fun moduleCreateStart (Ljava/lang/String;I)V - public abstract fun moduleDataCreateEnd (Ljava/lang/String;I)V - public abstract fun moduleDataCreateStart (Ljava/lang/String;I)V -} - public abstract class com/facebook/react/runtime/BindingsInstaller { public fun (Lcom/facebook/jni/HybridData;)V } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/reactperflogger/NativeModulePerfLogger.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/reactperflogger/NativeModulePerfLogger.kt index 8411d3cf92d5f2..d141736e1a28cb 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/reactperflogger/NativeModulePerfLogger.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/reactperflogger/NativeModulePerfLogger.kt @@ -9,7 +9,7 @@ package com.facebook.react.reactperflogger import com.facebook.jni.HybridData -public abstract class NativeModulePerfLogger protected constructor() { +internal abstract class NativeModulePerfLogger protected constructor() { @Suppress("NoHungarianNotation") private val mHybridData: HybridData @@ -20,25 +20,25 @@ public abstract class NativeModulePerfLogger protected constructor() { protected abstract fun initHybrid(): HybridData - public abstract fun moduleDataCreateStart(moduleName: String, id: Int) + abstract fun moduleDataCreateStart(moduleName: String, id: Int) - public abstract fun moduleDataCreateEnd(moduleName: String, id: Int) + abstract fun moduleDataCreateEnd(moduleName: String, id: Int) - public abstract fun moduleCreateStart(moduleName: String, id: Int) + abstract fun moduleCreateStart(moduleName: String, id: Int) - public abstract fun moduleCreateCacheHit(moduleName: String, id: Int) + abstract fun moduleCreateCacheHit(moduleName: String, id: Int) - public abstract fun moduleCreateConstructStart(moduleName: String, id: Int) + abstract fun moduleCreateConstructStart(moduleName: String, id: Int) - public abstract fun moduleCreateConstructEnd(moduleName: String, id: Int) + abstract fun moduleCreateConstructEnd(moduleName: String, id: Int) - public abstract fun moduleCreateSetUpStart(moduleName: String, id: Int) + abstract fun moduleCreateSetUpStart(moduleName: String, id: Int) - public abstract fun moduleCreateSetUpEnd(moduleName: String, id: Int) + abstract fun moduleCreateSetUpEnd(moduleName: String, id: Int) - public abstract fun moduleCreateEnd(moduleName: String, id: Int) + abstract fun moduleCreateEnd(moduleName: String, id: Int) - public abstract fun moduleCreateFail(moduleName: String, id: Int) + abstract fun moduleCreateFail(moduleName: String, id: Int) /** Subclasses will override this method to load their own SO libraries. */ @Synchronized From d8cfd98070cbccc5e8a49446d76bdc2cb0c6939f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Guzm=C3=A1n?= Date: Tue, 5 Nov 2024 11:36:27 -0800 Subject: [PATCH 061/220] feat(image): support for `resizeMode` and `objectFit` value of `'none'` (#47110) Summary: As part of https://github.com/facebook/react-native/issues/34425, `objectFit` value of `'none'` needs to be supported for the Image component. In order to support this, a new value must also be added to support the equivalent in `resizeMode`. With this new value, the image will not be resized at all and keeping it in the initial position within a container (see in the screenshots). In this PR the support is added for both Fabric and Paper. ## Changelog: [GENERAL] [ADDED] - image `resizeMode` and `objectFit` support for `'none'`. Pull Request resolved: https://github.com/facebook/react-native/pull/47110 Test Plan: Using the `rn-tester`, there is a new image example for both `resizeMode` and `objectFit`. See below the results for both Android and iOS:

Fabric screenshots **Android:** | Resize Mode | Object Fit | | --------- | ---------- | | ![Screenshot_1729232899](https://github.com/user-attachments/assets/ea765afc-9f85-4ac3-96ab-229b3f1def20) | ![Screenshot_1729232912](https://github.com/user-attachments/assets/75033e76-5faa-438d-81b1-4bf8436f9ef2) | **iOS:** | Resize Mode | Object Fit | | --------- | ---------- | | ![Simulator Screenshot - iPhone 16 Pro Max - 2024-10-18 at 08 16 37](https://github.com/user-attachments/assets/ade02ba9-4792-4760-aada-6ea56b591801) | ![Simulator Screenshot - iPhone 16 Pro Max - 2024-10-18 at 08 16 55](https://github.com/user-attachments/assets/abf68db9-841a-4ee5-b5db-64fe84a69089) |
Paper screenshots **Android:** | Resize Mode | Object Fit | | --------- | ---------- | | ![Screenshot_1729286528](https://github.com/user-attachments/assets/88e89191-d70a-4013-8380-2ecefd9532b4) | ![Screenshot_1729286542](https://github.com/user-attachments/assets/43d84ae0-2ed3-47ad-a725-ac6aea0b3245) | **iOS:** | Resize Mode | Object Fit | | --------- | ---------- | | ![Simulator Screenshot - iPhone 16 Pro Max - 2024-10-18 at 22 21 22](https://github.com/user-attachments/assets/e14a81de-3a69-4e73-8c85-ec08ac30b04f) | ![Simulator Screenshot - iPhone 16 Pro Max - 2024-10-18 at 22 21 16](https://github.com/user-attachments/assets/595f9f5e-96a6-4f6b-9614-f6c236837ba8) |
Reviewed By: fabriziocucci Differential Revision: D65420002 Pulled By: javache fbshipit-source-id: df3bc8fc931b88cde5fe51d89685bf327e30ed9f --- .../react-native/Libraries/Image/Image.d.ts | 2 ++ .../Libraries/Image/ImageProps.js | 3 ++- .../Libraries/Image/ImageResizeMode.d.ts | 9 ++++++- .../Libraries/Image/ImageResizeMode.js | 5 +++- .../Libraries/Image/ImageUtils.js | 9 ++++--- .../Libraries/Image/RCTImageUtils.mm | 2 ++ .../Libraries/Image/RCTResizeMode.h | 5 +++- .../Libraries/Image/RCTResizeMode.mm | 1 + .../Libraries/StyleSheet/StyleSheetTypes.d.ts | 2 +- .../Libraries/StyleSheet/StyleSheetTypes.js | 9 ++++--- .../__snapshots__/public-api-test.js.snap | 18 ++++++------- .../react/views/image/ImageResizeMode.kt | 5 +++- .../react/views/image/ImageResizeModeTest.kt | 2 ++ .../renderer/components/image/conversions.h | 4 +++ .../RCTImagePrimitivesConversions.h | 4 +++ .../react/renderer/imagemanager/primitives.h | 1 + .../js/examples/Image/ImageExample.js | 26 +++++++++++++++++++ 17 files changed, 85 insertions(+), 22 deletions(-) diff --git a/packages/react-native/Libraries/Image/Image.d.ts b/packages/react-native/Libraries/Image/Image.d.ts index 95e42447033cbf..d50679a548bfb2 100644 --- a/packages/react-native/Libraries/Image/Image.d.ts +++ b/packages/react-native/Libraries/Image/Image.d.ts @@ -200,6 +200,8 @@ export interface ImagePropsBase * 'center': Scale the image down so that it is completely visible, * if bigger than the area of the view. * The image will not be scaled up. + * + * 'none': Do not resize the image. The image will be displayed at its intrinsic size. */ resizeMode?: ImageResizeMode | undefined; diff --git a/packages/react-native/Libraries/Image/ImageProps.js b/packages/react-native/Libraries/Image/ImageProps.js index c0c39075872fdf..80c05862e4330a 100644 --- a/packages/react-native/Libraries/Image/ImageProps.js +++ b/packages/react-native/Libraries/Image/ImageProps.js @@ -19,6 +19,7 @@ import type { } from '../StyleSheet/StyleSheet'; import type {LayoutEvent, SyntheticEvent} from '../Types/CoreEventTypes'; import typeof Image from './Image'; +import type {ImageResizeMode} from './ImageResizeMode'; import type {ImageSource} from './ImageSource'; import type {ElementRef, Node, RefSetter} from 'react'; @@ -234,7 +235,7 @@ export type ImageProps = $ReadOnly<{| * * See https://reactnative.dev/docs/image#resizemode */ - resizeMode?: ?('cover' | 'contain' | 'stretch' | 'repeat' | 'center'), + resizeMode?: ?ImageResizeMode, /** * A unique identifier for this element to be used in UI Automation diff --git a/packages/react-native/Libraries/Image/ImageResizeMode.d.ts b/packages/react-native/Libraries/Image/ImageResizeMode.d.ts index 84174e3da9623c..5df952b678de26 100644 --- a/packages/react-native/Libraries/Image/ImageResizeMode.d.ts +++ b/packages/react-native/Libraries/Image/ImageResizeMode.d.ts @@ -12,7 +12,8 @@ export type ImageResizeMode = | 'contain' | 'stretch' | 'repeat' - | 'center'; + | 'center' + | 'none'; /** * @see ImageResizeMode.js @@ -46,4 +47,10 @@ export interface ImageResizeModeStatic { * image will keep it's size and aspect ratio. */ repeat: ImageResizeMode; + + /** + * none - The image will be displayed at its intrinsic size, which means the + * image will not be scaled up or down. + */ + none: ImageResizeMode; } diff --git a/packages/react-native/Libraries/Image/ImageResizeMode.js b/packages/react-native/Libraries/Image/ImageResizeMode.js index b63627b793bd43..50001ce552c82f 100644 --- a/packages/react-native/Libraries/Image/ImageResizeMode.js +++ b/packages/react-native/Libraries/Image/ImageResizeMode.js @@ -33,4 +33,7 @@ export type ImageResizeMode = // Resize by stretching it to fill the entire frame of the view without // clipping. This may change the aspect ratio of the image, distorting it. - | 'stretch'; + | 'stretch' + + // The image will not be resized at all. + | 'none'; diff --git a/packages/react-native/Libraries/Image/ImageUtils.js b/packages/react-native/Libraries/Image/ImageUtils.js index 732b5733bc6e81..c0e00bb534a84d 100644 --- a/packages/react-native/Libraries/Image/ImageUtils.js +++ b/packages/react-native/Libraries/Image/ImageUtils.js @@ -8,15 +8,18 @@ * @format */ -type ResizeMode = 'cover' | 'contain' | 'stretch' | 'repeat' | 'center'; +import type {ImageResizeMode} from './ImageResizeMode'; -const objectFitMap: {[string]: ResizeMode} = { +const objectFitMap: {[string]: ImageResizeMode} = { contain: 'contain', cover: 'cover', fill: 'stretch', 'scale-down': 'contain', + none: 'none', }; -export function convertObjectFitToResizeMode(objectFit: ?string): ?ResizeMode { +export function convertObjectFitToResizeMode( + objectFit: ?string, +): ?ImageResizeMode { return objectFit != null ? objectFitMap[objectFit] : undefined; } diff --git a/packages/react-native/Libraries/Image/RCTImageUtils.mm b/packages/react-native/Libraries/Image/RCTImageUtils.mm index 38fbd6bad434af..b7f85f83fc33a6 100644 --- a/packages/react-native/Libraries/Image/RCTImageUtils.mm +++ b/packages/react-native/Libraries/Image/RCTImageUtils.mm @@ -85,6 +85,7 @@ CGRect RCTTargetRect(CGSize sourceSize, CGSize destSize, CGFloat destScale, RCTR switch (resizeMode) { case RCTResizeModeStretch: case RCTResizeModeRepeat: + case RCTResizeModeNone: return (CGRect){CGPointZero, RCTCeilSize(destSize, destScale)}; @@ -249,6 +250,7 @@ BOOL RCTUpscalingRequired( case RCTResizeModeRepeat: case RCTResizeModeCenter: + case RCTResizeModeNone: return NO; } diff --git a/packages/react-native/Libraries/Image/RCTResizeMode.h b/packages/react-native/Libraries/Image/RCTResizeMode.h index 148e3dd2fe964d..e65f113a0dc14f 100644 --- a/packages/react-native/Libraries/Image/RCTResizeMode.h +++ b/packages/react-native/Libraries/Image/RCTResizeMode.h @@ -13,6 +13,7 @@ typedef NS_ENUM(NSInteger, RCTResizeMode) { RCTResizeModeStretch = UIViewContentModeScaleToFill, RCTResizeModeCenter = UIViewContentModeCenter, RCTResizeModeRepeat = -1, // Use negative values to avoid conflicts with iOS enum values. + RCTResizeModeNone = UIViewContentModeTopLeft, }; static inline RCTResizeMode RCTResizeModeFromUIViewContentMode(UIViewContentMode mode) @@ -30,12 +31,14 @@ static inline RCTResizeMode RCTResizeModeFromUIViewContentMode(UIViewContentMode case UIViewContentModeCenter: return RCTResizeModeCenter; break; + case UIViewContentModeTopLeft: + return RCTResizeModeNone; + break; case UIViewContentModeRedraw: case UIViewContentModeTop: case UIViewContentModeBottom: case UIViewContentModeLeft: case UIViewContentModeRight: - case UIViewContentModeTopLeft: case UIViewContentModeTopRight: case UIViewContentModeBottomLeft: case UIViewContentModeBottomRight: diff --git a/packages/react-native/Libraries/Image/RCTResizeMode.mm b/packages/react-native/Libraries/Image/RCTResizeMode.mm index c35c32e3fd16fc..88ea96eb036e4c 100644 --- a/packages/react-native/Libraries/Image/RCTResizeMode.mm +++ b/packages/react-native/Libraries/Image/RCTResizeMode.mm @@ -17,6 +17,7 @@ @implementation RCTConvert (RCTResizeMode) @"stretch" : @(RCTResizeModeStretch), @"center" : @(RCTResizeModeCenter), @"repeat" : @(RCTResizeModeRepeat), + @"none" : @(RCTResizeModeNone), }), RCTResizeModeStretch, integerValue) diff --git a/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.d.ts b/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.d.ts index a4aa69d027579e..05a8b6410f454e 100644 --- a/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.d.ts +++ b/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.d.ts @@ -568,6 +568,6 @@ export interface ImageStyle extends FlexStyle, ShadowStyleIOS, TransformsStyle { overlayColor?: ColorValue | undefined; tintColor?: ColorValue | undefined; opacity?: AnimatableNumericValue | undefined; - objectFit?: 'cover' | 'contain' | 'fill' | 'scale-down' | undefined; + objectFit?: 'cover' | 'contain' | 'fill' | 'scale-down' | 'none' | undefined; cursor?: CursorValue | undefined; } diff --git a/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.js b/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.js index ebc1dfa98b09c7..0d75a94204048c 100644 --- a/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.js +++ b/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.js @@ -11,6 +11,7 @@ 'use strict'; import type AnimatedNode from '../Animated/nodes/AnimatedNode'; +import type {ImageResizeMode} from './../Image/ImageResizeMode'; import type { ____DangerouslyImpreciseStyle_InternalOverrides, ____ImageStyle_InternalOverrides, @@ -941,8 +942,8 @@ export type ____TextStyle_Internal = $ReadOnly<{ export type ____ImageStyle_InternalCore = $ReadOnly<{ ...$Exact<____ViewStyle_Internal>, - resizeMode?: 'contain' | 'cover' | 'stretch' | 'center' | 'repeat', - objectFit?: 'cover' | 'contain' | 'fill' | 'scale-down', + resizeMode?: ImageResizeMode, + objectFit?: 'cover' | 'contain' | 'fill' | 'scale-down' | 'none', tintColor?: ____ColorValue_Internal, overlayColor?: string, }>; @@ -954,8 +955,8 @@ export type ____ImageStyle_Internal = $ReadOnly<{ export type ____DangerouslyImpreciseStyle_InternalCore = $ReadOnly<{ ...$Exact<____TextStyle_Internal>, - resizeMode?: 'contain' | 'cover' | 'stretch' | 'center' | 'repeat', - objectFit?: 'cover' | 'contain' | 'fill' | 'scale-down', + resizeMode?: ImageResizeMode, + objectFit?: 'cover' | 'contain' | 'fill' | 'scale-down' | 'none', tintColor?: ____ColorValue_Internal, overlayColor?: string, }>; diff --git a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap index ceca9bbce45dd6..ea0a2fe12eff77 100644 --- a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap +++ b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap @@ -4869,7 +4869,7 @@ export type ImageProps = $ReadOnly<{| | \\"strict-origin-when-cross-origin\\" | \\"unsafe-url\\" ), - resizeMode?: ?(\\"cover\\" | \\"contain\\" | \\"stretch\\" | \\"repeat\\" | \\"center\\"), + resizeMode?: ?ImageResizeMode, testID?: ?string, tintColor?: ColorValue, src?: ?string, @@ -4892,7 +4892,8 @@ exports[`public API should not change unintentionally Libraries/Image/ImageResiz | \\"contain\\" | \\"cover\\" | \\"repeat\\" - | \\"stretch\\"; + | \\"stretch\\" + | \\"none\\"; " `; @@ -4989,10 +4990,9 @@ export type { ImageProps } from \\"./ImageProps\\"; `; exports[`public API should not change unintentionally Libraries/Image/ImageUtils.js 1`] = ` -"type ResizeMode = \\"cover\\" | \\"contain\\" | \\"stretch\\" | \\"repeat\\" | \\"center\\"; -declare export function convertObjectFitToResizeMode( +"declare export function convertObjectFitToResizeMode( objectFit: ?string -): ?ResizeMode; +): ?ImageResizeMode; " `; @@ -8261,8 +8261,8 @@ export type ____TextStyle_Internal = $ReadOnly<{ }>; export type ____ImageStyle_InternalCore = $ReadOnly<{ ...$Exact<____ViewStyle_Internal>, - resizeMode?: \\"contain\\" | \\"cover\\" | \\"stretch\\" | \\"center\\" | \\"repeat\\", - objectFit?: \\"cover\\" | \\"contain\\" | \\"fill\\" | \\"scale-down\\", + resizeMode?: ImageResizeMode, + objectFit?: \\"cover\\" | \\"contain\\" | \\"fill\\" | \\"scale-down\\" | \\"none\\", tintColor?: ____ColorValue_Internal, overlayColor?: string, }>; @@ -8272,8 +8272,8 @@ export type ____ImageStyle_Internal = $ReadOnly<{ }>; export type ____DangerouslyImpreciseStyle_InternalCore = $ReadOnly<{ ...$Exact<____TextStyle_Internal>, - resizeMode?: \\"contain\\" | \\"cover\\" | \\"stretch\\" | \\"center\\" | \\"repeat\\", - objectFit?: \\"cover\\" | \\"contain\\" | \\"fill\\" | \\"scale-down\\", + resizeMode?: ImageResizeMode, + objectFit?: \\"cover\\" | \\"contain\\" | \\"fill\\" | \\"scale-down\\" | \\"none\\", tintColor?: ____ColorValue_Internal, overlayColor?: string, }>; diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/image/ImageResizeMode.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/image/ImageResizeMode.kt index 76da29958b1169..61098ad9c38771 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/image/ImageResizeMode.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/image/ImageResizeMode.kt @@ -19,6 +19,7 @@ public object ImageResizeMode { private const val RESIZE_MODE_STRETCH = "stretch" private const val RESIZE_MODE_CENTER = "center" private const val RESIZE_MODE_REPEAT = "repeat" + private const val RESIZE_MODE_NONE = "none" /** Converts JS resize modes into `ScalingUtils.ScaleType`. See `ImageResizeMode.js`. */ @JvmStatic @@ -30,6 +31,7 @@ public object ImageResizeMode { RESIZE_MODE_CENTER -> return ScalingUtils.ScaleType.CENTER_INSIDE // Handled via a combination of ScaleType and TileMode RESIZE_MODE_REPEAT -> return ScaleTypeStartInside.INSTANCE + RESIZE_MODE_NONE -> return ScaleTypeStartInside.INSTANCE } if (resizeModeValue != null) { @@ -45,7 +47,8 @@ public object ImageResizeMode { if (RESIZE_MODE_CONTAIN == resizeModeValue || RESIZE_MODE_COVER == resizeModeValue || RESIZE_MODE_STRETCH == resizeModeValue || - RESIZE_MODE_CENTER == resizeModeValue) { + RESIZE_MODE_CENTER == resizeModeValue || + RESIZE_MODE_NONE == resizeModeValue) { return TileMode.CLAMP } if (RESIZE_MODE_REPEAT == resizeModeValue) { diff --git a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/image/ImageResizeModeTest.kt b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/image/ImageResizeModeTest.kt index 1c6f98d76ec7bf..c3c589986af95b 100644 --- a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/image/ImageResizeModeTest.kt +++ b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/image/ImageResizeModeTest.kt @@ -28,6 +28,8 @@ class ImageResizeModeTest { .isEqualTo(ScalingUtils.ScaleType.FIT_XY) Assertions.assertThat(ImageResizeMode.toScaleType("center")) .isEqualTo(ScalingUtils.ScaleType.CENTER_INSIDE) + Assertions.assertThat(ImageResizeMode.toScaleType("none")) + .isEqualTo(ScaleTypeStartInside.INSTANCE) // No resizeMode set Assertions.assertThat(ImageResizeMode.defaultValue()) diff --git a/packages/react-native/ReactCommon/react/renderer/components/image/conversions.h b/packages/react-native/ReactCommon/react/renderer/components/image/conversions.h index 0a76824f588b46..2803206c792d5c 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/image/conversions.h +++ b/packages/react-native/ReactCommon/react/renderer/components/image/conversions.h @@ -148,6 +148,8 @@ inline void fromRawValue( result = ImageResizeMode::Center; } else if (stringValue == "repeat") { result = ImageResizeMode::Repeat; + } else if (stringValue == "none") { + result = ImageResizeMode::None; } else { LOG(ERROR) << "Unsupported ImageResizeMode value: " << stringValue; react_native_expect(false); @@ -168,6 +170,8 @@ inline std::string toString(const ImageResizeMode& value) { return "center"; case ImageResizeMode::Repeat: return "repeat"; + case ImageResizeMode::None: + return "none"; } } diff --git a/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/RCTImagePrimitivesConversions.h b/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/RCTImagePrimitivesConversions.h index 88487f94d48c68..50194b7a7548d7 100644 --- a/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/RCTImagePrimitivesConversions.h +++ b/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/RCTImagePrimitivesConversions.h @@ -26,6 +26,8 @@ inline static UIViewContentMode RCTContentModeFromImageResizeMode(facebook::reac // Repeat resize mode is handled by the UIImage. Use scale to fill // so the repeated image fills the UIImageView. return UIViewContentModeScaleToFill; + case facebook::react::ImageResizeMode::None: + return UIViewContentModeTopLeft; } } @@ -42,6 +44,8 @@ inline std::string toString(const facebook::react::ImageResizeMode &value) return "center"; case facebook::react::ImageResizeMode::Repeat: return "repeat"; + case facebook::react::ImageResizeMode::None: + return "none"; } } diff --git a/packages/react-native/ReactCommon/react/renderer/imagemanager/primitives.h b/packages/react-native/ReactCommon/react/renderer/imagemanager/primitives.h index 18aba9e10b53be..e8d4be21db453e 100644 --- a/packages/react-native/ReactCommon/react/renderer/imagemanager/primitives.h +++ b/packages/react-native/ReactCommon/react/renderer/imagemanager/primitives.h @@ -47,6 +47,7 @@ enum class ImageResizeMode { Stretch, Center, Repeat, + None, }; class ImageErrorInfo { diff --git a/packages/rn-tester/js/examples/Image/ImageExample.js b/packages/rn-tester/js/examples/Image/ImageExample.js index 81e42ad8adb72e..b3dddd83e875d8 100644 --- a/packages/rn-tester/js/examples/Image/ImageExample.js +++ b/packages/rn-tester/js/examples/Image/ImageExample.js @@ -825,6 +825,9 @@ const styles = StyleSheet.create({ objectFitScaleDown: { objectFit: 'scale-down', }, + objectFitNone: { + objectFit: 'none', + }, imageInBundle: { borderColor: 'yellow', borderWidth: 4, @@ -1466,6 +1469,17 @@ exports.examples = [ />
+ + + + None + + + + ); })} @@ -1537,6 +1551,18 @@ exports.examples = [ /> + + + + None + + + + ); })} From 2168dca4ac22b50559989303e5529e6c1d179180 Mon Sep 17 00:00:00 2001 From: Soe Lynn Date: Tue, 5 Nov 2024 12:11:51 -0800 Subject: [PATCH 062/220] Fix warning for adjustImageWhenDisabled (#47401) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47401 Changelog [Internal]: Replace deprecated `adjustImageWhenDisabled` with `UIButtonConfiguration` Reviewed By: cipolleschi Differential Revision: D65457771 fbshipit-source-id: ffb5b4fc629ba671cb6fec1dc333bf693e4be8ea --- .../DevSupport/RCTPausedInDebuggerOverlayController.mm | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/react-native/React/DevSupport/RCTPausedInDebuggerOverlayController.mm b/packages/react-native/React/DevSupport/RCTPausedInDebuggerOverlayController.mm index c6c201c03cd861..8be2bce952a330 100644 --- a/packages/react-native/React/DevSupport/RCTPausedInDebuggerOverlayController.mm +++ b/packages/react-native/React/DevSupport/RCTPausedInDebuggerOverlayController.mm @@ -56,7 +56,11 @@ - (void)viewDidLoad UIButton *resumeButton = [UIButton buttonWithType:UIButtonTypeCustom]; [resumeButton setImage:[UIImage systemImageNamed:@"forward.frame.fill"] forState:UIControlStateNormal]; resumeButton.tintColor = [UIColor colorWithRed:0.37 green:0.37 blue:0.37 alpha:1]; - resumeButton.adjustsImageWhenDisabled = NO; + + resumeButton.configurationUpdateHandler = ^(UIButton *button) { + button.imageView.tintAdjustmentMode = UIViewTintAdjustmentModeNormal; + }; + resumeButton.enabled = NO; [NSLayoutConstraint activateConstraints:@[ [resumeButton.widthAnchor constraintEqualToConstant:48], From 72bd840dd3dc7b6e3e88a74ac9ddb000a0cb3a60 Mon Sep 17 00:00:00 2001 From: David Vacca Date: Tue, 5 Nov 2024 12:34:51 -0800 Subject: [PATCH 063/220] Deprecate BridgelessCatalystInstance class (#47385) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47385 BridgelessCatalystInstance class is deprecated, please to migrate to new architecture using [com.facebook.react.defaults.DefaultReactHost] instead. changelog: [Android][Changed] Deprecate BridgelessCatalystInstance class Reviewed By: cortinico Differential Revision: D65430789 fbshipit-source-id: 011b372c93c39862d5821713aa8f673084b52c2a --- .../react/runtime/BridgelessCatalystInstance.kt | 17 +++++++++-------- .../react/runtime/BridgelessReactContextTest.kt | 1 + 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/BridgelessCatalystInstance.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/BridgelessCatalystInstance.kt index 1a988f2afacca0..99c3296c5e7a14 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/BridgelessCatalystInstance.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/BridgelessCatalystInstance.kt @@ -21,14 +21,15 @@ import com.facebook.react.bridge.RuntimeExecutor import com.facebook.react.bridge.RuntimeScheduler import com.facebook.react.bridge.UIManager import com.facebook.react.bridge.queue.ReactQueueConfiguration -import com.facebook.react.common.annotations.DeprecatedInNewArchitecture import com.facebook.react.common.annotations.VisibleForTesting import com.facebook.react.internal.turbomodule.core.interfaces.TurboModuleRegistry import com.facebook.react.turbomodule.core.interfaces.CallInvokerHolder import com.facebook.react.turbomodule.core.interfaces.NativeMethodCallInvokerHolder @DoNotStrip -@DeprecatedInNewArchitecture +@Deprecated( + message = + "This class is deprecated, please to migrate to new architecture using [com.facebook.react.defaults.DefaultReactHost] instead.") public class BridgelessCatalystInstance(private val reactHost: ReactHostImpl) : CatalystInstance { override fun handleMemoryPressure(level: Int) { @@ -147,23 +148,23 @@ public class BridgelessCatalystInstance(private val reactHost: ReactHostImpl) : throw UnsupportedOperationException("Unimplemented method 'setGlobalVariable'") } - @DeprecatedInNewArchitecture( + @Deprecated( message = - "This method will be deprecated later as part of Stable APIs with bridge removal and not encouraged usage.") + "This class is deprecated, please to migrate to new architecture using [com.facebook.react.defaults.DefaultReactHost] instead.") override fun setTurboModuleRegistry(turboModuleRegistry: TurboModuleRegistry) { throw UnsupportedOperationException("Unimplemented method 'setTurboModuleRegistry'") } - @DeprecatedInNewArchitecture( + @Deprecated( message = - "This method will be deprecated later as part of Stable APIs with bridge removal and not encouraged usage.") + "This class is deprecated, please to migrate to new architecture using [com.facebook.react.defaults.DefaultReactHost] instead.") override fun setFabricUIManager(fabricUIManager: UIManager) { throw UnsupportedOperationException("Unimplemented method 'setFabricUIManager'") } - @DeprecatedInNewArchitecture( + @Deprecated( message = - "This method will be deprecated later as part of Stable APIs with bridge removal and not encouraged usage.") + "This class is deprecated, please to migrate to new architecture using [com.facebook.react.defaults.DefaultReactHost] instead.") override fun getFabricUIManager(): UIManager { throw UnsupportedOperationException("Unimplemented method 'getFabricUIManager'") } diff --git a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/runtime/BridgelessReactContextTest.kt b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/runtime/BridgelessReactContextTest.kt index 74c5847a63ccab..cd8bb9bfaa5ab6 100644 --- a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/runtime/BridgelessReactContextTest.kt +++ b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/runtime/BridgelessReactContextTest.kt @@ -71,6 +71,7 @@ class BridgelessReactContextTest { assertThat(bridgelessReactContext.getFabricUIManager()).isEqualTo(fabricUiManager) } + @Suppress("DEPRECATION") @Test fun getCatalystInstanceTest() { assertThat(bridgelessReactContext.getCatalystInstance()) From bbe714e487fb51c61820fdc5d89c9782da79b657 Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Tue, 5 Nov 2024 13:59:31 -0800 Subject: [PATCH 064/220] Undo a breaking change on ReactViewGroup constructor (#47423) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47423 cipolleschi found out that we broke the `ReactViewGroup` constructor when making this class Nullsafe. Specifically now users would need to pass a `Context` and not a `Context?` as libraries will break (and this will break a lot of them). So I'm undoing this change by annotating this parameter as Nullable. Changelog: [Android] [Changed] - Undo a breaking change on ReactViewGroup constructor Reviewed By: tdn120 Differential Revision: D65483379 fbshipit-source-id: 43f7bcab5f10b1b8b5601de1dab314d7bbb1eefe --- .../com/facebook/react/views/view/ReactViewGroup.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java index 8277b71a9f010d..6c33e2ee70e2ad 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java @@ -143,7 +143,13 @@ public void shutdown() { private float mBackfaceOpacity; private String mBackfaceVisibility; - public ReactViewGroup(Context context) { + /** + * Creates a new `ReactViewGroup` instance. + * + * @param context A {@link Context} instance. It's Nullable to not break compatibility with OSS + * users (could be made non-null in the future but requires proper comms). + */ + public ReactViewGroup(@Nullable Context context) { super(context); initView(); } From d2a91617da736117cf06fae0b2f32fa1186c5af3 Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Tue, 5 Nov 2024 14:33:29 -0800 Subject: [PATCH 065/220] Prevent @react-native-bot from double posting on missing reproducer (#47427) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47427 I've noticed that react-native-bot posts twice once we can't find a reproducer. (see here: https://github.com/facebook/react-native/issues/47421) This fixes it by letting it post only once. Changelog: [Internal] [Changed] - Prevent react-native-bot from double posting on missing reproducer Reviewed By: mdvacca Differential Revision: D65485634 fbshipit-source-id: dbe9b1311aef246dead6d9b922c1256363e894f7 --- .../workflow-scripts/checkForReproducer.js | 26 +------------------ .github/workflow-scripts/verifyVersion.js | 5 ---- 2 files changed, 1 insertion(+), 30 deletions(-) diff --git a/.github/workflow-scripts/checkForReproducer.js b/.github/workflow-scripts/checkForReproducer.js index b4814d5441d9aa..f1f336da2ca574 100644 --- a/.github/workflow-scripts/checkForReproducer.js +++ b/.github/workflow-scripts/checkForReproducer.js @@ -9,11 +9,6 @@ const NEEDS_REPRO_LABEL = 'Needs: Repro'; const NEEDS_AUTHOR_FEEDBACK_LABEL = 'Needs: Author Feedback'; -const NEEDS_REPRO_HEADER = 'Missing Reproducible Example'; -const NEEDS_REPRO_MESSAGE = - `| :warning: | Missing Reproducible Example |\n` + - `| --- | --- |\n` + - `| :information_source: | We could not detect a reproducible example in your issue report. Please provide either:
  • If your bug is UI related: a [Snack](https://snack.expo.dev)
  • If your bug is build/update related: use our [Reproducer Template](https://github.com/react-native-community/reproducer-react-native/generate). A reproducer needs to be in a GitHub repository under your username.
|`; const SKIP_ISSUES_OLDER_THAN = '2023-07-01T00:00:00Z'; module.exports = async (github, context) => { @@ -25,7 +20,6 @@ module.exports = async (github, context) => { const issue = await github.rest.issues.get(issueData); const comments = await github.rest.issues.listComments(issueData); - const author = issue.data.user.login; const issueDate = issue.data.created_at; @@ -43,10 +37,6 @@ module.exports = async (github, context) => { return; } - const botComment = comments.data.find(comment => - comment.body.includes(NEEDS_REPRO_HEADER), - ); - const entities = [issue.data, ...comments.data]; // Look for Snack or a GH repo associated with the user that added an issue or comment @@ -74,25 +64,11 @@ module.exports = async (github, context) => { throw error; } } - - if (!botComment) return; - - await github.rest.issues.deleteComment({ - ...issueData, - comment_id: botComment.id, - }); } else { await github.rest.issues.addLabels({ ...issueData, labels: [NEEDS_REPRO_LABEL, NEEDS_AUTHOR_FEEDBACK_LABEL], }); - - if (botComment) return; - - await github.rest.issues.createComment({ - ...issueData, - body: NEEDS_REPRO_MESSAGE, - }); } }; @@ -101,7 +77,7 @@ function containsPattern(body, pattern) { return body.search(regexp) !== -1; } -// Prevents the bot from responding when maintainer has changed Needs: Repro the label +// Prevents the bot from responding when maintainer has changed the 'Needs: Repro' label async function hasMaintainerChangedLabel(github, issueData, author) { const timeline = await github.rest.issues.listEventsForTimeline(issueData); diff --git a/.github/workflow-scripts/verifyVersion.js b/.github/workflow-scripts/verifyVersion.js index c28c6b0dd11fdb..5f51adff75e5fb 100644 --- a/.github/workflow-scripts/verifyVersion.js +++ b/.github/workflow-scripts/verifyVersion.js @@ -10,11 +10,6 @@ module.exports = async (github, context) => { const issue = context.payload.issue; - // Ignore issues using upgrade template (they use a special label) - if (issue.labels.find(label => label.name === 'Type: Upgrade Issue')) { - return; - } - const issueVersionUnparsed = getReactNativeVersionFromIssueBodyIfExists(issue); const issueVersion = parseVersionFromString(issueVersionUnparsed); From c4f58d2452786deeb23639a67d7174382a4bebf7 Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Tue, 5 Nov 2024 14:33:29 -0800 Subject: [PATCH 066/220] Update messages for @react-native-bot (#47428) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47428 This changes the messages that the bot is printing. I've moved from using a table to using GitHub's admonitions that renders nicely are are more informative. Changelog: [Internal] [Changed] - Update messages for react-native-bot Reviewed By: mdvacca Differential Revision: D65485633 fbshipit-source-id: f43f7bd75280bfd0aceab48b2517306c1057b778 --- .github/workflow-scripts/actOnLabel.js | 64 +++++++++++--------------- 1 file changed, 26 insertions(+), 38 deletions(-) diff --git a/.github/workflow-scripts/actOnLabel.js b/.github/workflow-scripts/actOnLabel.js index a4c2158466cad8..7692e67b31d564 100644 --- a/.github/workflow-scripts/actOnLabel.js +++ b/.github/workflow-scripts/actOnLabel.js @@ -48,96 +48,84 @@ module.exports = async (github, context, labelWithContext) => { switch (labelWithContext.label) { case 'Type: Invalid': await addComment( - `| :warning: | Issue is Invalid |\n` + - `| --- | --- |\n` + - `| :information_source: | This issue doesn't match any of the expected types for this repository - closing. |`, + `> [!CAUTION]` + + `> **Invalid issue**: This issue is not valid, either is not a bug in React Native, it doesn't match any of the issue template, or we can't help further with this.`, ); await closeIssue(); return; case 'Type: Question': await addComment( - `| :warning: | Issue is a Question |\n` + - `| --- | --- |\n` + - `| :information_source: | We are using GitHub issues exclusively to track bugs in React Native. GitHub may not be the ideal place to ask a question, but you can try asking over on [Stack Overflow](http://stackoverflow.com/questions/tagged/react-native), or on [Reactiflux](https://www.reactiflux.com/). |`, + `> [!NOTE]` + + `> **Not a bug report**: This issue looks like a question. We are using GitHub issues exclusively to track bugs in React Native. GitHub may not be the ideal place to ask a question, but you can try asking over on [Stack Overflow](http://stackoverflow.com/questions/tagged/react-native), or on [Reactiflux](https://www.reactiflux.com/).`, ); await closeIssue(); return; - case 'Type: Docs': + case 'Resolution: For Stack Overflow': await addComment( - `| :warning: | Documentation Issue |\n` + - `| --- | --- |\n` + - `| :information_source: | Please report documentation issues in the [react-native-website](https://github.com/facebook/react-native-website/issues) repository. |`, + `> [!NOTE]` + + `> **Not a bug report**: This issue looks like a question. We are using GitHub issues exclusively to track bugs in React Native. GitHub may not be the ideal place to ask a question, but you can try asking over on [Stack Overflow](http://stackoverflow.com/questions/tagged/react-native), or on [Reactiflux](https://www.reactiflux.com/).`, ); await closeIssue(); return; - case 'Resolution: For Stack Overflow': + case 'Type: Docs': await addComment( - `| :warning: | Issue is a Question |\n` + - `| --- | --- |\n` + - `| :information_source: | We are using GitHub issues exclusively to track bugs in the core React Native library. Please try asking over on [Stack Overflow](http://stackoverflow.com/questions/tagged/react-native) as it is better suited for this type of question. |`, + `> [!NOTE]` + + `> **Docs issue**: This issue looks like an issue related to our docs. Please report documentation issues in the [react-native-website](https://github.com/facebook/react-native-website/issues) repository.`, ); await closeIssue(); return; case 'Type: Expo': await addComment( - `| :warning: | Issue is Related to Expo |\n` + - `| --- | --- |\n` + - `| :information_source: | It looks like your issue is related to Expo and not React Native core. Please open your issue in [Expo's repository](https://github.com/expo/expo/issues/new). If you are able to create a repro that showcases that this issue is also happening in React Native vanilla, we will be happy to re-open. |`, + `> [!NOTE]` + + `> **Expo related**: It looks like your issue is related to Expo and not React Native core. Please open your issue in [Expo's repository](https://github.com/expo/expo/issues/new). If you are able to create a repro that showcases that this issue is also happening in React Native vanilla, we will be happy to re-open.`, ); await closeIssue(); return; case 'Needs: Issue Template': await addComment( - `| :warning: | Missing Required Fields |\n` + - `| --- | --- |\n` + - `| :information_source: | It looks like your issue may be missing some necessary information. GitHub provides an example template whenever a [new issue is created](https://github.com/facebook/react-native/issues/new?template=bug_report.md). Could you go back and make sure to fill out the template? You may edit this issue, or close it and open a new one. |`, + `> [!WARNING]` + + `> **Missing issue template**: It looks like your issue may be missing some necessary information. GitHub provides an example template whenever a [new issue is created](https://github.com/facebook/react-native/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A&projects=&template=bug_report.yml). Could you go back and make sure to fill out the template? You may edit this issue, or close it and open a new one.`, ); await requestAuthorFeedback(); return; case 'Needs: Environment Info': await addComment( - `| :warning: | Missing Environment Information |\n` + - `| --- | --- |\n` + - `| :information_source: | Your issue may be missing information about your development environment. You can obtain the missing information by running react-native info in a console. |`, + `> [!WARNING]` + + `> **Missing info**: It looks like your issue may be missing information about your development environment. You can obtain the missing information by running react-native info in a console.`, ); await requestAuthorFeedback(); return; case 'Newer Patch Available': await addComment( - `| :warning: | Newer Version of React Native is Available! |\n` + - `| --- | --- |\n` + - `| :information_source: | You are on a supported minor version, but it looks like there's a newer patch available - ${labelWithContext.newestPatch}. Please [upgrade](https://reactnative.dev/docs/upgrading) to the highest patch for your minor or latest and verify if the issue persists (alternatively, create a new project and repro the issue in it). If it does not repro, please let us know so we can close out this issue. This helps us ensure we are looking at issues that still exist in the most recent releases. |`, + `> [!TIP]` + + `> **Newer version available**: You are on a supported minor version, but it looks like there's a newer patch available - ${labelWithContext.newestPatch}. Please [upgrade](https://reactnative.dev/docs/upgrading) to the highest patch for your minor or latest and verify if the issue persists (alternatively, create a new project and repro the issue in it). If it does not repro, please let us know so we can close out this issue. This helps us ensure we are looking at issues that still exist in the most recent releases.`, ); return; case 'Needs: Version Info': await addComment( - `| :warning: | Add or Reformat Version Info |\n` + - `| --- | --- |\n` + - `| :information_source: | We could not find or parse the version number of React Native in your issue report. Please use the template, and report your version including major, minor, and patch numbers - e.g. 0.70.2 |`, + `> [!WARNING]` + + `> **Could not parse version**: We could not find or parse the version number of React Native in your issue report. Please use the template, and report your version including major, minor, and patch numbers - e.g. 0.76.2.`, ); await requestAuthorFeedback(); return; case 'Needs: Repro': await addComment( - `| :warning: | Missing Reproducible Example |\n` + - `| --- | --- |\n` + - `| :information_source: | We could not detect a reproducible example in your issue report. Please provide either:
  • If your bug is UI related: a [Snack](https://snack.expo.dev)
  • If your bug is build/update related: use our [Reproducer Template](https://github.com/react-native-community/reproducer-react-native/generate)
|`, + `> [!WARNING]` + + `> **Missing reproducer**: We could not detect a reproducible example in your issue report. Please provide either:
  • If your bug is UI related: a [Snack](https://snack.expo.dev)
  • If your bug is build/upgrade related: a project using our [Reproducer Template](https://github.com/react-native-community/reproducer-react-native/generate)
  • Otherwise send us a Pull Request with the [RNTesterPlayground.js](https://github.com/facebook/react-native/blob/main/packages/rn-tester/js/examples/Playground/RNTesterPlayground.js) edited to reproduce your bug.
`, ); await requestAuthorFeedback(); return; case 'Type: Unsupported Version': await addComment( - `| :warning: | Unsupported Version of React Native |\n` + - `| --- | --- |\n` + - `| :information_source: | It looks like your issue or the example you provided uses an [unsupported version of React Native](https://github.com/reactwg/react-native-releases/blob/main/README.md#releases-support-policy).

Due to the number of issues we receive, we're currently only accepting new issues against one of the supported versions. Please [upgrade](https://reactnative.dev/docs/upgrading) to latest and verify if the issue persists (alternatively, create a new project and repro the issue in it). If you cannot upgrade, please open your issue on [StackOverflow](https://stackoverflow.com/questions/tagged/react-native) to get further community support. |`, + `> [!WARNING]` + + `> **Unsupported version**: It looks like your issue or the example you provided uses an [unsupported version of React Native](https://github.com/reactwg/react-native-releases/blob/main/docs/support.md).

Due to the number of issues we receive, we're currently only accepting new issues against one of the supported versions. Please [upgrade](https://reactnative.dev/docs/upgrading) to latest and verify if the issue persists (alternatively, create a new project and repro the issue in it). If you cannot upgrade, please open your issue on [StackOverflow](https://stackoverflow.com/questions/tagged/react-native) to get further community support.`, ); await requestAuthorFeedback(); return; case 'Type: Too Old Version': await addComment( - `| :warning: | Too Old Version of React Native |\n` + - `| --- | --- |\n` + - `| :information_source: | It looks like your issue or the example you provided uses a [**Too Old Version of React Native**](https://github.com/reactwg/react-native-releases/blob/main/README.md#releases-support-policy).

Due to the number of issues we receive, we're currently only accepting new issues against one of the supported versions. Please [upgrade](https://reactnative.dev/docs/upgrading) to latest and verify if the issue persists (alternatively, create a new project and repro the issue in it). If you cannot upgrade, please open your issue on [StackOverflow](https://stackoverflow.com/questions/tagged/react-native) to get further community support. |`, + `> [!CAUTION]` + + `> **Too old version**: It looks like your issue or the example you provided uses a [**Too Old Version of React Native**](https://github.com/reactwg/react-native-releases/blob/main/docs/support.md).

Due to the number of issues we receive, we're currently only accepting new issues against one of the supported versions. Please [upgrade](https://reactnative.dev/docs/upgrading) to latest and verify if the issue persists (alternatively, create a new project and repro the issue in it). If you cannot upgrade, please open your issue on [StackOverflow](https://stackoverflow.com/questions/tagged/react-native) to get further community support.`, ); await closeIssue(); return; From a72c35f98ccd1a49d367678b46a29c814ad5de43 Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Tue, 5 Nov 2024 15:41:41 -0800 Subject: [PATCH 067/220] Stable API - Make `VibrationModule` internal (#47414) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47414 This class should not be accessed directly, therefore I'm making it internal. Technically breaking but I verified that there are no meaningful usages in OSS: https://github.com/search?type=code&q=NOT+is%3Afork+NOT+org%3Afacebook+com.facebook.react.modules.vibration.VibrationModule Changelog: [Android] [Breaking] - Stable API - Make ClipboardModule internal Reviewed By: mdvacca Differential Revision: D65479292 fbshipit-source-id: 383790e6432c3c8c6f47289d2156099d263cc8ca --- .../react-native/ReactAndroid/api/ReactAndroid.api | 12 ------------ .../react/modules/vibration/VibrationModule.kt | 12 ++++++------ 2 files changed, 6 insertions(+), 18 deletions(-) diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index d8bf1e485e2798..20de33332daf97 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -3662,18 +3662,6 @@ public final class com/facebook/react/modules/toast/ToastModule : com/facebook/f public final class com/facebook/react/modules/toast/ToastModule$Companion { } -public final class com/facebook/react/modules/vibration/VibrationModule : com/facebook/fbreact/specs/NativeVibrationSpec { - public static final field Companion Lcom/facebook/react/modules/vibration/VibrationModule$Companion; - public static final field NAME Ljava/lang/String; - public fun (Lcom/facebook/react/bridge/ReactApplicationContext;)V - public fun cancel ()V - public fun vibrate (D)V - public fun vibrateByPattern (Lcom/facebook/react/bridge/ReadableArray;D)V -} - -public final class com/facebook/react/modules/vibration/VibrationModule$Companion { -} - public final class com/facebook/react/modules/websocket/WebSocketModule : com/facebook/fbreact/specs/NativeWebSocketModuleSpec { public fun (Lcom/facebook/react/bridge/ReactApplicationContext;)V public fun addListener (Ljava/lang/String;)V diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/vibration/VibrationModule.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/vibration/VibrationModule.kt index 2056bbb274915b..029c4380633eca 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/vibration/VibrationModule.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/vibration/VibrationModule.kt @@ -20,10 +20,10 @@ import com.facebook.react.module.annotations.ReactModule @SuppressLint("MissingPermission") @ReactModule(name = NativeVibrationSpec.NAME) -public class VibrationModule(reactContext: ReactApplicationContext) : +internal class VibrationModule(reactContext: ReactApplicationContext) : NativeVibrationSpec(reactContext) { - public override fun vibrate(durationDouble: Double) { + override fun vibrate(durationDouble: Double) { val duration = durationDouble.toInt() val v = getVibrator() ?: return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { @@ -33,7 +33,7 @@ public class VibrationModule(reactContext: ReactApplicationContext) : } } - public override fun vibrateByPattern(pattern: ReadableArray, repeatDouble: Double) { + override fun vibrateByPattern(pattern: ReadableArray, repeatDouble: Double) { val repeat = repeatDouble.toInt() val v = getVibrator() ?: return val patternLong = LongArray(pattern.size()) @@ -47,7 +47,7 @@ public class VibrationModule(reactContext: ReactApplicationContext) : } } - public override fun cancel() { + override fun cancel() { getVibrator()?.cancel() } @@ -62,7 +62,7 @@ public class VibrationModule(reactContext: ReactApplicationContext) : getReactApplicationContext().getSystemService(Context.VIBRATOR_SERVICE) as Vibrator? } - public companion object { - public const val NAME: String = NativeVibrationSpec.NAME + companion object { + const val NAME: String = NativeVibrationSpec.NAME } } From 2dcffef5c471d418a1922842d6c8a09a636c932a Mon Sep 17 00:00:00 2001 From: Yedidya Feldblum Date: Tue, 5 Nov 2024 15:44:57 -0800 Subject: [PATCH 068/220] let Pointer be nothrow-move-constructible (#47331) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47331 Reviewed By: Gownta Differential Revision: D65271354 fbshipit-source-id: cd3ff9db94f2ad332afd68dae438c404f8807f70 --- packages/react-native/ReactCommon/jsi/jsi/jsi.cpp | 2 +- packages/react-native/ReactCommon/jsi/jsi/jsi.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/react-native/ReactCommon/jsi/jsi/jsi.cpp b/packages/react-native/ReactCommon/jsi/jsi/jsi.cpp index 8de94ebc2f270f..13588e1d04bcef 100644 --- a/packages/react-native/ReactCommon/jsi/jsi/jsi.cpp +++ b/packages/react-native/ReactCommon/jsi/jsi/jsi.cpp @@ -258,7 +258,7 @@ std::u16string Runtime::utf16(const String& str) { return convertUTF8ToUTF16(utf8Str); } -Pointer& Pointer::operator=(Pointer&& other) { +Pointer& Pointer::operator=(Pointer&& other) noexcept { if (ptr_) { ptr_->invalidate(); } diff --git a/packages/react-native/ReactCommon/jsi/jsi/jsi.h b/packages/react-native/ReactCommon/jsi/jsi/jsi.h index 8d75b06c96e0e4..07e3722cb0e31a 100644 --- a/packages/react-native/ReactCommon/jsi/jsi/jsi.h +++ b/packages/react-native/ReactCommon/jsi/jsi/jsi.h @@ -418,7 +418,7 @@ class JSI_EXPORT Runtime { // Base class for pointer-storing types. class JSI_EXPORT Pointer { protected: - explicit Pointer(Pointer&& other) : ptr_(other.ptr_) { + explicit Pointer(Pointer&& other) noexcept : ptr_(other.ptr_) { other.ptr_ = nullptr; } @@ -428,7 +428,7 @@ class JSI_EXPORT Pointer { } } - Pointer& operator=(Pointer&& other); + Pointer& operator=(Pointer&& other) noexcept; friend class Runtime; friend class Value; From 120a12f01ad0bdf55a8c44235c5f34754a62e2c2 Mon Sep 17 00:00:00 2001 From: Soe Lynn Date: Tue, 5 Nov 2024 15:45:22 -0800 Subject: [PATCH 069/220] Convert [bridge_ reload] to RCTReloadCommand (#47400) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47400 Changelog [Internal]: Convert `[bridge_ reload]` to RCTReloadCommand Reviewed By: cipolleschi Differential Revision: D65455862 fbshipit-source-id: 5d5e504cc0b4151a2fb4c86c08e84dbd7040ed68 --- packages/react-native/React/Base/RCTBridge.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-native/React/Base/RCTBridge.mm b/packages/react-native/React/Base/RCTBridge.mm index e5f9b8a5982bad..8a44d2ae74889e 100644 --- a/packages/react-native/React/Base/RCTBridge.mm +++ b/packages/react-native/React/Base/RCTBridge.mm @@ -207,7 +207,7 @@ void RCTUIManagerSetDispatchAccessibilityManagerInitOntoMain(BOOL enabled) void onReload(const PageReloadRequest &request) override { RCTAssertMainQueue(); - [bridge_ reload]; + RCTTriggerReloadCommandListeners(@"Reloading due to PageReloadRequest from DevTools."); } void onSetPausedInDebuggerMessage(const OverlaySetPausedInDebuggerMessageRequest &request) override From ef6b6f315c707374c59f31f51c6c3265b2ebaec5 Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Tue, 5 Nov 2024 16:15:09 -0800 Subject: [PATCH 070/220] earlyjs: Attach js build to all errors (#46868) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/46868 jsBuild prasing was done at the js level. But, for the c++ pipeline, we have to parse the js build in native. Changelog: [Internal] Reviewed By: javache Differential Revision: D63927093 fbshipit-source-id: ce7ee46714ee0e72e450003330dbca78acb264a3 --- .../React/CoreModules/RCTExceptionsManager.h | 3 + .../React/CoreModules/RCTExceptionsManager.mm | 44 ++++++++++--- .../ReactAndroid/api/ReactAndroid.api | 1 + .../facebook/react/bridge/JavaOnlyMap.java | 4 ++ .../jserrorhandler/JsErrorHandler.cpp | 63 ++++++++++++++++--- .../ios/ReactCommon/RCTHost+Internal.h | 2 + .../platform/ios/ReactCommon/RCTHost.mm | 5 ++ 7 files changed, 106 insertions(+), 16 deletions(-) diff --git a/packages/react-native/React/CoreModules/RCTExceptionsManager.h b/packages/react-native/React/CoreModules/RCTExceptionsManager.h index d47ad65cf28042..6e9667979df585 100644 --- a/packages/react-native/React/CoreModules/RCTExceptionsManager.h +++ b/packages/react-native/React/CoreModules/RCTExceptionsManager.h @@ -19,6 +19,9 @@ NS_ASSUME_NONNULL_BEGIN stack:(nullable NSArray *)stack exceptionId:(NSNumber *)exceptionId extraDataAsJSON:(nullable NSString *)extraDataAsJSON; + +@optional +- (NSDictionary *)decorateJSExceptionData:(NSDictionary *)exceptionData; @end @interface RCTExceptionsManager : NSObject diff --git a/packages/react-native/React/CoreModules/RCTExceptionsManager.mm b/packages/react-native/React/CoreModules/RCTExceptionsManager.mm index d7f8f647604a90..82b1d295f256c0 100644 --- a/packages/react-native/React/CoreModules/RCTExceptionsManager.mm +++ b/packages/react-native/React/CoreModules/RCTExceptionsManager.mm @@ -83,6 +83,7 @@ - (void)reportFatal:(NSString *)message } } +// TODO(T205456329): This method is deprecated in favour of reportException. Delete in v0.77 RCT_EXPORT_METHOD(reportSoftException : (NSString *)message stack : (NSArray *)stack exceptionId @@ -91,6 +92,7 @@ - (void)reportFatal:(NSString *)message [self reportSoft:message stack:stack exceptionId:exceptionId extraDataAsJSON:nil]; } +// TODO(T205456329): This method is deprecated in favour of reportException. Delete in v0.77 RCT_EXPORT_METHOD(reportFatalException : (NSString *)message stack : (NSArray *)stack exceptionId @@ -103,15 +105,24 @@ - (void)reportFatal:(NSString *)message RCT_EXPORT_METHOD(reportException : (JS::NativeExceptionsManager::ExceptionData &)data) { - NSString *message = data.message(); - double exceptionId = data.id_(); + NSMutableDictionary *mutableErrorData = [NSMutableDictionary new]; + mutableErrorData[@"message"] = data.message(); + if (data.originalMessage()) { + mutableErrorData[@"originalMessage"] = data.originalMessage(); + } + if (data.name()) { + mutableErrorData[@"name"] = data.name(); + } + if (data.componentStack()) { + mutableErrorData[@"componentStack"] = data.componentStack(); + } // Reserialize data.stack() into an array of untyped dictionaries. // TODO: (moti) T53588496 Replace `(NSArray *)stack` in // reportFatalException etc with a typed interface. - NSMutableArray *stackArray = [NSMutableArray new]; + NSMutableArray *> *stackArray = [NSMutableArray *> new]; for (auto frame : data.stack()) { - NSMutableDictionary *frameDict = [NSMutableDictionary new]; + NSMutableDictionary *frameDict = [NSMutableDictionary new]; if (frame.column().has_value()) { frameDict[@"column"] = @(frame.column().value()); } @@ -126,13 +137,28 @@ - (void)reportFatal:(NSString *)message [stackArray addObject:frameDict]; } - NSDictionary *extraData = (NSDictionary *)data.extraData(); - NSString *extraDataAsJSON = RCTJSONStringify(extraData, NULL); + mutableErrorData[@"stack"] = stackArray; + mutableErrorData[@"id"] = @(data.id_()); + mutableErrorData[@"isFatal"] = @(data.isFatal()); + + if (data.extraData()) { + mutableErrorData[@"extraData"] = data.extraData(); + } + + NSDictionary *errorData = mutableErrorData; + if ([_delegate respondsToSelector:@selector(decorateJSExceptionData:)]) { + errorData = [_delegate decorateJSExceptionData:errorData]; + } + + NSString *extraDataAsJSON = RCTJSONStringify(errorData[@"extraData"], NULL); + NSString *message = errorData[@"message"]; + NSArray *> *stack = errorData[@"stack"]; + double exceptionId = [errorData[@"id"] doubleValue]; - if (data.isFatal()) { - [self reportFatal:message stack:stackArray exceptionId:exceptionId extraDataAsJSON:extraDataAsJSON]; + if (errorData[@"isFatal"]) { + [self reportFatal:message stack:stack exceptionId:exceptionId extraDataAsJSON:extraDataAsJSON]; } else { - [self reportSoft:message stack:stackArray exceptionId:exceptionId extraDataAsJSON:extraDataAsJSON]; + [self reportSoft:message stack:stack exceptionId:exceptionId extraDataAsJSON:extraDataAsJSON]; } } diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 20de33332daf97..64a170c54c3933 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -956,6 +956,7 @@ public class com/facebook/react/bridge/JavaOnlyMap : com/facebook/react/bridge/R public fun putMap (Ljava/lang/String;Lcom/facebook/react/bridge/ReadableMap;)V public fun putNull (Ljava/lang/String;)V public fun putString (Ljava/lang/String;Ljava/lang/String;)V + public fun remove (Ljava/lang/String;)V public fun toHashMap ()Ljava/util/HashMap; public fun toString ()Ljava/lang/String; } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaOnlyMap.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaOnlyMap.java index b3f217af8a53b3..afb27217b44cb2 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaOnlyMap.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaOnlyMap.java @@ -246,6 +246,10 @@ public String toString() { return mBackingMap.toString(); } + public void remove(@NonNull String key) { + mBackingMap.remove(key); + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/packages/react-native/ReactCommon/jserrorhandler/JsErrorHandler.cpp b/packages/react-native/ReactCommon/jserrorhandler/JsErrorHandler.cpp index 2c156e6e43126d..7c19502c334214 100644 --- a/packages/react-native/ReactCommon/jserrorhandler/JsErrorHandler.cpp +++ b/packages/react-native/ReactCommon/jserrorhandler/JsErrorHandler.cpp @@ -78,6 +78,43 @@ class SetFalseOnDestruct { } }; +void logErrorWhileReporting( + std::string message, + jsi::JSError& error, + jsi::JSError& originalError) { + LOG(ERROR) << "JsErrorHandler::" << message << std::endl + << "Js error message: " << error.getMessage() << std::endl + << "Original js error message: " << originalError.getMessage() + << std::endl; +} + +jsi::Value getBundleMetadata(jsi::Runtime& runtime, jsi::JSError& error) { + auto jsGetBundleMetadataValue = + runtime.global().getProperty(runtime, "__getBundleMetadata"); + + if (!jsGetBundleMetadataValue.isObject() || + !jsGetBundleMetadataValue.asObject(runtime).isFunction(runtime)) { + return jsi::Value::null(); + } + + auto jsGetBundleMetadataValueFn = + jsGetBundleMetadataValue.asObject(runtime).asFunction(runtime); + + try { + auto bundleMetadataValue = jsGetBundleMetadataValueFn.call(runtime); + if (bundleMetadataValue.isObject()) { + return bundleMetadataValue; + } + return bundleMetadataValue; + } catch (jsi::JSError& ex) { + logErrorWhileReporting( + "getBundleMetadata(): Error raised while calling __getBundleMetadata(). Returning null.", + ex, + error); + } + + return jsi::Value::null(); +} } // namespace namespace facebook::react { @@ -199,12 +236,11 @@ void JsErrorHandler::handleError( try { handleJSError(runtime, error, isFatal); return; - } catch (jsi::JSError& e) { - LOG(ERROR) - << "JsErrorHandler: Failed to report js error using js pipeline. Using C++ pipeline instead." - << std::endl - << "Reporting failure: " << e.getMessage() << std::endl - << "Original js error: " << error.getMessage() << std::endl; + } catch (jsi::JSError& ex) { + logErrorWhileReporting( + "handleError(): Error raised while reporting using js pipeline. Using c++ pipeline instead.", + ex, + error); } } @@ -249,8 +285,14 @@ void JsErrorHandler::handleErrorWithCppPipeline( objectAssign(runtime, extraData, extraDataValue.asObject(runtime)); } + auto isDEV = + isTruthy(runtime, runtime.global().getProperty(runtime, "__DEV__")); + extraData.setProperty(runtime, "jsEngine", jsEngineValue); extraData.setProperty(runtime, "rawStack", error.getStack()); + extraData.setProperty(runtime, "__DEV__", isDEV); + extraData.setProperty( + runtime, "bundleMetadata", getBundleMetadata(runtime, error)); auto cause = errorObj.getProperty(runtime, "cause"); if (cause.isObject()) { @@ -324,7 +366,14 @@ void JsErrorHandler::handleErrorWithCppPipeline( data.setProperty(runtime, "preventDefault", preventDefault); for (auto& errorListener : _errorListeners) { - errorListener(runtime, jsi::Value(runtime, data)); + try { + errorListener(runtime, jsi::Value(runtime, data)); + } catch (jsi::JSError& ex) { + logErrorWhileReporting( + "handleErrorWithCppPipeline(): Error raised inside an error listener. Executing next listener.", + ex, + error); + } } if (*shouldPreventDefault) { diff --git a/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost+Internal.h b/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost+Internal.h index e1708784a45340..dd92a4e30f9b51 100644 --- a/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost+Internal.h +++ b/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost+Internal.h @@ -15,4 +15,6 @@ - (void)setBundleURLProvider:(RCTHostBundleURLProvider)bundleURLProvider; - (void)setContextContainerHandler:(id)contextContainerHandler; +@property (nonatomic, readonly) RCTBundleManager *bundleManager; + @end diff --git a/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost.mm b/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost.mm index 814e8503d9e997..55cd2553f951ee 100644 --- a/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost.mm +++ b/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost.mm @@ -273,6 +273,11 @@ - (RCTSurfacePresenter *)surfacePresenter return [_instance surfacePresenter]; } +- (RCTBundleManager *)bundleManager +{ + return _bundleManager; +} + - (void)callFunctionOnJSModule:(NSString *)moduleName method:(NSString *)method args:(NSArray *)args { [_instance callFunctionOnJSModule:moduleName method:method args:args]; From 39dfbadd5d3468d079bf3b039401237c6e7f363c Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Tue, 5 Nov 2024 16:38:17 -0800 Subject: [PATCH 071/220] Stable API - Make classes in `com.facebook.react.views.safeareaview` internal (#47375) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47375 This makes the following class internal: - ReactSafeAreaView - ReactSafeAreaViewManager Those classes should have not been exposed in the first place. Marked as breaking but no meaningful usages are available in OSS: https://github.com/search?type=code&q=NOT+is%3Afork+NOT+org%3Afacebook+com.facebook.react.views.safeareaview.ReactSafeAreaView Changelog: [Android] [Breaking] - Stable API - Make classes in `com.facebook.react.views.safeareaview` internal Reviewed By: javache Differential Revision: D65422197 fbshipit-source-id: d245155c7c92a408cfbb2a7a0015a73fd1d9f9b8 --- .../ReactAndroid/api/ReactAndroid.api | 35 ------------------- .../ReactAndroid/gradle.properties | 8 ++++- .../views/safeareaview/ReactSafeAreaView.kt | 2 +- .../safeareaview/ReactSafeAreaViewManager.kt | 6 ++-- 4 files changed, 11 insertions(+), 40 deletions(-) diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 64a170c54c3933..bc56fc877b8d4e 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -6851,41 +6851,6 @@ public final class com/facebook/react/views/progressbar/ReactProgressBarViewMana public final fun createProgressBar (Landroid/content/Context;I)Landroid/widget/ProgressBar; } -public final class com/facebook/react/views/safeareaview/ReactSafeAreaView : android/view/ViewGroup { - public fun (Lcom/facebook/react/uimanager/ThemedReactContext;)V - public final fun getReactContext ()Lcom/facebook/react/uimanager/ThemedReactContext; -} - -public final class com/facebook/react/views/safeareaview/ReactSafeAreaViewManager : com/facebook/react/uimanager/ViewGroupManager, com/facebook/react/viewmanagers/SafeAreaViewManagerInterface { - public static final field Companion Lcom/facebook/react/views/safeareaview/ReactSafeAreaViewManager$Companion; - public static final field REACT_CLASS Ljava/lang/String; - public fun ()V - public fun createShadowNodeInstance ()Lcom/facebook/react/uimanager/LayoutShadowNode; - public synthetic fun createShadowNodeInstance ()Lcom/facebook/react/uimanager/ReactShadowNode; - public synthetic fun createViewInstance (Lcom/facebook/react/uimanager/ThemedReactContext;)Landroid/view/View; - public fun getName ()Ljava/lang/String; - public fun getShadowNodeClass ()Ljava/lang/Class; - public synthetic fun updateState (Landroid/view/View;Lcom/facebook/react/uimanager/ReactStylesDiffMap;Lcom/facebook/react/uimanager/StateWrapper;)Ljava/lang/Object; - public fun updateState (Lcom/facebook/react/views/safeareaview/ReactSafeAreaView;Lcom/facebook/react/uimanager/ReactStylesDiffMap;Lcom/facebook/react/uimanager/StateWrapper;)Ljava/lang/Object; -} - -public class com/facebook/react/views/safeareaview/ReactSafeAreaViewManager$$PropsSetter : com/facebook/react/uimanager/ViewManagerPropertyUpdater$ViewManagerSetter { - public fun ()V - public fun getProperties (Ljava/util/Map;)V - public synthetic fun setProperty (Lcom/facebook/react/uimanager/ViewManager;Landroid/view/View;Ljava/lang/String;Ljava/lang/Object;)V - public fun setProperty (Lcom/facebook/react/views/safeareaview/ReactSafeAreaViewManager;Lcom/facebook/react/views/safeareaview/ReactSafeAreaView;Ljava/lang/String;Ljava/lang/Object;)V -} - -public final class com/facebook/react/views/safeareaview/ReactSafeAreaViewManager$Companion { -} - -public class com/facebook/react/views/safeareaview/ReactSafeAreaViewShadowNode$$PropsSetter : com/facebook/react/uimanager/ViewManagerPropertyUpdater$ShadowNodeSetter { - public fun ()V - public fun getProperties (Ljava/util/Map;)V - public synthetic fun setProperty (Lcom/facebook/react/uimanager/ReactShadowNode;Ljava/lang/String;Ljava/lang/Object;)V - public fun setProperty (Lcom/facebook/react/views/safeareaview/ReactSafeAreaViewShadowNode;Ljava/lang/String;Ljava/lang/Object;)V -} - public abstract interface class com/facebook/react/views/scroll/FpsListener { public abstract fun disable (Ljava/lang/String;)V public abstract fun enable (Ljava/lang/String;)V diff --git a/packages/react-native/ReactAndroid/gradle.properties b/packages/react-native/ReactAndroid/gradle.properties index 6c3ec6535d733d..6748b2bfd5cde4 100644 --- a/packages/react-native/ReactAndroid/gradle.properties +++ b/packages/react-native/ReactAndroid/gradle.properties @@ -8,8 +8,14 @@ android.useAndroidX=true react.internal.disableJavaVersionAlignment=true # Binary Compatibility Validator properties + +# We ignore: +# - BuildConfig classes because they are generated and not part of the public API +# - PropsSetter classes because they are generated by the Annotation processor which is not used in OSS binaryCompatibilityValidator.ignoredClasses=com.facebook.react.BuildConfig,\ -com.facebook.react.views.unimplementedview.ReactUnimplementedViewManager$$PropsSetter + com.facebook.react.views.safeareaview.ReactSafeAreaViewManager$$PropsSetter,\ + com.facebook.react.views.unimplementedview.ReactUnimplementedViewManager$$PropsSetter,\ + com.facebook.react.views.safeareaview.ReactSafeAreaViewShadowNode$$PropsSetter binaryCompatibilityValidator.ignoredPackages=com.facebook.debug,\ com.facebook.fbreact,\ diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/safeareaview/ReactSafeAreaView.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/safeareaview/ReactSafeAreaView.kt index 34c94d75a67456..2022305e0a7d82 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/safeareaview/ReactSafeAreaView.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/safeareaview/ReactSafeAreaView.kt @@ -20,7 +20,7 @@ import com.facebook.react.uimanager.StateWrapper import com.facebook.react.uimanager.ThemedReactContext import com.facebook.react.uimanager.UIManagerModule -public class ReactSafeAreaView(public val reactContext: ThemedReactContext) : +internal class ReactSafeAreaView(public val reactContext: ThemedReactContext) : ViewGroup(reactContext) { internal var stateWrapper: StateWrapper? = null diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/safeareaview/ReactSafeAreaViewManager.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/safeareaview/ReactSafeAreaViewManager.kt index f414b281ae7f75..1b00aa85109142 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/safeareaview/ReactSafeAreaViewManager.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/safeareaview/ReactSafeAreaViewManager.kt @@ -19,7 +19,7 @@ import com.facebook.react.viewmanagers.SafeAreaViewManagerInterface /** View manager for [ReactSafeAreaView] components. */ @ReactModule(name = ReactSafeAreaViewManager.REACT_CLASS) -public class ReactSafeAreaViewManager() : +internal class ReactSafeAreaViewManager() : ViewGroupManager(), SafeAreaViewManagerInterface { private val delegate: ViewManagerDelegate = SafeAreaViewManagerDelegate(this) @@ -45,7 +45,7 @@ public class ReactSafeAreaViewManager() : return null } - public companion object { - public const val REACT_CLASS: String = "RCTSafeAreaView" + internal companion object { + const val REACT_CLASS: String = "RCTSafeAreaView" } } From b7ec7523ccd0d5fef50994c958a3a5b25ca7ea7e Mon Sep 17 00:00:00 2001 From: Phillip Pan Date: Tue, 5 Nov 2024 17:43:18 -0800 Subject: [PATCH 072/220] clean up contextContainer->insert("ReactNativeConfig") from oss (#47350) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47350 Changelog: [Internal] we don't need any of these now since no one is calling `contextContainer_->at("ReactNativeConfig")` anymore Reviewed By: NickGerleman Differential Revision: D65304976 fbshipit-source-id: 5f835ab9ac429aa1942cc8d9669812c1ac994238 --- .../AppDelegate/RCTRootViewFactory.mm | 20 ++----------------- .../react/fabric/FabricUIManagerBinding.cpp | 1 - 2 files changed, 2 insertions(+), 19 deletions(-) diff --git a/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.mm b/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.mm index 4b687c5a3e0f92..a92596cb67cc9c 100644 --- a/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.mm +++ b/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.mm @@ -26,7 +26,6 @@ #import #import #import -#import #if USE_HERMES #import #else @@ -35,7 +34,6 @@ #import #import #import -#import #import #import #import @@ -99,13 +97,8 @@ - (instancetype)initWithBundleURLBlock:(RCTBundleURLBlock)bundleURLBlock @end -@interface RCTRootViewFactory () { - std::shared_ptr _reactNativeConfig; - facebook::react::ContextContainer::Shared _contextContainer; -} -@end - @interface RCTRootViewFactory () { + facebook::react::ContextContainer::Shared _contextContainer; std::shared_ptr _runtimeScheduler; } @end @@ -124,8 +117,6 @@ - (instancetype)initWithTurboModuleDelegate:(id)t _configuration = configuration; _hostDelegate = hostdelegate; _contextContainer = std::make_shared(); - _reactNativeConfig = std::make_shared(); - _contextContainer->insert("ReactNativeConfig", _reactNativeConfig); _turboModuleManagerDelegate = turboModuleManagerDelegate; } return self; @@ -281,7 +272,6 @@ - (RCTHost *)createReactHost:(NSDictionary *)launchOptions [reactHost setBundleURLProvider:^NSURL *() { return [weakSelf bundleURL]; }]; - [reactHost setContextContainerHandler:self]; [reactHost start]; return reactHost; } @@ -289,18 +279,12 @@ - (RCTHost *)createReactHost:(NSDictionary *)launchOptions - (std::shared_ptr)createJSRuntimeFactory { #if USE_HERMES - return std::make_shared( - _reactNativeConfig, nullptr, /* allocInOldGenBeforeTTI */ false); + return std::make_shared(nullptr, nullptr, /* allocInOldGenBeforeTTI */ false); #else return std::make_shared(); #endif } -- (void)didCreateContextContainer:(std::shared_ptr)contextContainer -{ - contextContainer->insert("ReactNativeConfig", _reactNativeConfig); -} - - (NSArray> *)extraModulesForBridge:(RCTBridge *)bridge { if (_configuration.extraModulesForBridge != nil) { diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.cpp index 27976b921bad60..9cda709a4f2fbd 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.cpp @@ -473,7 +473,6 @@ void FabricUIManagerBinding::installFabricUIManager( globalJavaUiManager); }; - contextContainer->insert("ReactNativeConfig", config); contextContainer->insert("FabricUIManager", globalJavaUiManager); // Keep reference to config object and cache some feature flags here From 5c3c1524dd49bbe69b14b7490f077920108e5c68 Mon Sep 17 00:00:00 2001 From: David Vacca Date: Tue, 5 Nov 2024 21:44:38 -0800 Subject: [PATCH 073/220] Exclude $$PropSetter classes from public API (#47432) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47432 In this diff we are excluding the $$PropSetter classes from public API, we do this by adding the UnstableReactNativeAPI annotation on all $$PropSetter classes changelog: [internal] internal Reviewed By: cortinico Differential Revision: D65488026 fbshipit-source-id: 9f1bbe7b25fa69c0a40f6cb0ff38a8ae6ee8d97d --- .../ReactAndroid/api/ReactAndroid.api | 189 ------------------ .../processing/ReactPropertyProcessor.java | 2 + 2 files changed, 2 insertions(+), 189 deletions(-) diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index bc56fc877b8d4e..539a04cebdfe29 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -4258,13 +4258,6 @@ public class com/facebook/react/uimanager/LayoutShadowNode : com/facebook/react/ public fun setWidth (Lcom/facebook/react/bridge/Dynamic;)V } -public class com/facebook/react/uimanager/LayoutShadowNode$$PropsSetter : com/facebook/react/uimanager/ViewManagerPropertyUpdater$ShadowNodeSetter { - public fun ()V - public fun getProperties (Ljava/util/Map;)V - public fun setProperty (Lcom/facebook/react/uimanager/LayoutShadowNode;Ljava/lang/String;Ljava/lang/Object;)V - public synthetic fun setProperty (Lcom/facebook/react/uimanager/ReactShadowNode;Ljava/lang/String;Ljava/lang/Object;)V -} - public final class com/facebook/react/uimanager/LengthPercentage { public static final field Companion Lcom/facebook/react/uimanager/LengthPercentage$Companion; public fun ()V @@ -4918,13 +4911,6 @@ public class com/facebook/react/uimanager/ReactShadowNodeImpl : com/facebook/rea public final fun updateProperties (Lcom/facebook/react/uimanager/ReactStylesDiffMap;)V } -public class com/facebook/react/uimanager/ReactShadowNodeImpl$$PropsSetter : com/facebook/react/uimanager/ViewManagerPropertyUpdater$ShadowNodeSetter { - public fun ()V - public fun getProperties (Ljava/util/Map;)V - public synthetic fun setProperty (Lcom/facebook/react/uimanager/ReactShadowNode;Ljava/lang/String;Ljava/lang/Object;)V - public fun setProperty (Lcom/facebook/react/uimanager/ReactShadowNodeImpl;Ljava/lang/String;Ljava/lang/Object;)V -} - public abstract interface annotation class com/facebook/react/uimanager/ReactStage : java/lang/annotation/Annotation { public static final field BRIDGE_DID_LOAD I public static final field MODULE_DID_LOAD I @@ -4978,13 +4964,6 @@ public final class com/facebook/react/uimanager/RootViewManager : com/facebook/r public fun getName ()Ljava/lang/String; } -public class com/facebook/react/uimanager/RootViewManager$$PropsSetter : com/facebook/react/uimanager/ViewManagerPropertyUpdater$ViewManagerSetter { - public fun ()V - public fun getProperties (Ljava/util/Map;)V - public fun setProperty (Lcom/facebook/react/uimanager/RootViewManager;Landroid/view/ViewGroup;Ljava/lang/String;Ljava/lang/Object;)V - public synthetic fun setProperty (Lcom/facebook/react/uimanager/ViewManager;Landroid/view/View;Ljava/lang/String;Ljava/lang/Object;)V -} - public final class com/facebook/react/uimanager/RootViewManager$Companion { } @@ -6367,13 +6346,6 @@ public final class com/facebook/react/views/debuggingoverlay/DebuggingOverlayMan public fun receiveCommand (Lcom/facebook/react/views/debuggingoverlay/DebuggingOverlay;Ljava/lang/String;Lcom/facebook/react/bridge/ReadableArray;)V } -public class com/facebook/react/views/debuggingoverlay/DebuggingOverlayManager$$PropsSetter : com/facebook/react/uimanager/ViewManagerPropertyUpdater$ViewManagerSetter { - public fun ()V - public fun getProperties (Ljava/util/Map;)V - public synthetic fun setProperty (Lcom/facebook/react/uimanager/ViewManager;Landroid/view/View;Ljava/lang/String;Ljava/lang/Object;)V - public fun setProperty (Lcom/facebook/react/views/debuggingoverlay/DebuggingOverlayManager;Lcom/facebook/react/views/debuggingoverlay/DebuggingOverlay;Ljava/lang/String;Ljava/lang/Object;)V -} - public final class com/facebook/react/views/debuggingoverlay/DebuggingOverlayManager$Companion { } @@ -6435,13 +6407,6 @@ public final class com/facebook/react/views/drawer/ReactDrawerLayoutManager : co public fun setStatusBarBackgroundColor (Lcom/facebook/react/views/drawer/ReactDrawerLayout;Ljava/lang/Integer;)V } -public class com/facebook/react/views/drawer/ReactDrawerLayoutManager$$PropsSetter : com/facebook/react/uimanager/ViewManagerPropertyUpdater$ViewManagerSetter { - public fun ()V - public fun getProperties (Ljava/util/Map;)V - public synthetic fun setProperty (Lcom/facebook/react/uimanager/ViewManager;Landroid/view/View;Ljava/lang/String;Ljava/lang/Object;)V - public fun setProperty (Lcom/facebook/react/views/drawer/ReactDrawerLayoutManager;Lcom/facebook/react/views/drawer/ReactDrawerLayout;Ljava/lang/String;Ljava/lang/Object;)V -} - public final class com/facebook/react/views/drawer/ReactDrawerLayoutManager$Companion { } @@ -6603,13 +6568,6 @@ public final class com/facebook/react/views/image/ReactImageManager : com/facebo public final fun setTintColor (Lcom/facebook/react/views/image/ReactImageView;Ljava/lang/Integer;)V } -public class com/facebook/react/views/image/ReactImageManager$$PropsSetter : com/facebook/react/uimanager/ViewManagerPropertyUpdater$ViewManagerSetter { - public fun ()V - public fun getProperties (Ljava/util/Map;)V - public synthetic fun setProperty (Lcom/facebook/react/uimanager/ViewManager;Landroid/view/View;Ljava/lang/String;Ljava/lang/Object;)V - public fun setProperty (Lcom/facebook/react/views/image/ReactImageManager;Lcom/facebook/react/views/image/ReactImageView;Ljava/lang/String;Ljava/lang/Object;)V -} - public final class com/facebook/react/views/image/ReactImageManager$Companion { } @@ -6691,13 +6649,6 @@ public final class com/facebook/react/views/imagehelper/ResourceDrawableIdHelper public final fun getInstance ()Lcom/facebook/react/views/imagehelper/ResourceDrawableIdHelper; } -public class com/facebook/react/views/modal/ModalHostShadowNode$$PropsSetter : com/facebook/react/uimanager/ViewManagerPropertyUpdater$ShadowNodeSetter { - public fun ()V - public fun getProperties (Ljava/util/Map;)V - public synthetic fun setProperty (Lcom/facebook/react/uimanager/ReactShadowNode;Ljava/lang/String;Ljava/lang/Object;)V - public fun setProperty (Lcom/facebook/react/views/modal/ModalHostShadowNode;Ljava/lang/String;Ljava/lang/Object;)V -} - public final class com/facebook/react/views/modal/ReactModalHostManager : com/facebook/react/uimanager/ViewGroupManager, com/facebook/react/viewmanagers/ModalHostViewManagerInterface { public static final field Companion Lcom/facebook/react/views/modal/ReactModalHostManager$Companion; public static final field REACT_CLASS Ljava/lang/String; @@ -6732,13 +6683,6 @@ public final class com/facebook/react/views/modal/ReactModalHostManager : com/fa public fun updateState (Lcom/facebook/react/views/modal/ReactModalHostView;Lcom/facebook/react/uimanager/ReactStylesDiffMap;Lcom/facebook/react/uimanager/StateWrapper;)Ljava/lang/Object; } -public class com/facebook/react/views/modal/ReactModalHostManager$$PropsSetter : com/facebook/react/uimanager/ViewManagerPropertyUpdater$ViewManagerSetter { - public fun ()V - public fun getProperties (Ljava/util/Map;)V - public synthetic fun setProperty (Lcom/facebook/react/uimanager/ViewManager;Landroid/view/View;Ljava/lang/String;Ljava/lang/Object;)V - public fun setProperty (Lcom/facebook/react/views/modal/ReactModalHostManager;Lcom/facebook/react/views/modal/ReactModalHostView;Ljava/lang/String;Ljava/lang/Object;)V -} - public final class com/facebook/react/views/modal/ReactModalHostManager$Companion { } @@ -6804,13 +6748,6 @@ public final class com/facebook/react/views/progressbar/ProgressBarShadowNode : public final fun setStyle (Ljava/lang/String;)V } -public class com/facebook/react/views/progressbar/ProgressBarShadowNode$$PropsSetter : com/facebook/react/uimanager/ViewManagerPropertyUpdater$ShadowNodeSetter { - public fun ()V - public fun getProperties (Ljava/util/Map;)V - public synthetic fun setProperty (Lcom/facebook/react/uimanager/ReactShadowNode;Ljava/lang/String;Ljava/lang/Object;)V - public fun setProperty (Lcom/facebook/react/views/progressbar/ProgressBarShadowNode;Ljava/lang/String;Ljava/lang/Object;)V -} - public final class com/facebook/react/views/progressbar/ReactProgressBarViewManager : com/facebook/react/uimanager/BaseViewManager, com/facebook/react/viewmanagers/AndroidProgressBarManagerInterface { public static final field Companion Lcom/facebook/react/views/progressbar/ReactProgressBarViewManager$Companion; public static final field REACT_CLASS Ljava/lang/String; @@ -6840,13 +6777,6 @@ public final class com/facebook/react/views/progressbar/ReactProgressBarViewMana public fun updateExtraData (Lcom/facebook/react/views/progressbar/ProgressBarContainerView;Ljava/lang/Object;)V } -public class com/facebook/react/views/progressbar/ReactProgressBarViewManager$$PropsSetter : com/facebook/react/uimanager/ViewManagerPropertyUpdater$ViewManagerSetter { - public fun ()V - public fun getProperties (Ljava/util/Map;)V - public synthetic fun setProperty (Lcom/facebook/react/uimanager/ViewManager;Landroid/view/View;Ljava/lang/String;Ljava/lang/Object;)V - public fun setProperty (Lcom/facebook/react/views/progressbar/ReactProgressBarViewManager;Lcom/facebook/react/views/progressbar/ProgressBarContainerView;Ljava/lang/String;Ljava/lang/Object;)V -} - public final class com/facebook/react/views/progressbar/ReactProgressBarViewManager$Companion { public final fun createProgressBar (Landroid/content/Context;I)Landroid/widget/ProgressBar; } @@ -6874,13 +6804,6 @@ public final class com/facebook/react/views/scroll/ReactHorizontalScrollContaine public fun getName ()Ljava/lang/String; } -public class com/facebook/react/views/scroll/ReactHorizontalScrollContainerViewManager$$PropsSetter : com/facebook/react/uimanager/ViewManagerPropertyUpdater$ViewManagerSetter { - public fun ()V - public fun getProperties (Ljava/util/Map;)V - public synthetic fun setProperty (Lcom/facebook/react/uimanager/ViewManager;Landroid/view/View;Ljava/lang/String;Ljava/lang/Object;)V - public fun setProperty (Lcom/facebook/react/views/scroll/ReactHorizontalScrollContainerViewManager;Lcom/facebook/react/views/view/ReactViewGroup;Ljava/lang/String;Ljava/lang/Object;)V -} - public final class com/facebook/react/views/scroll/ReactHorizontalScrollContainerViewManager$Companion { } @@ -7010,13 +6933,6 @@ public class com/facebook/react/views/scroll/ReactHorizontalScrollViewManager : public fun updateState (Lcom/facebook/react/views/scroll/ReactHorizontalScrollView;Lcom/facebook/react/uimanager/ReactStylesDiffMap;Lcom/facebook/react/uimanager/StateWrapper;)Ljava/lang/Object; } -public class com/facebook/react/views/scroll/ReactHorizontalScrollViewManager$$PropsSetter : com/facebook/react/uimanager/ViewManagerPropertyUpdater$ViewManagerSetter { - public fun ()V - public fun getProperties (Ljava/util/Map;)V - public synthetic fun setProperty (Lcom/facebook/react/uimanager/ViewManager;Landroid/view/View;Ljava/lang/String;Ljava/lang/Object;)V - public fun setProperty (Lcom/facebook/react/views/scroll/ReactHorizontalScrollViewManager;Lcom/facebook/react/views/scroll/ReactHorizontalScrollView;Ljava/lang/String;Ljava/lang/Object;)V -} - public class com/facebook/react/views/scroll/ReactScrollView : android/widget/ScrollView, android/view/View$OnLayoutChangeListener, android/view/ViewGroup$OnHierarchyChangeListener, com/facebook/react/uimanager/ReactClippingViewGroup, com/facebook/react/uimanager/ReactOverflowViewWithInset, com/facebook/react/views/scroll/ReactScrollViewHelper$HasFlingAnimator, com/facebook/react/views/scroll/ReactScrollViewHelper$HasScrollEventThrottle, com/facebook/react/views/scroll/ReactScrollViewHelper$HasScrollState, com/facebook/react/views/scroll/ReactScrollViewHelper$HasSmoothScroll, com/facebook/react/views/scroll/ReactScrollViewHelper$HasStateWrapper { public fun (Landroid/content/Context;)V public fun (Landroid/content/Context;Lcom/facebook/react/views/scroll/FpsListener;)V @@ -7258,13 +7174,6 @@ public class com/facebook/react/views/scroll/ReactScrollViewManager : com/facebo public fun updateState (Lcom/facebook/react/views/scroll/ReactScrollView;Lcom/facebook/react/uimanager/ReactStylesDiffMap;Lcom/facebook/react/uimanager/StateWrapper;)Ljava/lang/Object; } -public class com/facebook/react/views/scroll/ReactScrollViewManager$$PropsSetter : com/facebook/react/uimanager/ViewManagerPropertyUpdater$ViewManagerSetter { - public fun ()V - public fun getProperties (Ljava/util/Map;)V - public synthetic fun setProperty (Lcom/facebook/react/uimanager/ViewManager;Landroid/view/View;Ljava/lang/String;Ljava/lang/Object;)V - public fun setProperty (Lcom/facebook/react/views/scroll/ReactScrollViewManager;Lcom/facebook/react/views/scroll/ReactScrollView;Ljava/lang/String;Ljava/lang/Object;)V -} - public final class com/facebook/react/views/scroll/ScrollEvent : com/facebook/react/uimanager/events/Event { public static final field Companion Lcom/facebook/react/views/scroll/ScrollEvent$Companion; public fun canCoalesce ()Z @@ -7338,13 +7247,6 @@ public class com/facebook/react/views/swiperefresh/SwipeRefreshLayoutManager : c public fun setSize (Lcom/facebook/react/views/swiperefresh/ReactSwipeRefreshLayout;Ljava/lang/String;)V } -public class com/facebook/react/views/swiperefresh/SwipeRefreshLayoutManager$$PropsSetter : com/facebook/react/uimanager/ViewManagerPropertyUpdater$ViewManagerSetter { - public fun ()V - public fun getProperties (Ljava/util/Map;)V - public synthetic fun setProperty (Lcom/facebook/react/uimanager/ViewManager;Landroid/view/View;Ljava/lang/String;Ljava/lang/Object;)V - public fun setProperty (Lcom/facebook/react/views/swiperefresh/SwipeRefreshLayoutManager;Lcom/facebook/react/views/swiperefresh/ReactSwipeRefreshLayout;Ljava/lang/String;Ljava/lang/Object;)V -} - public class com/facebook/react/views/switchview/ReactSwitchManager : com/facebook/react/uimanager/SimpleViewManager, com/facebook/react/viewmanagers/AndroidSwitchManagerInterface { public static final field REACT_CLASS Ljava/lang/String; public fun ()V @@ -7384,20 +7286,6 @@ public class com/facebook/react/views/switchview/ReactSwitchManager : com/facebo public fun setValue (Lcom/facebook/react/views/switchview/ReactSwitch;Z)V } -public class com/facebook/react/views/switchview/ReactSwitchManager$$PropsSetter : com/facebook/react/uimanager/ViewManagerPropertyUpdater$ViewManagerSetter { - public fun ()V - public fun getProperties (Ljava/util/Map;)V - public synthetic fun setProperty (Lcom/facebook/react/uimanager/ViewManager;Landroid/view/View;Ljava/lang/String;Ljava/lang/Object;)V - public fun setProperty (Lcom/facebook/react/views/switchview/ReactSwitchManager;Lcom/facebook/react/views/switchview/ReactSwitch;Ljava/lang/String;Ljava/lang/Object;)V -} - -public class com/facebook/react/views/switchview/ReactSwitchManager$ReactSwitchShadowNode$$PropsSetter : com/facebook/react/uimanager/ViewManagerPropertyUpdater$ShadowNodeSetter { - public fun ()V - public fun getProperties (Ljava/util/Map;)V - public synthetic fun setProperty (Lcom/facebook/react/uimanager/ReactShadowNode;Ljava/lang/String;Ljava/lang/Object;)V - public fun setProperty (Lcom/facebook/react/views/switchview/ReactSwitchManager$ReactSwitchShadowNode;Ljava/lang/String;Ljava/lang/Object;)V -} - public final class com/facebook/react/views/text/DefaultStyleValuesUtil { public static final field INSTANCE Lcom/facebook/react/views/text/DefaultStyleValuesUtil; public static final fun getDefaultTextColor (Landroid/content/Context;)Landroid/content/res/ColorStateList; @@ -7497,13 +7385,6 @@ public class com/facebook/react/views/text/ReactRawTextManager : com/facebook/re public fun updateExtraData (Landroid/view/View;Ljava/lang/Object;)V } -public class com/facebook/react/views/text/ReactRawTextManager$$PropsSetter : com/facebook/react/uimanager/ViewManagerPropertyUpdater$ViewManagerSetter { - public fun ()V - public fun getProperties (Ljava/util/Map;)V - public synthetic fun setProperty (Lcom/facebook/react/uimanager/ViewManager;Landroid/view/View;Ljava/lang/String;Ljava/lang/Object;)V - public fun setProperty (Lcom/facebook/react/views/text/ReactRawTextManager;Landroid/view/View;Ljava/lang/String;Ljava/lang/Object;)V -} - public class com/facebook/react/views/text/ReactRawTextShadowNode : com/facebook/react/uimanager/ReactShadowNodeImpl { public fun ()V public fun getText ()Ljava/lang/String; @@ -7512,13 +7393,6 @@ public class com/facebook/react/views/text/ReactRawTextShadowNode : com/facebook public fun toString ()Ljava/lang/String; } -public class com/facebook/react/views/text/ReactRawTextShadowNode$$PropsSetter : com/facebook/react/uimanager/ViewManagerPropertyUpdater$ShadowNodeSetter { - public fun ()V - public fun getProperties (Ljava/util/Map;)V - public synthetic fun setProperty (Lcom/facebook/react/uimanager/ReactShadowNode;Ljava/lang/String;Ljava/lang/Object;)V - public fun setProperty (Lcom/facebook/react/views/text/ReactRawTextShadowNode;Ljava/lang/String;Ljava/lang/Object;)V -} - public abstract class com/facebook/react/views/text/ReactTextAnchorViewManager : com/facebook/react/uimanager/BaseViewManager { public fun ()V public fun setAccessible (Lcom/facebook/react/views/text/ReactTextView;Z)V @@ -7553,13 +7427,6 @@ public class com/facebook/react/views/text/ReactTextShadowNode : com/facebook/re public fun setShouldNotifyOnTextLayout (Z)V } -public class com/facebook/react/views/text/ReactTextShadowNode$$PropsSetter : com/facebook/react/uimanager/ViewManagerPropertyUpdater$ShadowNodeSetter { - public fun ()V - public fun getProperties (Ljava/util/Map;)V - public synthetic fun setProperty (Lcom/facebook/react/uimanager/ReactShadowNode;Ljava/lang/String;Ljava/lang/Object;)V - public fun setProperty (Lcom/facebook/react/views/text/ReactTextShadowNode;Ljava/lang/String;Ljava/lang/Object;)V -} - public class com/facebook/react/views/text/ReactTextUpdate { public fun (Landroid/text/Spannable;IZFFFFI)V public fun (Landroid/text/Spannable;IZFFFFIII)V @@ -7643,13 +7510,6 @@ public class com/facebook/react/views/text/ReactTextViewManager : com/facebook/r public fun updateState (Lcom/facebook/react/views/text/ReactTextView;Lcom/facebook/react/uimanager/ReactStylesDiffMap;Lcom/facebook/react/uimanager/StateWrapper;)Ljava/lang/Object; } -public class com/facebook/react/views/text/ReactTextViewManager$$PropsSetter : com/facebook/react/uimanager/ViewManagerPropertyUpdater$ViewManagerSetter { - public fun ()V - public fun getProperties (Ljava/util/Map;)V - public synthetic fun setProperty (Lcom/facebook/react/uimanager/ViewManager;Landroid/view/View;Ljava/lang/String;Ljava/lang/Object;)V - public fun setProperty (Lcom/facebook/react/views/text/ReactTextViewManager;Lcom/facebook/react/views/text/ReactTextView;Ljava/lang/String;Ljava/lang/Object;)V -} - public abstract interface class com/facebook/react/views/text/ReactTextViewManagerCallback { public abstract fun onPostProcessSpannable (Landroid/text/Spannable;)V } @@ -7667,13 +7527,6 @@ public class com/facebook/react/views/text/ReactVirtualTextShadowNode : com/face public fun isVirtual ()Z } -public class com/facebook/react/views/text/ReactVirtualTextShadowNode$$PropsSetter : com/facebook/react/uimanager/ViewManagerPropertyUpdater$ShadowNodeSetter { - public fun ()V - public fun getProperties (Ljava/util/Map;)V - public synthetic fun setProperty (Lcom/facebook/react/uimanager/ReactShadowNode;Ljava/lang/String;Ljava/lang/Object;)V - public fun setProperty (Lcom/facebook/react/views/text/ReactVirtualTextShadowNode;Ljava/lang/String;Ljava/lang/Object;)V -} - public class com/facebook/react/views/text/ReactVirtualTextViewManager : com/facebook/react/uimanager/BaseViewManager { public fun ()V public synthetic fun createShadowNodeInstance ()Lcom/facebook/react/uimanager/ReactShadowNode; @@ -7684,13 +7537,6 @@ public class com/facebook/react/views/text/ReactVirtualTextViewManager : com/fac public fun updateExtraData (Landroid/view/View;Ljava/lang/Object;)V } -public class com/facebook/react/views/text/ReactVirtualTextViewManager$$PropsSetter : com/facebook/react/uimanager/ViewManagerPropertyUpdater$ViewManagerSetter { - public fun ()V - public fun getProperties (Ljava/util/Map;)V - public synthetic fun setProperty (Lcom/facebook/react/uimanager/ViewManager;Landroid/view/View;Ljava/lang/String;Ljava/lang/Object;)V - public fun setProperty (Lcom/facebook/react/views/text/ReactVirtualTextViewManager;Landroid/view/View;Ljava/lang/String;Ljava/lang/Object;)V -} - public class com/facebook/react/views/text/TextAttributeProps { public static final field TA_KEY_ACCESSIBILITY_ROLE S public static final field TA_KEY_ALIGNMENT S @@ -7847,13 +7693,6 @@ public final class com/facebook/react/views/text/TextTransform : java/lang/Enum public static fun values ()[Lcom/facebook/react/views/text/TextTransform; } -public class com/facebook/react/views/text/frescosupport/FrescoBasedReactTextInlineImageShadowNode$$PropsSetter : com/facebook/react/uimanager/ViewManagerPropertyUpdater$ShadowNodeSetter { - public fun ()V - public fun getProperties (Ljava/util/Map;)V - public synthetic fun setProperty (Lcom/facebook/react/uimanager/ReactShadowNode;Ljava/lang/String;Ljava/lang/Object;)V - public fun setProperty (Lcom/facebook/react/views/text/frescosupport/FrescoBasedReactTextInlineImageShadowNode;Ljava/lang/String;Ljava/lang/Object;)V -} - public class com/facebook/react/views/text/frescosupport/FrescoBasedReactTextInlineImageViewManager : com/facebook/react/uimanager/BaseViewManager { public static final field REACT_CLASS Ljava/lang/String; public fun ()V @@ -7866,13 +7705,6 @@ public class com/facebook/react/views/text/frescosupport/FrescoBasedReactTextInl public fun updateExtraData (Landroid/view/View;Ljava/lang/Object;)V } -public class com/facebook/react/views/text/frescosupport/FrescoBasedReactTextInlineImageViewManager$$PropsSetter : com/facebook/react/uimanager/ViewManagerPropertyUpdater$ViewManagerSetter { - public fun ()V - public fun getProperties (Ljava/util/Map;)V - public synthetic fun setProperty (Lcom/facebook/react/uimanager/ViewManager;Landroid/view/View;Ljava/lang/String;Ljava/lang/Object;)V - public fun setProperty (Lcom/facebook/react/views/text/frescosupport/FrescoBasedReactTextInlineImageViewManager;Landroid/view/View;Ljava/lang/String;Ljava/lang/Object;)V -} - public abstract interface class com/facebook/react/views/textinput/ContentSizeWatcher { public abstract fun onLayout ()V } @@ -8060,20 +7892,6 @@ public class com/facebook/react/views/textinput/ReactTextInputManager : com/face public fun updateState (Lcom/facebook/react/views/textinput/ReactEditText;Lcom/facebook/react/uimanager/ReactStylesDiffMap;Lcom/facebook/react/uimanager/StateWrapper;)Ljava/lang/Object; } -public class com/facebook/react/views/textinput/ReactTextInputManager$$PropsSetter : com/facebook/react/uimanager/ViewManagerPropertyUpdater$ViewManagerSetter { - public fun ()V - public fun getProperties (Ljava/util/Map;)V - public synthetic fun setProperty (Lcom/facebook/react/uimanager/ViewManager;Landroid/view/View;Ljava/lang/String;Ljava/lang/Object;)V - public fun setProperty (Lcom/facebook/react/views/textinput/ReactTextInputManager;Lcom/facebook/react/views/textinput/ReactEditText;Ljava/lang/String;Ljava/lang/Object;)V -} - -public class com/facebook/react/views/textinput/ReactTextInputShadowNode$$PropsSetter : com/facebook/react/uimanager/ViewManagerPropertyUpdater$ShadowNodeSetter { - public fun ()V - public fun getProperties (Ljava/util/Map;)V - public synthetic fun setProperty (Lcom/facebook/react/uimanager/ReactShadowNode;Ljava/lang/String;Ljava/lang/Object;)V - public fun setProperty (Lcom/facebook/react/views/textinput/ReactTextInputShadowNode;Ljava/lang/String;Ljava/lang/Object;)V -} - public abstract interface class com/facebook/react/views/textinput/ScrollWatcher { public abstract fun onScrollChanged (IIII)V } @@ -8210,13 +8028,6 @@ public class com/facebook/react/views/view/ReactViewManager : com/facebook/react protected fun setTransformProperty (Lcom/facebook/react/views/view/ReactViewGroup;Lcom/facebook/react/bridge/ReadableArray;Lcom/facebook/react/bridge/ReadableArray;)V } -public class com/facebook/react/views/view/ReactViewManager$$PropsSetter : com/facebook/react/uimanager/ViewManagerPropertyUpdater$ViewManagerSetter { - public fun ()V - public fun getProperties (Ljava/util/Map;)V - public synthetic fun setProperty (Lcom/facebook/react/uimanager/ViewManager;Landroid/view/View;Ljava/lang/String;Ljava/lang/Object;)V - public fun setProperty (Lcom/facebook/react/views/view/ReactViewManager;Lcom/facebook/react/views/view/ReactViewGroup;Ljava/lang/String;Ljava/lang/Object;)V -} - public final class com/facebook/react/views/view/ReactViewManager$Companion { } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/processing/ReactPropertyProcessor.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/processing/ReactPropertyProcessor.java index 7777f2703ce4eb..ac3d81bbd5bba3 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/processing/ReactPropertyProcessor.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/processing/ReactPropertyProcessor.java @@ -19,6 +19,7 @@ import com.facebook.react.bridge.DynamicFromObject; import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.common.annotations.UnstableReactNativeAPI; import com.facebook.react.uimanager.annotations.ReactProp; import com.facebook.react.uimanager.annotations.ReactPropGroup; import com.facebook.react.uimanager.annotations.ReactPropertyHolder; @@ -268,6 +269,7 @@ private void generateCode(ClassInfo classInfo, List properties) TypeSpec holderClass = TypeSpec.classBuilder(holderClassName) .addSuperinterface(superType) + .addAnnotation(UnstableReactNativeAPI.class) .addModifiers(PUBLIC) .addMethod(generateSetPropertySpec(classInfo, properties)) .addMethod(getMethods) From 4a119c4c3ac9bf4b234e2942a27a6efd68a801cc Mon Sep 17 00:00:00 2001 From: David Vacca Date: Tue, 5 Nov 2024 21:44:38 -0800 Subject: [PATCH 074/220] Migrate ReactVirtualTextViewManager to kotlin and reduce visibility tointernal (#47402) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47402 Migrate ReactVirtualTextViewManager to kotlin and reduce visibility tointernal changelog: [Android][Breaking] Reduce visibility of ReactVirtualTextViewManager to internal Reviewed By: cortinico Differential Revision: D65462051 fbshipit-source-id: fa6daef4e557d527d594616ca032ebf0180cbba2 --- .../ReactAndroid/api/ReactAndroid.api | 10 ---- .../ReactAndroid/gradle.properties | 6 +-- .../text/ReactVirtualTextViewManager.java | 47 ------------------- .../views/text/ReactVirtualTextViewManager.kt | 38 +++++++++++++++ .../ReactUnimplementedView.kt | 4 +- 5 files changed, 41 insertions(+), 64 deletions(-) delete mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactVirtualTextViewManager.java create mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactVirtualTextViewManager.kt diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 539a04cebdfe29..9d39acc376cbbd 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -7527,16 +7527,6 @@ public class com/facebook/react/views/text/ReactVirtualTextShadowNode : com/face public fun isVirtual ()Z } -public class com/facebook/react/views/text/ReactVirtualTextViewManager : com/facebook/react/uimanager/BaseViewManager { - public fun ()V - public synthetic fun createShadowNodeInstance ()Lcom/facebook/react/uimanager/ReactShadowNode; - public fun createShadowNodeInstance ()Lcom/facebook/react/views/text/ReactVirtualTextShadowNode; - public fun createViewInstance (Lcom/facebook/react/uimanager/ThemedReactContext;)Landroid/view/View; - public fun getName ()Ljava/lang/String; - public fun getShadowNodeClass ()Ljava/lang/Class; - public fun updateExtraData (Landroid/view/View;Ljava/lang/Object;)V -} - public class com/facebook/react/views/text/TextAttributeProps { public static final field TA_KEY_ACCESSIBILITY_ROLE S public static final field TA_KEY_ALIGNMENT S diff --git a/packages/react-native/ReactAndroid/gradle.properties b/packages/react-native/ReactAndroid/gradle.properties index 6748b2bfd5cde4..c4947b2bd07a58 100644 --- a/packages/react-native/ReactAndroid/gradle.properties +++ b/packages/react-native/ReactAndroid/gradle.properties @@ -11,11 +11,7 @@ react.internal.disableJavaVersionAlignment=true # We ignore: # - BuildConfig classes because they are generated and not part of the public API -# - PropsSetter classes because they are generated by the Annotation processor which is not used in OSS -binaryCompatibilityValidator.ignoredClasses=com.facebook.react.BuildConfig,\ - com.facebook.react.views.safeareaview.ReactSafeAreaViewManager$$PropsSetter,\ - com.facebook.react.views.unimplementedview.ReactUnimplementedViewManager$$PropsSetter,\ - com.facebook.react.views.safeareaview.ReactSafeAreaViewShadowNode$$PropsSetter +binaryCompatibilityValidator.ignoredClasses=com.facebook.react.BuildConfig binaryCompatibilityValidator.ignoredPackages=com.facebook.debug,\ com.facebook.fbreact,\ diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactVirtualTextViewManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactVirtualTextViewManager.java deleted file mode 100644 index 421a9e8c7b4257..00000000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactVirtualTextViewManager.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and 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.views.text; - -import android.view.View; -import com.facebook.react.common.annotations.VisibleForTesting; -import com.facebook.react.module.annotations.ReactModule; -import com.facebook.react.uimanager.BaseViewManager; -import com.facebook.react.uimanager.ThemedReactContext; - -/** - * Manages raw text nodes. Since they are used only as a virtual nodes any type of native view - * operation will throw an {@link IllegalStateException} - */ -@ReactModule(name = ReactVirtualTextViewManager.REACT_CLASS) -public class ReactVirtualTextViewManager extends BaseViewManager { - - @VisibleForTesting public static final String REACT_CLASS = "RCTVirtualText"; - - @Override - public String getName() { - return REACT_CLASS; - } - - @Override - public View createViewInstance(ThemedReactContext context) { - throw new IllegalStateException("Attempt to create a native view for RCTVirtualText"); - } - - @Override - public void updateExtraData(View view, Object extraData) {} - - @Override - public Class getShadowNodeClass() { - return ReactVirtualTextShadowNode.class; - } - - @Override - public ReactVirtualTextShadowNode createShadowNodeInstance() { - return new ReactVirtualTextShadowNode(); - } -} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactVirtualTextViewManager.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactVirtualTextViewManager.kt new file mode 100644 index 00000000000000..1ee05de1789188 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactVirtualTextViewManager.kt @@ -0,0 +1,38 @@ +/* + * Copyright (c) Meta Platforms, Inc. and 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.views.text + +import android.view.View +import com.facebook.react.module.annotations.ReactModule +import com.facebook.react.uimanager.BaseViewManager +import com.facebook.react.uimanager.ThemedReactContext + +/** + * Manages raw text nodes. Since they are used only as a virtual nodes any type of native view + * operation will throw an [IllegalStateException] + */ +@ReactModule(name = ReactVirtualTextViewManager.REACT_CLASS) +internal class ReactVirtualTextViewManager : BaseViewManager() { + + public override fun getName(): String = REACT_CLASS + + protected override fun createViewInstance(context: ThemedReactContext): View { + throw IllegalStateException("Attempt to create a native view for RCTVirtualText") + } + + public override fun updateExtraData(view: View, extraData: Any): Unit {} + + public override fun getShadowNodeClass(): Class = + ReactVirtualTextShadowNode::class.java + + override fun createShadowNodeInstance(): ReactVirtualTextShadowNode = ReactVirtualTextShadowNode() + + internal companion object { + public const val REACT_CLASS: String = "RCTVirtualText" + } +} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/unimplementedview/ReactUnimplementedView.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/unimplementedview/ReactUnimplementedView.kt index 60e58d86e9ca07..1f9d2f58625cc2 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/unimplementedview/ReactUnimplementedView.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/unimplementedview/ReactUnimplementedView.kt @@ -13,7 +13,7 @@ import android.view.Gravity import android.widget.LinearLayout import androidx.appcompat.widget.AppCompatTextView -public class ReactUnimplementedView(context: Context) : LinearLayout(context) { +internal class ReactUnimplementedView(context: Context) : LinearLayout(context) { private val textView: AppCompatTextView @@ -31,7 +31,7 @@ public class ReactUnimplementedView(context: Context) : LinearLayout(context) { addView(textView) } - public fun setName(name: String) { + internal fun setName(name: String) { textView.setText("'$name' is not Fabric compatible yet.") } } From 496b0a8729b41266683fdd84de5618b23d06ce3d Mon Sep 17 00:00:00 2001 From: David Vacca Date: Tue, 5 Nov 2024 21:44:38 -0800 Subject: [PATCH 075/220] Migrate ReactVirtualTextShadowNode to kotlin and make it internal (#47434) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47434 Migrate ReactVirtualTextShadowNode to kotlin and make it internal changelog: [Android][Breaking] Reduce visibility of ReactVirtualTextShadowNode to internal Reviewed By: shwanton Differential Revision: D65493927 fbshipit-source-id: 2b5997d000b5dc489ba93edb226455ef0855b98b --- .../react-native/ReactAndroid/api/ReactAndroid.api | 5 ----- ...tShadowNode.java => ReactVirtualTextShadowNode.kt} | 11 +++-------- 2 files changed, 3 insertions(+), 13 deletions(-) rename packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/{ReactVirtualTextShadowNode.java => ReactVirtualTextShadowNode.kt} (50%) diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 9d39acc376cbbd..b6c706efaf9fea 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -7522,11 +7522,6 @@ public class com/facebook/react/views/text/ReactTypefaceUtils { public static fun parseFontWeight (Ljava/lang/String;)I } -public class com/facebook/react/views/text/ReactVirtualTextShadowNode : com/facebook/react/views/text/ReactBaseTextShadowNode { - public fun ()V - public fun isVirtual ()Z -} - public class com/facebook/react/views/text/TextAttributeProps { public static final field TA_KEY_ACCESSIBILITY_ROLE S public static final field TA_KEY_ALIGNMENT S diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactVirtualTextShadowNode.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactVirtualTextShadowNode.kt similarity index 50% rename from packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactVirtualTextShadowNode.java rename to packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactVirtualTextShadowNode.kt index 3c6949a3081ef7..bb98579ccf8561 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactVirtualTextShadowNode.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactVirtualTextShadowNode.kt @@ -5,15 +5,10 @@ * LICENSE file in the root directory of this source tree. */ -package com.facebook.react.views.text; +package com.facebook.react.views.text /** A virtual text node. */ -public class ReactVirtualTextShadowNode extends ReactBaseTextShadowNode { +internal class ReactVirtualTextShadowNode : ReactBaseTextShadowNode() { - @Override - public boolean isVirtual() { - return true; - } - - public ReactVirtualTextShadowNode() {} + override fun isVirtual(): Boolean = true } From b4a24a163c98051f4f4edd005460c3dc96e1834b Mon Sep 17 00:00:00 2001 From: David Vacca Date: Wed, 6 Nov 2024 00:01:07 -0800 Subject: [PATCH 076/220] Migrate DebuggingOverlayManager to use ViewManagerDelegate (#47393) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47393 Migrate DebuggingOverlayManager to use ViewManagerDelegate changelog: [internal] internal Reviewed By: cortinico Differential Revision: D65428645 fbshipit-source-id: 9cf6932a209935b6e85b7d8870a7aa610c45aded --- .../ReactAndroid/api/ReactAndroid.api | 9 +- .../DebuggingOverlayManager.kt | 195 ++++++++++-------- 2 files changed, 113 insertions(+), 91 deletions(-) diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index b6c706efaf9fea..f3a39e6d1490aa 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -6335,13 +6335,20 @@ public final class com/facebook/react/views/debuggingoverlay/DebuggingOverlay : public final fun setTraceUpdates (Ljava/util/List;)V } -public final class com/facebook/react/views/debuggingoverlay/DebuggingOverlayManager : com/facebook/react/uimanager/SimpleViewManager { +public final class com/facebook/react/views/debuggingoverlay/DebuggingOverlayManager : com/facebook/react/uimanager/SimpleViewManager, com/facebook/react/viewmanagers/DebuggingOverlayManagerInterface { public static final field Companion Lcom/facebook/react/views/debuggingoverlay/DebuggingOverlayManager$Companion; public static final field REACT_CLASS Ljava/lang/String; public fun ()V + public synthetic fun clearElementsHighlights (Landroid/view/View;)V + public fun clearElementsHighlights (Lcom/facebook/react/views/debuggingoverlay/DebuggingOverlay;)V public synthetic fun createViewInstance (Lcom/facebook/react/uimanager/ThemedReactContext;)Landroid/view/View; public fun createViewInstance (Lcom/facebook/react/uimanager/ThemedReactContext;)Lcom/facebook/react/views/debuggingoverlay/DebuggingOverlay; + public fun getDelegate ()Lcom/facebook/react/uimanager/ViewManagerDelegate; public fun getName ()Ljava/lang/String; + public synthetic fun highlightElements (Landroid/view/View;Lcom/facebook/react/bridge/ReadableArray;)V + public fun highlightElements (Lcom/facebook/react/views/debuggingoverlay/DebuggingOverlay;Lcom/facebook/react/bridge/ReadableArray;)V + public synthetic fun highlightTraceUpdates (Landroid/view/View;Lcom/facebook/react/bridge/ReadableArray;)V + public fun highlightTraceUpdates (Lcom/facebook/react/views/debuggingoverlay/DebuggingOverlay;Lcom/facebook/react/bridge/ReadableArray;)V public synthetic fun receiveCommand (Landroid/view/View;Ljava/lang/String;Lcom/facebook/react/bridge/ReadableArray;)V public fun receiveCommand (Lcom/facebook/react/views/debuggingoverlay/DebuggingOverlay;Ljava/lang/String;Lcom/facebook/react/bridge/ReadableArray;)V } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/debuggingoverlay/DebuggingOverlayManager.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/debuggingoverlay/DebuggingOverlayManager.kt index 80abf619cc8280..431e86d37ccb29 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/debuggingoverlay/DebuggingOverlayManager.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/debuggingoverlay/DebuggingOverlayManager.kt @@ -17,114 +17,129 @@ import com.facebook.react.module.annotations.ReactModule import com.facebook.react.uimanager.PixelUtil.dpToPx import com.facebook.react.uimanager.SimpleViewManager import com.facebook.react.uimanager.ThemedReactContext +import com.facebook.react.uimanager.ViewManagerDelegate +import com.facebook.react.viewmanagers.DebuggingOverlayManagerDelegate +import com.facebook.react.viewmanagers.DebuggingOverlayManagerInterface @ReactModule(name = DebuggingOverlayManager.REACT_CLASS) -public class DebuggingOverlayManager : SimpleViewManager() { +public class DebuggingOverlayManager : + SimpleViewManager(), DebuggingOverlayManagerInterface { + + private val delegate: ViewManagerDelegate = + DebuggingOverlayManagerDelegate(this) + + public override fun getDelegate(): ViewManagerDelegate = delegate + override fun receiveCommand(view: DebuggingOverlay, commandId: String, args: ReadableArray?) { when (commandId) { - "highlightTraceUpdates" -> { - if (args == null) { - return - } + "highlightTraceUpdates" -> highlightTraceUpdates(view, args) + "highlightElements" -> highlightElements(view, args) + "clearElementsHighlights" -> clearElementsHighlights(view) + else -> { + ReactSoftExceptionLogger.logSoftException( + REACT_CLASS, + ReactNoCrashSoftException("Received unexpected command in DebuggingOverlayManager")) + } + } + } + + public override fun highlightTraceUpdates(view: DebuggingOverlay, args: ReadableArray?): Unit { + if (args == null) { + return + } + + val providedTraceUpdates = args.getArray(0) + val formattedTraceUpdates = mutableListOf() + + var successfullyParsedPayload = true + for (i in 0 until providedTraceUpdates.size()) { + val traceUpdate = providedTraceUpdates.getMap(i) + val serializedRectangle = traceUpdate.getMap("rectangle") + if (serializedRectangle == null) { + ReactSoftExceptionLogger.logSoftException( + REACT_CLASS, + ReactNoCrashSoftException( + "Unexpected payload for highlighting trace updates: rectangle field is null")) + successfullyParsedPayload = false + break + } - val providedTraceUpdates = args.getArray(0) - val formattedTraceUpdates = mutableListOf() + val id = traceUpdate.getInt("id") + val color = traceUpdate.getInt("color") - var successfullyParsedPayload = true - for (i in 0 until providedTraceUpdates.size()) { - val traceUpdate = providedTraceUpdates.getMap(i) - val serializedRectangle = traceUpdate.getMap("rectangle") - if (serializedRectangle == null) { + try { + val left = serializedRectangle.getDouble("x").toFloat() + val top = serializedRectangle.getDouble("y").toFloat() + val right = (left + serializedRectangle.getDouble("width")).toFloat() + val bottom = (top + serializedRectangle.getDouble("height")).toFloat() + + val rectangle = RectF(left.dpToPx(), top.dpToPx(), right.dpToPx(), bottom.dpToPx()) + + formattedTraceUpdates.add(TraceUpdate(id, rectangle, color)) + } catch (ex: Exception) { + when (ex) { + is NoSuchKeyException, + is UnexpectedNativeTypeException -> { ReactSoftExceptionLogger.logSoftException( REACT_CLASS, ReactNoCrashSoftException( - "Unexpected payload for highlighting trace updates: rectangle field is" + - " null")) + "Unexpected payload for highlighting trace updates: rectangle field should" + + " have x, y, width, height fields")) successfullyParsedPayload = false - break - } - - val id = traceUpdate.getInt("id") - val color = traceUpdate.getInt("color") - - try { - val left = serializedRectangle.getDouble("x").toFloat() - val top = serializedRectangle.getDouble("y").toFloat() - val right = (left + serializedRectangle.getDouble("width")).toFloat() - val bottom = (top + serializedRectangle.getDouble("height")).toFloat() - - val rectangle = RectF(left.dpToPx(), top.dpToPx(), right.dpToPx(), bottom.dpToPx()) - - formattedTraceUpdates.add(TraceUpdate(id, rectangle, color)) - } catch (ex: Exception) { - when (ex) { - is NoSuchKeyException, - is UnexpectedNativeTypeException -> { - ReactSoftExceptionLogger.logSoftException( - REACT_CLASS, - ReactNoCrashSoftException( - "Unexpected payload for highlighting trace updates: rectangle field should" + - " have x, y, width, height fields")) - successfullyParsedPayload = false - } - else -> throw ex - } } - } - - if (successfullyParsedPayload) { - view.setTraceUpdates(formattedTraceUpdates) + else -> throw ex } } - "highlightElements" -> { - if (args == null) { - return - } + } - val providedElements = args.getArray(0) - val elementsRectangles = mutableListOf() - - var successfullyParsedPayload = true - for (i in 0 until providedElements.size()) { - val element = providedElements.getMap(i) - - try { - val left = element.getDouble("x").toFloat() - val top = element.getDouble("y").toFloat() - val right = (left + element.getDouble("width")).toFloat() - val bottom = (top + element.getDouble("height")).toFloat() - val rect = RectF(left.dpToPx(), top.dpToPx(), right.dpToPx(), bottom.dpToPx()) - - elementsRectangles.add(rect) - } catch (ex: Exception) { - when (ex) { - is NoSuchKeyException, - is UnexpectedNativeTypeException -> { - ReactSoftExceptionLogger.logSoftException( - REACT_CLASS, - ReactNoCrashSoftException( - "Unexpected payload for highlighting elements: every element should have x," + - " y, width, height fields")) - successfullyParsedPayload = false - } - else -> throw ex - } - } - } + if (successfullyParsedPayload) { + view.setTraceUpdates(formattedTraceUpdates) + } + } - if (successfullyParsedPayload) { - view.setHighlightedElementsRectangles(elementsRectangles) + public override fun highlightElements(view: DebuggingOverlay, args: ReadableArray?): Unit { + if (args == null) { + return + } + + val providedElements = args.getArray(0) + val elementsRectangles = mutableListOf() + + var successfullyParsedPayload = true + for (i in 0 until providedElements.size()) { + val element = providedElements.getMap(i) + + try { + val left = element.getDouble("x").toFloat() + val top = element.getDouble("y").toFloat() + val right = (left + element.getDouble("width")).toFloat() + val bottom = (top + element.getDouble("height")).toFloat() + val rect = RectF(left.dpToPx(), top.dpToPx(), right.dpToPx(), bottom.dpToPx()) + + elementsRectangles.add(rect) + } catch (ex: Exception) { + when (ex) { + is NoSuchKeyException, + is UnexpectedNativeTypeException -> { + ReactSoftExceptionLogger.logSoftException( + REACT_CLASS, + ReactNoCrashSoftException( + "Unexpected payload for highlighting elements: every element should have x," + + " y, width, height fields")) + successfullyParsedPayload = false + } + else -> throw ex } } - "clearElementsHighlights" -> { - view.clearElementsHighlights() - } - else -> { - ReactSoftExceptionLogger.logSoftException( - REACT_CLASS, - ReactNoCrashSoftException("Received unexpected command in DebuggingOverlayManager")) - } } + + if (successfullyParsedPayload) { + view.setHighlightedElementsRectangles(elementsRectangles) + } + } + + public override fun clearElementsHighlights(view: DebuggingOverlay): Unit { + view.clearElementsHighlights() } public override fun createViewInstance(context: ThemedReactContext): DebuggingOverlay { From bed778fa5a304d399a6346a09d5498fbdeb116e8 Mon Sep 17 00:00:00 2001 From: David Vacca Date: Wed, 6 Nov 2024 00:01:07 -0800 Subject: [PATCH 077/220] Migrate ReactUnimplementedViewManager to use ViewManagerInterface (#47392) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47392 Migrate ReactUnimplementedViewManager to use ViewManagerInterface changelog: [internal] internal Reviewed By: cortinico Differential Revision: D65428644 fbshipit-source-id: 011d06b6cb06c4fcc5e072b625b943ec6b7f1a62 --- .../ReactUnimplementedViewManager.kt | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/unimplementedview/ReactUnimplementedViewManager.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/unimplementedview/ReactUnimplementedViewManager.kt index 0b886c04f78285..4ed89b6bcbd627 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/unimplementedview/ReactUnimplementedViewManager.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/unimplementedview/ReactUnimplementedViewManager.kt @@ -10,11 +10,21 @@ package com.facebook.react.views.unimplementedview import com.facebook.react.module.annotations.ReactModule import com.facebook.react.uimanager.ThemedReactContext import com.facebook.react.uimanager.ViewGroupManager +import com.facebook.react.uimanager.ViewManagerDelegate import com.facebook.react.uimanager.annotations.ReactProp +import com.facebook.react.viewmanagers.UnimplementedNativeViewManagerDelegate +import com.facebook.react.viewmanagers.UnimplementedNativeViewManagerInterface /** ViewManager for [ReactUnimplementedView] to represent a component that is not yet supported. */ @ReactModule(name = ReactUnimplementedViewManager.REACT_CLASS) -internal class ReactUnimplementedViewManager : ViewGroupManager() { +internal class ReactUnimplementedViewManager : + ViewGroupManager(), + UnimplementedNativeViewManagerInterface { + + private val delegate: ViewManagerDelegate = + UnimplementedNativeViewManagerDelegate(this) + + public override fun getDelegate(): ViewManagerDelegate = delegate protected override fun createViewInstance( reactContext: ThemedReactContext @@ -23,8 +33,8 @@ internal class ReactUnimplementedViewManager : ViewGroupManager") } internal companion object { From fddf7aaad188d5adf35a12a3869fab034fafca63 Mon Sep 17 00:00:00 2001 From: David Vacca Date: Wed, 6 Nov 2024 00:01:07 -0800 Subject: [PATCH 078/220] Migrate ReactHorizontalScrollContainerViewManager to use ViewManagerInterface (#47395) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47395 Migrate ReactHorizontalScrollContainerViewManager to use ViewManagerInterface changelog: [internal] internal Reviewed By: cortinico Differential Revision: D65428646 fbshipit-source-id: 7e36f3642ac31aa747c2b7f21c251173516fffad --- .../react-native/ReactAndroid/api/ReactAndroid.api | 4 +++- .../ReactHorizontalScrollContainerViewManager.kt | 11 ++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index f3a39e6d1490aa..34f2e9072694bd 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -6801,14 +6801,16 @@ public final class com/facebook/react/views/scroll/OnScrollDispatchHelper { public final fun onScrollChanged (II)Z } -public final class com/facebook/react/views/scroll/ReactHorizontalScrollContainerViewManager : com/facebook/react/views/view/ReactViewManager { +public final class com/facebook/react/views/scroll/ReactHorizontalScrollContainerViewManager : com/facebook/react/views/view/ReactViewManager, com/facebook/react/viewmanagers/AndroidHorizontalScrollContentViewManagerInterface { public static final field Companion Lcom/facebook/react/views/scroll/ReactHorizontalScrollContainerViewManager$Companion; public static final field REACT_CLASS Ljava/lang/String; public fun ()V public synthetic fun createViewInstance (ILcom/facebook/react/uimanager/ThemedReactContext;Lcom/facebook/react/uimanager/ReactStylesDiffMap;Lcom/facebook/react/uimanager/StateWrapper;)Landroid/view/View; public synthetic fun createViewInstance (Lcom/facebook/react/uimanager/ThemedReactContext;)Landroid/view/View; public fun createViewInstance (Lcom/facebook/react/uimanager/ThemedReactContext;)Lcom/facebook/react/views/view/ReactViewGroup; + public fun getDelegate ()Lcom/facebook/react/uimanager/ViewManagerDelegate; public fun getName ()Ljava/lang/String; + public synthetic fun setRemoveClippedSubviews (Landroid/view/View;Z)V } public final class com/facebook/react/views/scroll/ReactHorizontalScrollContainerViewManager$Companion { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollContainerViewManager.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollContainerViewManager.kt index c9d6c01e065df5..a82070f629509a 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollContainerViewManager.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollContainerViewManager.kt @@ -11,16 +11,25 @@ import com.facebook.react.module.annotations.ReactModule import com.facebook.react.uimanager.ReactStylesDiffMap import com.facebook.react.uimanager.StateWrapper import com.facebook.react.uimanager.ThemedReactContext +import com.facebook.react.uimanager.ViewManagerDelegate import com.facebook.react.uimanager.common.UIManagerType import com.facebook.react.uimanager.common.ViewUtil +import com.facebook.react.viewmanagers.AndroidHorizontalScrollContentViewManagerDelegate +import com.facebook.react.viewmanagers.AndroidHorizontalScrollContentViewManagerInterface import com.facebook.react.views.view.ReactViewGroup import com.facebook.react.views.view.ReactViewManager /** View manager for {@link ReactHorizontalScrollContainerView} components. */ @ReactModule(name = ReactHorizontalScrollContainerViewManager.REACT_CLASS) -public class ReactHorizontalScrollContainerViewManager : ReactViewManager() { +public class ReactHorizontalScrollContainerViewManager : + ReactViewManager(), AndroidHorizontalScrollContentViewManagerInterface { override public fun getName(): String = REACT_CLASS + private val delegate: ViewManagerDelegate = + AndroidHorizontalScrollContentViewManagerDelegate(this) + + public override fun getDelegate(): ViewManagerDelegate = delegate + protected override fun createViewInstance( reactTag: Int, context: ThemedReactContext, From f94ca279867bc774e98bf28e2fa5a6e0f50dba95 Mon Sep 17 00:00:00 2001 From: Riccardo Cipolleschi Date: Wed, 6 Nov 2024 02:32:16 -0800 Subject: [PATCH 079/220] Add job to test libraries on nightlies (#47409) Summary: We want to test libraries against React Native nightlies to check when we introduce breakig change ## Changelog: [Internal] - Add CI tests for libraries Pull Request resolved: https://github.com/facebook/react-native/pull/47409 Test Plan: GHA - https://github.com/facebook/react-native/actions/runs/11700016815/job/32583153239?pr=47409 Reviewed By: cortinico Differential Revision: D65530787 Pulled By: cipolleschi fbshipit-source-id: ef4d13c30995f119715ef4f12ea51eaa65152518 --- .../test-library-on-nightly/action.yml | 44 +++++++++++ .github/workflows/check-nightly.yml | 2 + .../workflows/test-libraries-on-nightlies.yml | 75 +++++++++++++++++++ 3 files changed, 121 insertions(+) create mode 100644 .github/actions/test-library-on-nightly/action.yml create mode 100644 .github/workflows/test-libraries-on-nightlies.yml diff --git a/.github/actions/test-library-on-nightly/action.yml b/.github/actions/test-library-on-nightly/action.yml new file mode 100644 index 00000000000000..1d59aec18fa44f --- /dev/null +++ b/.github/actions/test-library-on-nightly/action.yml @@ -0,0 +1,44 @@ +name: test-library-on-nightly +description: Tests a library on a nightly +inputs: + library-npm-package: + description: The library npm package to add + required: true + platform: + description: whether we want to build for iOS or Android + required: true +runs: + using: composite + steps: + - name: Create new app + shell: bash + run: | + cd /tmp + npx @react-native-community/cli init RNApp --skip-install --version nightly + - name: Add library + shell: bash + run: | + cd /tmp/RNApp + yarn add ${{ inputs.library-npm-package }} + + - name: Build iOS + shell: bash + if: ${{ inputs.platform == 'ios' }} + run: | + cd /tmp/RNApp/ios + bundle install + bundle exec pod install + cd .. + yarn ios + - name: Setup Java for Android + if: ${{ inputs.platform == 'android' }} + uses: actions/setup-java@v2 + with: + java-version: '17' + distribution: 'zulu' + - name: Build Android + shell: bash + if: ${{ inputs.platform == 'android' }} + run: | + cd /tmp/RNApp/android + ./gradlew assembleDebug diff --git a/.github/workflows/check-nightly.yml b/.github/workflows/check-nightly.yml index 2fb26d10811096..2534de488236aa 100644 --- a/.github/workflows/check-nightly.yml +++ b/.github/workflows/check-nightly.yml @@ -24,3 +24,5 @@ jobs: else echo 'Nightly Worked, All Good!' fi + - name: Test Libraries + uses: ./.github/workflows/test-libraries-on-nightlies.yml diff --git a/.github/workflows/test-libraries-on-nightlies.yml b/.github/workflows/test-libraries-on-nightlies.yml new file mode 100644 index 00000000000000..9587c9285642fd --- /dev/null +++ b/.github/workflows/test-libraries-on-nightlies.yml @@ -0,0 +1,75 @@ +name: Test Libraries on Nightlies + +on: + workflow_call: + +jobs: + test-library-on-nightly-android: + name: "[Android] ${{ matrix.library }}" + runs-on: ubuntu-latest + continue-on-error: true + strategy: + matrix: + library: [ + "react-native-async-storage", + "react-native-blob-util", + "@react-native-clipboard/clipboard", + "@react-native-community/datetimepicker", + "react-native-gesture-handler", + "react-native-image-picker", + "react-native-linear-gradient", + "@react-native-masked-view/masked-view", + "react-native-maps", + "@react-native-community/netinfo", + "react-native-reanimated", + "react-native-svg", + "react-native-video", + "react-native-webview", + "react-native-mmkv", + "react-native-screens", + "react-native-pager-view", + "@react-native-community/slider" + ] + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Test ${{ inputs.library-name }} + uses: ./.github/actions/test-library-on-nightly + with: + library-npm-package: ${{ matrix.library }} + platform: android + + test-library-on-nightly-ios: + name: "[iOS] ${{ matrix.library }}" + runs-on: macos-13-large + continue-on-error: true + strategy: + matrix: + library: [ + "react-native-async-storage", + "react-native-blob-util", + "@react-native-clipboard/clipboard", + "@react-native-community/datetimepicker", + "react-native-gesture-handler", + "react-native-image-picker", + "react-native-linear-gradient", + "@react-native-masked-view/masked-view", + "react-native-maps", + "@react-native-community/netinfo", + "react-native-reanimated", + "react-native-svg", + "react-native-video", + "react-native-webview", + "react-native-mmkv", + "react-native-screens", + "react-native-pager-view", + "@react-native-community/slider" + ] + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Test ${{ inputs.library-name }} + uses: ./.github/actions/test-library-on-nightly + with: + library-npm-package: ${{ matrix.library }} + platform: ios From 92f51c009f0d063f1f5c2ade5d66516b4627a960 Mon Sep 17 00:00:00 2001 From: "kunal.chavhan" Date: Wed, 6 Nov 2024 04:07:01 -0800 Subject: [PATCH 080/220] add e2e test for empty case in flatlist (#47444) Summary: Part of https://github.com/facebook/react-native/issues/46757 Solves: ME2E0010 ## Changelog: [INTERNAL][ADDED] - add e2e test for empty case in flatlist Pull Request resolved: https://github.com/facebook/react-native/pull/47444 Test Plan: ``` yarn e2e-test-ios yarn e2e-test-android ``` Reviewed By: cortinico Differential Revision: D65531064 Pulled By: cipolleschi fbshipit-source-id: 700c2fd6d43c24671021b6c3c5a4218e5699c7d9 --- packages/rn-tester/.maestro/flatlist.yml | 6 ++++++ packages/rn-tester/js/components/ListExampleShared.js | 2 ++ packages/rn-tester/js/examples/FlatList/FlatList-basic.js | 1 + 3 files changed, 9 insertions(+) diff --git a/packages/rn-tester/.maestro/flatlist.yml b/packages/rn-tester/.maestro/flatlist.yml index a358e615e026f6..8d93ca94ca274d 100644 --- a/packages/rn-tester/.maestro/flatlist.yml +++ b/packages/rn-tester/.maestro/flatlist.yml @@ -25,3 +25,9 @@ appId: ${APP_ID} # iOS: com.meta.RNTester.localDevelopment | Android: com.facebo timeout: 1000 - assertVisible: id: "item_600" +- assertVisible: + text: "Empty:" +- tapOn: + id: "switch_empty_option" +- assertVisible: + text: "The list is empty :o" diff --git a/packages/rn-tester/js/components/ListExampleShared.js b/packages/rn-tester/js/components/ListExampleShared.js index 804b04ba3f67d6..6626be70af5e64 100644 --- a/packages/rn-tester/js/components/ListExampleShared.js +++ b/packages/rn-tester/js/components/ListExampleShared.js @@ -257,6 +257,7 @@ function renderSmallSwitchOption( label: string, value: boolean, setValue: boolean => void, + testID?: string, ): null | React.Node { if (Platform.isTV) { return null; @@ -265,6 +266,7 @@ function renderSmallSwitchOption( {label}: { 'Empty', this.state.empty, this._setBooleanValue('empty'), + 'switch_empty_option', )} {renderSmallSwitchOption( 'Debug', From d352a9979d205e92fc0b832ed30f60427ae428f8 Mon Sep 17 00:00:00 2001 From: Riccardo Cipolleschi Date: Wed, 6 Nov 2024 04:07:13 -0800 Subject: [PATCH 081/220] Add checkout step to check nightly (#47448) Summary: In order to use a reusable workflow in GHA, we need first to checkout the repository so the action has access to the other workflows. ## Changelog: [Internal] - Add checkout step to Check Nightlies Pull Request resolved: https://github.com/facebook/react-native/pull/47448 Test Plan: GHA - https://github.com/facebook/react-native/actions/runs/11702038686?pr=47448 Reviewed By: cortinico Differential Revision: D65532274 Pulled By: cipolleschi fbshipit-source-id: 58117ac81973e3c07829d73d5bde4e6fd4d212f9 --- .github/workflows/check-nightly.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/check-nightly.yml b/.github/workflows/check-nightly.yml index 2534de488236aa..95974e965707ae 100644 --- a/.github/workflows/check-nightly.yml +++ b/.github/workflows/check-nightly.yml @@ -13,6 +13,8 @@ jobs: runs-on: ubuntu-latest if: github.repository == 'facebook/react-native' steps: + - name: Checkout + uses: actions/checkout@v4 - name: Check nightly run: | TODAY=$(date "+%Y%m%d") @@ -24,5 +26,7 @@ jobs: else echo 'Nightly Worked, All Good!' fi - - name: Test Libraries - uses: ./.github/workflows/test-libraries-on-nightlies.yml + + test-libraries: + uses: ./.github/workflows/test-libraries-on-nightlies.yml + needs: check-nightly From 10f6d5adb538a9b20043312fc09b192759100d63 Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Wed, 6 Nov 2024 04:16:43 -0800 Subject: [PATCH 082/220] Stable API - Make `ClipboardModule` internal (#47413) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47413 This class should not be accessed directly, therefore I'm making it internal. Technically breaking but I verified that there are no meaningful usages in OSS: https://github.com/search?type=code&q=NOT+is%3Afork+NOT+org%3Afacebook+com.facebook.react.modules.clipboard.ClipboardModule Changelog: [Android] [Breaking] - Stable API - Make `ClipboardModule` internal Reviewed By: mdvacca Differential Revision: D65479065 fbshipit-source-id: 1c534cafffdb27b808553eec7346e21fe4f38c24 --- .../react-native/ReactAndroid/api/ReactAndroid.api | 11 ----------- .../react/modules/clipboard/ClipboardModule.kt | 10 +++++----- 2 files changed, 5 insertions(+), 16 deletions(-) diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 34f2e9072694bd..49e85c24c3a5dd 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -3066,17 +3066,6 @@ public final class com/facebook/react/modules/camera/ImageStoreManager : com/fac public final class com/facebook/react/modules/camera/ImageStoreManager$Companion { } -public final class com/facebook/react/modules/clipboard/ClipboardModule : com/facebook/fbreact/specs/NativeClipboardSpec { - public static final field Companion Lcom/facebook/react/modules/clipboard/ClipboardModule$Companion; - public static final field NAME Ljava/lang/String; - public fun (Lcom/facebook/react/bridge/ReactApplicationContext;)V - public fun getString (Lcom/facebook/react/bridge/Promise;)V - public fun setString (Ljava/lang/String;)V -} - -public final class com/facebook/react/modules/clipboard/ClipboardModule$Companion { -} - public final class com/facebook/react/modules/common/ModuleDataCleaner { public static final field INSTANCE Lcom/facebook/react/modules/common/ModuleDataCleaner; public static final fun cleanDataFromModules (Lcom/facebook/react/bridge/ReactContext;)V diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/clipboard/ClipboardModule.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/clipboard/ClipboardModule.kt index 9fd4e38be331d9..5fca725d830e2a 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/clipboard/ClipboardModule.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/clipboard/ClipboardModule.kt @@ -16,14 +16,14 @@ import com.facebook.react.module.annotations.ReactModule /** A module that allows JS to get/set clipboard contents. */ @ReactModule(name = NativeClipboardSpec.NAME) -public class ClipboardModule(context: ReactApplicationContext) : NativeClipboardSpec(context) { +internal class ClipboardModule(context: ReactApplicationContext) : NativeClipboardSpec(context) { private val clipboardService: ClipboardManager get() = getReactApplicationContext().getSystemService(ReactApplicationContext.CLIPBOARD_SERVICE) as ClipboardManager - public override fun getString(promise: Promise) { + override fun getString(promise: Promise) { try { val clipboard = clipboardService val clipData = clipboard.primaryClip @@ -38,12 +38,12 @@ public class ClipboardModule(context: ReactApplicationContext) : NativeClipboard } } - public override fun setString(text: String?) { + override fun setString(text: String?) { val clipdata: ClipData = ClipData.newPlainText(null, text) clipboardService.setPrimaryClip(clipdata) } - public companion object { - public const val NAME: String = NativeClipboardSpec.NAME + companion object { + const val NAME: String = NativeClipboardSpec.NAME } } From 5b41c7a84ba23029e173cff6c089964c7ccd50dc Mon Sep 17 00:00:00 2001 From: Pieter De Baets Date: Wed, 6 Nov 2024 06:38:29 -0800 Subject: [PATCH 083/220] Convert com.facebook.react.views.text.TextTransform to Kotlin (#47412) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47412 Changelog: [Internal] Reviewed By: cortinico, fabriziocucci Differential Revision: D65478027 fbshipit-source-id: e65019b7a90b696c3764e1deaf94f5f8bb0a7a95 --- .../ReactAndroid/api/ReactAndroid.api | 8 ++- .../react/views/text/TextTransform.java | 58 ------------------- .../react/views/text/TextTransform.kt | 55 ++++++++++++++++++ 3 files changed, 62 insertions(+), 59 deletions(-) delete mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextTransform.java create mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextTransform.kt diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 49e85c24c3a5dd..60c865e204d1b3 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -7667,15 +7667,21 @@ public class com/facebook/react/views/text/TextLayoutManager { public final class com/facebook/react/views/text/TextTransform : java/lang/Enum { public static final field CAPITALIZE Lcom/facebook/react/views/text/TextTransform; + public static final field Companion Lcom/facebook/react/views/text/TextTransform$Companion; public static final field LOWERCASE Lcom/facebook/react/views/text/TextTransform; public static final field NONE Lcom/facebook/react/views/text/TextTransform; public static final field UNSET Lcom/facebook/react/views/text/TextTransform; public static final field UPPERCASE Lcom/facebook/react/views/text/TextTransform; - public static fun apply (Ljava/lang/String;Lcom/facebook/react/views/text/TextTransform;)Ljava/lang/String; + public static final fun apply (Ljava/lang/String;Lcom/facebook/react/views/text/TextTransform;)Ljava/lang/String; + public static fun getEntries ()Lkotlin/enums/EnumEntries; public static fun valueOf (Ljava/lang/String;)Lcom/facebook/react/views/text/TextTransform; public static fun values ()[Lcom/facebook/react/views/text/TextTransform; } +public final class com/facebook/react/views/text/TextTransform$Companion { + public final fun apply (Ljava/lang/String;Lcom/facebook/react/views/text/TextTransform;)Ljava/lang/String; +} + public class com/facebook/react/views/text/frescosupport/FrescoBasedReactTextInlineImageViewManager : com/facebook/react/uimanager/BaseViewManager { public static final field REACT_CLASS Ljava/lang/String; public fun ()V diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextTransform.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextTransform.java deleted file mode 100644 index 6670ec5247e5f4..00000000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextTransform.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and 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.views.text; - -import androidx.annotation.Nullable; -import java.text.BreakIterator; - -/** Types of text transforms for CustomTextTransformSpan */ -public enum TextTransform { - NONE, - UPPERCASE, - LOWERCASE, - CAPITALIZE, - UNSET; - - public static String apply(@Nullable String text, TextTransform textTransform) { - if (text == null) { - return null; - } - - String transformed; - switch (textTransform) { - case UPPERCASE: - transformed = text.toUpperCase(); - break; - case LOWERCASE: - transformed = text.toLowerCase(); - break; - case CAPITALIZE: - transformed = capitalize(text); - break; - default: - transformed = text; - } - - return transformed; - } - - private static String capitalize(String text) { - BreakIterator wordIterator = BreakIterator.getWordInstance(); - wordIterator.setText(text); - - StringBuilder res = new StringBuilder(text.length()); - int start = wordIterator.first(); - for (int end = wordIterator.next(); end != BreakIterator.DONE; end = wordIterator.next()) { - res.append(Character.toUpperCase(text.charAt(start))); - res.append(text.substring(start + 1, end)); - start = end; - } - - return res.toString(); - } -}; diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextTransform.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextTransform.kt new file mode 100644 index 00000000000000..7da115539bbf7b --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextTransform.kt @@ -0,0 +1,55 @@ +/* + * Copyright (c) Meta Platforms, Inc. and 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.views.text + +import java.text.BreakIterator +import java.util.Locale + +/** Types of text transforms for CustomTextTransformSpan */ +public enum class TextTransform { + + NONE, + UPPERCASE, + LOWERCASE, + CAPITALIZE, + UNSET; + + public companion object { + @JvmStatic + public fun apply(text: String?, textTransform: TextTransform?): String? { + if (text == null) { + return null + } + val transformed: String = + when (textTransform) { + UPPERCASE -> text.uppercase(Locale.getDefault()) + LOWERCASE -> text.lowercase(Locale.getDefault()) + CAPITALIZE -> capitalize(text) + else -> text + } + return transformed + } + + private fun capitalize(text: String): String { + val wordIterator = BreakIterator.getWordInstance() + wordIterator.setText(text) + + val res = StringBuilder(text.length) + var start = wordIterator.first() + var end = wordIterator.next() + while (end != BreakIterator.DONE) { + res.append(text[start].uppercaseChar()) + res.append(text.substring(start + 1, end)) + start = end + end = wordIterator.next() + } + + return res.toString() + } + } +} From b04f5fbfba61c5eb1808c4bcc795b03f6a950a05 Mon Sep 17 00:00:00 2001 From: Pieter De Baets Date: Wed, 6 Nov 2024 06:38:47 -0800 Subject: [PATCH 084/220] Add Binding.h header back for backwards compat (#47453) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47453 `react-native-screens` [depends on this header](https://github.com/software-mansion/react-native-screens/blob/main/android/src/main/cpp/NativeProxy.cpp#L2) and this is an unnecessary API breakage. Changelog: [Android][Fixed] Added back `` header. Reviewed By: fabriziocucci Differential Revision: D65534176 fbshipit-source-id: ce252f29be1c5322f44e20b6e36ab51db9c7a8ef --- .../ReactAndroid/src/main/jni/react/fabric/Binding.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 packages/react-native/ReactAndroid/src/main/jni/react/fabric/Binding.h diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/Binding.h b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/Binding.h new file mode 100644 index 00000000000000..55a8314e98fe02 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/Binding.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) Meta Platforms, Inc. and 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 + +// This header exists for backwards compatibility with libraries importing +// +#include "FabricUIManagerBinding.h" From e0be2efe4e80edf99f96a2ae6a25856f6df5e0ca Mon Sep 17 00:00:00 2001 From: Blake Friedman Date: Wed, 6 Nov 2024 07:26:30 -0800 Subject: [PATCH 085/220] fix/cli start (#47450) Summary: When decoupling the community-cli-plugin from the react-native-community/cli-server-api (https://github.com/facebook/react-native/issues/45311), a middleware stub was created to allow a runtime stub to be used in this case. This middleware should be used so as not to break when the optional cli-server-api dependency isn't present. Changelog: [General][Fixed] - Fix npm react-native start when cli-server-api isn't installed Pull Request resolved: https://github.com/facebook/react-native/pull/47450 Test Plan: Forced a runtime exception simulating the package not being dependent and was able to build rn-tester. ![CleanShot 2024-11-06 at 10 49 58@2x](https://github.com/user-attachments/assets/c040ec5b-7000-43bd-ba54-52a672ff3675) Reviewed By: cipolleschi Differential Revision: D65532486 Pulled By: blakef fbshipit-source-id: 2b380607de63ac2da906ef0cb1e48b9ef263cb68 --- .../community-cli-plugin/src/commands/start/runServer.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/community-cli-plugin/src/commands/start/runServer.js b/packages/community-cli-plugin/src/commands/start/runServer.js index 512255e8cba5e0..ce4f7bcd9dead4 100644 --- a/packages/community-cli-plugin/src/commands/start/runServer.js +++ b/packages/community-cli-plugin/src/commands/start/runServer.js @@ -19,10 +19,7 @@ import isDevServerRunning from '../../utils/isDevServerRunning'; import loadMetroConfig from '../../utils/loadMetroConfig'; import * as version from '../../utils/version'; import attachKeyHandlers from './attachKeyHandlers'; -import { - createDevServerMiddleware, - indexPageMiddleware, -} from '@react-native-community/cli-server-api'; +import {createDevServerMiddleware, indexPageMiddleware} from './middleware'; import {createDevMiddleware} from '@react-native/dev-middleware'; import chalk from 'chalk'; import Metro from 'metro'; From 0244710c4b1e5016069ec9f7b8e7116ff51f59f1 Mon Sep 17 00:00:00 2001 From: qnnp <58357109+qnnp-me@users.noreply.github.com> Date: Wed, 6 Nov 2024 08:45:18 -0800 Subject: [PATCH 086/220] refactor(PermissionsAndroid): Use the TypeScript key in syntax to restrict permissions and types of results (#47299) Summary: Changelog: [General][Added] Use the TypeScript key in syntax to restrict permissions and types of results - Use key in 'GRANTED' | 'DENIED' | 'NEVER_ASK_AGAIN for RESULTS constants to ensure that only these values are allowed - Use a detailed list of permission names for PERMISSIONS constants to restrict the type of key Pull Request resolved: https://github.com/facebook/react-native/pull/47299 Reviewed By: yungsters Differential Revision: D65480410 Pulled By: tdn120 fbshipit-source-id: ec23750d72ede0ba6ed96e80c35242da08b2508e --- .../PermissionsAndroid.d.ts | 51 ++++++++++++++++++- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/packages/react-native/Libraries/PermissionsAndroid/PermissionsAndroid.d.ts b/packages/react-native/Libraries/PermissionsAndroid/PermissionsAndroid.d.ts index 86708891d782ec..9e70bdd5040a15 100644 --- a/packages/react-native/Libraries/PermissionsAndroid/PermissionsAndroid.d.ts +++ b/packages/react-native/Libraries/PermissionsAndroid/PermissionsAndroid.d.ts @@ -66,11 +66,58 @@ export interface PermissionsAndroidStatic { /** * A list of permission results that are returned */ - RESULTS: {[key: string]: PermissionStatus}; + RESULTS: { + [key in 'GRANTED' | 'DENIED' | 'NEVER_ASK_AGAIN']: PermissionStatus; + }; /** * A list of specified "dangerous" permissions that require prompting the user */ - PERMISSIONS: {[key: string]: Permission}; + PERMISSIONS: { + [key in + | 'READ_CALENDAR' + | 'WRITE_CALENDAR' + | 'CAMERA' + | 'READ_CONTACTS' + | 'WRITE_CONTACTS' + | 'GET_ACCOUNTS' + | 'ACCESS_FINE_LOCATION' + | 'ACCESS_COARSE_LOCATION' + | 'ACCESS_BACKGROUND_LOCATION' + | 'RECORD_AUDIO' + | 'READ_PHONE_STATE' + | 'CALL_PHONE' + | 'READ_CALL_LOG' + | 'WRITE_CALL_LOG' + | 'ADD_VOICEMAIL' + | 'READ_VOICEMAIL' + | 'WRITE_VOICEMAIL' + | 'USE_SIP' + | 'PROCESS_OUTGOING_CALLS' + | 'BODY_SENSORS' + | 'BODY_SENSORS_BACKGROUND' + | 'SEND_SMS' + | 'RECEIVE_SMS' + | 'READ_SMS' + | 'RECEIVE_WAP_PUSH' + | 'RECEIVE_MMS' + | 'READ_EXTERNAL_STORAGE' + | 'READ_MEDIA_IMAGES' + | 'READ_MEDIA_VIDEO' + | 'READ_MEDIA_AUDIO' + | 'READ_MEDIA_VISUAL_USER_SELECTED' + | 'WRITE_EXTERNAL_STORAGE' + | 'BLUETOOTH_CONNECT' + | 'BLUETOOTH_SCAN' + | 'BLUETOOTH_ADVERTISE' + | 'ACCESS_MEDIA_LOCATION' + | 'ACCEPT_HANDOVER' + | 'ACTIVITY_RECOGNITION' + | 'ANSWER_PHONE_CALLS' + | 'READ_PHONE_NUMBERS' + | 'UWB_RANGING' + | 'POST_NOTIFICATIONS' + | 'NEARBY_WIFI_DEVICES']: Permission; + }; new (): PermissionsAndroidStatic; /** * @deprecated Use check instead From a3ab7895c9586977ccd165577e3c560e87712dac Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Wed, 6 Nov 2024 08:54:10 -0800 Subject: [PATCH 087/220] Add missing `\n` on actOnLabel.js (#47451) Summary: I forgot to add some `\n` in the bot messages. This fixes it. ## Changelog: [INTERNAL] - Add missing `\n` on actOnLabel.js Pull Request resolved: https://github.com/facebook/react-native/pull/47451 Test Plan: N/A Reviewed By: cipolleschi Differential Revision: D65533495 Pulled By: cortinico fbshipit-source-id: c2214d00800f6b70ec331a9ae72578414f50cd43 --- .github/workflow-scripts/actOnLabel.js | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflow-scripts/actOnLabel.js b/.github/workflow-scripts/actOnLabel.js index 7692e67b31d564..826fce7d23b694 100644 --- a/.github/workflow-scripts/actOnLabel.js +++ b/.github/workflow-scripts/actOnLabel.js @@ -48,83 +48,83 @@ module.exports = async (github, context, labelWithContext) => { switch (labelWithContext.label) { case 'Type: Invalid': await addComment( - `> [!CAUTION]` + + `> [!CAUTION]\n` + `> **Invalid issue**: This issue is not valid, either is not a bug in React Native, it doesn't match any of the issue template, or we can't help further with this.`, ); await closeIssue(); return; case 'Type: Question': await addComment( - `> [!NOTE]` + + `> [!NOTE]\n` + `> **Not a bug report**: This issue looks like a question. We are using GitHub issues exclusively to track bugs in React Native. GitHub may not be the ideal place to ask a question, but you can try asking over on [Stack Overflow](http://stackoverflow.com/questions/tagged/react-native), or on [Reactiflux](https://www.reactiflux.com/).`, ); await closeIssue(); return; case 'Resolution: For Stack Overflow': await addComment( - `> [!NOTE]` + + `> [!NOTE]\n` + `> **Not a bug report**: This issue looks like a question. We are using GitHub issues exclusively to track bugs in React Native. GitHub may not be the ideal place to ask a question, but you can try asking over on [Stack Overflow](http://stackoverflow.com/questions/tagged/react-native), or on [Reactiflux](https://www.reactiflux.com/).`, ); await closeIssue(); return; case 'Type: Docs': await addComment( - `> [!NOTE]` + + `> [!NOTE]\n` + `> **Docs issue**: This issue looks like an issue related to our docs. Please report documentation issues in the [react-native-website](https://github.com/facebook/react-native-website/issues) repository.`, ); await closeIssue(); return; case 'Type: Expo': await addComment( - `> [!NOTE]` + + `> [!NOTE]\n` + `> **Expo related**: It looks like your issue is related to Expo and not React Native core. Please open your issue in [Expo's repository](https://github.com/expo/expo/issues/new). If you are able to create a repro that showcases that this issue is also happening in React Native vanilla, we will be happy to re-open.`, ); await closeIssue(); return; case 'Needs: Issue Template': await addComment( - `> [!WARNING]` + + `> [!WARNING]\n` + `> **Missing issue template**: It looks like your issue may be missing some necessary information. GitHub provides an example template whenever a [new issue is created](https://github.com/facebook/react-native/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A&projects=&template=bug_report.yml). Could you go back and make sure to fill out the template? You may edit this issue, or close it and open a new one.`, ); await requestAuthorFeedback(); return; case 'Needs: Environment Info': await addComment( - `> [!WARNING]` + + `> [!WARNING]\n` + `> **Missing info**: It looks like your issue may be missing information about your development environment. You can obtain the missing information by running react-native info in a console.`, ); await requestAuthorFeedback(); return; case 'Newer Patch Available': await addComment( - `> [!TIP]` + + `> [!TIP]\n` + `> **Newer version available**: You are on a supported minor version, but it looks like there's a newer patch available - ${labelWithContext.newestPatch}. Please [upgrade](https://reactnative.dev/docs/upgrading) to the highest patch for your minor or latest and verify if the issue persists (alternatively, create a new project and repro the issue in it). If it does not repro, please let us know so we can close out this issue. This helps us ensure we are looking at issues that still exist in the most recent releases.`, ); return; case 'Needs: Version Info': await addComment( - `> [!WARNING]` + + `> [!WARNING]\n` + `> **Could not parse version**: We could not find or parse the version number of React Native in your issue report. Please use the template, and report your version including major, minor, and patch numbers - e.g. 0.76.2.`, ); await requestAuthorFeedback(); return; case 'Needs: Repro': await addComment( - `> [!WARNING]` + + `> [!WARNING]\n` + `> **Missing reproducer**: We could not detect a reproducible example in your issue report. Please provide either:
  • If your bug is UI related: a [Snack](https://snack.expo.dev)
  • If your bug is build/upgrade related: a project using our [Reproducer Template](https://github.com/react-native-community/reproducer-react-native/generate)
  • Otherwise send us a Pull Request with the [RNTesterPlayground.js](https://github.com/facebook/react-native/blob/main/packages/rn-tester/js/examples/Playground/RNTesterPlayground.js) edited to reproduce your bug.
`, ); await requestAuthorFeedback(); return; case 'Type: Unsupported Version': await addComment( - `> [!WARNING]` + + `> [!WARNING]\n` + `> **Unsupported version**: It looks like your issue or the example you provided uses an [unsupported version of React Native](https://github.com/reactwg/react-native-releases/blob/main/docs/support.md).

Due to the number of issues we receive, we're currently only accepting new issues against one of the supported versions. Please [upgrade](https://reactnative.dev/docs/upgrading) to latest and verify if the issue persists (alternatively, create a new project and repro the issue in it). If you cannot upgrade, please open your issue on [StackOverflow](https://stackoverflow.com/questions/tagged/react-native) to get further community support.`, ); await requestAuthorFeedback(); return; case 'Type: Too Old Version': await addComment( - `> [!CAUTION]` + + `> [!CAUTION]\n` + `> **Too old version**: It looks like your issue or the example you provided uses a [**Too Old Version of React Native**](https://github.com/reactwg/react-native-releases/blob/main/docs/support.md).

Due to the number of issues we receive, we're currently only accepting new issues against one of the supported versions. Please [upgrade](https://reactnative.dev/docs/upgrading) to latest and verify if the issue persists (alternatively, create a new project and repro the issue in it). If you cannot upgrade, please open your issue on [StackOverflow](https://stackoverflow.com/questions/tagged/react-native) to get further community support.`, ); await closeIssue(); From 17c164621de4c4d1c7f0c3dd7849567df82a2648 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Guzm=C3=A1n?= Date: Wed, 6 Nov 2024 09:19:27 -0800 Subject: [PATCH 088/220] test(image): [android] improving image property test cases (#47433) Summary: I've doing some enhancements around the Image component for Android, and in the process of understanding the codebase I saw some opportunity to improve the test cases as there is no much coverage around the underlying functionality. ## Changelog: [INTERNAL] [ADDED] - Improving Android Image property test cases Pull Request resolved: https://github.com/facebook/react-native/pull/47433 Test Plan: ```bash yarn test-android ``` Reviewed By: javache Differential Revision: D65530813 Pulled By: cortinico fbshipit-source-id: b314eaf7493c6f3c859b7cb0d06771c109e5e854 --- .../views/image/ReactImagePropertyTest.kt | 115 ++++++++++++++++++ 1 file changed, 115 insertions(+) diff --git a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/image/ReactImagePropertyTest.kt b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/image/ReactImagePropertyTest.kt index f1329e88d8f7bb..faa427a52dd2e3 100644 --- a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/image/ReactImagePropertyTest.kt +++ b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/image/ReactImagePropertyTest.kt @@ -9,6 +9,7 @@ package com.facebook.react.views.image import android.graphics.Color import android.util.DisplayMetrics +import com.facebook.common.logging.FLog import com.facebook.drawee.backends.pipeline.Fresco import com.facebook.drawee.drawable.ScalingUtils import com.facebook.react.bridge.Arguments @@ -19,6 +20,7 @@ import com.facebook.react.bridge.JavaOnlyMap import com.facebook.react.bridge.ReactTestHelper.createMockCatalystInstance import com.facebook.react.bridge.WritableArray import com.facebook.react.bridge.WritableMap +import com.facebook.react.common.ReactConstants import com.facebook.react.internal.featureflags.ReactNativeFeatureFlagsForTests import com.facebook.react.uimanager.DisplayMetricsHolder import com.facebook.react.uimanager.ReactStylesDiffMap @@ -34,7 +36,11 @@ import org.junit.runner.RunWith import org.mockito.MockedStatic import org.mockito.Mockito.any import org.mockito.Mockito.anyString +import org.mockito.Mockito.mock import org.mockito.Mockito.mockStatic +import org.mockito.Mockito.never +import org.mockito.Mockito.reset +import org.mockito.Mockito.verify import org.robolectric.RobolectricTestRunner import org.robolectric.RuntimeEnvironment @@ -47,6 +53,7 @@ class ReactImagePropertyTest { private lateinit var themeContext: ThemedReactContext private lateinit var arguments: MockedStatic private lateinit var rnLog: MockedStatic + private lateinit var flogMock: MockedStatic @Before fun setup() { @@ -57,6 +64,8 @@ class ReactImagePropertyTest { rnLog = mockStatic(RNLog::class.java) rnLog.`when` { RNLog.w(any(), anyString()) }.thenAnswer {} + flogMock = mockStatic(FLog::class.java) + SoLoader.setInTestMode() context = BridgeReactContext(RuntimeEnvironment.getApplication()) catalystInstanceMock = createMockCatalystInstance() @@ -73,6 +82,7 @@ class ReactImagePropertyTest { DisplayMetricsHolder.setWindowDisplayMetrics(null) arguments.close() rnLog.close() + flogMock.close() } private fun buildStyles(vararg keysAndValues: Any?): ReactStylesDiffMap { @@ -87,6 +97,20 @@ class ReactImagePropertyTest { assertThat(view.isFocusable).isTrue() } + @Test + fun testOverlayColor() { + val viewManager = ReactImageManager() + val mockView = mock(ReactImageView::class.java) + + viewManager.setOverlayColor(mockView, null) + verify(mockView).setOverlayColor(Color.TRANSPARENT) + reset(mockView) + + viewManager.setOverlayColor(mockView, Color.argb(50, 0, 0, 255)) + verify(mockView).setOverlayColor(Color.argb(50, 0, 0, 255)) + reset(mockView) + } + @Test fun testTintColor() { val viewManager = ReactImageManager() @@ -115,4 +139,95 @@ class ReactImagePropertyTest { assertThat(ImageSource.getTransparentBitmapImageSource(view.context)) .isEqualTo(view.imageSource) } + + @Test + fun testResizeMode() { + val viewManager = ReactImageManager() + val mockView = mock(ReactImageView::class.java) + + viewManager.setResizeMode(mockView, null) + verify(mockView).setScaleType(ScalingUtils.ScaleType.CENTER_CROP) + reset(mockView) + + viewManager.setResizeMode(mockView, "cover") + verify(mockView).setScaleType(ScalingUtils.ScaleType.CENTER_CROP) + reset(mockView) + + viewManager.setResizeMode(mockView, "contain") + verify(mockView).setScaleType(ScalingUtils.ScaleType.FIT_CENTER) + reset(mockView) + + viewManager.setResizeMode(mockView, "stretch") + verify(mockView).setScaleType(ScalingUtils.ScaleType.FIT_XY) + reset(mockView) + + viewManager.setResizeMode(mockView, "repeat") + verify(mockView).setScaleType(ScaleTypeStartInside.INSTANCE) + reset(mockView) + + viewManager.setResizeMode(mockView, "center") + verify(mockView).setScaleType(ScalingUtils.ScaleType.CENTER_INSIDE) + reset(mockView) + + viewManager.setResizeMode(mockView, "invalid") + verify(mockView).setScaleType(ScalingUtils.ScaleType.CENTER_CROP) + } + + @Test + fun testResizeMethod() { + val viewManager = ReactImageManager() + val mockView = mock(ReactImageView::class.java) + + viewManager.setResizeMethod(mockView, null) + verify(mockView).setResizeMethod(ImageResizeMethod.AUTO) + reset(mockView) + + viewManager.setResizeMethod(mockView, "auto") + verify(mockView).setResizeMethod(ImageResizeMethod.AUTO) + reset(mockView) + + viewManager.setResizeMethod(mockView, "resize") + verify(mockView).setResizeMethod(ImageResizeMethod.RESIZE) + reset(mockView) + + viewManager.setResizeMethod(mockView, "scale") + verify(mockView).setResizeMethod(ImageResizeMethod.SCALE) + reset(mockView) + + viewManager.setResizeMethod(mockView, "none") + verify(mockView).setResizeMethod(ImageResizeMethod.NONE) + reset(mockView) + + viewManager.setResizeMethod(mockView, "invalid") + verify(mockView).setResizeMethod(ImageResizeMethod.AUTO) + flogMock.verify { FLog.w(ReactConstants.TAG, "Invalid resize method: 'invalid'") } + } + + @Test + fun testResizeMultiplier() { + val viewManager = ReactImageManager() + val mockView = mock(ReactImageView::class.java) + + viewManager.setResizeMultiplier(mockView, 0.01f) + verify(mockView).setResizeMultiplier(0.01f) + reset(mockView) + + viewManager.setResizeMultiplier(mockView, 0.009f) + verify(mockView).setResizeMultiplier(0.009f) + flogMock.verify { FLog.w(ReactConstants.TAG, "Invalid resize multiplier: '0.009'") } + } + + @Test + fun testHeaders() { + val viewManager = ReactImageManager() + val mockView = mock(ReactImageView::class.java) + + viewManager.setHeaders(mockView, null) + verify(mockView, never()).setHeaders(any()) + + val headers = JavaOnlyMap() + headers.putString("key", "value") + viewManager.setHeaders(mockView, headers) + verify(mockView).setHeaders(headers) + } } From 3dec672398729cd668aff92249f1fdde231fb928 Mon Sep 17 00:00:00 2001 From: Arushi Kesarwani Date: Wed, 6 Nov 2024 10:26:16 -0800 Subject: [PATCH 089/220] Reducing visibility of SimpleSettableFuture (#47438) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47438 As part of sustainability week effort for switching to `internal` here: https://fb.workplace.com/groups/251759413609061/permalink/872342228217440/ Reducing visibility of SimpleSettableFuture from `public` to `internal` Changelog: [Android] [Breaking] - Stable API - Make SimpleSettableFuture internal Reviewed By: javache Differential Revision: D65502193 fbshipit-source-id: 4bdd9b43684c8bc075271d76856ef848c52e6b12 --- .../react-native/ReactAndroid/api/ReactAndroid.api | 13 ------------- .../react/common/futures/SimpleSettableFuture.kt | 2 +- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 60c865e204d1b3..e540ce715f000e 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -1907,19 +1907,6 @@ public final class com/facebook/react/common/build/ReactBuildConfig { public static final field IS_INTERNAL_BUILD Z } -public final class com/facebook/react/common/futures/SimpleSettableFuture : java/util/concurrent/Future { - public fun ()V - public fun cancel (Z)Z - public fun get ()Ljava/lang/Object; - public fun get (JLjava/util/concurrent/TimeUnit;)Ljava/lang/Object; - public final fun getOrThrow ()Ljava/lang/Object; - public final fun getOrThrow (JLjava/util/concurrent/TimeUnit;)Ljava/lang/Object; - public fun isCancelled ()Z - public fun isDone ()Z - public final fun set (Ljava/lang/Object;)V - public final fun setException (Ljava/lang/Exception;)V -} - public abstract interface class com/facebook/react/common/mapbuffer/MapBuffer : java/lang/Iterable, kotlin/jvm/internal/markers/KMappedMarker { public static final field Companion Lcom/facebook/react/common/mapbuffer/MapBuffer$Companion; public abstract fun contains (I)Z diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/common/futures/SimpleSettableFuture.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/common/futures/SimpleSettableFuture.kt index 79c5d5c3fdc383..95c093e6670f1f 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/common/futures/SimpleSettableFuture.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/common/futures/SimpleSettableFuture.kt @@ -17,7 +17,7 @@ import java.util.concurrent.TimeoutException * A super simple Future-like class that can safely notify another Thread when a value is ready. * Does not support canceling. */ -public class SimpleSettableFuture : Future { +internal class SimpleSettableFuture : Future { private val readyLatch = CountDownLatch(1) private var result: T? = null From 1be03877961f08f971517ca323bc1241c11fa88e Mon Sep 17 00:00:00 2001 From: Pieter De Baets Date: Wed, 6 Nov 2024 10:27:28 -0800 Subject: [PATCH 090/220] Convert com.facebook.react.bridge.JavaOnlyMap to Kotlin (#47416) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47416 Changelog: [Internal] Reviewed By: tdn120 Differential Revision: D65478448 fbshipit-source-id: 24e6732a80f5ee858fec5dbb38617e7dfad63f58 --- .../ReactAndroid/api/ReactAndroid.api | 18 +- .../facebook/react/bridge/JavaOnlyMap.java | 270 ------------------ .../com/facebook/react/bridge/JavaOnlyMap.kt | 180 ++++++++++++ .../com/facebook/react/bridge/ReadableMap.kt | 4 +- .../react/bridge/ReadableNativeMap.kt | 6 +- 5 files changed, 198 insertions(+), 280 deletions(-) delete mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaOnlyMap.java create mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaOnlyMap.kt diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index e540ce715f000e..25ffe8b9c394cb 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -926,12 +926,14 @@ public class com/facebook/react/bridge/JavaOnlyArray : com/facebook/react/bridge public fun toString ()Ljava/lang/String; } -public class com/facebook/react/bridge/JavaOnlyMap : com/facebook/react/bridge/ReadableMap, com/facebook/react/bridge/WritableMap { +public final class com/facebook/react/bridge/JavaOnlyMap : com/facebook/react/bridge/ReadableMap, com/facebook/react/bridge/WritableMap { + public static final field Companion Lcom/facebook/react/bridge/JavaOnlyMap$Companion; public fun ()V + public synthetic fun ([Ljava/lang/Object;Lkotlin/jvm/internal/DefaultConstructorMarker;)V public fun copy ()Lcom/facebook/react/bridge/WritableMap; - public static fun deepClone (Lcom/facebook/react/bridge/ReadableMap;)Lcom/facebook/react/bridge/JavaOnlyMap; + public static final fun deepClone (Lcom/facebook/react/bridge/ReadableMap;)Lcom/facebook/react/bridge/JavaOnlyMap; public fun equals (Ljava/lang/Object;)Z - public static fun from (Ljava/util/Map;)Lcom/facebook/react/bridge/JavaOnlyMap; + public static final fun from (Ljava/util/Map;)Lcom/facebook/react/bridge/JavaOnlyMap; public fun getArray (Ljava/lang/String;)Lcom/facebook/react/bridge/ReadableArray; public fun getBoolean (Ljava/lang/String;)Z public fun getDouble (Ljava/lang/String;)D @@ -947,7 +949,7 @@ public class com/facebook/react/bridge/JavaOnlyMap : com/facebook/react/bridge/R public fun isNull (Ljava/lang/String;)Z public fun keySetIterator ()Lcom/facebook/react/bridge/ReadableMapKeySetIterator; public fun merge (Lcom/facebook/react/bridge/ReadableMap;)V - public static fun of ([Ljava/lang/Object;)Lcom/facebook/react/bridge/JavaOnlyMap; + public static final fun of ([Ljava/lang/Object;)Lcom/facebook/react/bridge/JavaOnlyMap; public fun putArray (Ljava/lang/String;Lcom/facebook/react/bridge/ReadableArray;)V public fun putBoolean (Ljava/lang/String;Z)V public fun putDouble (Ljava/lang/String;D)V @@ -956,11 +958,17 @@ public class com/facebook/react/bridge/JavaOnlyMap : com/facebook/react/bridge/R public fun putMap (Ljava/lang/String;Lcom/facebook/react/bridge/ReadableMap;)V public fun putNull (Ljava/lang/String;)V public fun putString (Ljava/lang/String;Ljava/lang/String;)V - public fun remove (Ljava/lang/String;)V + public final fun remove (Ljava/lang/String;)V public fun toHashMap ()Ljava/util/HashMap; public fun toString ()Ljava/lang/String; } +public final class com/facebook/react/bridge/JavaOnlyMap$Companion { + public final fun deepClone (Lcom/facebook/react/bridge/ReadableMap;)Lcom/facebook/react/bridge/JavaOnlyMap; + public final fun from (Ljava/util/Map;)Lcom/facebook/react/bridge/JavaOnlyMap; + public final fun of ([Ljava/lang/Object;)Lcom/facebook/react/bridge/JavaOnlyMap; +} + public class com/facebook/react/bridge/JavaScriptContextHolder { public fun (J)V public fun clear ()V diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaOnlyMap.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaOnlyMap.java deleted file mode 100644 index afb27217b44cb2..00000000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaOnlyMap.java +++ /dev/null @@ -1,270 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and 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.bridge; - -import static androidx.core.util.Preconditions.checkNotNull; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -/** - * Java {@link HashMap} backed implementation of {@link ReadableMap} and {@link WritableMap} - * Instances of this class SHOULD NOT be used for communication between java and JS, use instances - * of {@link WritableNativeMap} created via {@link Arguments#createMap} or just {@link ReadableMap} - * interface if you want your "native" module method to take a map from JS as an argument. - * - *

Main purpose for this class is to be used in java-only unit tests, but could also be used - * outside of tests in the code that operates only in java and needs to communicate with RN modules - * via their JS-exposed API. - */ -public class JavaOnlyMap implements ReadableMap, WritableMap { - - private final Map mBackingMap; - - public static JavaOnlyMap of(Object... keysAndValues) { - return new JavaOnlyMap(keysAndValues); - } - - public static JavaOnlyMap from(Map map) { - return new JavaOnlyMap(map); - } - - public static JavaOnlyMap deepClone(ReadableMap map) { - JavaOnlyMap res = new JavaOnlyMap(); - ReadableMapKeySetIterator iter = map.keySetIterator(); - while (iter.hasNextKey()) { - String propKey = iter.nextKey(); - ReadableType type = map.getType(propKey); - switch (type) { - case Null: - res.putNull(propKey); - break; - case Boolean: - res.putBoolean(propKey, map.getBoolean(propKey)); - break; - case Number: - res.putDouble(propKey, map.getDouble(propKey)); - break; - case String: - res.putString(propKey, map.getString(propKey)); - break; - case Map: - res.putMap(propKey, deepClone(map.getMap(propKey))); - break; - case Array: - res.putArray(propKey, JavaOnlyArray.deepClone(map.getArray(propKey))); - break; - } - } - return res; - } - - /** - * @param keysAndValues keys and values, interleaved - */ - private JavaOnlyMap(Object... keysAndValues) { - if (keysAndValues.length % 2 != 0) { - throw new IllegalArgumentException("You must provide the same number of keys and values"); - } - mBackingMap = new HashMap(); - for (int i = 0; i < keysAndValues.length; i += 2) { - Object val = keysAndValues[i + 1]; - if (val instanceof Number) { - // all values from JS are doubles, so emulate that here for tests. - val = ((Number) val).doubleValue(); - } - mBackingMap.put(keysAndValues[i], val); - } - } - - public JavaOnlyMap() { - mBackingMap = new HashMap(); - } - - @Override - public boolean hasKey(@NonNull String name) { - return mBackingMap.containsKey(name); - } - - @Override - public boolean isNull(@NonNull String name) { - return mBackingMap.get(name) == null; - } - - @Override - public boolean getBoolean(@NonNull String name) { - return (Boolean) mBackingMap.get(name); - } - - @Override - public double getDouble(@NonNull String name) { - return ((Number) mBackingMap.get(name)).doubleValue(); - } - - @Override - public int getInt(@NonNull String name) { - return ((Number) mBackingMap.get(name)).intValue(); - } - - @Override - public long getLong(@NonNull String name) { - return ((Number) checkNotNull(mBackingMap.get(name))).longValue(); - } - - @Override - public String getString(@NonNull String name) { - return (String) mBackingMap.get(name); - } - - @Override - public ReadableMap getMap(@NonNull String name) { - return (ReadableMap) mBackingMap.get(name); - } - - @Override - public ReadableArray getArray(@NonNull String name) { - return (ReadableArray) mBackingMap.get(name); - } - - @Override - public @NonNull Dynamic getDynamic(@NonNull String name) { - return DynamicFromMap.create(this, name); - } - - @Override - public @NonNull ReadableType getType(@NonNull String name) { - Object value = mBackingMap.get(name); - if (value == null) { - return ReadableType.Null; - } else if (value instanceof Number) { - return ReadableType.Number; - } else if (value instanceof String) { - return ReadableType.String; - } else if (value instanceof Boolean) { - return ReadableType.Boolean; - } else if (value instanceof ReadableMap) { - return ReadableType.Map; - } else if (value instanceof ReadableArray) { - return ReadableType.Array; - } else if (value instanceof Dynamic) { - return ((Dynamic) value).getType(); - } else { - throw new IllegalArgumentException( - "Invalid value " + value.toString() + " for key " + name + "contained in JavaOnlyMap"); - } - } - - @Override - public @NonNull Iterator> getEntryIterator() { - return mBackingMap.entrySet().iterator(); - } - - @Override - public @NonNull ReadableMapKeySetIterator keySetIterator() { - return new ReadableMapKeySetIterator() { - Iterator> mIterator = mBackingMap.entrySet().iterator(); - - @Override - public boolean hasNextKey() { - return mIterator.hasNext(); - } - - @Override - public String nextKey() { - return mIterator.next().getKey(); - } - }; - } - - @Override - public void putBoolean(@NonNull String key, boolean value) { - mBackingMap.put(key, value); - } - - @Override - public void putDouble(@NonNull String key, double value) { - mBackingMap.put(key, value); - } - - @Override - public void putInt(@NonNull String key, int value) { - mBackingMap.put(key, new Double(value)); - } - - @Override - public void putLong(@NonNull String key, long value) { - mBackingMap.put(key, value); - } - - @Override - public void putString(@NonNull String key, @Nullable String value) { - mBackingMap.put(key, value); - } - - @Override - public void putNull(@NonNull String key) { - mBackingMap.put(key, null); - } - - @Override - public void putMap(@NonNull String key, @Nullable ReadableMap value) { - mBackingMap.put(key, value); - } - - @Override - public void merge(@NonNull ReadableMap source) { - mBackingMap.putAll(((JavaOnlyMap) source).mBackingMap); - } - - @Override - public WritableMap copy() { - final JavaOnlyMap target = new JavaOnlyMap(); - target.merge(this); - return target; - } - - @Override - public void putArray(@NonNull String key, @Nullable ReadableArray value) { - mBackingMap.put(key, value); - } - - @Override - public @NonNull HashMap toHashMap() { - return new HashMap(mBackingMap); - } - - @Override - public String toString() { - return mBackingMap.toString(); - } - - public void remove(@NonNull String key) { - mBackingMap.remove(key); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - JavaOnlyMap that = (JavaOnlyMap) o; - - if (mBackingMap != null ? !mBackingMap.equals(that.mBackingMap) : that.mBackingMap != null) - return false; - - return true; - } - - @Override - public int hashCode() { - return mBackingMap != null ? mBackingMap.hashCode() : 0; - } -} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaOnlyMap.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaOnlyMap.kt new file mode 100644 index 00000000000000..e1a9456ddc059e --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaOnlyMap.kt @@ -0,0 +1,180 @@ +/* + * Copyright (c) Meta Platforms, Inc. and 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.bridge + +import java.util.HashMap +import kotlin.collections.Iterator +import kotlin.collections.Map + +/** + * Java [HashMap] backed implementation of [ReadableMap] and [WritableMap] Instances of this class + * SHOULD NOT be used for communication between java and JS, use instances of [WritableNativeMap] + * created via [Arguments#createMap] or just [ReadableMap] interface if you want your "native" + * module method to take a map from JS as an argument. + * + * Main purpose for this class is to be used in java-only unit tests, but could also be used outside + * of tests in the code that operates only in java and needs to communicate with RN modules via + * their JS-exposed API. + */ +public class JavaOnlyMap() : ReadableMap, WritableMap { + public companion object { + @JvmStatic public fun of(vararg keysAndValues: Any?): JavaOnlyMap = JavaOnlyMap(*keysAndValues) + + @JvmStatic public fun from(map: Map): JavaOnlyMap = JavaOnlyMap(map) + + @JvmStatic + public fun deepClone(map: ReadableMap?): JavaOnlyMap { + val res = JavaOnlyMap() + if (map == null) { + return res + } + val iter = map.keySetIterator() + while (iter.hasNextKey()) { + val propKey = iter.nextKey() + val type = map.getType(propKey) + when (type) { + ReadableType.Null -> res.putNull(propKey) + ReadableType.Boolean -> res.putBoolean(propKey, map.getBoolean(propKey)) + ReadableType.Number -> res.putDouble(propKey, map.getDouble(propKey)) + ReadableType.String -> res.putString(propKey, map.getString(propKey)) + ReadableType.Map -> res.putMap(propKey, deepClone(checkNotNull(map.getMap(propKey)))) + ReadableType.Array -> + res.putArray(propKey, JavaOnlyArray.deepClone(map.getArray(propKey))) + } + } + return res + } + } + + private val backingMap: MutableMap = HashMap() + + /** @param keysAndValues keys and values, interleaved */ + private constructor(vararg keysAndValues: Any?) : this() { + require(keysAndValues.size % 2 == 0) { "You must provide the same number of keys and values" } + for (i in keysAndValues.indices step 2) { + var value = keysAndValues[i + 1] + if (value is Number) { + // all values from JS are doubles, so emulate that here for tests. + value = value.toDouble() + } + backingMap[keysAndValues[i] as String] = value + } + } + + override fun hasKey(name: String): Boolean = backingMap.containsKey(name) + + override fun isNull(name: String): Boolean = backingMap[name] == null + + override fun getBoolean(name: String): Boolean = backingMap[name] as Boolean + + override fun getDouble(name: String): Double = (backingMap[name] as Number).toDouble() + + override fun getInt(name: String): Int = (backingMap[name] as Number).toInt() + + override fun getLong(name: String): Long = (checkNotNull(backingMap[name] as Number).toLong()) + + override fun getString(name: String): String? = backingMap[name] as String? + + override fun getMap(name: String): ReadableMap? = backingMap[name] as ReadableMap? + + override fun getArray(name: String): ReadableArray? = backingMap[name] as ReadableArray? + + override fun getDynamic(name: String): Dynamic = DynamicFromMap.create(this, name) + + override fun getType(name: String): ReadableType { + val value = backingMap[name] + return when { + value == null -> ReadableType.Null + value is Number -> ReadableType.Number + value is String -> ReadableType.String + value is Boolean -> ReadableType.Boolean + value is ReadableMap -> ReadableType.Map + value is ReadableArray -> ReadableType.Array + value is Dynamic -> value.type + else -> { + throw IllegalArgumentException( + "Invalid value $value for key $name contained in JavaOnlyMap") + } + } + } + + override val entryIterator: Iterator> + get() = backingMap.entries.iterator() + + override fun keySetIterator(): ReadableMapKeySetIterator { + return object : ReadableMapKeySetIterator { + private val iterator = backingMap.entries.iterator() + + override fun hasNextKey(): Boolean = iterator.hasNext() + + override fun nextKey(): String = iterator.next().key + } + } + + override fun putBoolean(key: String, value: Boolean) { + backingMap[key] = value + } + + override fun putDouble(key: String, value: Double) { + backingMap[key] = value + } + + override fun putInt(key: String, value: Int) { + backingMap[key] = value.toDouble() + } + + override fun putLong(key: String, value: Long) { + backingMap[key] = value.toDouble() + } + + override fun putString(key: String, value: String?) { + backingMap[key] = value + } + + override fun putNull(key: String) { + backingMap[key] = null + } + + override fun putMap(key: String, value: ReadableMap?) { + backingMap[key] = value + } + + override fun merge(source: ReadableMap) { + backingMap.putAll((source as JavaOnlyMap).backingMap) + } + + override fun copy(): WritableMap { + val target = JavaOnlyMap() + target.merge(this) + return target + } + + override fun putArray(key: String, value: ReadableArray?) { + backingMap[key] = value + } + + public fun remove(key: String) { + backingMap.remove(key) + } + + override fun toHashMap(): HashMap = HashMap(backingMap) + + override fun toString(): String = backingMap.toString() + + override fun equals(other: Any?): Boolean { + return if (this === other) { + true + } else if (other == null || javaClass != other.javaClass) { + false + } else { + backingMap == (other as JavaOnlyMap).backingMap + } + } + + override fun hashCode(): Int = backingMap.hashCode() +} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableMap.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableMap.kt index a8319fcecae4c1..4920fb6dda4ee3 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableMap.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableMap.kt @@ -16,7 +16,7 @@ import kotlin.collections.Map * Kotlin. */ public interface ReadableMap { - public val entryIterator: Iterator> + public val entryIterator: Iterator> public fun getArray(name: String): ReadableArray? @@ -42,5 +42,5 @@ public interface ReadableMap { public fun keySetIterator(): ReadableMapKeySetIterator - public fun toHashMap(): HashMap + public fun toHashMap(): HashMap } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableNativeMap.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableNativeMap.kt index 68812fe11f6080..580282b5134317 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableNativeMap.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableNativeMap.kt @@ -20,10 +20,10 @@ public open class ReadableNativeMap protected constructor() : NativeMap(), Reada private val keys: Array by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { importKeys().also { jniPassCounter++ } } - private val localMap: HashMap by + private val localMap: HashMap by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { val length = keys.size - val res = HashMap(length) + val res = HashMap(length) val values = importValues() jniPassCounter++ for (i in 0 until length) { @@ -157,7 +157,7 @@ public open class ReadableNativeMap protected constructor() : NativeMap(), Reada false } else localMap == other.localMap - override fun toHashMap(): HashMap { + override fun toHashMap(): HashMap { // we can almost just return getLocalMap(), but we need to convert nested arrays and maps to the // correct types first val hashMap = HashMap(localMap) From 0c21db360cecc6a3265eea50d628106c58b67af8 Mon Sep 17 00:00:00 2001 From: Alex Hunt Date: Wed, 6 Nov 2024 10:27:31 -0800 Subject: [PATCH 091/220] Remove unused ReactFabricInternals API (#47454) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47454 As far as I can tell, this module is now unused both within the codebase and externally. Delete to reduce our public API surface (deep module is an accessible import path). Changelog: [General][Breaking] - Remove ReactFabricInternals module Reviewed By: cortinico Differential Revision: D65535378 fbshipit-source-id: 25ee16ccc637815ffe1c69a5fc546bd3e11d1689 --- .../ReactNative/ReactFabricInternals.js | 17 ----------------- .../__snapshots__/public-api-test.js.snap | 8 -------- 2 files changed, 25 deletions(-) delete mode 100644 packages/react-native/Libraries/ReactNative/ReactFabricInternals.js diff --git a/packages/react-native/Libraries/ReactNative/ReactFabricInternals.js b/packages/react-native/Libraries/ReactNative/ReactFabricInternals.js deleted file mode 100644 index 749a11eded825d..00000000000000 --- a/packages/react-native/Libraries/ReactNative/ReactFabricInternals.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and 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 - */ - -'use strict'; - -const createReactNativeComponentClass = require('../Renderer/shims/createReactNativeComponentClass'); - -module.exports = { - createReactNativeComponentClass, -}; diff --git a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap index ea0a2fe12eff77..9412916deb8427 100644 --- a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap +++ b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap @@ -7525,14 +7525,6 @@ declare module.exports: UIManagerJS; " `; -exports[`public API should not change unintentionally Libraries/ReactNative/ReactFabricInternals.js 1`] = ` -"declare const createReactNativeComponentClass: $FlowFixMe; -declare module.exports: { - createReactNativeComponentClass: createReactNativeComponentClass, -}; -" -`; - exports[`public API should not change unintentionally Libraries/ReactNative/ReactFabricPublicInstance/ReactFabricHostComponent.js 1`] = ` "declare export default class ReactFabricHostComponent implements INativeMethods From abd118a719fe0aeb13f980729ff9ce5fb8358b83 Mon Sep 17 00:00:00 2001 From: Arushi Kesarwani Date: Wed, 6 Nov 2024 10:31:21 -0800 Subject: [PATCH 092/220] Reducing visibility of OkHttpCallUtil (#47439) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47439 As part of sustainability week effort for switching to internal here: https://fb.workplace.com/groups/251759413609061/permalink/872342228217440/ Reducing visibility of OkHttpCallUtil from `public` to `internal` Changelog: [Android] [Breaking] - Stable API - Make OkHttpCallUtil internal Reviewed By: javache Differential Revision: D65506859 fbshipit-source-id: 4ad55d9112da3b3f04b734f41c5a263f4eabfefb --- packages/react-native/ReactAndroid/api/ReactAndroid.api | 5 ----- .../java/com/facebook/react/common/network/OkHttpCallUtil.kt | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 25ffe8b9c394cb..d77188fdf37f25 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -2009,11 +2009,6 @@ public final class com/facebook/react/common/mapbuffer/WritableMapBuffer : com/f public final fun put (IZ)Lcom/facebook/react/common/mapbuffer/WritableMapBuffer; } -public final class com/facebook/react/common/network/OkHttpCallUtil { - public static final field INSTANCE Lcom/facebook/react/common/network/OkHttpCallUtil; - public static final fun cancelTag (Lokhttp3/OkHttpClient;Ljava/lang/Object;)V -} - public final class com/facebook/react/config/ReactFeatureFlags { public static final field INSTANCE Lcom/facebook/react/config/ReactFeatureFlags; public static field dispatchPointerEvents Z diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/common/network/OkHttpCallUtil.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/common/network/OkHttpCallUtil.kt index 7b5ccf4be28fc5..c989a388587876 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/common/network/OkHttpCallUtil.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/common/network/OkHttpCallUtil.kt @@ -13,7 +13,7 @@ import okhttp3.OkHttpClient /** * Helper class that provides the necessary methods for canceling queued and running OkHttp calls */ -public object OkHttpCallUtil { +internal object OkHttpCallUtil { @JvmStatic public fun cancelTag(client: OkHttpClient, tag: Any) { // client.dispatcher is private, so we need to use reflection to access From dbe509a23a974f16804aefea055a24c06910b259 Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Wed, 6 Nov 2024 11:50:28 -0800 Subject: [PATCH 093/220] Undo breaking change of UiManager.eventDispatcher by solving circular dependency (#47457) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47457 The `UIManager.eventDispatcher` return type is wrong and is causing a breaking change in 0.77 For 0.76 we fixed it in the release branch but we should fix it for good in main as well. To solve it I had to fix the circular dependency between .bridge and .uimanager. I wish I could have isolated the .events package better but as everythign is public, any change we do is going to be a breaking change so I'm being over cautios here. Changelog: [Android] [Fixed] - Undo breaking change of UiManager.eventDispatcher return type Reviewed By: tdn120 Differential Revision: D65540601 fbshipit-source-id: 4b1f62806baac5f6c3ffdd51b8628ef088447604 --- packages/react-native/ReactAndroid/api/ReactAndroid.api | 4 +--- .../src/main/java/com/facebook/react/bridge/UIManager.kt | 3 ++- .../test/java/com/facebook/testutils/fakes/FakeUIManager.kt | 3 ++- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index d77188fdf37f25..d082bd2dc03ced 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -1563,7 +1563,7 @@ public abstract interface class com/facebook/react/bridge/UIManager : com/facebo public abstract fun addUIManagerEventListener (Lcom/facebook/react/bridge/UIManagerListener;)V public abstract fun dispatchCommand (IILcom/facebook/react/bridge/ReadableArray;)V public abstract fun dispatchCommand (ILjava/lang/String;Lcom/facebook/react/bridge/ReadableArray;)V - public abstract fun getEventDispatcher ()Ljava/lang/Object; + public abstract fun getEventDispatcher ()Lcom/facebook/react/uimanager/events/EventDispatcher; public abstract fun initialize ()V public abstract fun invalidate ()V public abstract fun markActiveTouchForTag (II)V @@ -2623,7 +2623,6 @@ public class com/facebook/react/fabric/FabricUIManager : com/facebook/react/brid public fun dispatchCommand (ILjava/lang/String;Lcom/facebook/react/bridge/ReadableArray;)V public fun getColor (I[Ljava/lang/String;)I public fun getEventDispatcher ()Lcom/facebook/react/uimanager/events/EventDispatcher; - public synthetic fun getEventDispatcher ()Ljava/lang/Object; public fun getInspectorDataForInstance (ILandroid/view/View;)Lcom/facebook/react/bridge/ReadableMap; public fun getPerformanceCounters ()Ljava/util/Map; public fun getThemeData (I[F)Z @@ -5157,7 +5156,6 @@ public class com/facebook/react/uimanager/UIManagerModule : com/facebook/react/b public fun getDefaultEventTypes ()Lcom/facebook/react/bridge/WritableMap; public fun getDirectEventNamesResolver ()Lcom/facebook/react/uimanager/UIManagerModule$CustomEventNamesResolver; public fun getEventDispatcher ()Lcom/facebook/react/uimanager/events/EventDispatcher; - public synthetic fun getEventDispatcher ()Ljava/lang/Object; public fun getName ()Ljava/lang/String; public fun getPerformanceCounters ()Ljava/util/Map; public fun getUIImplementation ()Lcom/facebook/react/uimanager/UIImplementation; diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/UIManager.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/UIManager.kt index f893f0ea209f8c..c0729f86de9566 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/UIManager.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/UIManager.kt @@ -12,6 +12,7 @@ import androidx.annotation.AnyThread import androidx.annotation.UiThread import com.facebook.infer.annotation.ThreadConfined import com.facebook.react.common.annotations.UnstableReactNativeAPI +import com.facebook.react.uimanager.events.EventDispatcher @OptIn(UnstableReactNativeAPI::class) public interface UIManager : PerformanceCounter { @@ -78,7 +79,7 @@ public interface UIManager : PerformanceCounter { public fun dispatchCommand(reactTag: Int, commandId: String, commandArgs: ReadableArray?) /** @return the [EventDispatcher] object that is used by this class. */ - public val eventDispatcher: Any? + public val eventDispatcher: EventDispatcher /** * Used by native animated module to bypass the process of updating the values through the shadow diff --git a/packages/react-native/ReactAndroid/src/test/java/com/facebook/testutils/fakes/FakeUIManager.kt b/packages/react-native/ReactAndroid/src/test/java/com/facebook/testutils/fakes/FakeUIManager.kt index b37693bd51fc17..49ba0848635f5e 100644 --- a/packages/react-native/ReactAndroid/src/test/java/com/facebook/testutils/fakes/FakeUIManager.kt +++ b/packages/react-native/ReactAndroid/src/test/java/com/facebook/testutils/fakes/FakeUIManager.kt @@ -17,6 +17,7 @@ import com.facebook.react.bridge.UIManagerListener import com.facebook.react.bridge.WritableMap import com.facebook.react.common.annotations.UnstableReactNativeAPI import com.facebook.react.fabric.interop.UIBlockViewResolver +import com.facebook.react.uimanager.events.EventDispatcher @OptIn(UnstableReactNativeAPI::class) class FakeUIManager : UIManager, UIBlockViewResolver { @@ -65,7 +66,7 @@ class FakeUIManager : UIManager, UIBlockViewResolver { error("Not yet implemented") } - override val eventDispatcher: Any? + override val eventDispatcher: EventDispatcher get() = TODO("Not yet implemented") override fun synchronouslyUpdateViewOnUIThread(reactTag: Int, props: ReadableMap?) { From e603fde886f8440c3320a3e2b38cd536dc4095a2 Mon Sep 17 00:00:00 2001 From: Adam Woods-Mccormick Date: Wed, 6 Nov 2024 12:49:38 -0800 Subject: [PATCH 094/220] Revert D65478448: Convert com.facebook.react.bridge.JavaOnlyMap to Kotlin Differential Revision: D65478448 Original commit changeset: 24e6732a80f5 Original Phabricator Diff: D65478448 fbshipit-source-id: fffd2259aa2757b816373bfded96948b3e6dfeba --- .../ReactAndroid/api/ReactAndroid.api | 18 +- .../facebook/react/bridge/JavaOnlyMap.java | 270 ++++++++++++++++++ .../com/facebook/react/bridge/JavaOnlyMap.kt | 180 ------------ .../com/facebook/react/bridge/ReadableMap.kt | 4 +- .../react/bridge/ReadableNativeMap.kt | 6 +- 5 files changed, 280 insertions(+), 198 deletions(-) create mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaOnlyMap.java delete mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaOnlyMap.kt diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index d082bd2dc03ced..4f305598e644dd 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -926,14 +926,12 @@ public class com/facebook/react/bridge/JavaOnlyArray : com/facebook/react/bridge public fun toString ()Ljava/lang/String; } -public final class com/facebook/react/bridge/JavaOnlyMap : com/facebook/react/bridge/ReadableMap, com/facebook/react/bridge/WritableMap { - public static final field Companion Lcom/facebook/react/bridge/JavaOnlyMap$Companion; +public class com/facebook/react/bridge/JavaOnlyMap : com/facebook/react/bridge/ReadableMap, com/facebook/react/bridge/WritableMap { public fun ()V - public synthetic fun ([Ljava/lang/Object;Lkotlin/jvm/internal/DefaultConstructorMarker;)V public fun copy ()Lcom/facebook/react/bridge/WritableMap; - public static final fun deepClone (Lcom/facebook/react/bridge/ReadableMap;)Lcom/facebook/react/bridge/JavaOnlyMap; + public static fun deepClone (Lcom/facebook/react/bridge/ReadableMap;)Lcom/facebook/react/bridge/JavaOnlyMap; public fun equals (Ljava/lang/Object;)Z - public static final fun from (Ljava/util/Map;)Lcom/facebook/react/bridge/JavaOnlyMap; + public static fun from (Ljava/util/Map;)Lcom/facebook/react/bridge/JavaOnlyMap; public fun getArray (Ljava/lang/String;)Lcom/facebook/react/bridge/ReadableArray; public fun getBoolean (Ljava/lang/String;)Z public fun getDouble (Ljava/lang/String;)D @@ -949,7 +947,7 @@ public final class com/facebook/react/bridge/JavaOnlyMap : com/facebook/react/br public fun isNull (Ljava/lang/String;)Z public fun keySetIterator ()Lcom/facebook/react/bridge/ReadableMapKeySetIterator; public fun merge (Lcom/facebook/react/bridge/ReadableMap;)V - public static final fun of ([Ljava/lang/Object;)Lcom/facebook/react/bridge/JavaOnlyMap; + public static fun of ([Ljava/lang/Object;)Lcom/facebook/react/bridge/JavaOnlyMap; public fun putArray (Ljava/lang/String;Lcom/facebook/react/bridge/ReadableArray;)V public fun putBoolean (Ljava/lang/String;Z)V public fun putDouble (Ljava/lang/String;D)V @@ -958,17 +956,11 @@ public final class com/facebook/react/bridge/JavaOnlyMap : com/facebook/react/br public fun putMap (Ljava/lang/String;Lcom/facebook/react/bridge/ReadableMap;)V public fun putNull (Ljava/lang/String;)V public fun putString (Ljava/lang/String;Ljava/lang/String;)V - public final fun remove (Ljava/lang/String;)V + public fun remove (Ljava/lang/String;)V public fun toHashMap ()Ljava/util/HashMap; public fun toString ()Ljava/lang/String; } -public final class com/facebook/react/bridge/JavaOnlyMap$Companion { - public final fun deepClone (Lcom/facebook/react/bridge/ReadableMap;)Lcom/facebook/react/bridge/JavaOnlyMap; - public final fun from (Ljava/util/Map;)Lcom/facebook/react/bridge/JavaOnlyMap; - public final fun of ([Ljava/lang/Object;)Lcom/facebook/react/bridge/JavaOnlyMap; -} - public class com/facebook/react/bridge/JavaScriptContextHolder { public fun (J)V public fun clear ()V diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaOnlyMap.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaOnlyMap.java new file mode 100644 index 00000000000000..afb27217b44cb2 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaOnlyMap.java @@ -0,0 +1,270 @@ +/* + * Copyright (c) Meta Platforms, Inc. and 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.bridge; + +import static androidx.core.util.Preconditions.checkNotNull; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +/** + * Java {@link HashMap} backed implementation of {@link ReadableMap} and {@link WritableMap} + * Instances of this class SHOULD NOT be used for communication between java and JS, use instances + * of {@link WritableNativeMap} created via {@link Arguments#createMap} or just {@link ReadableMap} + * interface if you want your "native" module method to take a map from JS as an argument. + * + *

Main purpose for this class is to be used in java-only unit tests, but could also be used + * outside of tests in the code that operates only in java and needs to communicate with RN modules + * via their JS-exposed API. + */ +public class JavaOnlyMap implements ReadableMap, WritableMap { + + private final Map mBackingMap; + + public static JavaOnlyMap of(Object... keysAndValues) { + return new JavaOnlyMap(keysAndValues); + } + + public static JavaOnlyMap from(Map map) { + return new JavaOnlyMap(map); + } + + public static JavaOnlyMap deepClone(ReadableMap map) { + JavaOnlyMap res = new JavaOnlyMap(); + ReadableMapKeySetIterator iter = map.keySetIterator(); + while (iter.hasNextKey()) { + String propKey = iter.nextKey(); + ReadableType type = map.getType(propKey); + switch (type) { + case Null: + res.putNull(propKey); + break; + case Boolean: + res.putBoolean(propKey, map.getBoolean(propKey)); + break; + case Number: + res.putDouble(propKey, map.getDouble(propKey)); + break; + case String: + res.putString(propKey, map.getString(propKey)); + break; + case Map: + res.putMap(propKey, deepClone(map.getMap(propKey))); + break; + case Array: + res.putArray(propKey, JavaOnlyArray.deepClone(map.getArray(propKey))); + break; + } + } + return res; + } + + /** + * @param keysAndValues keys and values, interleaved + */ + private JavaOnlyMap(Object... keysAndValues) { + if (keysAndValues.length % 2 != 0) { + throw new IllegalArgumentException("You must provide the same number of keys and values"); + } + mBackingMap = new HashMap(); + for (int i = 0; i < keysAndValues.length; i += 2) { + Object val = keysAndValues[i + 1]; + if (val instanceof Number) { + // all values from JS are doubles, so emulate that here for tests. + val = ((Number) val).doubleValue(); + } + mBackingMap.put(keysAndValues[i], val); + } + } + + public JavaOnlyMap() { + mBackingMap = new HashMap(); + } + + @Override + public boolean hasKey(@NonNull String name) { + return mBackingMap.containsKey(name); + } + + @Override + public boolean isNull(@NonNull String name) { + return mBackingMap.get(name) == null; + } + + @Override + public boolean getBoolean(@NonNull String name) { + return (Boolean) mBackingMap.get(name); + } + + @Override + public double getDouble(@NonNull String name) { + return ((Number) mBackingMap.get(name)).doubleValue(); + } + + @Override + public int getInt(@NonNull String name) { + return ((Number) mBackingMap.get(name)).intValue(); + } + + @Override + public long getLong(@NonNull String name) { + return ((Number) checkNotNull(mBackingMap.get(name))).longValue(); + } + + @Override + public String getString(@NonNull String name) { + return (String) mBackingMap.get(name); + } + + @Override + public ReadableMap getMap(@NonNull String name) { + return (ReadableMap) mBackingMap.get(name); + } + + @Override + public ReadableArray getArray(@NonNull String name) { + return (ReadableArray) mBackingMap.get(name); + } + + @Override + public @NonNull Dynamic getDynamic(@NonNull String name) { + return DynamicFromMap.create(this, name); + } + + @Override + public @NonNull ReadableType getType(@NonNull String name) { + Object value = mBackingMap.get(name); + if (value == null) { + return ReadableType.Null; + } else if (value instanceof Number) { + return ReadableType.Number; + } else if (value instanceof String) { + return ReadableType.String; + } else if (value instanceof Boolean) { + return ReadableType.Boolean; + } else if (value instanceof ReadableMap) { + return ReadableType.Map; + } else if (value instanceof ReadableArray) { + return ReadableType.Array; + } else if (value instanceof Dynamic) { + return ((Dynamic) value).getType(); + } else { + throw new IllegalArgumentException( + "Invalid value " + value.toString() + " for key " + name + "contained in JavaOnlyMap"); + } + } + + @Override + public @NonNull Iterator> getEntryIterator() { + return mBackingMap.entrySet().iterator(); + } + + @Override + public @NonNull ReadableMapKeySetIterator keySetIterator() { + return new ReadableMapKeySetIterator() { + Iterator> mIterator = mBackingMap.entrySet().iterator(); + + @Override + public boolean hasNextKey() { + return mIterator.hasNext(); + } + + @Override + public String nextKey() { + return mIterator.next().getKey(); + } + }; + } + + @Override + public void putBoolean(@NonNull String key, boolean value) { + mBackingMap.put(key, value); + } + + @Override + public void putDouble(@NonNull String key, double value) { + mBackingMap.put(key, value); + } + + @Override + public void putInt(@NonNull String key, int value) { + mBackingMap.put(key, new Double(value)); + } + + @Override + public void putLong(@NonNull String key, long value) { + mBackingMap.put(key, value); + } + + @Override + public void putString(@NonNull String key, @Nullable String value) { + mBackingMap.put(key, value); + } + + @Override + public void putNull(@NonNull String key) { + mBackingMap.put(key, null); + } + + @Override + public void putMap(@NonNull String key, @Nullable ReadableMap value) { + mBackingMap.put(key, value); + } + + @Override + public void merge(@NonNull ReadableMap source) { + mBackingMap.putAll(((JavaOnlyMap) source).mBackingMap); + } + + @Override + public WritableMap copy() { + final JavaOnlyMap target = new JavaOnlyMap(); + target.merge(this); + return target; + } + + @Override + public void putArray(@NonNull String key, @Nullable ReadableArray value) { + mBackingMap.put(key, value); + } + + @Override + public @NonNull HashMap toHashMap() { + return new HashMap(mBackingMap); + } + + @Override + public String toString() { + return mBackingMap.toString(); + } + + public void remove(@NonNull String key) { + mBackingMap.remove(key); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + JavaOnlyMap that = (JavaOnlyMap) o; + + if (mBackingMap != null ? !mBackingMap.equals(that.mBackingMap) : that.mBackingMap != null) + return false; + + return true; + } + + @Override + public int hashCode() { + return mBackingMap != null ? mBackingMap.hashCode() : 0; + } +} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaOnlyMap.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaOnlyMap.kt deleted file mode 100644 index e1a9456ddc059e..00000000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaOnlyMap.kt +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and 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.bridge - -import java.util.HashMap -import kotlin.collections.Iterator -import kotlin.collections.Map - -/** - * Java [HashMap] backed implementation of [ReadableMap] and [WritableMap] Instances of this class - * SHOULD NOT be used for communication between java and JS, use instances of [WritableNativeMap] - * created via [Arguments#createMap] or just [ReadableMap] interface if you want your "native" - * module method to take a map from JS as an argument. - * - * Main purpose for this class is to be used in java-only unit tests, but could also be used outside - * of tests in the code that operates only in java and needs to communicate with RN modules via - * their JS-exposed API. - */ -public class JavaOnlyMap() : ReadableMap, WritableMap { - public companion object { - @JvmStatic public fun of(vararg keysAndValues: Any?): JavaOnlyMap = JavaOnlyMap(*keysAndValues) - - @JvmStatic public fun from(map: Map): JavaOnlyMap = JavaOnlyMap(map) - - @JvmStatic - public fun deepClone(map: ReadableMap?): JavaOnlyMap { - val res = JavaOnlyMap() - if (map == null) { - return res - } - val iter = map.keySetIterator() - while (iter.hasNextKey()) { - val propKey = iter.nextKey() - val type = map.getType(propKey) - when (type) { - ReadableType.Null -> res.putNull(propKey) - ReadableType.Boolean -> res.putBoolean(propKey, map.getBoolean(propKey)) - ReadableType.Number -> res.putDouble(propKey, map.getDouble(propKey)) - ReadableType.String -> res.putString(propKey, map.getString(propKey)) - ReadableType.Map -> res.putMap(propKey, deepClone(checkNotNull(map.getMap(propKey)))) - ReadableType.Array -> - res.putArray(propKey, JavaOnlyArray.deepClone(map.getArray(propKey))) - } - } - return res - } - } - - private val backingMap: MutableMap = HashMap() - - /** @param keysAndValues keys and values, interleaved */ - private constructor(vararg keysAndValues: Any?) : this() { - require(keysAndValues.size % 2 == 0) { "You must provide the same number of keys and values" } - for (i in keysAndValues.indices step 2) { - var value = keysAndValues[i + 1] - if (value is Number) { - // all values from JS are doubles, so emulate that here for tests. - value = value.toDouble() - } - backingMap[keysAndValues[i] as String] = value - } - } - - override fun hasKey(name: String): Boolean = backingMap.containsKey(name) - - override fun isNull(name: String): Boolean = backingMap[name] == null - - override fun getBoolean(name: String): Boolean = backingMap[name] as Boolean - - override fun getDouble(name: String): Double = (backingMap[name] as Number).toDouble() - - override fun getInt(name: String): Int = (backingMap[name] as Number).toInt() - - override fun getLong(name: String): Long = (checkNotNull(backingMap[name] as Number).toLong()) - - override fun getString(name: String): String? = backingMap[name] as String? - - override fun getMap(name: String): ReadableMap? = backingMap[name] as ReadableMap? - - override fun getArray(name: String): ReadableArray? = backingMap[name] as ReadableArray? - - override fun getDynamic(name: String): Dynamic = DynamicFromMap.create(this, name) - - override fun getType(name: String): ReadableType { - val value = backingMap[name] - return when { - value == null -> ReadableType.Null - value is Number -> ReadableType.Number - value is String -> ReadableType.String - value is Boolean -> ReadableType.Boolean - value is ReadableMap -> ReadableType.Map - value is ReadableArray -> ReadableType.Array - value is Dynamic -> value.type - else -> { - throw IllegalArgumentException( - "Invalid value $value for key $name contained in JavaOnlyMap") - } - } - } - - override val entryIterator: Iterator> - get() = backingMap.entries.iterator() - - override fun keySetIterator(): ReadableMapKeySetIterator { - return object : ReadableMapKeySetIterator { - private val iterator = backingMap.entries.iterator() - - override fun hasNextKey(): Boolean = iterator.hasNext() - - override fun nextKey(): String = iterator.next().key - } - } - - override fun putBoolean(key: String, value: Boolean) { - backingMap[key] = value - } - - override fun putDouble(key: String, value: Double) { - backingMap[key] = value - } - - override fun putInt(key: String, value: Int) { - backingMap[key] = value.toDouble() - } - - override fun putLong(key: String, value: Long) { - backingMap[key] = value.toDouble() - } - - override fun putString(key: String, value: String?) { - backingMap[key] = value - } - - override fun putNull(key: String) { - backingMap[key] = null - } - - override fun putMap(key: String, value: ReadableMap?) { - backingMap[key] = value - } - - override fun merge(source: ReadableMap) { - backingMap.putAll((source as JavaOnlyMap).backingMap) - } - - override fun copy(): WritableMap { - val target = JavaOnlyMap() - target.merge(this) - return target - } - - override fun putArray(key: String, value: ReadableArray?) { - backingMap[key] = value - } - - public fun remove(key: String) { - backingMap.remove(key) - } - - override fun toHashMap(): HashMap = HashMap(backingMap) - - override fun toString(): String = backingMap.toString() - - override fun equals(other: Any?): Boolean { - return if (this === other) { - true - } else if (other == null || javaClass != other.javaClass) { - false - } else { - backingMap == (other as JavaOnlyMap).backingMap - } - } - - override fun hashCode(): Int = backingMap.hashCode() -} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableMap.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableMap.kt index 4920fb6dda4ee3..a8319fcecae4c1 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableMap.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableMap.kt @@ -16,7 +16,7 @@ import kotlin.collections.Map * Kotlin. */ public interface ReadableMap { - public val entryIterator: Iterator> + public val entryIterator: Iterator> public fun getArray(name: String): ReadableArray? @@ -42,5 +42,5 @@ public interface ReadableMap { public fun keySetIterator(): ReadableMapKeySetIterator - public fun toHashMap(): HashMap + public fun toHashMap(): HashMap } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableNativeMap.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableNativeMap.kt index 580282b5134317..68812fe11f6080 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableNativeMap.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableNativeMap.kt @@ -20,10 +20,10 @@ public open class ReadableNativeMap protected constructor() : NativeMap(), Reada private val keys: Array by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { importKeys().also { jniPassCounter++ } } - private val localMap: HashMap by + private val localMap: HashMap by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { val length = keys.size - val res = HashMap(length) + val res = HashMap(length) val values = importValues() jniPassCounter++ for (i in 0 until length) { @@ -157,7 +157,7 @@ public open class ReadableNativeMap protected constructor() : NativeMap(), Reada false } else localMap == other.localMap - override fun toHashMap(): HashMap { + override fun toHashMap(): HashMap { // we can almost just return getLocalMap(), but we need to convert nested arrays and maps to the // correct types first val hashMap = HashMap(localMap) From 147e6c34588ec87a7f97b0b0914deb4aeb2a8499 Mon Sep 17 00:00:00 2001 From: Grace Nichols Date: Wed, 6 Nov 2024 12:58:27 -0800 Subject: [PATCH 095/220] Revert D65540601: Undo breaking change of UiManager.eventDispatcher by solving circular dependency Differential Revision: D65540601 Original commit changeset: 4b1f62806baa Original Phabricator Diff: D65540601 fbshipit-source-id: 9abc3a663882634bb7d42b16bc95d8c2934a2ca5 --- packages/react-native/ReactAndroid/api/ReactAndroid.api | 4 +++- .../src/main/java/com/facebook/react/bridge/UIManager.kt | 3 +-- .../test/java/com/facebook/testutils/fakes/FakeUIManager.kt | 3 +-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 4f305598e644dd..f4565cf70f3236 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -1555,7 +1555,7 @@ public abstract interface class com/facebook/react/bridge/UIManager : com/facebo public abstract fun addUIManagerEventListener (Lcom/facebook/react/bridge/UIManagerListener;)V public abstract fun dispatchCommand (IILcom/facebook/react/bridge/ReadableArray;)V public abstract fun dispatchCommand (ILjava/lang/String;Lcom/facebook/react/bridge/ReadableArray;)V - public abstract fun getEventDispatcher ()Lcom/facebook/react/uimanager/events/EventDispatcher; + public abstract fun getEventDispatcher ()Ljava/lang/Object; public abstract fun initialize ()V public abstract fun invalidate ()V public abstract fun markActiveTouchForTag (II)V @@ -2615,6 +2615,7 @@ public class com/facebook/react/fabric/FabricUIManager : com/facebook/react/brid public fun dispatchCommand (ILjava/lang/String;Lcom/facebook/react/bridge/ReadableArray;)V public fun getColor (I[Ljava/lang/String;)I public fun getEventDispatcher ()Lcom/facebook/react/uimanager/events/EventDispatcher; + public synthetic fun getEventDispatcher ()Ljava/lang/Object; public fun getInspectorDataForInstance (ILandroid/view/View;)Lcom/facebook/react/bridge/ReadableMap; public fun getPerformanceCounters ()Ljava/util/Map; public fun getThemeData (I[F)Z @@ -5148,6 +5149,7 @@ public class com/facebook/react/uimanager/UIManagerModule : com/facebook/react/b public fun getDefaultEventTypes ()Lcom/facebook/react/bridge/WritableMap; public fun getDirectEventNamesResolver ()Lcom/facebook/react/uimanager/UIManagerModule$CustomEventNamesResolver; public fun getEventDispatcher ()Lcom/facebook/react/uimanager/events/EventDispatcher; + public synthetic fun getEventDispatcher ()Ljava/lang/Object; public fun getName ()Ljava/lang/String; public fun getPerformanceCounters ()Ljava/util/Map; public fun getUIImplementation ()Lcom/facebook/react/uimanager/UIImplementation; diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/UIManager.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/UIManager.kt index c0729f86de9566..f893f0ea209f8c 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/UIManager.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/UIManager.kt @@ -12,7 +12,6 @@ import androidx.annotation.AnyThread import androidx.annotation.UiThread import com.facebook.infer.annotation.ThreadConfined import com.facebook.react.common.annotations.UnstableReactNativeAPI -import com.facebook.react.uimanager.events.EventDispatcher @OptIn(UnstableReactNativeAPI::class) public interface UIManager : PerformanceCounter { @@ -79,7 +78,7 @@ public interface UIManager : PerformanceCounter { public fun dispatchCommand(reactTag: Int, commandId: String, commandArgs: ReadableArray?) /** @return the [EventDispatcher] object that is used by this class. */ - public val eventDispatcher: EventDispatcher + public val eventDispatcher: Any? /** * Used by native animated module to bypass the process of updating the values through the shadow diff --git a/packages/react-native/ReactAndroid/src/test/java/com/facebook/testutils/fakes/FakeUIManager.kt b/packages/react-native/ReactAndroid/src/test/java/com/facebook/testutils/fakes/FakeUIManager.kt index 49ba0848635f5e..b37693bd51fc17 100644 --- a/packages/react-native/ReactAndroid/src/test/java/com/facebook/testutils/fakes/FakeUIManager.kt +++ b/packages/react-native/ReactAndroid/src/test/java/com/facebook/testutils/fakes/FakeUIManager.kt @@ -17,7 +17,6 @@ import com.facebook.react.bridge.UIManagerListener import com.facebook.react.bridge.WritableMap import com.facebook.react.common.annotations.UnstableReactNativeAPI import com.facebook.react.fabric.interop.UIBlockViewResolver -import com.facebook.react.uimanager.events.EventDispatcher @OptIn(UnstableReactNativeAPI::class) class FakeUIManager : UIManager, UIBlockViewResolver { @@ -66,7 +65,7 @@ class FakeUIManager : UIManager, UIBlockViewResolver { error("Not yet implemented") } - override val eventDispatcher: EventDispatcher + override val eventDispatcher: Any? get() = TODO("Not yet implemented") override fun synchronouslyUpdateViewOnUIThread(reactTag: Int, props: ReadableMap?) { From c53d3e190109cb82f58bac3b8fec029628eaa04c Mon Sep 17 00:00:00 2001 From: Alan Lee Date: Wed, 6 Nov 2024 15:19:38 -0800 Subject: [PATCH 096/220] xplat/js/react-native-github/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/util/ReactFindViewUtil.java (#47431) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47431 Convert Java to Kotlin Changelog: [Internal] Reviewed By: tdn120 Differential Revision: D65430703 fbshipit-source-id: a1fcab2dd577fe67a1507c330466dabe7483c843 --- .../ReactAndroid/api/ReactAndroid.api | 18 +-- .../uimanager/util/ReactFindViewUtil.java | 138 ------------------ .../react/uimanager/util/ReactFindViewUtil.kt | 129 ++++++++++++++++ 3 files changed, 138 insertions(+), 147 deletions(-) delete mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/util/ReactFindViewUtil.java create mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/util/ReactFindViewUtil.kt diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index f4565cf70f3236..19d74b8100cc1e 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -6099,15 +6099,15 @@ public final class com/facebook/react/uimanager/style/Overflow$Companion { public final fun fromString (Ljava/lang/String;)Lcom/facebook/react/uimanager/style/Overflow; } -public class com/facebook/react/uimanager/util/ReactFindViewUtil { - public fun ()V - public static fun addViewListener (Lcom/facebook/react/uimanager/util/ReactFindViewUtil$OnViewFoundListener;)V - public static fun addViewsListener (Lcom/facebook/react/uimanager/util/ReactFindViewUtil$OnMultipleViewsFoundListener;Ljava/util/Set;)V - public static fun findView (Landroid/view/View;Lcom/facebook/react/uimanager/util/ReactFindViewUtil$OnViewFoundListener;)V - public static fun findView (Landroid/view/View;Ljava/lang/String;)Landroid/view/View; - public static fun notifyViewRendered (Landroid/view/View;)V - public static fun removeViewListener (Lcom/facebook/react/uimanager/util/ReactFindViewUtil$OnViewFoundListener;)V - public static fun removeViewsListener (Lcom/facebook/react/uimanager/util/ReactFindViewUtil$OnMultipleViewsFoundListener;)V +public final class com/facebook/react/uimanager/util/ReactFindViewUtil { + public static final field INSTANCE Lcom/facebook/react/uimanager/util/ReactFindViewUtil; + public static final fun addViewListener (Lcom/facebook/react/uimanager/util/ReactFindViewUtil$OnViewFoundListener;)V + public static final fun addViewsListener (Lcom/facebook/react/uimanager/util/ReactFindViewUtil$OnMultipleViewsFoundListener;Ljava/util/Set;)V + public static final fun findView (Landroid/view/View;Lcom/facebook/react/uimanager/util/ReactFindViewUtil$OnViewFoundListener;)V + public static final fun findView (Landroid/view/View;Ljava/lang/String;)Landroid/view/View; + public static final fun notifyViewRendered (Landroid/view/View;)V + public static final fun removeViewListener (Lcom/facebook/react/uimanager/util/ReactFindViewUtil$OnViewFoundListener;)V + public static final fun removeViewsListener (Lcom/facebook/react/uimanager/util/ReactFindViewUtil$OnMultipleViewsFoundListener;)V } public abstract interface class com/facebook/react/uimanager/util/ReactFindViewUtil$OnMultipleViewsFoundListener { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/util/ReactFindViewUtil.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/util/ReactFindViewUtil.java deleted file mode 100644 index ccfd1fa655a30c..00000000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/util/ReactFindViewUtil.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and 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.util; - -import android.view.View; -import android.view.ViewGroup; -import androidx.annotation.Nullable; -import com.facebook.infer.annotation.Nullsafe; -import com.facebook.react.R; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** Finds views in React Native view hierarchies */ -@Nullsafe(Nullsafe.Mode.LOCAL) -public class ReactFindViewUtil { - - private static final List mOnViewFoundListeners = new ArrayList<>(); - private static final Map> - mOnMultipleViewsFoundListener = new HashMap<>(); - - /** Callback to be invoked when a react native view has been found */ - public interface OnViewFoundListener { - - /** Returns the native id of the view of interest */ - String getNativeId(); - - /** - * Called when the view has been found - * - * @param view - */ - void onViewFound(View view); - } - - /** Callback to be invoked when all react native views with geiven NativeIds have been found */ - public interface OnMultipleViewsFoundListener { - - void onViewFound(View view, String nativeId); - } - - /** - * Finds a view that is tagged with {@param nativeId} as its nativeID prop under the {@param root} - * view hierarchy. Returns the view if found, null otherwise. - * - * @param root root of the view hierarchy from which to find the view - */ - public static @Nullable View findView(View root, String nativeId) { - String tag = getNativeId(root); - if (tag != null && tag.equals(nativeId)) { - return root; - } - - if (root instanceof ViewGroup) { - ViewGroup viewGroup = (ViewGroup) root; - for (int i = 0; i < viewGroup.getChildCount(); i++) { - View view = findView(viewGroup.getChildAt(i), nativeId); - if (view != null) { - return view; - } - } - } - - return null; - } - - /** - * Finds a view tagged with {@param onViewFoundListener}'s nativeID in the given {@param root} - * view hierarchy. If the view does not exist yet due to React Native's async layout, a listener - * will be added. When the view is found, the {@param onViewFoundListener} will be invoked. - * - * @param root root of the view hierarchy from which to find the view - */ - public static void findView(View root, OnViewFoundListener onViewFoundListener) { - View view = findView(root, onViewFoundListener.getNativeId()); - if (view != null) { - onViewFoundListener.onViewFound(view); - } - addViewListener(onViewFoundListener); - } - - /** - * Registers an OnViewFoundListener to be invoked when a view with a matching nativeID is found. - * Remove this listener using removeViewListener() if it's no longer needed. - */ - public static void addViewListener(OnViewFoundListener onViewFoundListener) { - mOnViewFoundListeners.add(onViewFoundListener); - } - - /** Removes an OnViewFoundListener previously registered with addViewListener(). */ - public static void removeViewListener(OnViewFoundListener onViewFoundListener) { - mOnViewFoundListeners.remove(onViewFoundListener); - } - - public static void addViewsListener(OnMultipleViewsFoundListener listener, Set ids) { - mOnMultipleViewsFoundListener.put(listener, ids); - } - - public static void removeViewsListener(OnMultipleViewsFoundListener listener) { - mOnMultipleViewsFoundListener.remove(listener); - } - - /** Invokes any listeners that are listening on this {@param view}'s native id */ - public static void notifyViewRendered(View view) { - String nativeId = getNativeId(view); - if (nativeId == null) { - return; - } - Iterator iterator = mOnViewFoundListeners.iterator(); - while (iterator.hasNext()) { - OnViewFoundListener listener = iterator.next(); - if (nativeId.equals(listener.getNativeId())) { - listener.onViewFound(view); - iterator.remove(); - } - } - for (Map.Entry> entry : - mOnMultipleViewsFoundListener.entrySet()) { - Set nativeIds = entry.getValue(); - if (nativeIds != null && nativeIds.contains(nativeId)) { - entry.getKey().onViewFound(view, nativeId); - } - } - } - - private static @Nullable String getNativeId(View view) { - Object tag = view.getTag(R.id.view_tag_native_id); - return tag instanceof String ? (String) tag : null; - } -} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/util/ReactFindViewUtil.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/util/ReactFindViewUtil.kt new file mode 100644 index 00000000000000..a0a5a2112d1173 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/util/ReactFindViewUtil.kt @@ -0,0 +1,129 @@ +/* + * Copyright (c) Meta Platforms, Inc. and 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.util + +import android.view.View +import android.view.ViewGroup +import com.facebook.react.R +import java.util.ArrayList +import java.util.HashMap + +/** Finds views in React Native view hierarchies */ +public object ReactFindViewUtil { + + private val onViewFoundListeners: MutableList = ArrayList() + private val onMultipleViewsFoundListener: MutableMap> = + HashMap() + + /** Callback to be invoked when a react native view has been found */ + public interface OnViewFoundListener { + /** Returns the native id of the view of interest */ + public fun getNativeId(): String + + /** + * Called when the view has been found + * + * @param view + */ + public fun onViewFound(view: View) + } + + /** Callback to be invoked when all react native views with geiven NativeIds have been found */ + public fun interface OnMultipleViewsFoundListener { + public fun onViewFound(view: View, nativeId: String) + } + + /** + * Finds a view that is tagged with {@param nativeId} as its nativeID prop under the {@param root} + * view hierarchy. Returns the view if found, null otherwise. + * + * @param root root of the view hierarchy from which to find the view + */ + @JvmStatic + public fun findView(root: View, nativeId: String): View? { + if (getNativeId(root) == nativeId) { + return root + } + + if (root is ViewGroup) { + for (i in 0..): Unit { + onMultipleViewsFoundListener[listener] = ids + } + + @JvmStatic + public fun removeViewsListener(listener: OnMultipleViewsFoundListener): Unit { + onMultipleViewsFoundListener.remove(listener) + } + + /** Invokes any listeners that are listening on this {@param view}'s native id */ + @JvmStatic + public fun notifyViewRendered(view: View): Unit { + val nativeId = getNativeId(view) ?: return + val iterator = onViewFoundListeners.iterator() + while (iterator.hasNext()) { + val listener = iterator.next() + if (nativeId == listener.getNativeId()) { + listener.onViewFound(view) + iterator.remove() + } + } + onMultipleViewsFoundListener.forEach { (listener, nativeIds) -> + if (nativeId in nativeIds) { + listener.onViewFound(view, nativeId) + } + } + } + + private fun getNativeId(view: View): String? { + val tag = view.getTag(R.id.view_tag_native_id) + return tag as? String + } +} From e6090df7dcf41938099bf0a87b1d73de08e70bda Mon Sep 17 00:00:00 2001 From: Alan Lee Date: Wed, 6 Nov 2024 15:43:58 -0800 Subject: [PATCH 097/220] xplat/js/react-native-github/packages/react-native/ReactAndroid/src/main/java/com/facebook/perftest/PerfTestConfig.java (#47440) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47440 Removing file as it does not seem to be used Changelog: [Internal] Reviewed By: cortinico Differential Revision: D65457514 fbshipit-source-id: 39efa12176fe65a491fa4285099134f2bf753159 --- .../com/facebook/perftest/PerfTestConfig.java | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/perftest/PerfTestConfig.java diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/perftest/PerfTestConfig.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/perftest/PerfTestConfig.java deleted file mode 100644 index 6f5d5cecc51533..00000000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/perftest/PerfTestConfig.java +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and 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.perftest; - -/** PerfTestConfig stub. */ -public class PerfTestConfig { - - public boolean isRunningInPerfTest() { - return false; - } -} From 50b3c2272f2f314ef1cc837b99bdbbfdd2b335cb Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Wed, 6 Nov 2024 17:58:27 -0800 Subject: [PATCH 098/220] ExceptionsManager: Fix soft error reporting (#47465) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47465 When you do @(NO), in objc, it creates an NSNumber. So this if condition actually evaluates to true: ``` if (@(NO)) ``` This means that all soft errors will get logged as fatals on ios. Changelog: [Internal] Created from CodeHub with https://fburl.com/edit-in-codehub Reviewed By: realsoelynn Differential Revision: D65551648 fbshipit-source-id: 99b5bcb5fa1b0b5dc8055a3c86fc983863a25526 --- packages/react-native/React/CoreModules/RCTExceptionsManager.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-native/React/CoreModules/RCTExceptionsManager.mm b/packages/react-native/React/CoreModules/RCTExceptionsManager.mm index 82b1d295f256c0..2a6f3a5c461a5e 100644 --- a/packages/react-native/React/CoreModules/RCTExceptionsManager.mm +++ b/packages/react-native/React/CoreModules/RCTExceptionsManager.mm @@ -155,7 +155,7 @@ - (void)reportFatal:(NSString *)message NSArray *> *stack = errorData[@"stack"]; double exceptionId = [errorData[@"id"] doubleValue]; - if (errorData[@"isFatal"]) { + if ([errorData[@"isFatal"] boolValue]) { [self reportFatal:message stack:stack exceptionId:exceptionId extraDataAsJSON:extraDataAsJSON]; } else { [self reportSoft:message stack:stack exceptionId:exceptionId extraDataAsJSON:extraDataAsJSON]; From bc3ea5c957837adc9d2973f0ecda81cb9dbcd8e4 Mon Sep 17 00:00:00 2001 From: David Vacca Date: Wed, 6 Nov 2024 18:04:31 -0800 Subject: [PATCH 099/220] Revert migration of ReactHorizontalScrollContainerViewManager to use ViewManagerInterface (#47472) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47472 using ViewManagerDelegates for ReactHorizontalScrollContainerViewManager which extends ReactClippingViewManager will introduce a bug (not updating props that are managed by ReactClippingViewManager) I'm reverting the migration and we should fix the bug in codegen This diff is a revert of D65428646 changelog: [internal] internal Reviewed By: sammy-SC, Abbondanzo Differential Revision: D65564730 fbshipit-source-id: ff183876321d4d36e51da8f38ff6f381207c7c3a --- .../react-native/ReactAndroid/api/ReactAndroid.api | 4 +--- .../ReactHorizontalScrollContainerViewManager.kt | 11 +---------- 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 19d74b8100cc1e..b8776e459e582b 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -6772,16 +6772,14 @@ public final class com/facebook/react/views/scroll/OnScrollDispatchHelper { public final fun onScrollChanged (II)Z } -public final class com/facebook/react/views/scroll/ReactHorizontalScrollContainerViewManager : com/facebook/react/views/view/ReactViewManager, com/facebook/react/viewmanagers/AndroidHorizontalScrollContentViewManagerInterface { +public final class com/facebook/react/views/scroll/ReactHorizontalScrollContainerViewManager : com/facebook/react/views/view/ReactViewManager { public static final field Companion Lcom/facebook/react/views/scroll/ReactHorizontalScrollContainerViewManager$Companion; public static final field REACT_CLASS Ljava/lang/String; public fun ()V public synthetic fun createViewInstance (ILcom/facebook/react/uimanager/ThemedReactContext;Lcom/facebook/react/uimanager/ReactStylesDiffMap;Lcom/facebook/react/uimanager/StateWrapper;)Landroid/view/View; public synthetic fun createViewInstance (Lcom/facebook/react/uimanager/ThemedReactContext;)Landroid/view/View; public fun createViewInstance (Lcom/facebook/react/uimanager/ThemedReactContext;)Lcom/facebook/react/views/view/ReactViewGroup; - public fun getDelegate ()Lcom/facebook/react/uimanager/ViewManagerDelegate; public fun getName ()Ljava/lang/String; - public synthetic fun setRemoveClippedSubviews (Landroid/view/View;Z)V } public final class com/facebook/react/views/scroll/ReactHorizontalScrollContainerViewManager$Companion { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollContainerViewManager.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollContainerViewManager.kt index a82070f629509a..c9d6c01e065df5 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollContainerViewManager.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollContainerViewManager.kt @@ -11,25 +11,16 @@ import com.facebook.react.module.annotations.ReactModule import com.facebook.react.uimanager.ReactStylesDiffMap import com.facebook.react.uimanager.StateWrapper import com.facebook.react.uimanager.ThemedReactContext -import com.facebook.react.uimanager.ViewManagerDelegate import com.facebook.react.uimanager.common.UIManagerType import com.facebook.react.uimanager.common.ViewUtil -import com.facebook.react.viewmanagers.AndroidHorizontalScrollContentViewManagerDelegate -import com.facebook.react.viewmanagers.AndroidHorizontalScrollContentViewManagerInterface import com.facebook.react.views.view.ReactViewGroup import com.facebook.react.views.view.ReactViewManager /** View manager for {@link ReactHorizontalScrollContainerView} components. */ @ReactModule(name = ReactHorizontalScrollContainerViewManager.REACT_CLASS) -public class ReactHorizontalScrollContainerViewManager : - ReactViewManager(), AndroidHorizontalScrollContentViewManagerInterface { +public class ReactHorizontalScrollContainerViewManager : ReactViewManager() { override public fun getName(): String = REACT_CLASS - private val delegate: ViewManagerDelegate = - AndroidHorizontalScrollContentViewManagerDelegate(this) - - public override fun getDelegate(): ViewManagerDelegate = delegate - protected override fun createViewInstance( reactTag: Int, context: ThemedReactContext, From 8e375f05050bea1c6a0d720b537401d8c0f2c6ab Mon Sep 17 00:00:00 2001 From: Phillip Pan Date: Wed, 6 Nov 2024 18:13:34 -0800 Subject: [PATCH 100/220] introduce internal API to reload bridgeless without surface restart (#47404) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47404 Changelog: [Internal] introducing an internal API to reload without starting up the surfaces that were stopped at time of reload Reviewed By: sammy-SC Differential Revision: D65461606 fbshipit-source-id: 9e58bebdc3e03ead7f91376b7aaba5c7944bddcf --- .../ios/ReactCommon/RCTHost+Internal.h | 1 + .../platform/ios/ReactCommon/RCTHost.mm | 52 ++++++++++++------- 2 files changed, 34 insertions(+), 19 deletions(-) diff --git a/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost+Internal.h b/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost+Internal.h index dd92a4e30f9b51..d039fa668f0462 100644 --- a/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost+Internal.h +++ b/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost+Internal.h @@ -14,6 +14,7 @@ - (void)registerSegmentWithId:(NSNumber *)segmentId path:(NSString *)path; - (void)setBundleURLProvider:(RCTHostBundleURLProvider)bundleURLProvider; - (void)setContextContainerHandler:(id)contextContainerHandler; +- (void)reload; @property (nonatomic, readonly) RCTBundleManager *bundleManager; diff --git a/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost.mm b/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost.mm index 55cd2553f951ee..b796713ed0670a 100644 --- a/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost.mm +++ b/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost.mm @@ -287,25 +287,7 @@ - (void)callFunctionOnJSModule:(NSString *)moduleName method:(NSString *)method - (void)didReceiveReloadCommand { - [_instance invalidate]; - _instance = nil; - if (_bundleURLProvider) { - [self _setBundleURL:_bundleURLProvider()]; - } - - _instance = [[RCTInstance alloc] initWithDelegate:self - jsRuntimeFactory:[self _provideJSEngine] - bundleManager:_bundleManager - turboModuleManagerDelegate:_turboModuleManagerDelegate - moduleRegistry:_moduleRegistry - parentInspectorTarget:_inspectorTarget.get() - launchOptions:_launchOptions]; - [_hostDelegate hostDidStart:self]; - - for (RCTFabricSurface *surface in [self _getAttachedSurfaces]) { - [surface resetWithSurfacePresenter:self.surfacePresenter]; - [_instance callFunctionOnBufferedRuntimeExecutor:[surface](facebook::jsi::Runtime &_) { [surface start]; }]; - } + [self _reloadWithShouldRestartSurfaces:YES]; } - (void)dealloc @@ -388,6 +370,11 @@ - (void)setContextContainerHandler:(id)contextConta _contextContainerHandler = contextContainerHandler; } +- (void)reload +{ + [self _reloadWithShouldRestartSurfaces:NO]; +} + #pragma mark - Private - (void)_attachSurface:(RCTFabricSurface *)surface @@ -432,6 +419,33 @@ - (void)_setBundleURL:(NSURL *)bundleURL RCTReloadCommandSetBundleURL(_bundleURL); } +- (void)_reloadWithShouldRestartSurfaces:(BOOL)shouldRestartSurfaces +{ + [_instance invalidate]; + _instance = nil; + if (_bundleURLProvider) { + [self _setBundleURL:_bundleURLProvider()]; + } + + _instance = [[RCTInstance alloc] initWithDelegate:self + jsRuntimeFactory:[self _provideJSEngine] + bundleManager:_bundleManager + turboModuleManagerDelegate:_turboModuleManagerDelegate + moduleRegistry:_moduleRegistry + parentInspectorTarget:_inspectorTarget.get() + launchOptions:_launchOptions]; + [_hostDelegate hostDidStart:self]; + + for (RCTFabricSurface *surface in [self _getAttachedSurfaces]) { + [surface resetWithSurfacePresenter:self.surfacePresenter]; + if (shouldRestartSurfaces) { + [_instance callFunctionOnBufferedRuntimeExecutor:[surface](facebook::jsi::Runtime &_) { [surface start]; }]; + } + } +} + +#pragma mark - jsinspector_modern + - (jsinspector_modern::HostTarget *)inspectorTarget { return _inspectorTarget.get(); From 0ca2ba082de06c054b23ce96692fbcd1c45d9931 Mon Sep 17 00:00:00 2001 From: Sam Zhou Date: Wed, 6 Nov 2024 18:14:19 -0800 Subject: [PATCH 101/220] Fix final few problematic `React.ElementRef` in react-native (#47473) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47473 For example, ``` declare function C(ref: React.RefSetter>): React.Node; type T = React.ElementRef ``` Previously Flow will evaluate `T` to `Set`, by automatically replacing generic types with their upper bounds. But in the future it might be replaced with `empty`. This diff cleans up instances like this in react-native codebase. Changelog: [Internal] Reviewed By: alexmckenley Differential Revision: D65562571 fbshipit-source-id: bca2f4f022a5a23a5aa40886f5661899cb315f2e --- .../Animated/components/AnimatedSectionList.js | 4 +++- .../__snapshots__/public-api-test.js.snap | 2 +- .../js/examples/FlatList/FlatList-basic.js | 14 +++----------- .../js/examples/Touchable/TouchableExample.js | 7 +++---- 4 files changed, 10 insertions(+), 17 deletions(-) diff --git a/packages/react-native/Libraries/Animated/components/AnimatedSectionList.js b/packages/react-native/Libraries/Animated/components/AnimatedSectionList.js index 5b2f80c2c53eab..c7b47147931967 100644 --- a/packages/react-native/Libraries/Animated/components/AnimatedSectionList.js +++ b/packages/react-native/Libraries/Animated/components/AnimatedSectionList.js @@ -8,6 +8,7 @@ * @format */ +import type {SectionBase} from '../../Lists/SectionList'; import type {AnimatedComponentType} from '../createAnimatedComponent'; import SectionList from '../../Lists/SectionList'; @@ -16,5 +17,6 @@ import * as React from 'react'; export default (createAnimatedComponent(SectionList): AnimatedComponentType< React.ElementConfig, - React.ElementRef, + // $FlowExpectedError[unclear-type] + SectionList>, >); diff --git a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap index 9412916deb8427..0dcbaf39eb3447 100644 --- a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap +++ b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap @@ -707,7 +707,7 @@ declare export default typeof AnimatedScrollView; exports[`public API should not change unintentionally Libraries/Animated/components/AnimatedSectionList.js 1`] = ` "declare export default AnimatedComponentType< React.ElementConfig, - React.ElementRef, + SectionList>, >; " `; diff --git a/packages/rn-tester/js/examples/FlatList/FlatList-basic.js b/packages/rn-tester/js/examples/FlatList/FlatList-basic.js index 0d7860a8a4d7bc..84d6e614917fce 100644 --- a/packages/rn-tester/js/examples/FlatList/FlatList-basic.js +++ b/packages/rn-tester/js/examples/FlatList/FlatList-basic.js @@ -12,8 +12,7 @@ import type {Item} from '../../components/ListExampleShared'; import type {RNTesterModuleExample} from '../../types/RNTesterTypes'; -import type {AnimatedComponentType} from 'react-native/Libraries/Animated/createAnimatedComponent'; -import typeof FlatListType from 'react-native/Libraries/Lists/FlatList'; +import type FlatList from 'react-native/Libraries/Lists/FlatList'; import type {RenderItemProps} from 'react-native/Libraries/Lists/VirtualizedList'; import { @@ -300,14 +299,7 @@ class FlatListExample extends React.PureComponent { ); } - _captureRef = ( - ref: React.ElementRef< - AnimatedComponentType< - React.ElementConfig, - React.ElementRef, - >, - > | null, - ) => { + _captureRef = (ref: FlatList | null) => { this._listRef = ref; }; // $FlowFixMe[missing-local-annot] @@ -431,7 +423,7 @@ class FlatListExample extends React.PureComponent { })); }; - _listRef: React.ElementRef | null; + _listRef: FlatList | null; } const styles = StyleSheet.create({ diff --git a/packages/rn-tester/js/examples/Touchable/TouchableExample.js b/packages/rn-tester/js/examples/Touchable/TouchableExample.js index ca97f24a11886f..aa069309b0995d 100644 --- a/packages/rn-tester/js/examples/Touchable/TouchableExample.js +++ b/packages/rn-tester/js/examples/Touchable/TouchableExample.js @@ -314,7 +314,7 @@ function TouchableNativeMethodChecker< T: component(ref?: React.RefSetter, ...any), >(props: {|Component: T, name: string|}): React.Node { const [status, setStatus] = useState(null); - const ref = useRef>(null); + const ref = useRef(null); useEffect(() => { setStatus(ref.current != null && typeof ref.current.measure === 'function'); @@ -557,9 +557,8 @@ const TouchableTouchSoundDisabled = () => { ); }; -// $FlowFixMe[missing-local-annot] -function TouchableOnFocus, ...any)>() { - const ref = useRef | {focus: Function}>(null); +function TouchableOnFocus() { + const ref = useRef(null); const [isFocused, setIsFocused] = useState(false); const [focusStatus, setFocusStatus] = useState( 'This touchable is not focused.', From 46526fc2fe1dd0ce937fad35469b64b9fb05eaa2 Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Wed, 6 Nov 2024 18:32:38 -0800 Subject: [PATCH 102/220] Stable API - Make classes inside `com.facebook.react.views.progressbar` internal (#47376) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47376 This makes several classes inside `com.facebook.react.views.progressbar` internal: - ReactProgressBarViewManager - ProgressBarShadowNode - ProgressBarContainerView Those classes should have not been exposed in the first place and users should not depend on them directly. Marked as Breaking but verified that there are no meaningful usages in OSS. Changelog: [Android] [Breaking] - Stable API - Make classes inside `com.facebook.react.views.progressbar` internal Reviewed By: javache Differential Revision: D65423290 fbshipit-source-id: dc98fdca996eb648593adb2c32787cbf0d878e3e --- .../ReactAndroid/api/ReactAndroid.api | 45 ----------------- .../ReactAndroid/gradle.properties | 4 +- .../progressbar/ProgressBarContainerView.kt | 2 +- .../progressbar/ProgressBarShadowNode.kt | 4 +- .../ReactProgressBarViewManager.kt | 50 +++++++++---------- 5 files changed, 31 insertions(+), 74 deletions(-) diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index b8776e459e582b..5c8c46bf4035f3 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -6714,51 +6714,6 @@ public abstract interface class com/facebook/react/views/modal/ReactModalHostVie public abstract fun onRequestClose (Landroid/content/DialogInterface;)V } -public final class com/facebook/react/views/progressbar/ProgressBarContainerView : android/widget/FrameLayout { - public static final field MAX_PROGRESS I - public fun (Landroid/content/Context;)V -} - -public final class com/facebook/react/views/progressbar/ProgressBarShadowNode : com/facebook/react/uimanager/LayoutShadowNode, com/facebook/yoga/YogaMeasureFunction { - public fun ()V - public final fun getStyle ()Ljava/lang/String; - public fun measure (Lcom/facebook/yoga/YogaNode;FLcom/facebook/yoga/YogaMeasureMode;FLcom/facebook/yoga/YogaMeasureMode;)J - public final fun setStyle (Ljava/lang/String;)V -} - -public final class com/facebook/react/views/progressbar/ReactProgressBarViewManager : com/facebook/react/uimanager/BaseViewManager, com/facebook/react/viewmanagers/AndroidProgressBarManagerInterface { - public static final field Companion Lcom/facebook/react/views/progressbar/ReactProgressBarViewManager$Companion; - public static final field REACT_CLASS Ljava/lang/String; - public fun ()V - public synthetic fun createShadowNodeInstance ()Lcom/facebook/react/uimanager/ReactShadowNode; - public fun createShadowNodeInstance ()Lcom/facebook/react/views/progressbar/ProgressBarShadowNode; - public synthetic fun createViewInstance (Lcom/facebook/react/uimanager/ThemedReactContext;)Landroid/view/View; - public fun getName ()Ljava/lang/String; - public fun getShadowNodeClass ()Ljava/lang/Class; - public fun measure (Landroid/content/Context;Lcom/facebook/react/bridge/ReadableMap;Lcom/facebook/react/bridge/ReadableMap;Lcom/facebook/react/bridge/ReadableMap;FLcom/facebook/yoga/YogaMeasureMode;FLcom/facebook/yoga/YogaMeasureMode;[F)J - public synthetic fun onAfterUpdateTransaction (Landroid/view/View;)V - public synthetic fun setAnimating (Landroid/view/View;Z)V - public fun setAnimating (Lcom/facebook/react/views/progressbar/ProgressBarContainerView;Z)V - public synthetic fun setColor (Landroid/view/View;Ljava/lang/Integer;)V - public fun setColor (Lcom/facebook/react/views/progressbar/ProgressBarContainerView;Ljava/lang/Integer;)V - public synthetic fun setIndeterminate (Landroid/view/View;Z)V - public fun setIndeterminate (Lcom/facebook/react/views/progressbar/ProgressBarContainerView;Z)V - public synthetic fun setProgress (Landroid/view/View;D)V - public fun setProgress (Lcom/facebook/react/views/progressbar/ProgressBarContainerView;D)V - public synthetic fun setStyleAttr (Landroid/view/View;Ljava/lang/String;)V - public fun setStyleAttr (Lcom/facebook/react/views/progressbar/ProgressBarContainerView;Ljava/lang/String;)V - public synthetic fun setTestID (Landroid/view/View;Ljava/lang/String;)V - public fun setTestID (Lcom/facebook/react/views/progressbar/ProgressBarContainerView;Ljava/lang/String;)V - public synthetic fun setTypeAttr (Landroid/view/View;Ljava/lang/String;)V - public fun setTypeAttr (Lcom/facebook/react/views/progressbar/ProgressBarContainerView;Ljava/lang/String;)V - public synthetic fun updateExtraData (Landroid/view/View;Ljava/lang/Object;)V - public fun updateExtraData (Lcom/facebook/react/views/progressbar/ProgressBarContainerView;Ljava/lang/Object;)V -} - -public final class com/facebook/react/views/progressbar/ReactProgressBarViewManager$Companion { - public final fun createProgressBar (Landroid/content/Context;I)Landroid/widget/ProgressBar; -} - public abstract interface class com/facebook/react/views/scroll/FpsListener { public abstract fun disable (Ljava/lang/String;)V public abstract fun enable (Ljava/lang/String;)V diff --git a/packages/react-native/ReactAndroid/gradle.properties b/packages/react-native/ReactAndroid/gradle.properties index c4947b2bd07a58..8866d933a00e53 100644 --- a/packages/react-native/ReactAndroid/gradle.properties +++ b/packages/react-native/ReactAndroid/gradle.properties @@ -11,7 +11,9 @@ react.internal.disableJavaVersionAlignment=true # We ignore: # - BuildConfig classes because they are generated and not part of the public API -binaryCompatibilityValidator.ignoredClasses=com.facebook.react.BuildConfig +binaryCompatibilityValidator.ignoredClasses=com.facebook.react.BuildConfig,\ + com.facebook.react.views.progressbar.ReactProgressBarViewManager$$PropsSetter,\ + com.facebook.react.views.progressbar.ProgressBarShadowNode$$PropsSetter binaryCompatibilityValidator.ignoredPackages=com.facebook.debug,\ com.facebook.fbreact,\ diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/progressbar/ProgressBarContainerView.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/progressbar/ProgressBarContainerView.kt index c5531cc69fd900..c24b2540fd5760 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/progressbar/ProgressBarContainerView.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/progressbar/ProgressBarContainerView.kt @@ -18,7 +18,7 @@ import com.facebook.react.bridge.JSApplicationIllegalArgumentException * Controls an enclosing [ProgressBar]. Exists so that the [ProgressBar] can be recreated if the * style would change. */ -public class ProgressBarContainerView(context: Context) : FrameLayout(context) { +internal class ProgressBarContainerView(context: Context) : FrameLayout(context) { internal var color: Int? = null internal var indeterminate = true diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/progressbar/ProgressBarShadowNode.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/progressbar/ProgressBarShadowNode.kt index 791ab36a3404da..8f35b5cbc4fb4c 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/progressbar/ProgressBarShadowNode.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/progressbar/ProgressBarShadowNode.kt @@ -21,7 +21,7 @@ import com.facebook.yoga.YogaNode * Node responsible for holding the style of the ProgressBar, see under [ ] for possible styles. * ReactProgressBarViewManager manages how this style is applied to the ProgressBar. */ -public class ProgressBarShadowNode : LayoutShadowNode(), YogaMeasureFunction { +internal class ProgressBarShadowNode : LayoutShadowNode(), YogaMeasureFunction { private val height: SparseIntArray = SparseIntArray() private val width: SparseIntArray = SparseIntArray() private val measured: MutableSet = HashSet() @@ -31,7 +31,7 @@ public class ProgressBarShadowNode : LayoutShadowNode(), YogaMeasureFunction { } @set:ReactProp(name = ReactProgressBarViewManager.PROP_STYLE) - public var style: String? = ReactProgressBarViewManager.DEFAULT_STYLE + var style: String? = ReactProgressBarViewManager.DEFAULT_STYLE set(value) { field = value ?: ReactProgressBarViewManager.DEFAULT_STYLE } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/progressbar/ReactProgressBarViewManager.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/progressbar/ReactProgressBarViewManager.kt index 69ad62ac8eb264..b254df069e64b0 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/progressbar/ReactProgressBarViewManager.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/progressbar/ReactProgressBarViewManager.kt @@ -34,7 +34,7 @@ import java.util.WeakHashMap * a new one with the style given. */ @ReactModule(name = ReactProgressBarViewManager.REACT_CLASS) -public class ReactProgressBarViewManager : +internal class ReactProgressBarViewManager : BaseViewManager(), AndroidProgressBarManagerInterface { private val measuredStyles = WeakHashMap>() @@ -42,60 +42,60 @@ public class ReactProgressBarViewManager : private val delegate: ViewManagerDelegate = AndroidProgressBarManagerDelegate(this) - public override fun getName(): String = REACT_CLASS + override fun getName(): String = REACT_CLASS - protected override fun createViewInstance(context: ThemedReactContext): ProgressBarContainerView { + override fun createViewInstance(context: ThemedReactContext): ProgressBarContainerView { return ProgressBarContainerView(context) } @ReactProp(name = PROP_STYLE) - public override fun setStyleAttr(view: ProgressBarContainerView, styleName: String?) { + override fun setStyleAttr(view: ProgressBarContainerView, styleName: String?) { view.setStyle(styleName) } @ReactProp(name = ViewProps.COLOR, customType = "Color") - public override fun setColor(view: ProgressBarContainerView, color: Int?) { + override fun setColor(view: ProgressBarContainerView, color: Int?) { view.color = color } @ReactProp(name = PROP_INDETERMINATE) - public override fun setIndeterminate(view: ProgressBarContainerView, indeterminate: Boolean) { + override fun setIndeterminate(view: ProgressBarContainerView, indeterminate: Boolean) { view.indeterminate = indeterminate } @ReactProp(name = PROP_PROGRESS) - public override fun setProgress(view: ProgressBarContainerView, progress: Double) { + override fun setProgress(view: ProgressBarContainerView, progress: Double) { view.progress = progress } @ReactProp(name = PROP_ANIMATING) - public override fun setAnimating(view: ProgressBarContainerView, animating: Boolean) { + override fun setAnimating(view: ProgressBarContainerView, animating: Boolean) { view.animating = animating } - public override fun setTestID(view: ProgressBarContainerView, value: String?) { + override fun setTestID(view: ProgressBarContainerView, value: String?) { super.setTestId(view, value) } @ReactProp(name = PROP_ATTR) - public override fun setTypeAttr(view: ProgressBarContainerView, value: String?): Unit = Unit + override fun setTypeAttr(view: ProgressBarContainerView, value: String?): Unit = Unit - public override fun createShadowNodeInstance(): ProgressBarShadowNode = ProgressBarShadowNode() + override fun createShadowNodeInstance(): ProgressBarShadowNode = ProgressBarShadowNode() - public override fun getShadowNodeClass(): Class = + override fun getShadowNodeClass(): Class = ProgressBarShadowNode::class.java - public override fun updateExtraData(root: ProgressBarContainerView, extraData: Any) { + override fun updateExtraData(root: ProgressBarContainerView, extraData: Any) { // do nothing } - protected override fun onAfterUpdateTransaction(view: ProgressBarContainerView) { + override fun onAfterUpdateTransaction(view: ProgressBarContainerView) { view.apply() } - protected override fun getDelegate(): ViewManagerDelegate = delegate + override fun getDelegate(): ViewManagerDelegate = delegate - public override fun measure( + override fun measure( context: Context, localData: ReadableMap, props: ReadableMap, @@ -119,15 +119,15 @@ public class ReactProgressBarViewManager : toDIPFromPixel(value.first.toFloat()), toDIPFromPixel(value.second.toFloat())) } - public companion object { - public const val REACT_CLASS: String = "AndroidProgressBar" + companion object { + const val REACT_CLASS: String = "AndroidProgressBar" - internal const val PROP_STYLE: String = "styleAttr" - internal const val PROP_ATTR: String = "typeAttr" - internal const val PROP_INDETERMINATE: String = "indeterminate" - internal const val PROP_PROGRESS: String = "progress" - internal const val PROP_ANIMATING: String = "animating" - internal const val DEFAULT_STYLE: String = "Normal" + const val PROP_STYLE: String = "styleAttr" + const val PROP_ATTR: String = "typeAttr" + const val PROP_INDETERMINATE: String = "indeterminate" + const val PROP_PROGRESS: String = "progress" + const val PROP_ANIMATING: String = "animating" + const val DEFAULT_STYLE: String = "Normal" private val progressBarCtorLock = Any() @@ -136,7 +136,7 @@ public class ReactProgressBarViewManager : * ProgressBar constructor that may cause crashes when two ProgressBars are constructed at the * same time on two different threads. This static ctor wrapper protects against that. */ - public fun createProgressBar(context: Context?, style: Int): ProgressBar { + fun createProgressBar(context: Context?, style: Int): ProgressBar { synchronized(progressBarCtorLock) { return ProgressBar(context, null, style) } From 61e660b40ee014acb2da5d833d60912a3965ac7c Mon Sep 17 00:00:00 2001 From: Liron Yahdav Date: Wed, 6 Nov 2024 20:15:08 -0800 Subject: [PATCH 103/220] Expose some VirtualizedList functions to allow creating VirtualizedListContextProvider outside of VirtualizedList (#47463) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47463 Note this is just a temporary approach which will be cleaned up later. Changelog: [Internal] Reviewed By: yungsters Differential Revision: D65514902 fbshipit-source-id: f722031c5cd34eb1400b3f732fd94c0b03d5434d --- .../Lists/VirtualizedList.js | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/packages/virtualized-lists/Lists/VirtualizedList.js b/packages/virtualized-lists/Lists/VirtualizedList.js index 2b68de589a5c63..bb4fc3d32d0e87 100644 --- a/packages/virtualized-lists/Lists/VirtualizedList.js +++ b/packages/virtualized-lists/Lists/VirtualizedList.js @@ -1653,6 +1653,10 @@ class VirtualizedList extends StateSafePureComponent { }; }; + unstable_onScroll(e: Object) { + this._onScroll(e); + } + _onScroll = (e: Object) => { this._nestedChildLists.forEach(childList => { childList._onScroll(e); @@ -1805,6 +1809,10 @@ class VirtualizedList extends StateSafePureComponent { return hiPri; } + unstable_onScrollBeginDrag(e: ScrollEvent) { + this._onScrollBeginDrag(e); + } + _onScrollBeginDrag = (e: ScrollEvent): void => { this._nestedChildLists.forEach(childList => { childList._onScrollBeginDrag(e); @@ -1816,6 +1824,10 @@ class VirtualizedList extends StateSafePureComponent { this.props.onScrollBeginDrag && this.props.onScrollBeginDrag(e); }; + unstable_onScrollEndDrag(e: ScrollEvent) { + this._onScrollEndDrag(e); + } + _onScrollEndDrag = (e: ScrollEvent): void => { this._nestedChildLists.forEach(childList => { childList._onScrollEndDrag(e); @@ -1828,6 +1840,10 @@ class VirtualizedList extends StateSafePureComponent { this.props.onScrollEndDrag && this.props.onScrollEndDrag(e); }; + unstable_onMomentumScrollBegin(e: ScrollEvent) { + this._onMomentumScrollBegin(e); + } + _onMomentumScrollBegin = (e: ScrollEvent): void => { this._nestedChildLists.forEach(childList => { childList._onMomentumScrollBegin(e); @@ -1835,6 +1851,10 @@ class VirtualizedList extends StateSafePureComponent { this.props.onMomentumScrollBegin && this.props.onMomentumScrollBegin(e); }; + unstable_onMomentumScrollEnd(e: ScrollEvent) { + this._onMomentumScrollEnd(e); + } + _onMomentumScrollEnd = (e: ScrollEvent): void => { this._nestedChildLists.forEach(childList => { childList._onMomentumScrollEnd(e); From 7a6c7a462a7898e13327438a6603d83a39147abb Mon Sep 17 00:00:00 2001 From: Mathieu Acthernoene Date: Wed, 6 Nov 2024 21:09:36 -0800 Subject: [PATCH 104/220] feat(android): Edge-to-edge Modal (navigationBarTranslucent prop) (#47254) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: The future of Android is [edge-to-edge](https://github.com/react-native-community/discussions-and-proposals/discussions/827) and to make the React Native developer experience seamless in this regard, the ecosystem needs to transition from “opaque system bars by default” to “edge-to-edge by default.” Currently, there's no easy way to have edge-to-edge modals, as they are implemented using `Dialog` instances (a separate `Window`) and only provide a `statusBarTranslucent` prop. I tried to implement it in [`react-native-edge-to-edge`](https://github.com/zoontek/react-native-edge-to-edge) by listening to the `topShow` `UIManager` event. But if it works well when there's a defined animation, we can see a quick jump when there's none, because there's too much delay before the event, and edge-to-edge cannot be applied quick enough to the dialog window. ### react-native-edge-to-edge implem with animation (no jump) https://github.com/user-attachments/assets/4933a102-87a5-40e4-98d9-47f8c0817592 ### react-native-edge-to-edge implem without animation (jump) https://github.com/user-attachments/assets/e4675589-08fe-44fe-b9d8-0a6b3552b461 --- For this reason, and because listening to event feels a bit hacky, I think it will be better to go for a new prop directly on RN Modal component: `navigationBarTranslucent` > [!NOTE] > `navigationBarTranslucent` cannot be used without `statusBarTranslucent`, as setting both enable edge-to-edge, like [AndroidX would do](https://github.com/androidx/androidx/blob/androidx-main/activity/activity/src/main/java/androidx/activity/EdgeToEdge.kt) and it would requires extra (and unecessary, given the direction Android is taking) work to find a way to keep the status bar opaque but the navigation bar transparent that work on Android 6 to 15+ ### Additional infos - Colors used for the buttons navigation bar in the PR are the default Android ones ([light](https://github.com/androidx/androidx/blob/androidx-main/activity/activity/src/main/java/androidx/activity/EdgeToEdge.kt#L37) and [dark](https://github.com/androidx/androidx/blob/androidx-main/activity/activity/src/main/java/androidx/activity/EdgeToEdge.kt#L42)) - Compared to the Google implementation, the light scrim is applied from `O_MR1` to `Q` (and not `O` to `Q`) as the [`android:windowLightNavigationBar`](https://developer.android.com/reference/android/R.attr#windowLightNavigationBar) style attribute is not available on `O` (it can only be applied programmatically on API 26). ## Changelog: [ANDROID] [ADDED] - Add navigationBarTranslucent prop to Modal component Pull Request resolved: https://github.com/facebook/react-native/pull/47254 Test Plan: Run the tester app, toggle `navigationBarTranslucent`: https://github.com/user-attachments/assets/286d173b-35a5-4951-9105-f9f7562d6764 ----- did some additional testing with RNTester using different justification |flex-start|flex-end| |https://pxl.cl/5Rd20|https://pxl.cl/5Rd21| Reviewed By: javache Differential Revision: D65103501 Pulled By: alanleedev fbshipit-source-id: ef6473ecd785976d3e26c77bbc212222ec96c9f2 --- .../react-native/Libraries/Modal/Modal.d.ts | 5 +++ .../react-native/Libraries/Modal/Modal.js | 17 ++++++++ .../__snapshots__/public-api-test.js.snap | 1 + .../ReactAndroid/api/ReactAndroid.api | 6 +++ .../views/modal/ReactModalHostManager.kt | 8 ++++ .../react/views/modal/ReactModalHostView.kt | 14 ++++++- .../facebook/react/views/view/WindowUtil.kt | 42 +++++++++++++++++++ .../RCTModalHostViewNativeComponent.js | 8 ++++ .../js/examples/Modal/ModalPresentation.js | 23 +++++++++- 9 files changed, 122 insertions(+), 2 deletions(-) diff --git a/packages/react-native/Libraries/Modal/Modal.d.ts b/packages/react-native/Libraries/Modal/Modal.d.ts index 9548d81de09624..21fca65479c1f1 100644 --- a/packages/react-native/Libraries/Modal/Modal.d.ts +++ b/packages/react-native/Libraries/Modal/Modal.d.ts @@ -101,6 +101,11 @@ export interface ModalPropsAndroid { * Determines whether your modal should go under the system statusbar. */ statusBarTranslucent?: boolean | undefined; + + /** + * Determines whether your modal should go under the system navigationbar. + */ + navigationBarTranslucent?: boolean | undefined; } export type ModalProps = ModalBaseProps & diff --git a/packages/react-native/Libraries/Modal/Modal.js b/packages/react-native/Libraries/Modal/Modal.js index cc0a0622ff6b36..345191ab52850f 100644 --- a/packages/react-native/Libraries/Modal/Modal.js +++ b/packages/react-native/Libraries/Modal/Modal.js @@ -95,6 +95,14 @@ export type Props = $ReadOnly<{| */ statusBarTranslucent?: ?boolean, + /** + * The `navigationBarTranslucent` prop determines whether your modal should go under + * the system navigationbar. + * + * See https://reactnative.dev/docs/modal.html#navigationbartranslucent-android + */ + navigationBarTranslucent?: ?boolean, + /** * The `hardwareAccelerated` prop controls whether to force hardware * acceleration for the underlying window. @@ -176,6 +184,14 @@ function confirmProps(props: Props) { `Modal with '${props.presentationStyle}' presentation style and 'transparent' value is not supported.`, ); } + if ( + props.navigationBarTranslucent === true && + props.statusBarTranslucent !== true + ) { + console.warn( + 'Modal with translucent navigation bar and without translucent status bar is not supported.', + ); + } } } @@ -301,6 +317,7 @@ class Modal extends React.Component { onDismiss={onDismiss} visible={this.props.visible} statusBarTranslucent={this.props.statusBarTranslucent} + navigationBarTranslucent={this.props.navigationBarTranslucent} identifier={this._identifier} style={styles.modal} // $FlowFixMe[method-unbinding] added when improving typing for this parameters diff --git a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap index 0dcbaf39eb3447..1e595f18710dba 100644 --- a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap +++ b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap @@ -6411,6 +6411,7 @@ export type Props = $ReadOnly<{| ), transparent?: ?boolean, statusBarTranslucent?: ?boolean, + navigationBarTranslucent?: ?boolean, hardwareAccelerated?: ?boolean, visible?: ?boolean, onRequestClose?: ?DirectEventHandler, diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 5c8c46bf4035f3..67c7612eb31243 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -6264,6 +6264,7 @@ public abstract interface class com/facebook/react/viewmanagers/ModalHostViewMan public abstract fun setAnimationType (Landroid/view/View;Ljava/lang/String;)V public abstract fun setHardwareAccelerated (Landroid/view/View;Z)V public abstract fun setIdentifier (Landroid/view/View;I)V + public abstract fun setNavigationBarTranslucent (Landroid/view/View;Z)V public abstract fun setPresentationStyle (Landroid/view/View;Ljava/lang/String;)V public abstract fun setStatusBarTranslucent (Landroid/view/View;Z)V public abstract fun setSupportedOrientations (Landroid/view/View;Lcom/facebook/react/bridge/ReadableArray;)V @@ -6647,6 +6648,8 @@ public final class com/facebook/react/views/modal/ReactModalHostManager : com/fa public fun setHardwareAccelerated (Lcom/facebook/react/views/modal/ReactModalHostView;Z)V public synthetic fun setIdentifier (Landroid/view/View;I)V public fun setIdentifier (Lcom/facebook/react/views/modal/ReactModalHostView;I)V + public synthetic fun setNavigationBarTranslucent (Landroid/view/View;Z)V + public fun setNavigationBarTranslucent (Lcom/facebook/react/views/modal/ReactModalHostView;Z)V public synthetic fun setPresentationStyle (Landroid/view/View;Ljava/lang/String;)V public fun setPresentationStyle (Lcom/facebook/react/views/modal/ReactModalHostView;Ljava/lang/String;)V public synthetic fun setStatusBarTranslucent (Landroid/view/View;Z)V @@ -6675,6 +6678,7 @@ public final class com/facebook/react/views/modal/ReactModalHostView : android/v public fun getChildCount ()I public final fun getEventDispatcher ()Lcom/facebook/react/uimanager/events/EventDispatcher; public final fun getHardwareAccelerated ()Z + public final fun getNavigationBarTranslucent ()Z public final fun getOnRequestCloseListener ()Lcom/facebook/react/views/modal/ReactModalHostView$OnRequestCloseListener; public final fun getOnShowListener ()Landroid/content/DialogInterface$OnShowListener; public final fun getStateWrapper ()Lcom/facebook/react/uimanager/StateWrapper; @@ -6690,6 +6694,7 @@ public final class com/facebook/react/views/modal/ReactModalHostView : android/v public final fun setEventDispatcher (Lcom/facebook/react/uimanager/events/EventDispatcher;)V public final fun setHardwareAccelerated (Z)V public fun setId (I)V + public final fun setNavigationBarTranslucent (Z)V public final fun setOnRequestCloseListener (Lcom/facebook/react/views/modal/ReactModalHostView$OnRequestCloseListener;)V public final fun setOnShowListener (Landroid/content/DialogInterface$OnShowListener;)V public final fun setStateWrapper (Lcom/facebook/react/uimanager/StateWrapper;)V @@ -7965,5 +7970,6 @@ public final class com/facebook/react/views/view/ViewGroupClickEvent : com/faceb public final class com/facebook/react/views/view/WindowUtilKt { public static final fun setStatusBarTranslucency (Landroid/view/Window;Z)V public static final fun setStatusBarVisibility (Landroid/view/Window;Z)V + public static final fun setSystemBarsTranslucency (Landroid/view/Window;Z)V } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostManager.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostManager.kt index f8cadda3ab2dae..88157aea50294c 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostManager.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostManager.kt @@ -57,6 +57,14 @@ public class ReactModalHostManager : view.statusBarTranslucent = statusBarTranslucent } + @ReactProp(name = "navigationBarTranslucent") + public override fun setNavigationBarTranslucent( + view: ReactModalHostView, + navigationBarTranslucent: Boolean + ) { + view.navigationBarTranslucent = navigationBarTranslucent + } + @ReactProp(name = "hardwareAccelerated") public override fun setHardwareAccelerated( view: ReactModalHostView, diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.kt index 88c1c68269b082..83d8bc287e3b6a 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.kt @@ -48,6 +48,7 @@ import com.facebook.react.uimanager.events.EventDispatcher import com.facebook.react.views.common.ContextUtils import com.facebook.react.views.view.ReactViewGroup import com.facebook.react.views.view.setStatusBarTranslucency +import com.facebook.react.views.view.setSystemBarsTranslucency import java.util.Objects /** @@ -79,6 +80,12 @@ public class ReactModalHostView(context: ThemedReactContext) : createNewDialog = true } + public var navigationBarTranslucent: Boolean = false + set(value) { + field = value + createNewDialog = true + } + public var animationType: String? = null set(value) { field = value @@ -335,7 +342,12 @@ public class ReactModalHostView(context: ThemedReactContext) : } } - dialogWindow.setStatusBarTranslucency(statusBarTranslucent) + // Navigation bar cannot be translucent without status bar being translucent too + dialogWindow.setSystemBarsTranslucency(navigationBarTranslucent) + + if (!navigationBarTranslucent) { + dialogWindow.setStatusBarTranslucency(statusBarTranslucent) + } if (transparent) { dialogWindow.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/WindowUtil.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/WindowUtil.kt index 4795564901c049..7e6bb5186c42dc 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/WindowUtil.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/WindowUtil.kt @@ -7,10 +7,14 @@ package com.facebook.react.views.view +import android.content.res.Configuration +import android.graphics.Color import android.os.Build import android.view.Window import android.view.WindowManager import androidx.core.view.ViewCompat +import androidx.core.view.WindowCompat +import androidx.core.view.WindowInsetsControllerCompat @Suppress("DEPRECATION") public fun Window.setStatusBarTranslucency(isTranslucent: Boolean) { @@ -61,3 +65,41 @@ private fun Window.statusBarShow() { addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN) clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN) } + +@Suppress("DEPRECATION") +public fun Window.setSystemBarsTranslucency(isTranslucent: Boolean) { + WindowCompat.setDecorFitsSystemWindows(this, !isTranslucent) + + if (isTranslucent) { + val isDarkMode = + context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK == + Configuration.UI_MODE_NIGHT_YES + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + isStatusBarContrastEnforced = false + isNavigationBarContrastEnforced = true + } + + statusBarColor = Color.TRANSPARENT + navigationBarColor = + when { + Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q -> Color.TRANSPARENT + Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1 && !isDarkMode -> + Color.argb(0xe6, 0xFF, 0xFF, 0xFF) + else -> Color.argb(0x80, 0x1b, 0x1b, 0x1b) + } + + WindowInsetsControllerCompat(this, this.decorView).run { + isAppearanceLightNavigationBars = !isDarkMode + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + attributes.layoutInDisplayCutoutMode = + when { + Build.VERSION.SDK_INT >= Build.VERSION_CODES.R -> + WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS + else -> WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES + } + } + } +} diff --git a/packages/react-native/src/private/specs/components/RCTModalHostViewNativeComponent.js b/packages/react-native/src/private/specs/components/RCTModalHostViewNativeComponent.js index 86bf895d767526..58ec2940079bc8 100644 --- a/packages/react-native/src/private/specs/components/RCTModalHostViewNativeComponent.js +++ b/packages/react-native/src/private/specs/components/RCTModalHostViewNativeComponent.js @@ -58,6 +58,14 @@ type NativeProps = $ReadOnly<{| */ statusBarTranslucent?: WithDefault, + /** + * The `navigationBarTranslucent` prop determines whether your modal should go under + * the system navigationbar. + * + * See https://reactnative.dev/docs/modal#navigationBarTranslucent + */ + navigationBarTranslucent?: WithDefault, + /** * The `hardwareAccelerated` prop controls whether to force hardware * acceleration for the underlying window. diff --git a/packages/rn-tester/js/examples/Modal/ModalPresentation.js b/packages/rn-tester/js/examples/Modal/ModalPresentation.js index ee440e05fcc491..028232b0b8603a 100644 --- a/packages/rn-tester/js/examples/Modal/ModalPresentation.js +++ b/packages/rn-tester/js/examples/Modal/ModalPresentation.js @@ -56,6 +56,7 @@ function ModalPresentation() { transparent: false, hardwareAccelerated: false, statusBarTranslucent: false, + navigationBarTranslucent: false, presentationStyle: Platform.select({ ios: 'fullScreen', default: undefined, @@ -72,6 +73,7 @@ function ModalPresentation() { const presentationStyle = props.presentationStyle; const hardwareAccelerated = props.hardwareAccelerated; const statusBarTranslucent = props.statusBarTranslucent; + const navigationBarTranslucent = props.navigationBarTranslucent; const backdropColor = props.backdropColor; const backgroundColor = useContext(RNTesterThemeContext).BackgroundColor; @@ -92,10 +94,29 @@ function ModalPresentation() { - setProps(prev => ({...prev, statusBarTranslucent: enabled})) + setProps(prev => ({ + ...prev, + statusBarTranslucent: enabled, + navigationBarTranslucent: false, + })) } /> + + + Navigation Bar Translucent 🟢 + + { + setProps(prev => ({ + ...prev, + statusBarTranslucent: enabled, + navigationBarTranslucent: enabled, + })); + }} + /> + Hardware Acceleration 🟢 From f01b47257a75d0e43ee4aed76b6de421ce692604 Mon Sep 17 00:00:00 2001 From: Yedidya Feldblum Date: Wed, 6 Nov 2024 23:10:36 -0800 Subject: [PATCH 105/220] let PointerValue::invalidate() be noexcept (#47354) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47354 `PointerValue::invalidate()` is called from `Pointer` destructor, which is implicitly `noexcept`, and from `Pointer` move-assignment operator, which is now `noexcept`. Reviewed By: neildhar Differential Revision: D65271399 fbshipit-source-id: 26fd9707e4389da78537d0d607adaef0c68690ca --- packages/react-native/ReactCommon/jsc/JSCRuntime.cpp | 12 ++++++------ packages/react-native/ReactCommon/jsi/jsi/jsi.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/react-native/ReactCommon/jsc/JSCRuntime.cpp b/packages/react-native/ReactCommon/jsc/JSCRuntime.cpp index 2216126af41028..6ea718b1e473de 100644 --- a/packages/react-native/ReactCommon/jsc/JSCRuntime.cpp +++ b/packages/react-native/ReactCommon/jsc/JSCRuntime.cpp @@ -94,7 +94,7 @@ class JSCRuntime : public jsi::Runtime { const std::atomic& ctxInvalid, JSValueRef sym); #endif - void invalidate() override; + void invalidate() noexcept override; JSGlobalContextRef ctx_; const std::atomic& ctxInvalid_; @@ -114,7 +114,7 @@ class JSCRuntime : public jsi::Runtime { #else JSCStringValue(JSStringRef str); #endif - void invalidate() override; + void invalidate() noexcept override; JSStringRef str_; #ifndef NDEBUG @@ -135,7 +135,7 @@ class JSCRuntime : public jsi::Runtime { #endif ); - void invalidate() override; + void invalidate() noexcept override; JSGlobalContextRef ctx_; const std::atomic& ctxInvalid_; @@ -506,7 +506,7 @@ JSCRuntime::JSCSymbolValue::JSCSymbolValue( #endif } -void JSCRuntime::JSCSymbolValue::invalidate() { +void JSCRuntime::JSCSymbolValue::invalidate() noexcept { #ifndef NDEBUG counter_ -= 1; #endif @@ -531,7 +531,7 @@ JSCRuntime::JSCStringValue::JSCStringValue(JSStringRef str) : str_(JSStringRetain(str)) {} #endif -void JSCRuntime::JSCStringValue::invalidate() { +void JSCRuntime::JSCStringValue::invalidate() noexcept { // These JSC{String,Object}Value objects are implicitly owned by the // {String,Object} objects, thus when a String/Object is destructed // the JSC{String,Object}Value should be released. @@ -566,7 +566,7 @@ JSCRuntime::JSCObjectValue::JSCObjectValue( #endif } -void JSCRuntime::JSCObjectValue::invalidate() { +void JSCRuntime::JSCObjectValue::invalidate() noexcept { #ifndef NDEBUG counter_ -= 1; #endif diff --git a/packages/react-native/ReactCommon/jsi/jsi/jsi.h b/packages/react-native/ReactCommon/jsi/jsi/jsi.h index 07e3722cb0e31a..a826923a6401d8 100644 --- a/packages/react-native/ReactCommon/jsi/jsi/jsi.h +++ b/packages/react-native/ReactCommon/jsi/jsi/jsi.h @@ -288,7 +288,7 @@ class JSI_EXPORT Runtime { // rvalue arguments/methods would also reduce the number of clones. struct PointerValue { - virtual void invalidate() = 0; + virtual void invalidate() noexcept = 0; protected: virtual ~PointerValue() = default; From 2dab7b078d75dc096b58ebbd7c47612e030b88b7 Mon Sep 17 00:00:00 2001 From: Tim Yung Date: Thu, 7 Nov 2024 00:00:14 -0800 Subject: [PATCH 106/220] ScrollView: Delete `unstable_setEnableSyncOnScroll` (#47399) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47399 Deletes `unstable_setEnableSyncOnScroll` which we are no longer experirmenting with in React Native. Changelog: [Internal] - Deleted `unstable_setEnableSyncOnScroll` on `ScrollView`, which was never part of the React Native Public API. Reviewed By: tdn120, sammy-SC Differential Revision: D65449039 fbshipit-source-id: 6608d5ccca477f1da5e0168c4a342cce17014b08 --- ...roidHorizontalScrollViewNativeComponent.js | 1 - .../Components/ScrollView/ScrollView.js | 109 ++++++------------ .../ScrollView/ScrollViewNativeComponent.js | 2 - .../__snapshots__/public-api-test.js.snap | 12 +- .../ScrollView/RCTScrollViewComponentView.mm | 27 ++--- .../ReactAndroid/api/ReactAndroid.api | 9 +- .../scroll/ReactHorizontalScrollView.java | 14 +-- .../ReactHorizontalScrollViewManager.java | 5 - .../react/views/scroll/ReactScrollView.java | 14 +-- .../views/scroll/ReactScrollViewHelper.kt | 22 +--- .../views/scroll/ReactScrollViewManager.java | 5 - .../react/views/scroll/ScrollEvent.kt | 12 +- .../textinput/ReactTextInputManager.java | 3 +- .../scrollview/ScrollViewEventEmitter.cpp | 8 -- .../scrollview/ScrollViewEventEmitter.h | 1 - .../components/scrollview/ScrollViewProps.cpp | 10 -- .../components/scrollview/ScrollViewProps.h | 1 - .../components/HScrollViewNativeComponents.js | 27 +---- .../components/VScrollViewNativeComponents.js | 26 +---- .../src/private/components/useSyncOnScroll.js | 48 -------- 20 files changed, 56 insertions(+), 300 deletions(-) delete mode 100644 packages/react-native/src/private/components/useSyncOnScroll.js diff --git a/packages/react-native/Libraries/Components/ScrollView/AndroidHorizontalScrollViewNativeComponent.js b/packages/react-native/Libraries/Components/ScrollView/AndroidHorizontalScrollViewNativeComponent.js index bdaef9b90941d1..c99ea196ae3bfc 100644 --- a/packages/react-native/Libraries/Components/ScrollView/AndroidHorizontalScrollViewNativeComponent.js +++ b/packages/react-native/Libraries/Components/ScrollView/AndroidHorizontalScrollViewNativeComponent.js @@ -31,7 +31,6 @@ export const __INTERNAL_VIEW_CONFIG: PartialViewConfig = { pagingEnabled: true, persistentScrollbar: true, horizontal: true, - enableSyncOnScroll: true, scrollEnabled: true, scrollEventThrottle: true, scrollPerfTag: true, diff --git a/packages/react-native/Libraries/Components/ScrollView/ScrollView.js b/packages/react-native/Libraries/Components/ScrollView/ScrollView.js index ac218c0fd208a5..f2dbf2646fbe44 100644 --- a/packages/react-native/Libraries/Components/ScrollView/ScrollView.js +++ b/packages/react-native/Libraries/Components/ScrollView/ScrollView.js @@ -8,10 +8,6 @@ * @flow strict-local */ -import type { - TScrollViewNativeComponentInstance, - TScrollViewNativeImperativeHandle, -} from '../../../src/private/components/useSyncOnScroll'; import type {HostInstance} from '../../Renderer/shims/ReactNativeTypes'; import type {EdgeInsetsProp} from '../../StyleSheet/EdgeInsetsPropType'; import type {PointProp} from '../../StyleSheet/PointPropType'; @@ -46,7 +42,6 @@ import StyleSheet from '../../StyleSheet/StyleSheet'; import Dimensions from '../../Utilities/Dimensions'; import dismissKeyboard from '../../Utilities/dismissKeyboard'; import Platform from '../../Utilities/Platform'; -import EventEmitter from '../../vendor/emitter/EventEmitter'; import Keyboard from '../Keyboard/Keyboard'; import TextInputState from '../TextInput/TextInputState'; import processDecelerationRate from './processDecelerationRate'; @@ -152,7 +147,7 @@ export type DecelerationRateType = 'fast' | 'normal' | number; export type ScrollResponderType = ScrollViewImperativeMethods; type PublicScrollViewInstance = $ReadOnly<{| - ...$Exact, + ...HostInstance, ...ScrollViewImperativeMethods, |}>; @@ -743,10 +738,6 @@ class ScrollView extends React.Component { _subscriptionKeyboardDidShow: ?EventSubscription = null; _subscriptionKeyboardDidHide: ?EventSubscription = null; - #onScrollEmitter: ?EventEmitter<{ - scroll: [{x: number, y: number}], - }> = null; - state: State = { layoutHeight: null, }; @@ -817,8 +808,6 @@ class ScrollView extends React.Component { if (this._scrollAnimatedValueAttachment) { this._scrollAnimatedValueAttachment.detach(); } - - this.#onScrollEmitter?.removeAllListeners(); } /** @@ -844,9 +833,8 @@ class ScrollView extends React.Component { return this._innerView.nativeInstance; }; - getNativeScrollRef: () => TScrollViewNativeComponentInstance | null = () => { - const {nativeInstance} = this._scrollView; - return nativeInstance == null ? null : nativeInstance.componentRef.current; + getNativeScrollRef: () => HostInstance | null = () => { + return this._scrollView.nativeInstance; }; /** @@ -937,20 +925,6 @@ class ScrollView extends React.Component { Commands.flashScrollIndicators(component); }; - _subscribeToOnScroll: ( - callback: ({x: number, y: number}) => void, - ) => EventSubscription = callback => { - let onScrollEmitter = this.#onScrollEmitter; - if (onScrollEmitter == null) { - onScrollEmitter = new EventEmitter(); - this.#onScrollEmitter = onScrollEmitter; - // This is the first subscription, so make sure the native component is - // also configured to output synchronous scroll events. - this._scrollView.nativeInstance?.unstable_setEnableSyncOnScroll(true); - } - return onScrollEmitter.addListener('scroll', callback); - }; - /** * This method should be used as the callback to onFocus in a TextInputs' * parent view. Note that any module using this mixin needs to return @@ -1154,11 +1128,6 @@ class ScrollView extends React.Component { _handleScroll = (e: ScrollEvent) => { this._observedScrollSinceBecomingResponder = true; this.props.onScroll && this.props.onScroll(e); - - this.#onScrollEmitter?.emit('scroll', { - x: e.nativeEvent.contentOffset.x, - y: e.nativeEvent.contentOffset.y, - }); }; _handleLayout = (e: LayoutEvent) => { @@ -1181,45 +1150,36 @@ class ScrollView extends React.Component { (instance: InnerViewInstance): InnerViewInstance => instance, ); - _scrollView: RefForwarder< - TScrollViewNativeImperativeHandle, - PublicScrollViewInstance | null, - > = createRefForwarder(nativeImperativeHandle => { - const nativeInstance = nativeImperativeHandle.componentRef.current; - if (nativeInstance == null) { - return null; - } - - // This is a hack. Ideally we would forwardRef to the underlying - // host component. However, since ScrollView has it's own methods that can be - // called as well, if we used the standard forwardRef then these - // methods wouldn't be accessible and thus be a breaking change. - // - // Therefore we edit ref to include ScrollView's public methods so that - // they are callable from the ref. - - // $FlowFixMe[prop-missing] - Known issue with appending custom methods. - const publicInstance: PublicScrollViewInstance = Object.assign( - nativeInstance, - { - getScrollResponder: this.getScrollResponder, - getScrollableNode: this.getScrollableNode, - getInnerViewNode: this.getInnerViewNode, - getInnerViewRef: this.getInnerViewRef, - getNativeScrollRef: this.getNativeScrollRef, - scrollTo: this.scrollTo, - scrollToEnd: this.scrollToEnd, - flashScrollIndicators: this.flashScrollIndicators, - scrollResponderZoomTo: this.scrollResponderZoomTo, - // TODO: Replace unstable_subscribeToOnScroll once scrollView.addEventListener('scroll', (e: ScrollEvent) => {}, {passive: false}); - unstable_subscribeToOnScroll: this._subscribeToOnScroll, - scrollResponderScrollNativeHandleToKeyboard: - this.scrollResponderScrollNativeHandleToKeyboard, - }, - ); + _scrollView: RefForwarder = + createRefForwarder(nativeInstance => { + // This is a hack. Ideally we would forwardRef to the underlying + // host component. However, since ScrollView has it's own methods that can be + // called as well, if we used the standard forwardRef then these + // methods wouldn't be accessible and thus be a breaking change. + // + // Therefore we edit ref to include ScrollView's public methods so that + // they are callable from the ref. + + // $FlowFixMe[prop-missing] - Known issue with appending custom methods. + const publicInstance: PublicScrollViewInstance = Object.assign( + nativeInstance, + { + getScrollResponder: this.getScrollResponder, + getScrollableNode: this.getScrollableNode, + getInnerViewNode: this.getInnerViewNode, + getInnerViewRef: this.getInnerViewRef, + getNativeScrollRef: this.getNativeScrollRef, + scrollTo: this.scrollTo, + scrollToEnd: this.scrollToEnd, + flashScrollIndicators: this.flashScrollIndicators, + scrollResponderZoomTo: this.scrollResponderZoomTo, + scrollResponderScrollNativeHandleToKeyboard: + this.scrollResponderScrollNativeHandleToKeyboard, + }, + ); - return publicInstance; - }); + return publicInstance; + }); /** * Warning, this may be called several times for a single keyboard opening. @@ -1829,8 +1789,9 @@ class ScrollView extends React.Component { } const refreshControl = this.props.refreshControl; - const scrollViewRef: React.RefSetter = - this._scrollView.getForwardingRef(this.props.scrollViewRef); + const scrollViewRef = this._scrollView.getForwardingRef( + this.props.scrollViewRef, + ); if (refreshControl) { if (Platform.OS === 'ios') { diff --git a/packages/react-native/Libraries/Components/ScrollView/ScrollViewNativeComponent.js b/packages/react-native/Libraries/Components/ScrollView/ScrollViewNativeComponent.js index 0d39831a6c5061..9e225c1dc21bbc 100644 --- a/packages/react-native/Libraries/Components/ScrollView/ScrollViewNativeComponent.js +++ b/packages/react-native/Libraries/Components/ScrollView/ScrollViewNativeComponent.js @@ -45,7 +45,6 @@ export const __INTERNAL_VIEW_CONFIG: PartialViewConfig = diff: require('../../Utilities/differ/pointsDiffer'), }, decelerationRate: true, - enableSyncOnScroll: true, // Fabric only. disableIntervalMomentum: true, maintainVisibleContentPosition: true, pagingEnabled: true, @@ -135,7 +134,6 @@ export const __INTERNAL_VIEW_CONFIG: PartialViewConfig = contentInsetAdjustmentBehavior: true, decelerationRate: true, endDraggingSensitivityMultiplier: true, - enableSyncOnScroll: true, // Fabric only. directionalLockEnabled: true, disableIntervalMomentum: true, indicatorStyle: true, diff --git a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap index 1e595f18710dba..3cf664c2093e42 100644 --- a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap +++ b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap @@ -2042,7 +2042,7 @@ exports[`public API should not change unintentionally Libraries/Components/Scrol export type DecelerationRateType = \\"fast\\" | \\"normal\\" | number; export type ScrollResponderType = ScrollViewImperativeMethods; type PublicScrollViewInstance = $ReadOnly<{| - ...$Exact, + ...HostInstance, ...ScrollViewImperativeMethods, |}>; type InnerViewInstance = React.ElementRef; @@ -2169,7 +2169,7 @@ declare class ScrollView extends React.Component { getScrollableNode: () => ?number; getInnerViewNode: () => ?number; getInnerViewRef: () => InnerViewInstance | null; - getNativeScrollRef: () => TScrollViewNativeComponentInstance | null; + getNativeScrollRef: () => HostInstance | null; scrollTo: ( options?: | { @@ -2184,9 +2184,6 @@ declare class ScrollView extends React.Component { ) => void; scrollToEnd: (options?: ?{ animated?: boolean, ... }) => void; flashScrollIndicators: () => void; - _subscribeToOnScroll: ( - callback: ({ x: number, y: number }) => void - ) => EventSubscription; scrollResponderScrollNativeHandleToKeyboard: ( nodeHandle: number | HostInstance, additionalOffset?: number, @@ -2224,10 +2221,7 @@ declare class ScrollView extends React.Component { _handleLayout: $FlowFixMe; _handleContentOnLayout: $FlowFixMe; _innerView: RefForwarder; - _scrollView: RefForwarder< - TScrollViewNativeImperativeHandle, - PublicScrollViewInstance | null, - >; + _scrollView: RefForwarder; scrollResponderKeyboardWillShow: (e: KeyboardEvent) => void; scrollResponderKeyboardWillHide: (e: KeyboardEvent) => void; scrollResponderKeyboardDidShow: (e: KeyboardEvent) => void; diff --git a/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm b/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm index bb63afb3c3d7f7..95f38d95fac3d4 100644 --- a/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm +++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm @@ -618,31 +618,18 @@ - (BOOL)touchesShouldCancelInContentView:(__unused UIView *)view - (void)scrollViewDidScroll:(UIScrollView *)scrollView { - const auto &props = static_cast(*_props); auto scrollMetrics = [self _scrollViewMetrics]; - if (props.enableSyncOnScroll) { + [self _updateStateWithContentOffset]; + + NSTimeInterval now = CACurrentMediaTime(); + if ((_lastScrollEventDispatchTime == 0) || (now - _lastScrollEventDispatchTime > _scrollEventThrottle)) { + _lastScrollEventDispatchTime = now; if (_eventEmitter) { - const auto &eventEmitter = static_cast(*_eventEmitter); - // TODO: temporary API to unblock testing of synchronous rendering. - eventEmitter.experimental_flushSync([&eventEmitter, &scrollMetrics, &self]() { - [self _updateStateWithContentOffset]; - // TODO: temporary API to unblock testing of synchronous rendering. - eventEmitter.experimental_onDiscreteScroll(scrollMetrics); - }); + static_cast(*_eventEmitter).onScroll(scrollMetrics); } - } else { - [self _updateStateWithContentOffset]; - - NSTimeInterval now = CACurrentMediaTime(); - if ((_lastScrollEventDispatchTime == 0) || (now - _lastScrollEventDispatchTime > _scrollEventThrottle)) { - _lastScrollEventDispatchTime = now; - if (_eventEmitter) { - static_cast(*_eventEmitter).onScroll(scrollMetrics); - } - RCTSendScrollEventForNativeAnimations_DEPRECATED(scrollView, self.tag, kOnScrollEvent); - } + RCTSendScrollEventForNativeAnimations_DEPRECATED(scrollView, self.tag, kOnScrollEvent); } [self _remountChildrenIfNeeded]; diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 67c7612eb31243..df42862cb41fc9 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -6798,7 +6798,6 @@ public class com/facebook/react/views/scroll/ReactHorizontalScrollView : android public fun setBorderWidth (IF)V public fun setDecelerationRate (F)V public fun setDisableIntervalMomentum (Z)V - public fun setEnableSyncOnScroll (Z)V public fun setEndFillColor (I)V public fun setLastScrollDispatchTime (J)V public fun setMaintainVisibleContentPosition (Lcom/facebook/react/views/scroll/MaintainVisibleScrollPositionHelper$Config;)V @@ -6846,7 +6845,6 @@ public class com/facebook/react/views/scroll/ReactHorizontalScrollViewManager : public fun setContentOffset (Lcom/facebook/react/views/scroll/ReactHorizontalScrollView;Lcom/facebook/react/bridge/ReadableMap;)V public fun setDecelerationRate (Lcom/facebook/react/views/scroll/ReactHorizontalScrollView;F)V public fun setDisableIntervalMomentum (Lcom/facebook/react/views/scroll/ReactHorizontalScrollView;Z)V - public fun setEnableSyncOnScroll (Lcom/facebook/react/views/scroll/ReactHorizontalScrollView;Z)V public fun setFadingEdgeLength (Lcom/facebook/react/views/scroll/ReactHorizontalScrollView;I)V public fun setHorizontal (Lcom/facebook/react/views/scroll/ReactHorizontalScrollView;Z)V public fun setMaintainVisibleContentPosition (Lcom/facebook/react/views/scroll/ReactHorizontalScrollView;Lcom/facebook/react/bridge/ReadableMap;)V @@ -6921,7 +6919,6 @@ public class com/facebook/react/views/scroll/ReactScrollView : android/widget/Sc public fun setContentOffset (Lcom/facebook/react/bridge/ReadableMap;)V public fun setDecelerationRate (F)V public fun setDisableIntervalMomentum (Z)V - public fun setEnableSyncOnScroll (Z)V public fun setEndFillColor (I)V public fun setLastScrollDispatchTime (J)V public fun setMaintainVisibleContentPosition (Lcom/facebook/react/views/scroll/MaintainVisibleScrollPositionHelper$Config;)V @@ -7003,7 +7000,6 @@ public final class com/facebook/react/views/scroll/ReactScrollViewHelper { public static final fun updateFabricScrollState (Landroid/view/ViewGroup;)V public final fun updateFabricScrollState (Landroid/view/ViewGroup;II)V public static final fun updateStateOnScrollChanged (Landroid/view/ViewGroup;FF)V - public static final fun updateStateOnScrollChanged (Landroid/view/ViewGroup;FFZ)V } public abstract interface class com/facebook/react/views/scroll/ReactScrollViewHelper$HasFlingAnimator { @@ -7086,7 +7082,6 @@ public class com/facebook/react/views/scroll/ReactScrollViewManager : com/facebo public fun setContentOffset (Lcom/facebook/react/views/scroll/ReactScrollView;Lcom/facebook/react/bridge/ReadableMap;)V public fun setDecelerationRate (Lcom/facebook/react/views/scroll/ReactScrollView;F)V public fun setDisableIntervalMomentum (Lcom/facebook/react/views/scroll/ReactScrollView;Z)V - public fun setEnableSyncOnScroll (Lcom/facebook/react/views/scroll/ReactScrollView;Z)V public fun setFadingEdgeLength (Lcom/facebook/react/views/scroll/ReactScrollView;I)V public fun setHorizontal (Lcom/facebook/react/views/scroll/ReactScrollView;Z)V public fun setIsInvertedVirtualizedList (Lcom/facebook/react/views/scroll/ReactScrollView;Z)V @@ -7116,13 +7111,13 @@ public final class com/facebook/react/views/scroll/ScrollEvent : com/facebook/re public static final field Companion Lcom/facebook/react/views/scroll/ScrollEvent$Companion; public fun canCoalesce ()Z public fun getEventName ()Ljava/lang/String; - public static final fun obtain (IILcom/facebook/react/views/scroll/ScrollEventType;FFFFIIIIZ)Lcom/facebook/react/views/scroll/ScrollEvent; + public static final fun obtain (IILcom/facebook/react/views/scroll/ScrollEventType;FFFFIIII)Lcom/facebook/react/views/scroll/ScrollEvent; public static final fun obtain (ILcom/facebook/react/views/scroll/ScrollEventType;FFFFIIII)Lcom/facebook/react/views/scroll/ScrollEvent; public fun onDispose ()V } public final class com/facebook/react/views/scroll/ScrollEvent$Companion { - public final fun obtain (IILcom/facebook/react/views/scroll/ScrollEventType;FFFFIIIIZ)Lcom/facebook/react/views/scroll/ScrollEvent; + public final fun obtain (IILcom/facebook/react/views/scroll/ScrollEventType;FFFFIIII)Lcom/facebook/react/views/scroll/ScrollEvent; public final fun obtain (ILcom/facebook/react/views/scroll/ScrollEventType;FFFFIIII)Lcom/facebook/react/views/scroll/ScrollEvent; } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java index 279868be6b4967..b4a8958b77781e 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java @@ -103,8 +103,6 @@ public class ReactHorizontalScrollView extends HorizontalScrollView private @Nullable Runnable mPostTouchRunnable; private boolean mRemoveClippedSubviews; private boolean mScrollEnabled = true; - private boolean mPreventReentry = false; - private boolean mEnableSyncOnScroll = false; private boolean mSendMomentumEvents; private @Nullable FpsListener mFpsListener = null; private @Nullable String mScrollPerfTag; @@ -231,10 +229,6 @@ public void setScrollEnabled(boolean scrollEnabled) { mScrollEnabled = scrollEnabled; } - public void setEnableSyncOnScroll(boolean enableSyncOnScroll) { - mEnableSyncOnScroll = enableSyncOnScroll; - } - public void setPagingEnabled(boolean pagingEnabled) { mPagingEnabled = pagingEnabled; } @@ -492,16 +486,10 @@ protected void onScrollChanged(int x, int y, int oldX, int oldY) { if (mRemoveClippedSubviews) { updateClippingRect(); } - if (mPreventReentry) { - return; - } - mPreventReentry = true; ReactScrollViewHelper.updateStateOnScrollChanged( this, mOnScrollDispatchHelper.getXFlingVelocity(), - mOnScrollDispatchHelper.getYFlingVelocity(), - mEnableSyncOnScroll); - mPreventReentry = false; + mOnScrollDispatchHelper.getYFlingVelocity()); } } finally { Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE); diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollViewManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollViewManager.java index 96b45c1316c70f..0d6b0a583aeec3 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollViewManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollViewManager.java @@ -95,11 +95,6 @@ public void setDecelerationRate(ReactHorizontalScrollView view, float decelerati view.setDecelerationRate(decelerationRate); } - @ReactProp(name = "enableSyncOnScroll") - public void setEnableSyncOnScroll(ReactHorizontalScrollView view, boolean enableSyncOnScroll) { - view.setEnableSyncOnScroll(enableSyncOnScroll); - } - @ReactProp(name = "disableIntervalMomentum") public void setDisableIntervalMomentum( ReactHorizontalScrollView view, boolean disableIntervalMomentum) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java index 7203f62ac8b8ad..beff0426e8b478 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java @@ -102,11 +102,9 @@ public class ReactScrollView extends ScrollView private @Nullable Runnable mPostTouchRunnable; private boolean mRemoveClippedSubviews; private boolean mScrollEnabled = true; - private boolean mPreventReentry = false; private boolean mSendMomentumEvents; private @Nullable FpsListener mFpsListener = null; private @Nullable String mScrollPerfTag; - private boolean mEnableSyncOnScroll = false; private @Nullable Drawable mEndBackground; private int mEndFillColor = Color.TRANSPARENT; private boolean mDisableIntervalMomentum = false; @@ -210,10 +208,6 @@ public void setScrollPerfTag(@Nullable String scrollPerfTag) { mScrollPerfTag = scrollPerfTag; } - public void setEnableSyncOnScroll(boolean enableSyncOnScroll) { - mEnableSyncOnScroll = enableSyncOnScroll; - } - public void setScrollEnabled(boolean scrollEnabled) { mScrollEnabled = scrollEnabled; } @@ -418,16 +412,10 @@ protected void onScrollChanged(int x, int y, int oldX, int oldY) { if (mRemoveClippedSubviews) { updateClippingRect(); } - if (mPreventReentry) { - return; - } - mPreventReentry = true; ReactScrollViewHelper.updateStateOnScrollChanged( this, mOnScrollDispatchHelper.getXFlingVelocity(), - mOnScrollDispatchHelper.getYFlingVelocity(), - mEnableSyncOnScroll); - mPreventReentry = false; + mOnScrollDispatchHelper.getYFlingVelocity()); } } finally { Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE); diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewHelper.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewHelper.kt index 39867529645f90..f7d1817fb1ebe9 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewHelper.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewHelper.kt @@ -103,7 +103,6 @@ public object ReactScrollViewHelper { scrollEventType: ScrollEventType, xVelocity: Float, yVelocity: Float, - experimental_isSynchronous: Boolean = false, ) where T : HasScrollEventThrottle?, T : ViewGroup { val now = System.currentTimeMillis() // Throttle the scroll event if scrollEventThrottle is set to be equal or more than 17 ms. @@ -138,8 +137,7 @@ public object ReactScrollViewHelper { contentView.width, contentView.height, scrollView.width, - scrollView.height, - experimental_isSynchronous)) + scrollView.height)) scrollView.lastScrollDispatchTime = now } } @@ -374,29 +372,13 @@ public object ReactScrollViewHelper { T : HasScrollEventThrottle?, T : HasScrollState?, T : HasStateWrapper?, - T : ViewGroup { - updateStateOnScrollChanged(scrollView, xVelocity, yVelocity, false) - } - - @JvmStatic - public fun updateStateOnScrollChanged( - scrollView: T, - xVelocity: Float, - yVelocity: Float, - experimental_synchronous: Boolean, - ) where - T : HasFlingAnimator?, - T : HasScrollEventThrottle?, - T : HasScrollState?, - T : HasStateWrapper?, T : ViewGroup { // Race an UpdateState with every onScroll. This makes it more likely that, in Fabric, // when JS processes the scroll event, the C++ ShadowNode representation will have a // "more correct" scroll position. It will frequently be /incorrect/ but this decreases // the error as much as possible. updateFabricScrollState(scrollView, scrollView.scrollX, scrollView.scrollY) - emitScrollEvent( - scrollView, ScrollEventType.SCROLL, xVelocity, yVelocity, experimental_synchronous) + emitScrollEvent(scrollView, xVelocity, yVelocity) } public fun registerFlingAnimator(scrollView: T) where diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewManager.java index 055679d6cd7ac6..e9d28efec0a296 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewManager.java @@ -167,11 +167,6 @@ public void setScrollPerfTag(ReactScrollView view, @Nullable String scrollPerfTa view.setScrollPerfTag(scrollPerfTag); } - @ReactProp(name = "enableSyncOnScroll") - public void setEnableSyncOnScroll(ReactScrollView view, boolean value) { - view.setEnableSyncOnScroll(value); - } - @ReactProp(name = "pagingEnabled") public void setPagingEnabled(ReactScrollView view, boolean pagingEnabled) { view.setPagingEnabled(pagingEnabled); diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ScrollEvent.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ScrollEvent.kt index 73b8f444f6bf6e..93f6b7110cd247 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ScrollEvent.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ScrollEvent.kt @@ -29,7 +29,6 @@ public class ScrollEvent private constructor() : Event() { private var scrollViewHeight = 0 private var scrollEventType: ScrollEventType? = null private var timestamp: Long = 0 - private var experimental_isSynchronous = false override fun onDispose() { try { @@ -53,7 +52,6 @@ public class ScrollEvent private constructor() : Event() { contentHeight: Int, scrollViewWidth: Int, scrollViewHeight: Int, - experimental_isSynchronous: Boolean, ) { super.init(surfaceId, viewTag) this.scrollEventType = scrollEventType @@ -66,7 +64,6 @@ public class ScrollEvent private constructor() : Event() { this.scrollViewWidth = scrollViewWidth this.scrollViewHeight = scrollViewHeight this.timestamp = SystemClock.uptimeMillis() - this.experimental_isSynchronous = experimental_isSynchronous } override fun getEventName(): String = @@ -74,10 +71,6 @@ public class ScrollEvent private constructor() : Event() { override fun canCoalesce(): Boolean = scrollEventType == ScrollEventType.SCROLL - override fun experimental_isSynchronous(): Boolean { - return experimental_isSynchronous - } - override fun getEventData(): WritableMap { val contentInset = Arguments.createMap() contentInset.putDouble("top", 0.0) @@ -125,7 +118,6 @@ public class ScrollEvent private constructor() : Event() { contentHeight: Int, scrollViewWidth: Int, scrollViewHeight: Int, - experimental_isSynchronous: Boolean, ): ScrollEvent = (EVENTS_POOL.acquire() ?: ScrollEvent()).apply { init( @@ -139,8 +131,7 @@ public class ScrollEvent private constructor() : Event() { contentWidth, contentHeight, scrollViewWidth, - scrollViewHeight, - experimental_isSynchronous) + scrollViewHeight) } @Deprecated( @@ -172,7 +163,6 @@ public class ScrollEvent private constructor() : Event() { contentHeight, scrollViewWidth, scrollViewHeight, - false, ) } } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java index 3d53a038396f38..f18e569c923339 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java @@ -1302,8 +1302,7 @@ public void onScrollChanged(int horiz, int vert, int oldHoriz, int oldVert) { 0, // can't get content width 0, // can't get content height mReactEditText.getWidth(), - mReactEditText.getHeight(), - false); + mReactEditText.getHeight()); mEventDispatcher.dispatchEvent(event); diff --git a/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewEventEmitter.cpp b/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewEventEmitter.cpp index 917741a1de08ed..80a5e9d223de01 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewEventEmitter.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewEventEmitter.cpp @@ -13,14 +13,6 @@ void ScrollViewEventEmitter::onScroll(const ScrollEvent& scrollEvent) const { dispatchUniqueEvent("scroll", std::make_shared(scrollEvent)); } -void ScrollViewEventEmitter::experimental_onDiscreteScroll( - const ScrollEvent& scrollEvent) const { - dispatchEvent( - "scroll", - std::make_shared(scrollEvent), - RawEvent::Category::Discrete); -} - void ScrollViewEventEmitter::onScrollToTop( const ScrollEvent& scrollEvent) const { dispatchUniqueEvent( diff --git a/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewEventEmitter.h b/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewEventEmitter.h index 5d0bbb7caf7264..7bd8a555ecc671 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewEventEmitter.h +++ b/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewEventEmitter.h @@ -23,7 +23,6 @@ class ScrollViewEventEmitter : public ViewEventEmitter { using Metrics = ScrollEvent; void onScroll(const ScrollEvent& scrollEvent) const; - void experimental_onDiscreteScroll(const ScrollEvent& scrollEvent) const; void onScrollBeginDrag(const ScrollEvent& scrollEvent) const; void onScrollEndDrag(const ScrollEvent& scrollEvent) const; void onMomentumScrollBegin(const ScrollEvent& scrollEvent) const; diff --git a/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.cpp b/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.cpp index 0dbb4a0f519309..556fc85d083317 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.cpp @@ -120,15 +120,6 @@ ScrollViewProps::ScrollViewProps( "endDraggingSensitivityMultiplier", sourceProps.endDraggingSensitivityMultiplier, (Float)1)), - enableSyncOnScroll( - ReactNativeFeatureFlags::enableCppPropsIteratorSetter() - ? sourceProps.enableSyncOnScroll - : convertRawProp( - context, - rawProps, - "enableSyncOnScroll", - sourceProps.enableSyncOnScroll, - false)), directionalLockEnabled( ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.directionalLockEnabled @@ -411,7 +402,6 @@ void ScrollViewProps::setProp( RAW_SET_PROP_SWITCH_CASE_BASIC(maximumZoomScale); RAW_SET_PROP_SWITCH_CASE_BASIC(minimumZoomScale); RAW_SET_PROP_SWITCH_CASE_BASIC(scrollEnabled); - RAW_SET_PROP_SWITCH_CASE_BASIC(enableSyncOnScroll); RAW_SET_PROP_SWITCH_CASE_BASIC(endDraggingSensitivityMultiplier); RAW_SET_PROP_SWITCH_CASE_BASIC(pagingEnabled); RAW_SET_PROP_SWITCH_CASE_BASIC(pinchGestureEnabled); diff --git a/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.h b/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.h index 387ff3ec0351db..8516d4ab0dc84a 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.h +++ b/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.h @@ -43,7 +43,6 @@ class ScrollViewProps final : public ViewProps { bool automaticallyAdjustKeyboardInsets{false}; Float decelerationRate{0.998f}; Float endDraggingSensitivityMultiplier{1}; - bool enableSyncOnScroll{false}; bool directionalLockEnabled{}; ScrollViewIndicatorStyle indicatorStyle{}; ScrollViewKeyboardDismissMode keyboardDismissMode{}; diff --git a/packages/react-native/src/private/components/HScrollViewNativeComponents.js b/packages/react-native/src/private/components/HScrollViewNativeComponents.js index 37e754e8b7eb64..612af54491731f 100644 --- a/packages/react-native/src/private/components/HScrollViewNativeComponents.js +++ b/packages/react-native/src/private/components/HScrollViewNativeComponents.js @@ -12,43 +12,18 @@ import type {ScrollViewNativeProps} from '../../../Libraries/Components/ScrollView/ScrollViewNativeComponentType'; import type {ViewProps} from '../../../Libraries/Components/View/ViewPropTypes'; import type {HostComponent} from '../../../Libraries/Renderer/shims/ReactNativeTypes'; -import type {TScrollViewNativeImperativeHandle} from './useSyncOnScroll'; import AndroidHorizontalScrollViewNativeComponent from '../../../Libraries/Components/ScrollView/AndroidHorizontalScrollViewNativeComponent'; import ScrollContentViewNativeComponent from '../../../Libraries/Components/ScrollView/ScrollContentViewNativeComponent'; import ScrollViewNativeComponent from '../../../Libraries/Components/ScrollView/ScrollViewNativeComponent'; import Platform from '../../../Libraries/Utilities/Platform'; import AndroidHorizontalScrollContentViewNativeComponent from '../specs/components/AndroidHorizontalScrollContentViewNativeComponent'; -import useSyncOnScroll from './useSyncOnScroll'; -import * as React from 'react'; -import {forwardRef} from 'react'; -const HScrollViewNativeComponentForPlatform = +export const HScrollViewNativeComponent: HostComponent = Platform.OS === 'android' ? AndroidHorizontalScrollViewNativeComponent : ScrollViewNativeComponent; -// TODO: After upgrading to React 19, remove `forwardRef` from this component. -export const HScrollViewNativeComponent: component( - ref: React.RefSetter, - ...ScrollViewNativeProps -) = forwardRef(function HScrollViewNativeComponent( - props: ScrollViewNativeProps, - ref: ?React.RefSetter, -): React.Node { - const [componentRef, enableSyncOnScroll] = useSyncOnScroll(ref); - // NOTE: When `useSyncOnScroll` triggers an update, `props` will not have - // changed. Notably, `props.children` will be the same, allowing React to - // bail out during reconciliation. - return ( - - ); -}); - export const HScrollContentViewNativeComponent: HostComponent = Platform.OS === 'android' ? AndroidHorizontalScrollContentViewNativeComponent diff --git a/packages/react-native/src/private/components/VScrollViewNativeComponents.js b/packages/react-native/src/private/components/VScrollViewNativeComponents.js index 41c691f23a47d0..e110d875cf1a8a 100644 --- a/packages/react-native/src/private/components/VScrollViewNativeComponents.js +++ b/packages/react-native/src/private/components/VScrollViewNativeComponents.js @@ -12,36 +12,14 @@ import type {ScrollViewNativeProps} from '../../../Libraries/Components/ScrollView/ScrollViewNativeComponentType'; import type {ViewProps} from '../../../Libraries/Components/View/ViewPropTypes'; import type {HostComponent} from '../../../Libraries/Renderer/shims/ReactNativeTypes'; -import type {TScrollViewNativeImperativeHandle} from './useSyncOnScroll'; import ScrollContentViewNativeComponent from '../../../Libraries/Components/ScrollView/ScrollContentViewNativeComponent'; import ScrollViewNativeComponent from '../../../Libraries/Components/ScrollView/ScrollViewNativeComponent'; import View from '../../../Libraries/Components/View/View'; import Platform from '../../../Libraries/Utilities/Platform'; -import useSyncOnScroll from './useSyncOnScroll'; -import * as React from 'react'; -import {forwardRef} from 'react'; -// TODO: After upgrading to React 19, remove `forwardRef` from this component. -export const VScrollViewNativeComponent: component( - ref: React.RefSetter, - ...props: ScrollViewNativeProps -) = forwardRef(function VScrollViewNativeComponent( - props: ScrollViewNativeProps, - ref: ?React.RefSetter, -): React.Node { - const [componentRef, enableSyncOnScroll] = useSyncOnScroll(ref); - // NOTE: When `useSyncOnScroll` triggers an update, `props` will not have - // changed. Notably, `props.children` will be the same, allowing React to - // bail out during reconciliation. - return ( - - ); -}); +export const VScrollViewNativeComponent: HostComponent = + ScrollViewNativeComponent; export const VScrollContentViewNativeComponent: HostComponent = Platform.OS === 'android' ? View : ScrollContentViewNativeComponent; diff --git a/packages/react-native/src/private/components/useSyncOnScroll.js b/packages/react-native/src/private/components/useSyncOnScroll.js deleted file mode 100644 index ec9e0059d14243..00000000000000 --- a/packages/react-native/src/private/components/useSyncOnScroll.js +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and 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 - * @oncall react_native - */ - -import type {ScrollViewNativeProps} from '../../../Libraries/Components/ScrollView/ScrollViewNativeComponentType'; -import type {HostComponent} from '../../../Libraries/Renderer/shims/ReactNativeTypes'; - -import * as React from 'react'; -import {useImperativeHandle, useRef, useState} from 'react'; - -export type TScrollViewNativeComponentInstance = React.ElementRef< - HostComponent, ->; - -export type TScrollViewNativeImperativeHandle = { - componentRef: React.RefObject, - unstable_setEnableSyncOnScroll: (enabled: true) => void, -}; - -/** - * Hook used by `HScrollViewNativeComponent` and `VScrollViewNativeComponent` - * to make an implementation of `unstable_setEnableSyncOnScroll` available that - * does not require updating all `ScrollView` children. - */ -export default function useSyncOnScroll( - inputRef: ?React.RefSetter, -): [React.RefSetter, true | void] { - const componentRef = useRef(null); - const [enableSyncOnScroll, setEnableSyncOnScroll] = useState(); - - useImperativeHandle(inputRef, () => { - return { - componentRef, - unstable_setEnableSyncOnScroll(enabled: true): void { - setEnableSyncOnScroll(enabled); - }, - }; - }, []); - - return [componentRef, enableSyncOnScroll]; -} From fb69f406dfa77fd267bb71957ed9dff1e912c253 Mon Sep 17 00:00:00 2001 From: Alan Lee Date: Thu, 7 Nov 2024 01:03:33 -0800 Subject: [PATCH 107/220] Make IntentModule Nullsafe (#47430) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47430 Make IntentModule Nullsafe. Fixed nullability warnings. Changelog: [Internal] Reviewed By: tdn120 Differential Revision: D65463226 fbshipit-source-id: 2da597e66ad170ec4a2a2949348e522bb361c209 --- .../react/modules/intent/IntentModule.java | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/intent/IntentModule.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/intent/IntentModule.java index 4324495b07adb2..c471c56af3e564 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/intent/IntentModule.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/intent/IntentModule.java @@ -15,7 +15,9 @@ import android.nfc.NfcAdapter; import android.provider.Settings; import androidx.annotation.Nullable; +import androidx.core.util.Preconditions; import com.facebook.fbreact.specs.NativeIntentAndroidSpec; +import com.facebook.infer.annotation.Nullsafe; import com.facebook.react.bridge.JSApplicationIllegalArgumentException; import com.facebook.react.bridge.LifecycleEventListener; import com.facebook.react.bridge.Promise; @@ -28,6 +30,7 @@ import java.util.List; /** Intent module. Launch other activities or open URLs. */ +@Nullsafe(Nullsafe.Mode.LOCAL) @ReactModule(name = NativeIntentAndroidSpec.NAME) public class IntentModule extends NativeIntentAndroidSpec { @@ -124,7 +127,7 @@ public void onHostDestroy() {} * @param url the URL to open */ @Override - public void openURL(String url, Promise promise) { + public void openURL(@Nullable String url, Promise promise) { if (url == null || url.isEmpty()) { promise.reject(new JSApplicationIllegalArgumentException("Invalid URL: " + url)); return; @@ -149,7 +152,7 @@ public void openURL(String url, Promise promise) { * @param promise a promise that is always resolved with a boolean argument */ @Override - public void canOpenURL(String url, Promise promise) { + public void canOpenURL(@Nullable String url, Promise promise) { if (url == null || url.isEmpty()) { promise.reject(new JSApplicationIllegalArgumentException("Invalid URL: " + url)); return; @@ -160,8 +163,8 @@ public void canOpenURL(String url, Promise promise) { // We need Intent.FLAG_ACTIVITY_NEW_TASK since getReactApplicationContext() returns // the ApplicationContext instead of the Activity context. intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - boolean canOpen = - intent.resolveActivity(getReactApplicationContext().getPackageManager()) != null; + PackageManager packageManager = getReactApplicationContext().getPackageManager(); + boolean canOpen = packageManager != null && intent.resolveActivity(packageManager) != null; promise.resolve(canOpen); } catch (Exception e) { promise.reject( @@ -179,7 +182,7 @@ public void canOpenURL(String url, Promise promise) { public void openSettings(Promise promise) { try { Intent intent = new Intent(); - Activity currentActivity = getCurrentActivity(); + Activity currentActivity = Preconditions.checkNotNull(getCurrentActivity()); String selfPackageName = getReactApplicationContext().getPackageName(); intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); @@ -219,7 +222,7 @@ public void sendIntent(String action, @Nullable ReadableArray extras, Promise pr Intent intent = new Intent(action); PackageManager packageManager = getReactApplicationContext().getPackageManager(); - if (intent.resolveActivity(packageManager) == null) { + if (packageManager == null || intent.resolveActivity(packageManager) == null) { promise.reject( new JSApplicationIllegalArgumentException( "Could not launch Intent with action " + action + ".")); @@ -235,6 +238,7 @@ public void sendIntent(String action, @Nullable ReadableArray extras, Promise pr switch (type) { case String: { + // NULLSAFE_FIXME[Parameter Not Nullable] intent.putExtra(name, map.getString(EXTRA_MAP_KEY_FOR_VALUE)); break; } @@ -244,11 +248,13 @@ public void sendIntent(String action, @Nullable ReadableArray extras, Promise pr // See: https://github.com/facebook/react-native/issues/4141 // We might need to find a workaround if this is really an issue Double number = map.getDouble(EXTRA_MAP_KEY_FOR_VALUE); + // NULLSAFE_FIXME[Parameter Not Nullable] intent.putExtra(name, number); break; } case Boolean: { + // NULLSAFE_FIXME[Parameter Not Nullable] intent.putExtra(name, map.getBoolean(EXTRA_MAP_KEY_FOR_VALUE)); break; } @@ -270,8 +276,13 @@ private void sendOSIntent(Intent intent, Boolean useNewTaskFlag) { Activity currentActivity = getCurrentActivity(); String selfPackageName = getReactApplicationContext().getPackageName(); - ComponentName componentName = - intent.resolveActivity(getReactApplicationContext().getPackageManager()); + PackageManager packageManager = getReactApplicationContext().getPackageManager(); + ComponentName componentName = null; + if (packageManager == null) { + componentName = intent.getComponent(); + } else { + componentName = intent.resolveActivity(packageManager); + } String otherPackageName = (componentName != null ? componentName.getPackageName() : ""); // If there is no currentActivity or we are launching to a different package we need to set From 5e18f7f788ccbea60e96b8e7deab29d423ccf1a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Kwa=C5=9Bniewski?= Date: Thu, 7 Nov 2024 04:01:20 -0800 Subject: [PATCH 108/220] fix: typo in spm.rb (#47480) Summary: This PR fixes a typo in spm.rb ## Changelog: [IOS] [FIXED] - Typo in spm.rb Pull Request resolved: https://github.com/facebook/react-native/pull/47480 Test Plan: N/a Reviewed By: GijsWeterings Differential Revision: D65596339 Pulled By: cortinico fbshipit-source-id: c318cec1422dbcb322e70dc5f189d86af42b626d --- packages/react-native/scripts/cocoapods/spm.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-native/scripts/cocoapods/spm.rb b/packages/react-native/scripts/cocoapods/spm.rb index 78ca3c31e084b1..0b132076169b5d 100644 --- a/packages/react-native/scripts/cocoapods/spm.rb +++ b/packages/react-native/scripts/cocoapods/spm.rb @@ -45,7 +45,7 @@ def apply_on_post_install(installer) log_warning "If you're using Xcode 15 or earlier you might need to close and reopen the Xcode workspace" unless ENV["USE_FRAMEWORKS"] == "dynamic" @dependencies_by_pod.each do |pod_name, dependencies| - log_warning "Pod #{pod_name} is using swift package(s) #{dependencies.map{|i| i[:products]}.flatten.uniq.join(", ")} with static linking, this might cause linker errors. Consider using USE_FRAMEOWRKS=dynamic, see https://github.com/facebook/react-native/pull/44627#issuecomment-2123119711 for more information" + log_warning "Pod #{pod_name} is using swift package(s) #{dependencies.map{|i| i[:products]}.flatten.uniq.join(", ")} with static linking, this might cause linker errors. Consider using USE_FRAMEWORKS=dynamic, see https://github.com/facebook/react-native/pull/44627#issuecomment-2123119711 for more information" end end end From ace690aba9cd4cc73932f404a03ef36af0de53e7 Mon Sep 17 00:00:00 2001 From: Riccardo Cipolleschi Date: Thu, 7 Nov 2024 04:08:58 -0800 Subject: [PATCH 109/220] Generate RN specific Files in RN (#47458) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47458 We are in a weird situation where React Native depends on some files that are generated by Codegen. Codegen runs in the user project, so those dependencies are not available to React Native if we try to build it in isolation. This is a problem and a blocker to prepare the prebuilds for iOS. This image show the changes we are introducing: On the right we have the current situation. On the left the new one. {F1954418630} ## Changelog: [Internal] - Generate React Native specific code inside React Native Reviewed By: cortinico, blakef Differential Revision: D65541505 fbshipit-source-id: 1412d7f23c4d2230b795af41f1e832c8a70d5859 --- .gitignore | 2 +- .../AppDelegate/React-RCTAppDelegate.podspec | 2 +- .../Libraries/Blob/React-RCTBlob.podspec | 2 +- .../Libraries/Image/React-RCTImage.podspec | 2 +- .../LinkingIOS/React-RCTLinking.podspec | 2 +- .../React-RCTAnimation.podspec | 2 +- .../Network/React-RCTNetwork.podspec | 2 +- .../React-RCTPushNotification.podspec | 2 +- .../Settings/React-RCTSettings.podspec | 2 +- .../Vibration/React-RCTVibration.podspec | 2 +- .../CoreModules/React-CoreModules.podspec | 2 +- .../React/React-RCTFBReactNativeSpec.podspec | 84 +++++++++++++++++++ .../React-FabricComponents.podspec | 2 +- .../ReactCommon/jsi/React-jsi.podspec | 7 +- .../React-defaultsnativemodule.podspec | 20 ++++- .../dom/React-domnativemodule.podspec | 24 +++++- .../React-featureflagsnativemodule.podspec | 22 ++++- .../React-idlecallbacksnativemodule.podspec | 21 ++++- .../React-microtasksnativemodule.podspec | 21 ++++- .../samples/ReactCommon-Samples.podspec | 4 +- .../platform/ios/React-RuntimeApple.podspec | 2 +- .../codegen/generate-artifacts-executor.js | 62 ++++++++++++-- packages/react-native/scripts/prepack.js | 2 + .../react-native/scripts/react_native_pods.rb | 1 + 24 files changed, 255 insertions(+), 39 deletions(-) create mode 100644 packages/react-native/React/React-RCTFBReactNativeSpec.podspec diff --git a/.gitignore b/.gitignore index e734a3cffbb6f8..b26247390fb3d8 100644 --- a/.gitignore +++ b/.gitignore @@ -124,7 +124,7 @@ vendor/ !/packages/rn-tester/Pods/__offline_mirrors_jsc__ # @react-native/codegen -/packages/react-native/React/FBReactNativeSpec/FBReactNativeSpec +/packages/react-native/React/FBReactNativeSpec/ /packages/react-native-codegen/lib /packages/react-native-codegen/tmp/ /packages/react-native/ReactCommon/react/renderer/components/rncore/ diff --git a/packages/react-native/Libraries/AppDelegate/React-RCTAppDelegate.podspec b/packages/react-native/Libraries/AppDelegate/React-RCTAppDelegate.podspec index b54f1e41af5c40..edaf73d1f060a1 100644 --- a/packages/react-native/Libraries/AppDelegate/React-RCTAppDelegate.podspec +++ b/packages/react-native/Libraries/AppDelegate/React-RCTAppDelegate.podspec @@ -74,7 +74,7 @@ Pod::Spec.new do |s| s.dependency "React-RCTImage" s.dependency "React-CoreModules" s.dependency "React-nativeconfig" - s.dependency "ReactCodegen" + s.dependency "React-RCTFBReactNativeSpec" s.dependency "React-defaultsnativemodule" add_dependency(s, "ReactCommon", :subspec => "turbomodule/core", :additional_framework_paths => ["react/nativemodule/core"]) diff --git a/packages/react-native/Libraries/Blob/React-RCTBlob.podspec b/packages/react-native/Libraries/Blob/React-RCTBlob.podspec index c592234ed13394..9d758c174cf0ad 100644 --- a/packages/react-native/Libraries/Blob/React-RCTBlob.podspec +++ b/packages/react-native/Libraries/Blob/React-RCTBlob.podspec @@ -57,7 +57,7 @@ Pod::Spec.new do |s| s.dependency "React-Core/RCTWebSocket" s.dependency "React-RCTNetwork" - add_dependency(s, "ReactCodegen") + add_dependency(s, "React-RCTFBReactNativeSpec") add_dependency(s, "React-NativeModulesApple") add_dependency(s, "React-jsinspector", :framework_name => 'jsinspector_modern') add_dependency(s, "ReactCommon", :subspec => "turbomodule/core", :additional_framework_paths => ["react/nativemodule/core"]) diff --git a/packages/react-native/Libraries/Image/React-RCTImage.podspec b/packages/react-native/Libraries/Image/React-RCTImage.podspec index f0a56a7d67d60a..5e9d333701a898 100644 --- a/packages/react-native/Libraries/Image/React-RCTImage.podspec +++ b/packages/react-native/Libraries/Image/React-RCTImage.podspec @@ -53,7 +53,7 @@ Pod::Spec.new do |s| s.dependency "React-Core/RCTImageHeaders" s.dependency "React-RCTNetwork" - add_dependency(s, "ReactCodegen") + add_dependency(s, "React-RCTFBReactNativeSpec") add_dependency(s, "ReactCommon", :subspec => "turbomodule/core", :additional_framework_paths => ["react/nativemodule/core"]) add_dependency(s, "React-NativeModulesApple") diff --git a/packages/react-native/Libraries/LinkingIOS/React-RCTLinking.podspec b/packages/react-native/Libraries/LinkingIOS/React-RCTLinking.podspec index 2988120a1741f4..c2120fd2d4aabb 100644 --- a/packages/react-native/Libraries/LinkingIOS/React-RCTLinking.podspec +++ b/packages/react-native/Libraries/LinkingIOS/React-RCTLinking.podspec @@ -50,7 +50,7 @@ Pod::Spec.new do |s| s.dependency "ReactCommon/turbomodule/core", version s.dependency "React-jsi", version - add_dependency(s, "ReactCodegen", :additional_framework_paths => ["build/generated/ios"]) + add_dependency(s, "React-RCTFBReactNativeSpec") add_dependency(s, "ReactCommon", :subspec => "turbomodule/core", :additional_framework_paths => ["react/nativemodule/core"]) add_dependency(s, "React-NativeModulesApple", :additional_framework_paths => ["build/generated/ios"]) end diff --git a/packages/react-native/Libraries/NativeAnimation/React-RCTAnimation.podspec b/packages/react-native/Libraries/NativeAnimation/React-RCTAnimation.podspec index 8a10d02f1fe8b0..7143d45c72cc69 100644 --- a/packages/react-native/Libraries/NativeAnimation/React-RCTAnimation.podspec +++ b/packages/react-native/Libraries/NativeAnimation/React-RCTAnimation.podspec @@ -50,7 +50,7 @@ Pod::Spec.new do |s| s.dependency "React-jsi" s.dependency "React-Core/RCTAnimationHeaders" - add_dependency(s, "ReactCodegen", :additional_framework_paths => ["build/generated/ios"]) + add_dependency(s, "React-RCTFBReactNativeSpec") add_dependency(s, "ReactCommon", :subspec => "turbomodule/core", :additional_framework_paths => ["react/nativemodule/core"]) add_dependency(s, "React-NativeModulesApple") end diff --git a/packages/react-native/Libraries/Network/React-RCTNetwork.podspec b/packages/react-native/Libraries/Network/React-RCTNetwork.podspec index 3ad05bd89049c8..b3292864b2c4b7 100644 --- a/packages/react-native/Libraries/Network/React-RCTNetwork.podspec +++ b/packages/react-native/Libraries/Network/React-RCTNetwork.podspec @@ -50,7 +50,7 @@ Pod::Spec.new do |s| s.dependency "React-jsi" s.dependency "React-Core/RCTNetworkHeaders" - add_dependency(s, "ReactCodegen", :additional_framework_paths => ["build/generated/ios"]) + add_dependency(s, "React-RCTFBReactNativeSpec") add_dependency(s, "ReactCommon", :subspec => "turbomodule/core", :additional_framework_paths => ["react/nativemodule/core"]) add_dependency(s, "React-NativeModulesApple", :additional_framework_paths => ["build/generated/ios"]) end diff --git a/packages/react-native/Libraries/PushNotificationIOS/React-RCTPushNotification.podspec b/packages/react-native/Libraries/PushNotificationIOS/React-RCTPushNotification.podspec index 899cbb03ffcd7f..0ea9322132f5e3 100644 --- a/packages/react-native/Libraries/PushNotificationIOS/React-RCTPushNotification.podspec +++ b/packages/react-native/Libraries/PushNotificationIOS/React-RCTPushNotification.podspec @@ -50,7 +50,7 @@ Pod::Spec.new do |s| s.dependency "React-Core/RCTPushNotificationHeaders" s.dependency "React-jsi" - add_dependency(s, "ReactCodegen", :additional_framework_paths => ["build/generated/ios"]) + add_dependency(s, "React-RCTFBReactNativeSpec") add_dependency(s, "ReactCommon", :subspec => "turbomodule/core", :additional_framework_paths => ["react/nativemodule/core"]) add_dependency(s, "React-NativeModulesApple") end diff --git a/packages/react-native/Libraries/Settings/React-RCTSettings.podspec b/packages/react-native/Libraries/Settings/React-RCTSettings.podspec index ff18fb036ef403..b2a41b3d239274 100644 --- a/packages/react-native/Libraries/Settings/React-RCTSettings.podspec +++ b/packages/react-native/Libraries/Settings/React-RCTSettings.podspec @@ -50,7 +50,7 @@ Pod::Spec.new do |s| s.dependency "React-jsi" s.dependency "React-Core/RCTSettingsHeaders" - add_dependency(s, "ReactCodegen", :additional_framework_paths => ["build/generated/ios"]) + add_dependency(s, "React-RCTFBReactNativeSpec") add_dependency(s, "ReactCommon", :subspec => "turbomodule/core", :additional_framework_paths => ["react/nativemodule/core"]) add_dependency(s, "React-NativeModulesApple", :additional_framework_paths => ["build/generated/ios"]) end diff --git a/packages/react-native/Libraries/Vibration/React-RCTVibration.podspec b/packages/react-native/Libraries/Vibration/React-RCTVibration.podspec index 9454476fd80941..f54d4862c755ae 100644 --- a/packages/react-native/Libraries/Vibration/React-RCTVibration.podspec +++ b/packages/react-native/Libraries/Vibration/React-RCTVibration.podspec @@ -50,7 +50,7 @@ Pod::Spec.new do |s| s.dependency "React-jsi" s.dependency "React-Core/RCTVibrationHeaders" - add_dependency(s, "ReactCodegen", :additional_framework_paths => ["build/generated/ios"]) + add_dependency(s, "React-RCTFBReactNativeSpec") add_dependency(s, "ReactCommon", :subspec => "turbomodule/core", :additional_framework_paths => ["react/nativemodule/core"]) add_dependency(s, "React-NativeModulesApple") end diff --git a/packages/react-native/React/CoreModules/React-CoreModules.podspec b/packages/react-native/React/CoreModules/React-CoreModules.podspec index 43ef20bc2e989f..d41b66c0f5a383 100644 --- a/packages/react-native/React/CoreModules/React-CoreModules.podspec +++ b/packages/react-native/React/CoreModules/React-CoreModules.podspec @@ -71,7 +71,7 @@ Pod::Spec.new do |s| s.dependency "SocketRocket", socket_rocket_version add_dependency(s, "React-jsinspector", :framework_name => 'jsinspector_modern') - add_dependency(s, "ReactCodegen") + add_dependency(s, "React-RCTFBReactNativeSpec") add_dependency(s, "ReactCommon", :subspec => "turbomodule/core", :additional_framework_paths => ["react/nativemodule/core"]) add_dependency(s, "React-NativeModulesApple") end diff --git a/packages/react-native/React/React-RCTFBReactNativeSpec.podspec b/packages/react-native/React/React-RCTFBReactNativeSpec.podspec new file mode 100644 index 00000000000000..84513f04a43e5c --- /dev/null +++ b/packages/react-native/React/React-RCTFBReactNativeSpec.podspec @@ -0,0 +1,84 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +require "json" + +package = JSON.parse(File.read(File.join(__dir__, "..", "package.json"))) +version = package['version'] + +source = { :git => 'https://github.com/facebook/react-native.git' } +if version == '1000.0.0' + # This is an unpublished version, use the latest commit hash of the react-native repo, which we’re presumably in. + source[:commit] = `git rev-parse HEAD`.strip if system("git rev-parse --git-dir > /dev/null 2>&1") +else + source[:tag] = "v#{version}" +end + +module_name = "FBReactNativeSpec" +header_dir = "FBReactNativeSpec" + +folly_config = get_folly_config() +folly_compiler_flags = folly_config[:compiler_flags] +folly_version = folly_config[:version] +boost_config = get_boost_config() +boost_compiler_flags = boost_config[:compiler_flags] +new_arch_flags = ENV['RCT_NEW_ARCH_ENABLED'] == '1' ? ' -DRCT_NEW_ARCH_ENABLED=1' : '' + +header_search_paths = [ + "\"$(PODS_ROOT)/RCT-Folly\"", +] + +Pod::Spec.new do |s| + s.name = "React-RCTFBReactNativeSpec" + s.version = version + s.summary = "FBReactNativeSpec for React Native." + s.homepage = "https://reactnative.dev/" + s.license = package["license"] + s.author = "Meta Platforms, Inc. and its affiliates" + s.platforms = min_supported_versions + s.source = source + s.source_files = "FBReactNativeSpec/**/*.{c,h,m,mm,S,cpp}" + s.compiler_flags = folly_compiler_flags + ' ' + boost_compiler_flags + new_arch_flags + s.header_dir = header_dir + s.module_name = module_name + s.pod_target_xcconfig = { + "HEADER_SEARCH_PATHS" => header_search_paths, + "OTHER_CFLAGS" => "$(inherited) " + folly_compiler_flags + new_arch_flags, + "CLANG_CXX_LANGUAGE_STANDARD" => rct_cxx_language_standard() + } + + s.dependency "React-jsi" + s.dependency "React-jsiexecutor" + s.dependency "RCT-Folly" + s.dependency "RCTRequired" + s.dependency "RCTTypeSafety" + s.dependency "React-Core" + s.dependency "React-NativeModulesApple" + add_dependency(s, "ReactCommon", :subspec => "turbomodule/core", :additional_framework_paths => ["react/nativemodule/core"]) + add_dependency(s, "ReactCommon", :subspec => "turbomodule/bridging", :additional_framework_paths => ["react/nativemodule/bridging"]) + + if ENV["USE_HERMES"] == nil || ENV["USE_HERMES"] == "1" + s.dependency "hermes-engine" + else + s.dependency "React-jsc" + end + + + s.script_phases = [ + { + :name => '[RN]Check FBReactNativeSpec', + :execution_position => :before_compile, + :script => <<-EOS +echo "Checking whether Codegen has run..." +fbReactNativeSpecPath="$REACT_NATIVE_PATH/React/FBReactNativeSpec" + +if [[ ! -d "$fbReactNativeSpecPath" ]]; then + echo 'error: Codegen did not run properly in your project. Please reinstall cocoapods with `bundle exec pod install`.' + exit 1 +fi + EOS + } + ] +end diff --git a/packages/react-native/ReactCommon/React-FabricComponents.podspec b/packages/react-native/ReactCommon/React-FabricComponents.podspec index 0ee540321355b0..0d4e55a1475e4e 100644 --- a/packages/react-native/ReactCommon/React-FabricComponents.podspec +++ b/packages/react-native/ReactCommon/React-FabricComponents.podspec @@ -92,7 +92,7 @@ Pod::Spec.new do |s| "react/renderer/components/view/platform/cxx", "react/renderer/imagemanager/platform/ios" ]) - add_dependency(s, "ReactCodegen", :additional_framework_paths => ["build/generated/ios"]) + # add_dependency(s, "React-RCTFBReactNativeSpec") if ENV["USE_HERMES"] == nil || ENV["USE_HERMES"] == "1" s.dependency "hermes-engine" diff --git a/packages/react-native/ReactCommon/jsi/React-jsi.podspec b/packages/react-native/ReactCommon/jsi/React-jsi.podspec index 9425d6761f4d64..fb3cbe9556f4ed 100644 --- a/packages/react-native/ReactCommon/jsi/React-jsi.podspec +++ b/packages/react-native/ReactCommon/jsi/React-jsi.podspec @@ -38,8 +38,11 @@ Pod::Spec.new do |s| s.header_dir = "jsi" s.compiler_flags = folly_compiler_flags + ' ' + boost_compiler_flags - s.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/RCT-Folly\" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_ROOT)/fast_float/include\" \"$(PODS_ROOT)/fmt/include\"", - "DEFINES_MODULE" => "YES" } + s.pod_target_xcconfig = { + "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/RCT-Folly\" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_ROOT)/fast_float/include\" \"$(PODS_ROOT)/fmt/include\"", + "CLANG_CXX_LANGUAGE_STANDARD" => rct_cxx_language_standard(), + "DEFINES_MODULE" => "YES" + } s.dependency "boost" s.dependency "DoubleConversion" diff --git a/packages/react-native/ReactCommon/react/nativemodule/defaults/React-defaultsnativemodule.podspec b/packages/react-native/ReactCommon/react/nativemodule/defaults/React-defaultsnativemodule.podspec index 77cc249c1bfec5..ec20ddc21f0819 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/defaults/React-defaultsnativemodule.podspec +++ b/packages/react-native/ReactCommon/react/nativemodule/defaults/React-defaultsnativemodule.podspec @@ -16,7 +16,13 @@ else source[:tag] = "v#{version}" end -header_search_paths = [] +header_search_paths = [ + "\"$(PODS_ROOT)/RCT-Folly\"", +] + +folly_config = get_folly_config() +folly_compiler_flags = folly_config[:compiler_flags] +folly_version = folly_config[:version] if ENV['USE_FRAMEWORKS'] header_search_paths << "\"$(PODS_TARGET_SRCROOT)/../../..\"" # this is needed to allow the defaultsnativemodule to access its own files @@ -31,10 +37,12 @@ Pod::Spec.new do |s| s.author = "Meta Platforms, Inc. and its affiliates" s.platforms = min_supported_versions s.source = source + s.compiler_flags = folly_compiler_flags s.source_files = "*.{cpp,h}" s.header_dir = "react/nativemodule/defaults" s.pod_target_xcconfig = { "CLANG_CXX_LANGUAGE_STANDARD" => rct_cxx_language_standard(), "HEADER_SEARCH_PATHS" => header_search_paths.join(' '), + "OTHER_CFLAGS" => "$(inherited) " + folly_compiler_flags, "DEFINES_MODULE" => "YES" } if ENV['USE_FRAMEWORKS'] @@ -42,10 +50,18 @@ Pod::Spec.new do |s| s.header_mappings_dir = "../.." end - install_modules_dependencies(s) + s.dependency "RCT-Folly" + s.dependency "React-jsi" + s.dependency "React-jsiexecutor" + if ENV["USE_HERMES"] == nil || ENV["USE_HERMES"] == "1" + s.dependency "hermes-engine" + else + s.dependency "React-jsc" + end s.dependency "React-domnativemodule" s.dependency "React-featureflagsnativemodule" s.dependency "React-microtasksnativemodule" s.dependency "React-idlecallbacksnativemodule" + add_dependency(s, "React-RCTFBReactNativeSpec") end diff --git a/packages/react-native/ReactCommon/react/nativemodule/dom/React-domnativemodule.podspec b/packages/react-native/ReactCommon/react/nativemodule/dom/React-domnativemodule.podspec index 03b8f843d01862..21a02fdc0963ad 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/dom/React-domnativemodule.podspec +++ b/packages/react-native/ReactCommon/react/nativemodule/dom/React-domnativemodule.podspec @@ -16,7 +16,14 @@ else source[:tag] = "v#{version}" end -header_search_paths = [] +header_search_paths = [ + "\"$(PODS_ROOT)/RCT-Folly\"", + "\"$(PODS_ROOT)/Headers/Private/Yoga\"", +] + +folly_config = get_folly_config() +folly_compiler_flags = folly_config[:compiler_flags] +folly_version = folly_config[:version] if ENV['USE_FRAMEWORKS'] header_search_paths << "\"$(PODS_TARGET_SRCROOT)/../../..\"" # this is needed to allow the domnativemodule to access its own files @@ -31,10 +38,12 @@ Pod::Spec.new do |s| s.author = "Meta Platforms, Inc. and its affiliates" s.platforms = min_supported_versions s.source = source + s.compiler_flags = folly_compiler_flags s.source_files = "*.{cpp,h}" s.header_dir = "react/nativemodule/dom" s.pod_target_xcconfig = { "CLANG_CXX_LANGUAGE_STANDARD" => rct_cxx_language_standard(), "HEADER_SEARCH_PATHS" => header_search_paths.join(' '), + "OTHER_CFLAGS" => "$(inherited) " + folly_compiler_flags, "DEFINES_MODULE" => "YES" } if ENV['USE_FRAMEWORKS'] @@ -42,9 +51,18 @@ Pod::Spec.new do |s| s.header_mappings_dir = "../.." end - install_modules_dependencies(s) - + s.dependency "RCT-Folly" + s.dependency "React-jsi" + s.dependency "React-jsiexecutor" + if ENV["USE_HERMES"] == nil || ENV["USE_HERMES"] == "1" + s.dependency "hermes-engine" + else + s.dependency "React-jsc" + end + s.dependency "Yoga" s.dependency "ReactCommon/turbomodule/core" s.dependency "React-Fabric" s.dependency "React-FabricComponents" + add_dependency(s, "React-graphics", :additional_framework_paths => ["react/renderer/graphics/platform/ios"]) + add_dependency(s, "React-RCTFBReactNativeSpec") end diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/React-featureflagsnativemodule.podspec b/packages/react-native/ReactCommon/react/nativemodule/featureflags/React-featureflagsnativemodule.podspec index 6e87da441efd5c..272b06566e10ee 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/featureflags/React-featureflagsnativemodule.podspec +++ b/packages/react-native/ReactCommon/react/nativemodule/featureflags/React-featureflagsnativemodule.podspec @@ -16,7 +16,13 @@ else source[:tag] = "v#{version}" end -header_search_paths = [] +header_search_paths = [ + "\"$(PODS_ROOT)/RCT-Folly\"", +] + +folly_config = get_folly_config() +folly_compiler_flags = folly_config[:compiler_flags] +folly_version = folly_config[:version] if ENV['USE_FRAMEWORKS'] header_search_paths << "\"$(PODS_TARGET_SRCROOT)/../../..\"" # this is needed to allow the feature flags access its own files @@ -31,10 +37,12 @@ Pod::Spec.new do |s| s.author = "Meta Platforms, Inc. and its affiliates" s.platforms = min_supported_versions s.source = source + s.compiler_flags = folly_compiler_flags s.source_files = "*.{cpp,h}" s.header_dir = "react/nativemodule/featureflags" s.pod_target_xcconfig = { "CLANG_CXX_LANGUAGE_STANDARD" => rct_cxx_language_standard(), "HEADER_SEARCH_PATHS" => header_search_paths.join(' '), + "OTHER_CFLAGS" => "$(inherited) " + folly_compiler_flags, "DEFINES_MODULE" => "YES" } if ENV['USE_FRAMEWORKS'] @@ -42,7 +50,15 @@ Pod::Spec.new do |s| s.header_mappings_dir = "../.." end - install_modules_dependencies(s) - + s.dependency "RCT-Folly" + s.dependency "React-jsi" + s.dependency "React-jsiexecutor" + if ENV["USE_HERMES"] == nil || ENV["USE_HERMES"] == "1" + s.dependency "hermes-engine" + else + s.dependency "React-jsc" + end s.dependency "ReactCommon/turbomodule/core" + s.dependency "React-RCTFBReactNativeSpec" + s.dependency "React-featureflags" end diff --git a/packages/react-native/ReactCommon/react/nativemodule/idlecallbacks/React-idlecallbacksnativemodule.podspec b/packages/react-native/ReactCommon/react/nativemodule/idlecallbacks/React-idlecallbacksnativemodule.podspec index e29f942205b187..c526a7f290bbe1 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/idlecallbacks/React-idlecallbacksnativemodule.podspec +++ b/packages/react-native/ReactCommon/react/nativemodule/idlecallbacks/React-idlecallbacksnativemodule.podspec @@ -16,7 +16,13 @@ else source[:tag] = "v#{version}" end -header_search_paths = [] +header_search_paths = [ + "\"$(PODS_ROOT)/RCT-Folly\"", +] + +folly_config = get_folly_config() +folly_compiler_flags = folly_config[:compiler_flags] +folly_version = folly_config[:version] if ENV['USE_FRAMEWORKS'] header_search_paths << "\"$(PODS_TARGET_SRCROOT)/../../..\"" # this is needed to allow the module access its own files @@ -31,10 +37,12 @@ Pod::Spec.new do |s| s.author = "Meta Platforms, Inc. and its affiliates" s.platforms = min_supported_versions s.source = source + s.compiler_flags = folly_compiler_flags s.source_files = "*.{cpp,h}" s.header_dir = "react/nativemodule/idlecallbacks" s.pod_target_xcconfig = { "CLANG_CXX_LANGUAGE_STANDARD" => rct_cxx_language_standard(), "HEADER_SEARCH_PATHS" => header_search_paths.join(' '), + "OTHER_CFLAGS" => "$(inherited) " + folly_compiler_flags, "DEFINES_MODULE" => "YES" } if ENV['USE_FRAMEWORKS'] @@ -42,8 +50,15 @@ Pod::Spec.new do |s| s.header_mappings_dir = "../.." end - install_modules_dependencies(s) - + s.dependency "RCT-Folly" + s.dependency "React-jsi" + s.dependency "React-jsiexecutor" + if ENV["USE_HERMES"] == nil || ENV["USE_HERMES"] == "1" + s.dependency "hermes-engine" + else + s.dependency "React-jsc" + end s.dependency "ReactCommon/turbomodule/core" s.dependency "React-runtimescheduler" + add_dependency(s, "React-RCTFBReactNativeSpec") end diff --git a/packages/react-native/ReactCommon/react/nativemodule/microtasks/React-microtasksnativemodule.podspec b/packages/react-native/ReactCommon/react/nativemodule/microtasks/React-microtasksnativemodule.podspec index 20d26d847b98fb..e490082e17b036 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/microtasks/React-microtasksnativemodule.podspec +++ b/packages/react-native/ReactCommon/react/nativemodule/microtasks/React-microtasksnativemodule.podspec @@ -16,7 +16,13 @@ else source[:tag] = "v#{version}" end -header_search_paths = [] +header_search_paths = [ + "\"$(PODS_ROOT)/RCT-Folly\"", +] + +folly_config = get_folly_config() +folly_compiler_flags = folly_config[:compiler_flags] +folly_version = folly_config[:version] if ENV['USE_FRAMEWORKS'] header_search_paths << "\"$(PODS_TARGET_SRCROOT)/../../..\"" # this is needed to allow the microtasks module access its own files @@ -31,9 +37,11 @@ Pod::Spec.new do |s| s.author = "Meta Platforms, Inc. and its affiliates" s.platforms = min_supported_versions s.source = source + s.compiler_flags = folly_compiler_flags s.source_files = "*.{cpp,h}" s.header_dir = "react/nativemodule/microtasks" s.pod_target_xcconfig = { "CLANG_CXX_LANGUAGE_STANDARD" => rct_cxx_language_standard(), + "OTHER_CFLAGS" => "$(inherited) " + folly_compiler_flags, "HEADER_SEARCH_PATHS" => header_search_paths.join(' '), "DEFINES_MODULE" => "YES" } @@ -42,7 +50,14 @@ Pod::Spec.new do |s| s.header_mappings_dir = "../.." end - install_modules_dependencies(s) - + s.dependency "RCT-Folly" + s.dependency "React-jsi" + s.dependency "React-jsiexecutor" + if ENV["USE_HERMES"] == nil || ENV["USE_HERMES"] == "1" + s.dependency "hermes-engine" + else + s.dependency "React-jsc" + end s.dependency "ReactCommon/turbomodule/core" + add_dependency(s, "React-RCTFBReactNativeSpec") end diff --git a/packages/react-native/ReactCommon/react/nativemodule/samples/ReactCommon-Samples.podspec b/packages/react-native/ReactCommon/react/nativemodule/samples/ReactCommon-Samples.podspec index b6155cbb19d533..5c35ba1eab3ecf 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/samples/ReactCommon-Samples.podspec +++ b/packages/react-native/ReactCommon/react/nativemodule/samples/ReactCommon-Samples.podspec @@ -69,9 +69,9 @@ Pod::Spec.new do |s| s.dependency "React-Core" s.dependency "React-cxxreact" s.dependency "React-jsi" - add_dependency(s, "ReactCodegen", :additional_framework_paths => ["build/generated/ios"]) + add_dependency(s, "React-RCTFBReactNativeSpec") add_dependency(s, "ReactCommon", :subspec => "turbomodule/core", :additional_framework_paths => ["react/nativemodule/core"]) - add_dependency(s, "React-NativeModulesApple", :additional_framework_paths => ["build/generated/ios"]) + add_dependency(s, "React-NativeModulesApple") if using_hermes s.dependency "hermes-engine" diff --git a/packages/react-native/ReactCommon/react/runtime/platform/ios/React-RuntimeApple.podspec b/packages/react-native/ReactCommon/react/runtime/platform/ios/React-RuntimeApple.podspec index ed57c3c9a9a679..7bf217816fa753 100644 --- a/packages/react-native/ReactCommon/react/runtime/platform/ios/React-RuntimeApple.podspec +++ b/packages/react-native/ReactCommon/react/runtime/platform/ios/React-RuntimeApple.podspec @@ -71,7 +71,7 @@ Pod::Spec.new do |s| s.dependency "React-jsinspector" s.dependency "React-featureflags" - add_dependency(s, "ReactCodegen") + add_dependency(s, "React-RCTFBReactNativeSpec") if ENV["USE_HERMES"] == nil || ENV["USE_HERMES"] == "1" s.dependency "hermes-engine" diff --git a/packages/react-native/scripts/codegen/generate-artifacts-executor.js b/packages/react-native/scripts/codegen/generate-artifacts-executor.js index d9af18b0806b8b..f50288816f38bb 100644 --- a/packages/react-native/scripts/codegen/generate-artifacts-executor.js +++ b/packages/react-native/scripts/codegen/generate-artifacts-executor.js @@ -47,7 +47,11 @@ const RNCORE_CONFIGS = { const CORE_LIBRARIES_WITH_OUTPUT_FOLDER = { rncore: RNCORE_CONFIGS, FBReactNativeSpec: { - ios: null, + ios: path.join( + REACT_NATIVE_PACKAGE_ROOT_FOLDER, + 'React', + 'FBReactNativeSpec', + ), android: path.join( REACT_NATIVE_PACKAGE_ROOT_FOLDER, 'ReactAndroid', @@ -451,13 +455,7 @@ function shouldSkipGenerationForRncore(schemaInfo, platform) { if (platform !== 'ios' || schemaInfo.library.config.name !== 'rncore') { return false; } - const rncoreOutputPath = path.join( - RNCORE_CONFIGS.ios, - 'react', - 'renderer', - 'components', - 'rncore', - ); + const rncoreOutputPath = CORE_LIBRARIES_WITH_OUTPUT_FOLDER.rncore.ios; const rncoreAbsolutePath = path.resolve(rncoreOutputPath); return ( rncoreAbsolutePath.includes('node_modules') && @@ -466,6 +464,26 @@ function shouldSkipGenerationForRncore(schemaInfo, platform) { ); } +function shouldSkipGenerationForFBReactNativeSpec(schemaInfo, platform) { + if ( + platform !== 'ios' || + schemaInfo.library.config.name !== 'FBReactNativeSpec' + ) { + return false; + } + + const fbReactNativeSpecOutputPath = + CORE_LIBRARIES_WITH_OUTPUT_FOLDER.FBReactNativeSpec.ios; + const fbReactNativeSpecAbsolutePath = path.resolve( + fbReactNativeSpecOutputPath, + ); + return ( + fbReactNativeSpecAbsolutePath.includes('node_modules') && + fs.existsSync(fbReactNativeSpecAbsolutePath) && + fs.readdirSync(fbReactNativeSpecAbsolutePath).length > 0 + ); +} + function generateCode(outputPath, schemaInfo, includesGeneratedCode, platform) { if (shouldSkipGenerationForRncore(schemaInfo, platform)) { codegenLog( @@ -475,6 +493,14 @@ function generateCode(outputPath, schemaInfo, includesGeneratedCode, platform) { return; } + if (shouldSkipGenerationForFBReactNativeSpec(schemaInfo, platform)) { + codegenLog( + '[Codegen - FBReactNativeSpec] Skipping iOS code generation for FBReactNativeSpec as it has been generated already.', + true, + ); + return; + } + const libraryName = schemaInfo.library.config.name; const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), libraryName)); const tmpOutputDir = path.join(tmpDir, 'out'); @@ -615,6 +641,8 @@ function generateCustomURLHandlers(libraries, outputDir) { .replace(/{imageDataDecoderClassNames}/, customImageDataDecoderClasses) .replace(/{requestHandlersClassNames}/, customURLHandlerClasses); + fs.mkdirSync(outputDir, {recursive: true}); + fs.writeFileSync( path.join(outputDir, 'RCTModulesConformingToProtocolsProvider.mm'), finalMMFile, @@ -676,6 +704,23 @@ function generateRNCoreComponentsIOS(projectRoot /*: string */) /*: void*/ { generateCode('', rncoreSchemaInfo, false, ios); } +function generateFBReactNativeSpecIOS(projectRoot /*: string */) /*: void*/ { + const ios = 'ios'; + buildCodegenIfNeeded(); + const pkgJson = readPkgJsonInDirectory(projectRoot); + const fbReactNativeSpecLib = findProjectRootLibraries( + pkgJson, + projectRoot, + ).filter(library => library.config.name === 'FBReactNativeSpec')[0]; + if (!fbReactNativeSpecLib) { + throw new Error( + "[Codegen] Can't find FBReactNativeSpec library. Failed to generate rncore artifacts", + ); + } + const fbReactNativeSchemaInfo = generateSchemaInfo(fbReactNativeSpecLib, ios); + generateCode('', fbReactNativeSchemaInfo, false, ios); +} + // Execute /** @@ -773,6 +818,7 @@ function execute(projectRoot, targetPlatform, baseOutputPath) { module.exports = { execute, generateRNCoreComponentsIOS, + generateFBReactNativeSpecIOS, // exported for testing purposes only: _extractLibrariesFromJSON: extractLibrariesFromJSON, _cleanupEmptyFilesAndFolders: cleanupEmptyFilesAndFolders, diff --git a/packages/react-native/scripts/prepack.js b/packages/react-native/scripts/prepack.js index 694e891117dd62..c88cb4638f17e5 100644 --- a/packages/react-native/scripts/prepack.js +++ b/packages/react-native/scripts/prepack.js @@ -10,6 +10,7 @@ */ const { + generateFBReactNativeSpecIOS, generateRNCoreComponentsIOS, } = require('./codegen/generate-artifacts-executor'); const fs = require('fs'); @@ -18,6 +19,7 @@ function main() { console.info('[Prepack] Copying README.md'); fs.copyFileSync('../../README.md', './README.md'); generateRNCoreComponentsIOS('.'); + generateFBReactNativeSpecIOS('.'); } if (require.main === module) { diff --git a/packages/react-native/scripts/react_native_pods.rb b/packages/react-native/scripts/react_native_pods.rb index 14cb67b102d7dd..7d99f2b9e7d327 100644 --- a/packages/react-native/scripts/react_native_pods.rb +++ b/packages/react-native/scripts/react_native_pods.rb @@ -130,6 +130,7 @@ def use_react_native! ( pod 'React-jserrorhandler', :path => "#{prefix}/ReactCommon/jserrorhandler" pod 'React-nativeconfig', :path => "#{prefix}/ReactCommon" pod 'RCTDeprecation', :path => "#{prefix}/ReactApple/Libraries/RCTFoundation/RCTDeprecation" + pod 'React-RCTFBReactNativeSpec', :path => "#{prefix}/React" if hermes_enabled setup_hermes!(:react_native_path => prefix) From 8bb3033d73e87f6220e7332c1f4668069e850266 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Guzm=C3=A1n?= Date: Thu, 7 Nov 2024 04:37:19 -0800 Subject: [PATCH 110/220] fix(flow): excluding `packages/rn-tester/Pods/` from flow checks (#47474) Summary: When running the commands to check the flow types locally, there is quite some noise from files under `packages/rn-tester/Pods` that should not be checked as they are not from the source code itself. Screenshot 2024-11-07 at 00 50 55 ## Changelog: [INTERNAL] [FIXED] - Excluding `packages/rn-tester/Pods/` from flow checks Pull Request resolved: https://github.com/facebook/react-native/pull/47474 Test Plan: ```bash yarn flow ``` Reviewed By: cortinico Differential Revision: D65594400 Pulled By: cipolleschi fbshipit-source-id: d5e8828f41fc87c9a95293c250f24673ebbc6cd4 --- .flowconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.flowconfig b/.flowconfig index 44a756caaed099..8eb6023d7ade54 100644 --- a/.flowconfig +++ b/.flowconfig @@ -26,6 +26,9 @@ ; helloworld /packages/helloworld/ios/Pods/ +; Ignore rn-tester Pods +/packages/rn-tester/Pods/ + [untyped] .*/node_modules/@react-native-community/cli/.*/.* From ffa159e147bda74fbfb25f3c9902da3991957a15 Mon Sep 17 00:00:00 2001 From: Riccardo Cipolleschi Date: Thu, 7 Nov 2024 04:50:55 -0800 Subject: [PATCH 111/220] Set ASSUME_NONULL in codegen files (#47481) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47481 The Codegenerated files has this option turned off. This is causing Xcode to output hundreds of warnings due to missing nullability options. RThis fixes them. ## CHANGELOG [Internal] - Set ASSUME_NONNULL regions in codegen'd files Reviewed By: dmytrorykun Differential Revision: D65596598 fbshipit-source-id: bbf664944e103c05ef593a7e07bf5b767445950c --- .../react-native/scripts/codegen/generate-specs-cli-executor.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/react-native/scripts/codegen/generate-specs-cli-executor.js b/packages/react-native/scripts/codegen/generate-specs-cli-executor.js index daae945a196c28..ece43d63b21957 100644 --- a/packages/react-native/scripts/codegen/generate-specs-cli-executor.js +++ b/packages/react-native/scripts/codegen/generate-specs-cli-executor.js @@ -80,6 +80,7 @@ function generateSpecFromInMemorySchema( schema, outputDirectory, packageName, + assumeNonnull: platform === 'ios', useLocalIncludePaths, }, { From 9e399d940a34269ca92e314598e1dce2e7eeafc6 Mon Sep 17 00:00:00 2001 From: Riccardo Cipolleschi Date: Thu, 7 Nov 2024 04:57:49 -0800 Subject: [PATCH 112/220] Remove XCBeautify from CI (#47482) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47482 XCBeautify swallow some errors, especially all the linker errors when some symbol is not defined. The full error is not available in the raw log either. This makes much harder to debug those issues when they happen. We can remove xcbeautify for the time being, while we find a better solution. ## Changelog [Internal] - Remove XCBeautify from ci Reviewed By: dmytrorykun Differential Revision: D65596745 fbshipit-source-id: 0550d4cbeadc5bec8acc61b5edc1320d3445bcaf --- .github/actions/prepare-ios-tests/action.yml | 3 --- .github/actions/test-ios-rntester/action.yml | 8 ++++---- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/.github/actions/prepare-ios-tests/action.yml b/.github/actions/prepare-ios-tests/action.yml index daa43b3b64e1b2..6465f0db99bd2c 100644 --- a/.github/actions/prepare-ios-tests/action.yml +++ b/.github/actions/prepare-ios-tests/action.yml @@ -3,9 +3,6 @@ description: Prepare iOS Tests runs: using: composite steps: - - name: brew install xcbeautify - run: brew install xcbeautify - shell: bash - name: Run Ruby Tests shell: bash run: | diff --git a/.github/actions/test-ios-rntester/action.yml b/.github/actions/test-ios-rntester/action.yml index 61c28f6b8b1642..25acfe2cd60353 100644 --- a/.github/actions/test-ios-rntester/action.yml +++ b/.github/actions/test-ios-rntester/action.yml @@ -121,21 +121,21 @@ runs: if: ${{ inputs.run-unit-tests != 'true' && inputs.run-e2e-tests == 'false' }} shell: bash run: | - set -o pipefail && xcodebuild build \ + xcodebuild build \ -workspace packages/rn-tester/RNTesterPods.xcworkspace \ -scheme RNTester \ - -sdk iphonesimulator | xcbeautify + -sdk iphonesimulator - name: Build RNTester (E2E Tests) shell: bash if: ${{ inputs.run-e2e-tests == 'true' }} run: | - set -o pipefail && xcodebuild \ + xcodebuild \ -scheme "RNTester" \ -workspace packages/rn-tester/RNTesterPods.xcworkspace \ -configuration "${{ inputs.flavor }}" \ -sdk "iphonesimulator" \ -destination "generic/platform=iOS Simulator" \ - -derivedDataPath "/tmp/RNTesterBuild" | xcbeautify + -derivedDataPath "/tmp/RNTesterBuild" echo "Print path to *.app file" find "/tmp/RNTesterBuild" -type d -name "*.app" From 4567e2a89713833e2a746057bd3b74b7ffff2fc5 Mon Sep 17 00:00:00 2001 From: Alex Hunt Date: Thu, 7 Nov 2024 05:13:53 -0800 Subject: [PATCH 113/220] Remove redundant UnimplementedView export from BackHandler (#47461) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47461 As titled, is overwritten later in the file. Changelog: [Internal] Reviewed By: cortinico Differential Revision: D65546370 fbshipit-source-id: 4ea71d24e429b7bbded3e7bb7c75015a2c9d95d8 --- packages/react-native/Libraries/Utilities/BackHandler.ios.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/react-native/Libraries/Utilities/BackHandler.ios.js b/packages/react-native/Libraries/Utilities/BackHandler.ios.js index 3cd03706467aa3..49bd876d817a9b 100644 --- a/packages/react-native/Libraries/Utilities/BackHandler.ios.js +++ b/packages/react-native/Libraries/Utilities/BackHandler.ios.js @@ -10,8 +10,6 @@ 'use strict'; -module.exports = require('../Components/UnimplementedViews/UnimplementedView'); - type BackPressEventName = 'backPress' | 'hardwareBackPress'; function emptyFunction(): void {} From 7817ab5de2ce324df734a5dfd705f2454937328f Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Thu, 7 Nov 2024 05:25:17 -0800 Subject: [PATCH 114/220] Reland: Undo breaking change of UiManager.eventDispatcher by solving circular dependency (#47478) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47478 That's a reland of D65540601 The `UIManager.eventDispatcher` return type is wrong and is causing a breaking change in 0.77 For 0.76 we fixed it in the release branch but we should fix it for good in main as well. To solve it I had to fix the circular dependency between .bridge and .uimanager. I wish I could have isolated the .events package better but as everythign is public, any change we do is going to be a breaking change so I'm being over cautios here. Changelog: [Android] [Fixed] - Undo breaking change of UiManager.eventDispatcher return type Reviewed By: javache Differential Revision: D65595391 fbshipit-source-id: fc7f6dce78e531c5ec0cc493ed90c0012262b77f --- packages/react-native/ReactAndroid/api/ReactAndroid.api | 4 +--- .../src/main/java/com/facebook/react/bridge/UIManager.kt | 3 ++- .../test/java/com/facebook/testutils/fakes/FakeUIManager.kt | 3 ++- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index df42862cb41fc9..6b666914780d39 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -1555,7 +1555,7 @@ public abstract interface class com/facebook/react/bridge/UIManager : com/facebo public abstract fun addUIManagerEventListener (Lcom/facebook/react/bridge/UIManagerListener;)V public abstract fun dispatchCommand (IILcom/facebook/react/bridge/ReadableArray;)V public abstract fun dispatchCommand (ILjava/lang/String;Lcom/facebook/react/bridge/ReadableArray;)V - public abstract fun getEventDispatcher ()Ljava/lang/Object; + public abstract fun getEventDispatcher ()Lcom/facebook/react/uimanager/events/EventDispatcher; public abstract fun initialize ()V public abstract fun invalidate ()V public abstract fun markActiveTouchForTag (II)V @@ -2615,7 +2615,6 @@ public class com/facebook/react/fabric/FabricUIManager : com/facebook/react/brid public fun dispatchCommand (ILjava/lang/String;Lcom/facebook/react/bridge/ReadableArray;)V public fun getColor (I[Ljava/lang/String;)I public fun getEventDispatcher ()Lcom/facebook/react/uimanager/events/EventDispatcher; - public synthetic fun getEventDispatcher ()Ljava/lang/Object; public fun getInspectorDataForInstance (ILandroid/view/View;)Lcom/facebook/react/bridge/ReadableMap; public fun getPerformanceCounters ()Ljava/util/Map; public fun getThemeData (I[F)Z @@ -5149,7 +5148,6 @@ public class com/facebook/react/uimanager/UIManagerModule : com/facebook/react/b public fun getDefaultEventTypes ()Lcom/facebook/react/bridge/WritableMap; public fun getDirectEventNamesResolver ()Lcom/facebook/react/uimanager/UIManagerModule$CustomEventNamesResolver; public fun getEventDispatcher ()Lcom/facebook/react/uimanager/events/EventDispatcher; - public synthetic fun getEventDispatcher ()Ljava/lang/Object; public fun getName ()Ljava/lang/String; public fun getPerformanceCounters ()Ljava/util/Map; public fun getUIImplementation ()Lcom/facebook/react/uimanager/UIImplementation; diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/UIManager.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/UIManager.kt index f893f0ea209f8c..c0729f86de9566 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/UIManager.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/UIManager.kt @@ -12,6 +12,7 @@ import androidx.annotation.AnyThread import androidx.annotation.UiThread import com.facebook.infer.annotation.ThreadConfined import com.facebook.react.common.annotations.UnstableReactNativeAPI +import com.facebook.react.uimanager.events.EventDispatcher @OptIn(UnstableReactNativeAPI::class) public interface UIManager : PerformanceCounter { @@ -78,7 +79,7 @@ public interface UIManager : PerformanceCounter { public fun dispatchCommand(reactTag: Int, commandId: String, commandArgs: ReadableArray?) /** @return the [EventDispatcher] object that is used by this class. */ - public val eventDispatcher: Any? + public val eventDispatcher: EventDispatcher /** * Used by native animated module to bypass the process of updating the values through the shadow diff --git a/packages/react-native/ReactAndroid/src/test/java/com/facebook/testutils/fakes/FakeUIManager.kt b/packages/react-native/ReactAndroid/src/test/java/com/facebook/testutils/fakes/FakeUIManager.kt index b37693bd51fc17..49ba0848635f5e 100644 --- a/packages/react-native/ReactAndroid/src/test/java/com/facebook/testutils/fakes/FakeUIManager.kt +++ b/packages/react-native/ReactAndroid/src/test/java/com/facebook/testutils/fakes/FakeUIManager.kt @@ -17,6 +17,7 @@ import com.facebook.react.bridge.UIManagerListener import com.facebook.react.bridge.WritableMap import com.facebook.react.common.annotations.UnstableReactNativeAPI import com.facebook.react.fabric.interop.UIBlockViewResolver +import com.facebook.react.uimanager.events.EventDispatcher @OptIn(UnstableReactNativeAPI::class) class FakeUIManager : UIManager, UIBlockViewResolver { @@ -65,7 +66,7 @@ class FakeUIManager : UIManager, UIBlockViewResolver { error("Not yet implemented") } - override val eventDispatcher: Any? + override val eventDispatcher: EventDispatcher get() = TODO("Not yet implemented") override fun synchronouslyUpdateViewOnUIThread(reactTag: Int, props: ReadableMap?) { From 425093863cded077486aa6830d7dcc0461f8d64f Mon Sep 17 00:00:00 2001 From: Peter Abbondanzo Date: Thu, 7 Nov 2024 07:53:01 -0800 Subject: [PATCH 115/220] Log image load errors (#47419) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47419 Minor improvements to `ImageExample` so we log when images fail to load. Also replaces a `Text` component with `RNTesterText` so it's legible. Changelog: [Internal] Reviewed By: cortinico Differential Revision: D65363864 fbshipit-source-id: 6c7ce8d5af6aabfed21479c784911bdcffe4684e --- packages/rn-tester/js/examples/Image/ImageExample.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/rn-tester/js/examples/Image/ImageExample.js b/packages/rn-tester/js/examples/Image/ImageExample.js index b3dddd83e875d8..bbd0054bf78bf4 100644 --- a/packages/rn-tester/js/examples/Image/ImageExample.js +++ b/packages/rn-tester/js/examples/Image/ImageExample.js @@ -131,6 +131,11 @@ class NetworkImageCallbackExample extends React.Component< { + this._loadEventFired( + `✘ onError "${event.nativeEvent.error}" (+${Date.now() - mountTime}ms)`, + ); + }} onLoadStart={() => this._loadEventFired(`✔ onLoadStart (+${Date.now() - mountTime}ms)`) } @@ -465,7 +470,9 @@ class FadeDurationExample extends React.Component< - This image will fade in over the time of 1.5s. + + This image will fade in over the time of 1.5s. + ); } From 0ee963ea65bcc88122044d51027511e611bde584 Mon Sep 17 00:00:00 2001 From: Riccardo Cipolleschi Date: Thu, 7 Nov 2024 07:53:07 -0800 Subject: [PATCH 116/220] Cleanup after Codegen refactoring (#47483) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47483 I relaized too late that there were a couple of comments on [#47458](https://github.com/facebook/react-native/pull/47458) to add some explanation/remove commented code. This change applies those comments ## Changelog [Internal] - Cleanup after landing [#47458](https://github.com/facebook/react-native/pull/47458) Reviewed By: dmytrorykun Differential Revision: D65597157 fbshipit-source-id: 238bb75e4b45efae9a8736a7b4feb10f5af5e3d9 --- packages/react-native/React/React-RCTFBReactNativeSpec.podspec | 3 +++ .../react-native/ReactCommon/React-FabricComponents.podspec | 1 - 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/react-native/React/React-RCTFBReactNativeSpec.podspec b/packages/react-native/React/React-RCTFBReactNativeSpec.podspec index 84513f04a43e5c..cb8c9f986934dc 100644 --- a/packages/react-native/React/React-RCTFBReactNativeSpec.podspec +++ b/packages/react-native/React/React-RCTFBReactNativeSpec.podspec @@ -5,6 +5,9 @@ require "json" +# This Podspec wraps the code generated by Codegen that defines all the interfaces for the +# internal Native Modules that React Native depends on. + package = JSON.parse(File.read(File.join(__dir__, "..", "package.json"))) version = package['version'] diff --git a/packages/react-native/ReactCommon/React-FabricComponents.podspec b/packages/react-native/ReactCommon/React-FabricComponents.podspec index 0d4e55a1475e4e..d8ff12b5d41196 100644 --- a/packages/react-native/ReactCommon/React-FabricComponents.podspec +++ b/packages/react-native/ReactCommon/React-FabricComponents.podspec @@ -92,7 +92,6 @@ Pod::Spec.new do |s| "react/renderer/components/view/platform/cxx", "react/renderer/imagemanager/platform/ios" ]) - # add_dependency(s, "React-RCTFBReactNativeSpec") if ENV["USE_HERMES"] == nil || ENV["USE_HERMES"] == "1" s.dependency "hermes-engine" From bf31c8f077c5c6fc74a45d349c665cc004567011 Mon Sep 17 00:00:00 2001 From: Tim Yung Date: Thu, 7 Nov 2024 09:29:44 -0800 Subject: [PATCH 117/220] RN: Feature Flag to Disable `InteractionManager` (#47475) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47475 Creates a feature flag to evalute the impact of disabling `InteractionManager` and replacing its scheduling behavior with `setImmediate`. Changelog: [Internal] Reviewed By: javache Differential Revision: D65577455 fbshipit-source-id: c0dc2b4d062eff4929ef37c5e217fd194addd790 --- .../Interaction/InteractionManager.js | 7 +- .../Interaction/InteractionManagerStub.js | 176 ++++++++++++++++++ .../__snapshots__/public-api-test.js.snap | 36 +++- .../ReactNativeFeatureFlags.config.js | 9 + .../featureflags/ReactNativeFeatureFlags.js | 8 +- 5 files changed, 233 insertions(+), 3 deletions(-) create mode 100644 packages/react-native/Libraries/Interaction/InteractionManagerStub.js diff --git a/packages/react-native/Libraries/Interaction/InteractionManager.js b/packages/react-native/Libraries/Interaction/InteractionManager.js index 7415f84266e374..3257921ec97f99 100644 --- a/packages/react-native/Libraries/Interaction/InteractionManager.js +++ b/packages/react-native/Libraries/Interaction/InteractionManager.js @@ -10,6 +10,7 @@ import type {Task} from './TaskQueue'; +import * as ReactNativeFeatureFlags from '../../src/private/featureflags/ReactNativeFeatureFlags'; import EventEmitter from '../vendor/emitter/EventEmitter'; const BatchedBridge = require('../BatchedBridge/BatchedBridge'); @@ -208,4 +209,8 @@ function _processUpdate() { _deleteInteractionSet.clear(); } -module.exports = InteractionManager; +module.exports = ( + ReactNativeFeatureFlags.disableInteractionManager() + ? require('./InteractionManagerStub') + : InteractionManager +) as typeof InteractionManager; diff --git a/packages/react-native/Libraries/Interaction/InteractionManagerStub.js b/packages/react-native/Libraries/Interaction/InteractionManagerStub.js new file mode 100644 index 00000000000000..c68afc5e740b68 --- /dev/null +++ b/packages/react-native/Libraries/Interaction/InteractionManagerStub.js @@ -0,0 +1,176 @@ +/** + * Copyright (c) Meta Platforms, Inc. and 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 {EventSubscription} from '../vendor/emitter/EventEmitter'; + +const invariant = require('invariant'); + +export type Handle = number; + +type Task = + | { + name: string, + run: () => void, + } + | { + name: string, + gen: () => Promise, + } + | (() => void); + +/** + * InteractionManager allows long-running work to be scheduled after any + * interactions/animations have completed. In particular, this allows JavaScript + * animations to run smoothly. + * + * Applications can schedule tasks to run after interactions with the following: + * + * ``` + * InteractionManager.runAfterInteractions(() => { + * // ...long-running synchronous task... + * }); + * ``` + * + * Compare this to other scheduling alternatives: + * + * - requestAnimationFrame(): for code that animates a view over time. + * - setImmediate/setTimeout(): run code later, note this may delay animations. + * - runAfterInteractions(): run code later, without delaying active animations. + * + * The touch handling system considers one or more active touches to be an + * 'interaction' and will delay `runAfterInteractions()` callbacks until all + * touches have ended or been cancelled. + * + * InteractionManager also allows applications to register animations by + * creating an interaction 'handle' on animation start, and clearing it upon + * completion: + * + * ``` + * var handle = InteractionManager.createInteractionHandle(); + * // run animation... (`runAfterInteractions` tasks are queued) + * // later, on animation completion: + * InteractionManager.clearInteractionHandle(handle); + * // queued tasks run if all handles were cleared + * ``` + * + * `runAfterInteractions` takes either a plain callback function, or a + * `PromiseTask` object with a `gen` method that returns a `Promise`. If a + * `PromiseTask` is supplied, then it is fully resolved (including asynchronous + * dependencies that also schedule more tasks via `runAfterInteractions`) before + * starting on the next task that might have been queued up synchronously + * earlier. + * + * By default, queued tasks are executed together in a loop in one + * `setImmediate` batch. If `setDeadline` is called with a positive number, then + * tasks will only be executed until the deadline (in terms of js event loop run + * time) approaches, at which point execution will yield via setTimeout, + * allowing events such as touches to start interactions and block queued tasks + * from executing, making apps more responsive. + * + * @deprecated + */ +const InteractionManagerStub = { + Events: { + interactionStart: 'interactionStart', + interactionComplete: 'interactionComplete', + }, + + /** + * Schedule a function to run after all interactions have completed. Returns a cancellable + * "promise". + * + * @deprecated + */ + runAfterInteractions(task: ?Task): { + then: ( + onFulfill?: ?(void) => ?(Promise | U), + onReject?: ?(error: mixed) => ?(Promise | U), + ) => Promise, + cancel: () => void, + ... + } { + let immediateID: ?$FlowIssue; + const promise = new Promise((resolve, reject) => { + immediateID = setImmediate(() => { + if (typeof task === 'object' && task !== null) { + if (typeof task.gen === 'function') { + task.gen().then(resolve, reject); + } else if (typeof task.run === 'function') { + try { + task.run(); + resolve(); + } catch (error) { + reject(error); + } + } else { + reject(new TypeError(`Task "${task.name}" missing gen or run.`)); + } + } else if (typeof task === 'function') { + try { + task(); + resolve(); + } catch (error) { + reject(error); + } + } else { + reject(new TypeError('Invalid task of type: ' + typeof task)); + } + }); + }); + + return { + // $FlowFixMe[method-unbinding] added when improving typing for this parameters + then: promise.then.bind(promise), + cancel() { + clearImmediate(immediateID); + }, + }; + }, + + /** + * Notify manager that an interaction has started. + * + * @deprecated + */ + createInteractionHandle(): Handle { + return -1; + }, + + /** + * Notify manager that an interaction has completed. + * + * @deprecated + */ + clearInteractionHandle(handle: Handle) { + invariant(!!handle, 'InteractionManager: Must provide a handle to clear.'); + }, + + /** + * @deprecated + */ + addListener(): EventSubscription { + return { + remove() {}, + }; + }, + + /** + * A positive number will use setTimeout to schedule any tasks after the + * eventLoopRunningTime hits the deadline value, otherwise all tasks will be + * executed in one setImmediate batch (default). + * + * @deprecated + */ + setDeadline(deadline: number) { + // Do nothing. + }, +}; + +module.exports = InteractionManagerStub; diff --git a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap index 3cf664c2093e42..d6551c65fc20bb 100644 --- a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap +++ b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap @@ -5335,7 +5335,41 @@ declare const InteractionManager: { addListener: $FlowFixMe, setDeadline(deadline: number): void, }; -declare module.exports: InteractionManager; +declare module.exports: typeof InteractionManager; +" +`; + +exports[`public API should not change unintentionally Libraries/Interaction/InteractionManagerStub.js 1`] = ` +"export type Handle = number; +type Task = + | { + name: string, + run: () => void, + } + | { + name: string, + gen: () => Promise, + } + | (() => void); +declare const InteractionManagerStub: { + Events: { + interactionStart: \\"interactionStart\\", + interactionComplete: \\"interactionComplete\\", + }, + runAfterInteractions(task: ?Task): { + then: ( + onFulfill?: ?(void) => ?(Promise | U), + onReject?: ?(error: mixed) => ?(Promise | U) + ) => Promise, + cancel: () => void, + ... + }, + createInteractionHandle(): Handle, + clearInteractionHandle(handle: Handle): void, + addListener(): EventSubscription, + setDeadline(deadline: number): void, +}; +declare module.exports: InteractionManagerStub; " `; diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index 38f1cb81e2adc4..fd6533860926b0 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -501,6 +501,15 @@ const definitions: FeatureFlagDefinitions = { purpose: 'experimentation', }, }, + disableInteractionManager: { + defaultValue: false, + metadata: { + dateAdded: '2024-11-06', + description: + 'Disables InteractionManager and replaces its scheduler with `setImmediate`.', + purpose: 'experimentation', + }, + }, enableAccessToHostTreeInFabric: { defaultValue: false, metadata: { diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index e79a8cbdd8d4a2..b43a170addc67c 100644 --- a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<27ae96c2bc3459bd89e52063a8ed9490>> + * @generated SignedSource<<141c9d17083660b8726d2780813168dd>> * @flow strict */ @@ -30,6 +30,7 @@ export type ReactNativeFeatureFlagsJsOnly = { jsOnlyTestFlag: Getter, animatedShouldDebounceQueueFlush: Getter, animatedShouldUseSingleOp: Getter, + disableInteractionManager: Getter, enableAccessToHostTreeInFabric: Getter, enableAnimatedAllowlist: Getter, enableAnimatedClearImmediateFix: Getter, @@ -118,6 +119,11 @@ export const animatedShouldDebounceQueueFlush: Getter = createJavaScrip */ export const animatedShouldUseSingleOp: Getter = createJavaScriptFlagGetter('animatedShouldUseSingleOp', false); +/** + * Disables InteractionManager and replaces its scheduler with `setImmediate`. + */ +export const disableInteractionManager: Getter = createJavaScriptFlagGetter('disableInteractionManager', false); + /** * Enables access to the host tree in Fabric using DOM-compatible APIs. */ From bcdf6ad1afae2a783ca077fc29906e370bf3f7a2 Mon Sep 17 00:00:00 2001 From: Pieter De Baets Date: Thu, 7 Nov 2024 10:16:21 -0800 Subject: [PATCH 118/220] Convert com.facebook.react.bridge.JavaOnlyMap to Kotlin (#47479) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47479 Changelog: [Internal] Reviewed By: cortinico Differential Revision: D65595979 fbshipit-source-id: be8217ef1fd9f59af57a1e100a4d9e86b66d8027 --- .../ReactAndroid/api/ReactAndroid.api | 18 +- .../facebook/react/bridge/JavaOnlyMap.java | 270 ------------------ .../com/facebook/react/bridge/JavaOnlyMap.kt | 180 ++++++++++++ .../com/facebook/react/bridge/ReadableMap.kt | 4 +- .../react/bridge/ReadableNativeMap.kt | 6 +- 5 files changed, 198 insertions(+), 280 deletions(-) delete mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaOnlyMap.java create mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaOnlyMap.kt diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 6b666914780d39..56ae22217e9af6 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -926,12 +926,14 @@ public class com/facebook/react/bridge/JavaOnlyArray : com/facebook/react/bridge public fun toString ()Ljava/lang/String; } -public class com/facebook/react/bridge/JavaOnlyMap : com/facebook/react/bridge/ReadableMap, com/facebook/react/bridge/WritableMap { +public final class com/facebook/react/bridge/JavaOnlyMap : com/facebook/react/bridge/ReadableMap, com/facebook/react/bridge/WritableMap { + public static final field Companion Lcom/facebook/react/bridge/JavaOnlyMap$Companion; public fun ()V + public synthetic fun ([Ljava/lang/Object;Lkotlin/jvm/internal/DefaultConstructorMarker;)V public fun copy ()Lcom/facebook/react/bridge/WritableMap; - public static fun deepClone (Lcom/facebook/react/bridge/ReadableMap;)Lcom/facebook/react/bridge/JavaOnlyMap; + public static final fun deepClone (Lcom/facebook/react/bridge/ReadableMap;)Lcom/facebook/react/bridge/JavaOnlyMap; public fun equals (Ljava/lang/Object;)Z - public static fun from (Ljava/util/Map;)Lcom/facebook/react/bridge/JavaOnlyMap; + public static final fun from (Ljava/util/Map;)Lcom/facebook/react/bridge/JavaOnlyMap; public fun getArray (Ljava/lang/String;)Lcom/facebook/react/bridge/ReadableArray; public fun getBoolean (Ljava/lang/String;)Z public fun getDouble (Ljava/lang/String;)D @@ -947,7 +949,7 @@ public class com/facebook/react/bridge/JavaOnlyMap : com/facebook/react/bridge/R public fun isNull (Ljava/lang/String;)Z public fun keySetIterator ()Lcom/facebook/react/bridge/ReadableMapKeySetIterator; public fun merge (Lcom/facebook/react/bridge/ReadableMap;)V - public static fun of ([Ljava/lang/Object;)Lcom/facebook/react/bridge/JavaOnlyMap; + public static final fun of ([Ljava/lang/Object;)Lcom/facebook/react/bridge/JavaOnlyMap; public fun putArray (Ljava/lang/String;Lcom/facebook/react/bridge/ReadableArray;)V public fun putBoolean (Ljava/lang/String;Z)V public fun putDouble (Ljava/lang/String;D)V @@ -956,11 +958,17 @@ public class com/facebook/react/bridge/JavaOnlyMap : com/facebook/react/bridge/R public fun putMap (Ljava/lang/String;Lcom/facebook/react/bridge/ReadableMap;)V public fun putNull (Ljava/lang/String;)V public fun putString (Ljava/lang/String;Ljava/lang/String;)V - public fun remove (Ljava/lang/String;)V + public final fun remove (Ljava/lang/String;)V public fun toHashMap ()Ljava/util/HashMap; public fun toString ()Ljava/lang/String; } +public final class com/facebook/react/bridge/JavaOnlyMap$Companion { + public final fun deepClone (Lcom/facebook/react/bridge/ReadableMap;)Lcom/facebook/react/bridge/JavaOnlyMap; + public final fun from (Ljava/util/Map;)Lcom/facebook/react/bridge/JavaOnlyMap; + public final fun of ([Ljava/lang/Object;)Lcom/facebook/react/bridge/JavaOnlyMap; +} + public class com/facebook/react/bridge/JavaScriptContextHolder { public fun (J)V public fun clear ()V diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaOnlyMap.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaOnlyMap.java deleted file mode 100644 index afb27217b44cb2..00000000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaOnlyMap.java +++ /dev/null @@ -1,270 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and 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.bridge; - -import static androidx.core.util.Preconditions.checkNotNull; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -/** - * Java {@link HashMap} backed implementation of {@link ReadableMap} and {@link WritableMap} - * Instances of this class SHOULD NOT be used for communication between java and JS, use instances - * of {@link WritableNativeMap} created via {@link Arguments#createMap} or just {@link ReadableMap} - * interface if you want your "native" module method to take a map from JS as an argument. - * - *

Main purpose for this class is to be used in java-only unit tests, but could also be used - * outside of tests in the code that operates only in java and needs to communicate with RN modules - * via their JS-exposed API. - */ -public class JavaOnlyMap implements ReadableMap, WritableMap { - - private final Map mBackingMap; - - public static JavaOnlyMap of(Object... keysAndValues) { - return new JavaOnlyMap(keysAndValues); - } - - public static JavaOnlyMap from(Map map) { - return new JavaOnlyMap(map); - } - - public static JavaOnlyMap deepClone(ReadableMap map) { - JavaOnlyMap res = new JavaOnlyMap(); - ReadableMapKeySetIterator iter = map.keySetIterator(); - while (iter.hasNextKey()) { - String propKey = iter.nextKey(); - ReadableType type = map.getType(propKey); - switch (type) { - case Null: - res.putNull(propKey); - break; - case Boolean: - res.putBoolean(propKey, map.getBoolean(propKey)); - break; - case Number: - res.putDouble(propKey, map.getDouble(propKey)); - break; - case String: - res.putString(propKey, map.getString(propKey)); - break; - case Map: - res.putMap(propKey, deepClone(map.getMap(propKey))); - break; - case Array: - res.putArray(propKey, JavaOnlyArray.deepClone(map.getArray(propKey))); - break; - } - } - return res; - } - - /** - * @param keysAndValues keys and values, interleaved - */ - private JavaOnlyMap(Object... keysAndValues) { - if (keysAndValues.length % 2 != 0) { - throw new IllegalArgumentException("You must provide the same number of keys and values"); - } - mBackingMap = new HashMap(); - for (int i = 0; i < keysAndValues.length; i += 2) { - Object val = keysAndValues[i + 1]; - if (val instanceof Number) { - // all values from JS are doubles, so emulate that here for tests. - val = ((Number) val).doubleValue(); - } - mBackingMap.put(keysAndValues[i], val); - } - } - - public JavaOnlyMap() { - mBackingMap = new HashMap(); - } - - @Override - public boolean hasKey(@NonNull String name) { - return mBackingMap.containsKey(name); - } - - @Override - public boolean isNull(@NonNull String name) { - return mBackingMap.get(name) == null; - } - - @Override - public boolean getBoolean(@NonNull String name) { - return (Boolean) mBackingMap.get(name); - } - - @Override - public double getDouble(@NonNull String name) { - return ((Number) mBackingMap.get(name)).doubleValue(); - } - - @Override - public int getInt(@NonNull String name) { - return ((Number) mBackingMap.get(name)).intValue(); - } - - @Override - public long getLong(@NonNull String name) { - return ((Number) checkNotNull(mBackingMap.get(name))).longValue(); - } - - @Override - public String getString(@NonNull String name) { - return (String) mBackingMap.get(name); - } - - @Override - public ReadableMap getMap(@NonNull String name) { - return (ReadableMap) mBackingMap.get(name); - } - - @Override - public ReadableArray getArray(@NonNull String name) { - return (ReadableArray) mBackingMap.get(name); - } - - @Override - public @NonNull Dynamic getDynamic(@NonNull String name) { - return DynamicFromMap.create(this, name); - } - - @Override - public @NonNull ReadableType getType(@NonNull String name) { - Object value = mBackingMap.get(name); - if (value == null) { - return ReadableType.Null; - } else if (value instanceof Number) { - return ReadableType.Number; - } else if (value instanceof String) { - return ReadableType.String; - } else if (value instanceof Boolean) { - return ReadableType.Boolean; - } else if (value instanceof ReadableMap) { - return ReadableType.Map; - } else if (value instanceof ReadableArray) { - return ReadableType.Array; - } else if (value instanceof Dynamic) { - return ((Dynamic) value).getType(); - } else { - throw new IllegalArgumentException( - "Invalid value " + value.toString() + " for key " + name + "contained in JavaOnlyMap"); - } - } - - @Override - public @NonNull Iterator> getEntryIterator() { - return mBackingMap.entrySet().iterator(); - } - - @Override - public @NonNull ReadableMapKeySetIterator keySetIterator() { - return new ReadableMapKeySetIterator() { - Iterator> mIterator = mBackingMap.entrySet().iterator(); - - @Override - public boolean hasNextKey() { - return mIterator.hasNext(); - } - - @Override - public String nextKey() { - return mIterator.next().getKey(); - } - }; - } - - @Override - public void putBoolean(@NonNull String key, boolean value) { - mBackingMap.put(key, value); - } - - @Override - public void putDouble(@NonNull String key, double value) { - mBackingMap.put(key, value); - } - - @Override - public void putInt(@NonNull String key, int value) { - mBackingMap.put(key, new Double(value)); - } - - @Override - public void putLong(@NonNull String key, long value) { - mBackingMap.put(key, value); - } - - @Override - public void putString(@NonNull String key, @Nullable String value) { - mBackingMap.put(key, value); - } - - @Override - public void putNull(@NonNull String key) { - mBackingMap.put(key, null); - } - - @Override - public void putMap(@NonNull String key, @Nullable ReadableMap value) { - mBackingMap.put(key, value); - } - - @Override - public void merge(@NonNull ReadableMap source) { - mBackingMap.putAll(((JavaOnlyMap) source).mBackingMap); - } - - @Override - public WritableMap copy() { - final JavaOnlyMap target = new JavaOnlyMap(); - target.merge(this); - return target; - } - - @Override - public void putArray(@NonNull String key, @Nullable ReadableArray value) { - mBackingMap.put(key, value); - } - - @Override - public @NonNull HashMap toHashMap() { - return new HashMap(mBackingMap); - } - - @Override - public String toString() { - return mBackingMap.toString(); - } - - public void remove(@NonNull String key) { - mBackingMap.remove(key); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - JavaOnlyMap that = (JavaOnlyMap) o; - - if (mBackingMap != null ? !mBackingMap.equals(that.mBackingMap) : that.mBackingMap != null) - return false; - - return true; - } - - @Override - public int hashCode() { - return mBackingMap != null ? mBackingMap.hashCode() : 0; - } -} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaOnlyMap.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaOnlyMap.kt new file mode 100644 index 00000000000000..878492529c845b --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaOnlyMap.kt @@ -0,0 +1,180 @@ +/* + * Copyright (c) Meta Platforms, Inc. and 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.bridge + +import java.util.HashMap +import kotlin.collections.Iterator +import kotlin.collections.Map + +/** + * Java [HashMap] backed implementation of [ReadableMap] and [WritableMap] Instances of this class + * SHOULD NOT be used for communication between java and JS, use instances of [WritableNativeMap] + * created via [Arguments#createMap] or just [ReadableMap] interface if you want your "native" + * module method to take a map from JS as an argument. + * + * Main purpose for this class is to be used in java-only unit tests, but could also be used outside + * of tests in the code that operates only in java and needs to communicate with RN modules via + * their JS-exposed API. + */ +public class JavaOnlyMap() : ReadableMap, WritableMap { + public companion object { + @JvmStatic public fun of(vararg keysAndValues: Any?): JavaOnlyMap = JavaOnlyMap(*keysAndValues) + + @JvmStatic public fun from(map: Map): JavaOnlyMap = JavaOnlyMap(map) + + @JvmStatic + public fun deepClone(map: ReadableMap?): JavaOnlyMap { + val res = JavaOnlyMap() + if (map == null) { + return res + } + val iter = map.keySetIterator() + while (iter.hasNextKey()) { + val propKey = iter.nextKey() + val type = map.getType(propKey) + when (type) { + ReadableType.Null -> res.putNull(propKey) + ReadableType.Boolean -> res.putBoolean(propKey, map.getBoolean(propKey)) + ReadableType.Number -> res.putDouble(propKey, map.getDouble(propKey)) + ReadableType.String -> res.putString(propKey, map.getString(propKey)) + ReadableType.Map -> res.putMap(propKey, deepClone(map.getMap(propKey))) + ReadableType.Array -> + res.putArray(propKey, JavaOnlyArray.deepClone(map.getArray(propKey))) + } + } + return res + } + } + + private val backingMap: MutableMap = HashMap() + + /** @param keysAndValues keys and values, interleaved */ + private constructor(vararg keysAndValues: Any?) : this() { + require(keysAndValues.size % 2 == 0) { "You must provide the same number of keys and values" } + for (i in keysAndValues.indices step 2) { + var value = keysAndValues[i + 1] + if (value is Number) { + // all values from JS are doubles, so emulate that here for tests. + value = value.toDouble() + } + backingMap[keysAndValues[i] as String] = value + } + } + + override fun hasKey(name: String): Boolean = backingMap.containsKey(name) + + override fun isNull(name: String): Boolean = backingMap[name] == null + + override fun getBoolean(name: String): Boolean = backingMap[name] as Boolean + + override fun getDouble(name: String): Double = (backingMap[name] as Number).toDouble() + + override fun getInt(name: String): Int = (backingMap[name] as Number).toInt() + + override fun getLong(name: String): Long = (backingMap[name] as Number).toLong() + + override fun getString(name: String): String? = backingMap[name] as String? + + override fun getMap(name: String): ReadableMap? = backingMap[name] as ReadableMap? + + override fun getArray(name: String): ReadableArray? = backingMap[name] as ReadableArray? + + override fun getDynamic(name: String): Dynamic = DynamicFromMap.create(this, name) + + override fun getType(name: String): ReadableType { + val value = backingMap[name] + return when { + value == null -> ReadableType.Null + value is Number -> ReadableType.Number + value is String -> ReadableType.String + value is Boolean -> ReadableType.Boolean + value is ReadableMap -> ReadableType.Map + value is ReadableArray -> ReadableType.Array + value is Dynamic -> value.type + else -> { + throw IllegalArgumentException( + "Invalid value $value for key $name contained in JavaOnlyMap") + } + } + } + + override val entryIterator: Iterator> + get() = backingMap.entries.iterator() + + override fun keySetIterator(): ReadableMapKeySetIterator { + return object : ReadableMapKeySetIterator { + private val iterator = backingMap.entries.iterator() + + override fun hasNextKey(): Boolean = iterator.hasNext() + + override fun nextKey(): String = iterator.next().key + } + } + + override fun putBoolean(key: String, value: Boolean) { + backingMap[key] = value + } + + override fun putDouble(key: String, value: Double) { + backingMap[key] = value + } + + override fun putInt(key: String, value: Int) { + backingMap[key] = value.toDouble() + } + + override fun putLong(key: String, value: Long) { + backingMap[key] = value.toDouble() + } + + override fun putString(key: String, value: String?) { + backingMap[key] = value + } + + override fun putNull(key: String) { + backingMap[key] = null + } + + override fun putMap(key: String, value: ReadableMap?) { + backingMap[key] = value + } + + override fun merge(source: ReadableMap) { + backingMap.putAll((source as JavaOnlyMap).backingMap) + } + + override fun copy(): WritableMap { + val target = JavaOnlyMap() + target.merge(this) + return target + } + + override fun putArray(key: String, value: ReadableArray?) { + backingMap[key] = value + } + + public fun remove(key: String) { + backingMap.remove(key) + } + + override fun toHashMap(): HashMap = HashMap(backingMap) + + override fun toString(): String = backingMap.toString() + + override fun equals(other: Any?): Boolean { + return if (this === other) { + true + } else if (other == null || javaClass != other.javaClass) { + false + } else { + backingMap == (other as JavaOnlyMap).backingMap + } + } + + override fun hashCode(): Int = backingMap.hashCode() +} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableMap.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableMap.kt index a8319fcecae4c1..4920fb6dda4ee3 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableMap.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableMap.kt @@ -16,7 +16,7 @@ import kotlin.collections.Map * Kotlin. */ public interface ReadableMap { - public val entryIterator: Iterator> + public val entryIterator: Iterator> public fun getArray(name: String): ReadableArray? @@ -42,5 +42,5 @@ public interface ReadableMap { public fun keySetIterator(): ReadableMapKeySetIterator - public fun toHashMap(): HashMap + public fun toHashMap(): HashMap } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableNativeMap.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableNativeMap.kt index 68812fe11f6080..580282b5134317 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableNativeMap.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableNativeMap.kt @@ -20,10 +20,10 @@ public open class ReadableNativeMap protected constructor() : NativeMap(), Reada private val keys: Array by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { importKeys().also { jniPassCounter++ } } - private val localMap: HashMap by + private val localMap: HashMap by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { val length = keys.size - val res = HashMap(length) + val res = HashMap(length) val values = importValues() jniPassCounter++ for (i in 0 until length) { @@ -157,7 +157,7 @@ public open class ReadableNativeMap protected constructor() : NativeMap(), Reada false } else localMap == other.localMap - override fun toHashMap(): HashMap { + override fun toHashMap(): HashMap { // we can almost just return getLocalMap(), but we need to convert nested arrays and maps to the // correct types first val hashMap = HashMap(localMap) From 791afd320988bbc67e9deac6f08ce0cb5a668f41 Mon Sep 17 00:00:00 2001 From: Fabrizio Cucci Date: Thu, 7 Nov 2024 10:23:27 -0800 Subject: [PATCH 119/220] Migrate com.facebook.react.views.text.ReactFontManager to Kotlin (#47488) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47488 As per title. Changelog: [Internal] Reviewed By: cortinico Differential Revision: D65594248 fbshipit-source-id: 5a21baefb768b1c6f8ec0c33158812d1de6113d5 --- .../ReactAndroid/api/ReactAndroid.api | 22 ++++--- .../react/views/text/ReactFontManager.java | 66 ------------------- .../react/views/text/ReactFontManager.kt | 58 ++++++++++++++++ 3 files changed, 72 insertions(+), 74 deletions(-) delete mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactFontManager.java create mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactFontManager.kt diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 56ae22217e9af6..061741e9d4df15 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -7302,14 +7302,20 @@ public abstract class com/facebook/react/views/text/ReactBaseTextShadowNode : co protected fun spannedFromShadowNode (Lcom/facebook/react/views/text/ReactBaseTextShadowNode;Ljava/lang/String;ZLcom/facebook/react/uimanager/NativeViewHierarchyOptimizer;)Landroid/text/Spannable; } -public class com/facebook/react/views/text/ReactFontManager { - public fun addCustomFont (Landroid/content/Context;Ljava/lang/String;I)V - public fun addCustomFont (Ljava/lang/String;Landroid/graphics/Typeface;)V - public static fun getInstance ()Lcom/facebook/react/views/text/ReactFontManager; - public fun getTypeface (Ljava/lang/String;IILandroid/content/res/AssetManager;)Landroid/graphics/Typeface; - public fun getTypeface (Ljava/lang/String;ILandroid/content/res/AssetManager;)Landroid/graphics/Typeface; - public fun getTypeface (Ljava/lang/String;IZLandroid/content/res/AssetManager;)Landroid/graphics/Typeface; - public fun setTypeface (Ljava/lang/String;ILandroid/graphics/Typeface;)V +public final class com/facebook/react/views/text/ReactFontManager { + public static final field Companion Lcom/facebook/react/views/text/ReactFontManager$Companion; + public synthetic fun (Lcom/facebook/react/views/text/ReactFontManager;Lkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun addCustomFont (Landroid/content/Context;Ljava/lang/String;I)V + public final fun addCustomFont (Ljava/lang/String;Landroid/graphics/Typeface;)V + public static final fun getInstance ()Lcom/facebook/react/views/text/ReactFontManager; + public final fun getTypeface (Ljava/lang/String;IILandroid/content/res/AssetManager;)Landroid/graphics/Typeface; + public final fun getTypeface (Ljava/lang/String;ILandroid/content/res/AssetManager;)Landroid/graphics/Typeface; + public final fun getTypeface (Ljava/lang/String;IZLandroid/content/res/AssetManager;)Landroid/graphics/Typeface; + public final fun setTypeface (Ljava/lang/String;ILandroid/graphics/Typeface;)V +} + +public final class com/facebook/react/views/text/ReactFontManager$Companion { + public final fun getInstance ()Lcom/facebook/react/views/text/ReactFontManager; } public class com/facebook/react/views/text/ReactRawTextManager : com/facebook/react/uimanager/ViewManager { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactFontManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactFontManager.java deleted file mode 100644 index 0b3310e3f1bb1d..00000000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactFontManager.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and 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.views.text; - -import android.content.Context; -import android.content.res.AssetManager; -import android.graphics.Typeface; -import androidx.annotation.Nullable; -import com.facebook.infer.annotation.Nullsafe; - -/** - * Responsible for loading and caching Typeface objects. - * - * @deprecated This class is deprecated and it will be deleted in the near future. Please use {@link - * com.facebook.react.common.assets.ReactFontManager} instead. - */ -@Nullsafe(Nullsafe.Mode.LOCAL) -@Deprecated -public class ReactFontManager { - - private static ReactFontManager sReactFontManagerInstance; - private final com.facebook.react.common.assets.ReactFontManager mDelegate; - - private ReactFontManager(com.facebook.react.common.assets.ReactFontManager delegate) { - mDelegate = delegate; - } - - public static ReactFontManager getInstance() { - if (sReactFontManagerInstance == null) { - sReactFontManagerInstance = - new ReactFontManager(com.facebook.react.common.assets.ReactFontManager.getInstance()); - } - return sReactFontManagerInstance; - } - - public Typeface getTypeface(String fontFamilyName, int style, AssetManager assetManager) { - return mDelegate.getTypeface(fontFamilyName, style, assetManager); - } - - public Typeface getTypeface( - String fontFamilyName, int weight, boolean italic, AssetManager assetManager) { - return mDelegate.getTypeface(fontFamilyName, weight, italic, assetManager); - } - - public Typeface getTypeface( - String fontFamilyName, int style, int weight, AssetManager assetManager) { - return mDelegate.getTypeface(fontFamilyName, style, weight, assetManager); - } - - public void addCustomFont(Context context, String fontFamily, int fontId) { - mDelegate.addCustomFont(context, fontFamily, fontId); - } - - public void addCustomFont(String fontFamily, @Nullable Typeface font) { - mDelegate.addCustomFont(fontFamily, font); - } - - public void setTypeface(String fontFamilyName, int style, Typeface typeface) { - mDelegate.setTypeface(fontFamilyName, style, typeface); - } -} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactFontManager.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactFontManager.kt new file mode 100644 index 00000000000000..313967c597f15e --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactFontManager.kt @@ -0,0 +1,58 @@ +/* + * Copyright (c) Meta Platforms, Inc. and 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.views.text + +import android.content.Context +import android.content.res.AssetManager +import android.graphics.Typeface + +/** Responsible for loading and caching Typeface objects. */ +@Deprecated( + message = + "This class is deprecated and will be deleted in the near future. Please use [com.facebook.react.common.assets.ReactFontManager] instead.") +@Suppress("DEPRECATION") +public class ReactFontManager private constructor(private val delegate: ReactFontManager) { + + public fun getTypeface(fontFamilyName: String, style: Int, assetManager: AssetManager): Typeface = + delegate.getTypeface(fontFamilyName, style, assetManager) + + public fun getTypeface( + fontFamilyName: String, + weight: Int, + italic: Boolean, + assetManager: AssetManager + ): Typeface = delegate.getTypeface(fontFamilyName, weight, italic, assetManager) + + public fun getTypeface( + fontFamilyName: String, + style: Int, + weight: Int, + assetManager: AssetManager + ): Typeface = delegate.getTypeface(fontFamilyName, style, weight, assetManager) + + public fun addCustomFont(context: Context, fontFamily: String, fontId: Int) { + delegate.addCustomFont(context, fontFamily, fontId) + } + + public fun addCustomFont(fontFamily: String, font: Typeface?) { + delegate.addCustomFont(fontFamily, font) + } + + public fun setTypeface(fontFamilyName: String, style: Int, typeface: Typeface) { + delegate.setTypeface(fontFamilyName, style, typeface) + } + + public companion object { + private var instance: ReactFontManager? = null + + @JvmStatic + public fun getInstance(): ReactFontManager { + return instance ?: ReactFontManager(ReactFontManager.getInstance()).also { instance = it } + } + } +} From 8b053a4fcac857b8c8e664d10b92d1ea71091bfc Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Thu, 7 Nov 2024 11:22:57 -0800 Subject: [PATCH 120/220] Implement always available js error handling (#47466) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47466 Now, when the useAlwaysAvailableJSErrorHandling feature flag is true, React Native will use the earlyjs c++ error reporting pipeline for handling all javascript errors! Changelog: [Internal] Reviewed By: javache Differential Revision: D64715159 fbshipit-source-id: 597a5278eb792f87dca10e06fa9816b3a8c47b84 --- packages/polyfills/console.js | 42 +++++++++++++++++++ packages/polyfills/error-guard.js | 12 +++--- .../Libraries/Core/ExceptionsManager.js | 5 +-- .../Libraries/Core/setUpErrorHandling.js | 38 +++++++++-------- .../react-native/Libraries/LogBox/LogBox.js | 2 +- .../ReactCommon/jserrorhandler/CMakeLists.txt | 1 + .../jserrorhandler/JsErrorHandler.cpp | 7 +++- .../React-jserrorhandler.podspec | 1 + .../react/runtime/ReactInstance.cpp | 35 +++++++++++++--- 9 files changed, 107 insertions(+), 36 deletions(-) diff --git a/packages/polyfills/console.js b/packages/polyfills/console.js index 8010aa163b9f45..22e4ffdc0aa4c7 100644 --- a/packages/polyfills/console.js +++ b/packages/polyfills/console.js @@ -553,6 +553,48 @@ if (global.nativeLoggingHook) { assert: consoleAssertPolyfill, }; + // TODO(T206796580): This was copy-pasted from ExceptionsManager.js + // Delete the copy there after the c++ pipeline is rolled out everywhere. + if (global.RN$useAlwaysAvailableJSErrorHandling === true) { + let originalConsoleError = console.error; + console.reportErrorsAsExceptions = true; + function stringifySafe(arg) { + return inspect(arg, {depth: 10}).replaceAll(/\n\s*/g, ' '); + } + console.error = function (...args) { + originalConsoleError.apply(this, args); + if (!console.reportErrorsAsExceptions) { + return; + } + if (global.RN$inExceptionHandler?.()) { + return; + } + let error; + + const firstArg = args[0]; + if (firstArg?.stack) { + // RN$handleException will console.error this with high enough fidelity. + error = firstArg; + } else { + 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 + return; + } + const message = args + .map(arg => (typeof arg === 'string' ? arg : stringifySafe(arg))) + .join(' '); + + error = new Error(message); + error.name = 'console.error'; + } + + const isFatal = false; + const reportToConsole = false; + global.RN$handleException(error, isFatal, reportToConsole); + }; + } + Object.defineProperty(console, '_isPolyfilled', { value: true, enumerable: false, diff --git a/packages/polyfills/error-guard.js b/packages/polyfills/error-guard.js index 389b5a20f81477..652efeb5abdf23 100644 --- a/packages/polyfills/error-guard.js +++ b/packages/polyfills/error-guard.js @@ -19,12 +19,12 @@ type Fn = (...Args) => Return; * when loading a module. This will report any errors encountered before * ExceptionsManager is configured. */ -let _globalHandler: ErrorHandler = function onError( - e: mixed, - isFatal: boolean, -) { - throw e; -}; +let _globalHandler: ErrorHandler = + global.RN$useAlwaysAvailableJSErrorHandling === true + ? global.RN$handleException + : (e: mixed, isFatal: boolean) => { + throw e; + }; /** * The particular require runtime that we are using looks for a global diff --git a/packages/react-native/Libraries/Core/ExceptionsManager.js b/packages/react-native/Libraries/Core/ExceptionsManager.js index 019c3eff95cca7..a0b22359ea0778 100644 --- a/packages/react-native/Libraries/Core/ExceptionsManager.js +++ b/packages/react-native/Libraries/Core/ExceptionsManager.js @@ -177,10 +177,7 @@ function reactConsoleErrorHandler(...args) { if (!console.reportErrorsAsExceptions) { return; } - if ( - inExceptionHandler || - (global.RN$inExceptionHandler && global.RN$inExceptionHandler()) - ) { + if (inExceptionHandler || global.RN$inExceptionHandler?.()) { // The fundamental trick here is that are multiple entry point to logging errors: // (see D19743075 for more background) // diff --git a/packages/react-native/Libraries/Core/setUpErrorHandling.js b/packages/react-native/Libraries/Core/setUpErrorHandling.js index 32846d42f83506..ffbfb618b42be3 100644 --- a/packages/react-native/Libraries/Core/setUpErrorHandling.js +++ b/packages/react-native/Libraries/Core/setUpErrorHandling.js @@ -10,24 +10,26 @@ 'use strict'; -/** - * Sets up the console and exception handling (redbox) for React Native. - * You can use this module directly, or just require InitializeCore. - */ -const ExceptionsManager = require('./ExceptionsManager'); -ExceptionsManager.installConsoleErrorReporter(); +if (global.RN$useAlwaysAvailableJSErrorHandling !== true) { + /** + * Sets up the console and exception handling (redbox) for React Native. + * You can use this module directly, or just require InitializeCore. + */ + const ExceptionsManager = require('./ExceptionsManager'); + ExceptionsManager.installConsoleErrorReporter(); -// Set up error handler -if (!global.__fbDisableExceptionsManager) { - const handleError = (e: mixed, isFatal: boolean) => { - try { - ExceptionsManager.handleException(e, isFatal); - } catch (ee) { - console.log('Failed to print error: ', ee.message); - throw e; - } - }; + // Set up error handler + if (!global.__fbDisableExceptionsManager) { + const handleError = (e: mixed, isFatal: boolean) => { + try { + ExceptionsManager.handleException(e, isFatal); + } catch (ee) { + console.log('Failed to print error: ', ee.message); + throw e; + } + }; - const ErrorUtils = require('../vendor/core/ErrorUtils'); - ErrorUtils.setGlobalHandler(handleError); + const ErrorUtils = require('../vendor/core/ErrorUtils'); + ErrorUtils.setGlobalHandler(handleError); + } } diff --git a/packages/react-native/Libraries/LogBox/LogBox.js b/packages/react-native/Libraries/LogBox/LogBox.js index 82930e7f34d29e..473f1e1a5b2130 100644 --- a/packages/react-native/Libraries/LogBox/LogBox.js +++ b/packages/react-native/Libraries/LogBox/LogBox.js @@ -55,7 +55,7 @@ if (__DEV__) { if (global.RN$registerExceptionListener != null) { global.RN$registerExceptionListener( (error: ExtendedExceptionData & {preventDefault: () => mixed}) => { - if (!error.isFatal) { + if (global.RN$isRuntimeReady?.() || !error.isFatal) { error.preventDefault(); addException(error); } diff --git a/packages/react-native/ReactCommon/jserrorhandler/CMakeLists.txt b/packages/react-native/ReactCommon/jserrorhandler/CMakeLists.txt index 71ee2630328601..b05009bd70b6dd 100644 --- a/packages/react-native/ReactCommon/jserrorhandler/CMakeLists.txt +++ b/packages/react-native/ReactCommon/jserrorhandler/CMakeLists.txt @@ -19,4 +19,5 @@ target_link_libraries(jserrorhandler jsi folly_runtime mapbufferjni + react_featureflags ) diff --git a/packages/react-native/ReactCommon/jserrorhandler/JsErrorHandler.cpp b/packages/react-native/ReactCommon/jserrorhandler/JsErrorHandler.cpp index 7c19502c334214..904baff427d78d 100644 --- a/packages/react-native/ReactCommon/jserrorhandler/JsErrorHandler.cpp +++ b/packages/react-native/ReactCommon/jserrorhandler/JsErrorHandler.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include "StackTraceParser.h" @@ -228,7 +229,9 @@ void JsErrorHandler::handleError( bool logToConsole) { // TODO: Current error parsing works and is stable. Can investigate using // REGEX_HERMES to get additional Hermes data, though it requires JS setup - if (_isRuntimeReady) { + + if (!ReactNativeFeatureFlags::useAlwaysAvailableJSErrorHandling() && + _isRuntimeReady) { if (isFatal) { _hasHandledFatalError = true; } @@ -325,7 +328,7 @@ void JsErrorHandler::handleErrorWithCppPipeline( auto id = nextExceptionId(); ParsedError parsedError = { - .message = "EarlyJsError: " + message, + .message = _isRuntimeReady ? message : ("EarlyJsError: " + message), .originalMessage = originalMessage, .name = name, .componentStack = componentStack, diff --git a/packages/react-native/ReactCommon/jserrorhandler/React-jserrorhandler.podspec b/packages/react-native/ReactCommon/jserrorhandler/React-jserrorhandler.podspec index da6c75c6838677..d2568852351335 100644 --- a/packages/react-native/ReactCommon/jserrorhandler/React-jserrorhandler.podspec +++ b/packages/react-native/ReactCommon/jserrorhandler/React-jserrorhandler.podspec @@ -52,6 +52,7 @@ Pod::Spec.new do |s| s.dependency "React-cxxreact" s.dependency "glog" s.dependency "ReactCommon/turbomodule/bridging" + add_dependency(s, "React-featureflags") add_dependency(s, "React-debug") if ENV['USE_HERMES'] == nil || ENV['USE_HERMES'] == "1" diff --git a/packages/react-native/ReactCommon/react/runtime/ReactInstance.cpp b/packages/react-native/ReactCommon/react/runtime/ReactInstance.cpp index 20a268761a5dee..bb19ff78d8b0b7 100644 --- a/packages/react-native/ReactCommon/react/runtime/ReactInstance.cpp +++ b/packages/react-native/ReactCommon/react/runtime/ReactInstance.cpp @@ -409,6 +409,27 @@ void ReactInstance::initializeRuntime( defineReactInstanceFlags(runtime, options); + defineReadOnlyGlobal( + runtime, + "RN$useAlwaysAvailableJSErrorHandling", + jsi::Value( + ReactNativeFeatureFlags::useAlwaysAvailableJSErrorHandling())); + + defineReadOnlyGlobal( + runtime, + "RN$isRuntimeReady", + jsi::Function::createFromHostFunction( + runtime, + jsi::PropNameID::forAscii(runtime, "isRuntimeReady"), + 0, + [jsErrorHandler = jsErrorHandler_]( + jsi::Runtime& /*runtime*/, + const jsi::Value& /*unused*/, + const jsi::Value* /*args*/, + size_t /*count*/) { + return jsErrorHandler->isRuntimeReady(); + })); + defineReadOnlyGlobal( runtime, "RN$inExceptionHandler", @@ -444,12 +465,16 @@ void ReactInstance::initializeRuntime( } auto isFatal = isTruthy(runtime, args[1]); - if (jsErrorHandler->isRuntimeReady()) { - if (isFatal) { - jsErrorHandler->notifyOfFatalError(); - } - return jsi::Value(false); + if (!ReactNativeFeatureFlags:: + useAlwaysAvailableJSErrorHandling()) { + if (jsErrorHandler->isRuntimeReady()) { + if (isFatal) { + jsErrorHandler->notifyOfFatalError(); + } + + return jsi::Value(false); + } } auto jsError = From d02da992a4c0893313b9f059a8be228f43fffa7a Mon Sep 17 00:00:00 2001 From: Thomas Nardone Date: Thu, 7 Nov 2024 11:39:35 -0800 Subject: [PATCH 121/220] Convert + Internalize SwipeRefreshLayoutManager (#47470) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47470 Convert to Kotlin and formalize it being an internal class (some methods were already `protected` in Java) Changelog: [Android] [Breaking] - Stable API - Make SwipeRefreshLayoutManager internal Reviewed By: cortinico Differential Revision: D65481861 fbshipit-source-id: afc5c624373fbcd3ca2d28b2834d2682de672997 --- .../ReactAndroid/api/ReactAndroid.api | 31 --- .../react/views/swiperefresh/RefreshEvent.kt | 4 +- .../SwipeRefreshLayoutManager.java | 194 ------------------ .../swiperefresh/SwipeRefreshLayoutManager.kt | 153 ++++++++++++++ 4 files changed, 155 insertions(+), 227 deletions(-) delete mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/swiperefresh/SwipeRefreshLayoutManager.java create mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/swiperefresh/SwipeRefreshLayoutManager.kt diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 061741e9d4df15..a9fb19df350f87 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -7155,37 +7155,6 @@ public class com/facebook/react/views/swiperefresh/ReactSwipeRefreshLayout : and public fun setRefreshing (Z)V } -public class com/facebook/react/views/swiperefresh/SwipeRefreshLayoutManager : com/facebook/react/uimanager/ViewGroupManager, com/facebook/react/viewmanagers/AndroidSwipeRefreshLayoutManagerInterface { - public static final field REACT_CLASS Ljava/lang/String; - public fun ()V - protected synthetic fun addEventEmitters (Lcom/facebook/react/uimanager/ThemedReactContext;Landroid/view/View;)V - protected fun addEventEmitters (Lcom/facebook/react/uimanager/ThemedReactContext;Lcom/facebook/react/views/swiperefresh/ReactSwipeRefreshLayout;)V - protected synthetic fun createViewInstance (Lcom/facebook/react/uimanager/ThemedReactContext;)Landroid/view/View; - protected fun createViewInstance (Lcom/facebook/react/uimanager/ThemedReactContext;)Lcom/facebook/react/views/swiperefresh/ReactSwipeRefreshLayout; - protected fun getDelegate ()Lcom/facebook/react/uimanager/ViewManagerDelegate; - public fun getExportedCustomDirectEventTypeConstants ()Ljava/util/Map; - public fun getExportedViewConstants ()Ljava/util/Map; - public fun getName ()Ljava/lang/String; - public synthetic fun receiveCommand (Landroid/view/View;Ljava/lang/String;Lcom/facebook/react/bridge/ReadableArray;)V - public fun receiveCommand (Lcom/facebook/react/views/swiperefresh/ReactSwipeRefreshLayout;Ljava/lang/String;Lcom/facebook/react/bridge/ReadableArray;)V - public synthetic fun setColors (Landroid/view/View;Lcom/facebook/react/bridge/ReadableArray;)V - public fun setColors (Lcom/facebook/react/views/swiperefresh/ReactSwipeRefreshLayout;Lcom/facebook/react/bridge/ReadableArray;)V - public synthetic fun setEnabled (Landroid/view/View;Z)V - public fun setEnabled (Lcom/facebook/react/views/swiperefresh/ReactSwipeRefreshLayout;Z)V - public synthetic fun setNativeRefreshing (Landroid/view/View;Z)V - public fun setNativeRefreshing (Lcom/facebook/react/views/swiperefresh/ReactSwipeRefreshLayout;Z)V - public synthetic fun setProgressBackgroundColor (Landroid/view/View;Ljava/lang/Integer;)V - public fun setProgressBackgroundColor (Lcom/facebook/react/views/swiperefresh/ReactSwipeRefreshLayout;Ljava/lang/Integer;)V - public synthetic fun setProgressViewOffset (Landroid/view/View;F)V - public fun setProgressViewOffset (Lcom/facebook/react/views/swiperefresh/ReactSwipeRefreshLayout;F)V - public synthetic fun setRefreshing (Landroid/view/View;Z)V - public fun setRefreshing (Lcom/facebook/react/views/swiperefresh/ReactSwipeRefreshLayout;Z)V - public synthetic fun setSize (Landroid/view/View;Ljava/lang/String;)V - public fun setSize (Lcom/facebook/react/views/swiperefresh/ReactSwipeRefreshLayout;I)V - public fun setSize (Lcom/facebook/react/views/swiperefresh/ReactSwipeRefreshLayout;Lcom/facebook/react/bridge/Dynamic;)V - public fun setSize (Lcom/facebook/react/views/swiperefresh/ReactSwipeRefreshLayout;Ljava/lang/String;)V -} - public class com/facebook/react/views/switchview/ReactSwitchManager : com/facebook/react/uimanager/SimpleViewManager, com/facebook/react/viewmanagers/AndroidSwitchManagerInterface { public static final field REACT_CLASS Ljava/lang/String; public fun ()V diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/swiperefresh/RefreshEvent.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/swiperefresh/RefreshEvent.kt index 65669d8b61ab3d..6cdeceb74d2183 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/swiperefresh/RefreshEvent.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/swiperefresh/RefreshEvent.kt @@ -15,9 +15,9 @@ import com.facebook.react.uimanager.events.Event internal class RefreshEvent : Event { @Deprecated("Use constructor with surfaceId", ReplaceWith("RefreshEvent(surfaceId, viewTag)")) - protected constructor(viewTag: Int) : this(ViewUtil.NO_SURFACE_ID, viewTag) + constructor(viewTag: Int) : this(ViewUtil.NO_SURFACE_ID, viewTag) - protected constructor(surfaceId: Int, viewTag: Int) : super(surfaceId, viewTag) + constructor(surfaceId: Int, viewTag: Int) : super(surfaceId, viewTag) override public fun getEventName(): String { return "topRefresh" diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/swiperefresh/SwipeRefreshLayoutManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/swiperefresh/SwipeRefreshLayoutManager.java deleted file mode 100644 index 255855f3cab4d2..00000000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/swiperefresh/SwipeRefreshLayoutManager.java +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and 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.views.swiperefresh; - -import static com.facebook.react.views.swiperefresh.SwipeRefreshLayoutManager.REACT_CLASS; - -import android.graphics.Color; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; -import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener; -import com.facebook.react.bridge.ColorPropConverter; -import com.facebook.react.bridge.Dynamic; -import com.facebook.react.bridge.ReadableArray; -import com.facebook.react.bridge.ReadableType; -import com.facebook.react.common.MapBuilder; -import com.facebook.react.module.annotations.ReactModule; -import com.facebook.react.uimanager.ThemedReactContext; -import com.facebook.react.uimanager.UIManagerHelper; -import com.facebook.react.uimanager.ViewGroupManager; -import com.facebook.react.uimanager.ViewManagerDelegate; -import com.facebook.react.uimanager.ViewProps; -import com.facebook.react.uimanager.annotations.ReactProp; -import com.facebook.react.uimanager.events.EventDispatcher; -import com.facebook.react.viewmanagers.AndroidSwipeRefreshLayoutManagerDelegate; -import com.facebook.react.viewmanagers.AndroidSwipeRefreshLayoutManagerInterface; -import java.util.HashMap; -import java.util.Map; - -/** - * ViewManager for {@link ReactSwipeRefreshLayout} which allows the user to "pull to refresh" a - * child view. Emits an {@code onRefresh} event when this happens. - */ -@ReactModule(name = REACT_CLASS) -public class SwipeRefreshLayoutManager extends ViewGroupManager - implements AndroidSwipeRefreshLayoutManagerInterface { - - public static final String REACT_CLASS = "AndroidSwipeRefreshLayout"; - - private final ViewManagerDelegate mDelegate; - - public SwipeRefreshLayoutManager() { - mDelegate = new AndroidSwipeRefreshLayoutManagerDelegate<>(this); - } - - @Override - protected ReactSwipeRefreshLayout createViewInstance(ThemedReactContext reactContext) { - return new ReactSwipeRefreshLayout(reactContext); - } - - @Override - public String getName() { - return REACT_CLASS; - } - - @Override - @ReactProp(name = ViewProps.ENABLED, defaultBoolean = true) - public void setEnabled(ReactSwipeRefreshLayout view, boolean enabled) { - view.setEnabled(enabled); - } - - @Override - @ReactProp(name = "colors", customType = "ColorArray") - public void setColors(ReactSwipeRefreshLayout view, @Nullable ReadableArray colors) { - if (colors != null) { - int[] colorValues = new int[colors.size()]; - for (int i = 0; i < colors.size(); i++) { - if (colors.getType(i) == ReadableType.Map) { - colorValues[i] = ColorPropConverter.getColor(colors.getMap(i), view.getContext()); - } else { - colorValues[i] = colors.getInt(i); - } - } - view.setColorSchemeColors(colorValues); - } else { - view.setColorSchemeColors(); - } - } - - @Override - @ReactProp(name = "progressBackgroundColor", customType = "Color") - public void setProgressBackgroundColor(ReactSwipeRefreshLayout view, Integer color) { - view.setProgressBackgroundColorSchemeColor(color == null ? Color.TRANSPARENT : color); - } - - // TODO(T46143833): Remove this method once the 'size' prop has been migrated to String in JS. - public void setSize(ReactSwipeRefreshLayout view, int value) { - view.setSize(value); - } - - @Override - public void setSize(ReactSwipeRefreshLayout view, String size) { - if (size == null || size.equals("default")) { - view.setSize(SwipeRefreshLayout.DEFAULT); - } else if (size.equals("large")) { - view.setSize(SwipeRefreshLayout.LARGE); - } else { - throw new IllegalArgumentException("Size must be 'default' or 'large', received: " + size); - } - } - - // This prop temporarily takes both 0 and 1 as well as 'default' and 'large'. - // 0 and 1 are deprecated and will be removed in a future release. - // See T46143833 - @ReactProp(name = "size") - public void setSize(ReactSwipeRefreshLayout view, Dynamic size) { - if (size.isNull()) { - view.setSize(SwipeRefreshLayout.DEFAULT); - } else if (size.getType() == ReadableType.Number) { - view.setSize(size.asInt()); - } else if (size.getType() == ReadableType.String) { - setSize(view, size.asString()); - } else { - throw new IllegalArgumentException("Size must be 'default' or 'large'"); - } - } - - @Override - @ReactProp(name = "refreshing") - public void setRefreshing(ReactSwipeRefreshLayout view, boolean refreshing) { - view.setRefreshing(refreshing); - } - - @Override - @ReactProp(name = "progressViewOffset", defaultFloat = 0) - public void setProgressViewOffset(final ReactSwipeRefreshLayout view, final float offset) { - view.setProgressViewOffset(offset); - } - - @Override - public void setNativeRefreshing(ReactSwipeRefreshLayout view, boolean value) { - setRefreshing(view, value); - } - - @Override - protected void addEventEmitters( - final ThemedReactContext reactContext, final ReactSwipeRefreshLayout view) { - view.setOnRefreshListener( - new OnRefreshListener() { - @Override - public void onRefresh() { - EventDispatcher eventDispatcher = - UIManagerHelper.getEventDispatcherForReactTag(reactContext, view.getId()); - if (eventDispatcher != null) { - eventDispatcher.dispatchEvent( - new RefreshEvent(UIManagerHelper.getSurfaceId(view), view.getId())); - } - } - }); - } - - @Override - public void receiveCommand( - @NonNull ReactSwipeRefreshLayout root, String commandId, @Nullable ReadableArray args) { - switch (commandId) { - case "setNativeRefreshing": - if (args != null) { - setRefreshing(root, args.getBoolean(0)); - } - break; - } - } - - @Nullable - @Override - public Map getExportedViewConstants() { - return MapBuilder.of( - "SIZE", - MapBuilder.of("DEFAULT", SwipeRefreshLayout.DEFAULT, "LARGE", SwipeRefreshLayout.LARGE)); - } - - @Override - public Map getExportedCustomDirectEventTypeConstants() { - @Nullable - Map baseEventTypeConstants = super.getExportedCustomDirectEventTypeConstants(); - Map eventTypeConstants = - baseEventTypeConstants == null ? new HashMap() : baseEventTypeConstants; - eventTypeConstants.putAll( - MapBuilder.builder() - .put("topRefresh", MapBuilder.of("registrationName", "onRefresh")) - .build()); - return eventTypeConstants; - } - - @Override - protected ViewManagerDelegate getDelegate() { - return mDelegate; - } -} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/swiperefresh/SwipeRefreshLayoutManager.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/swiperefresh/SwipeRefreshLayoutManager.kt new file mode 100644 index 00000000000000..c52887b07d7483 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/swiperefresh/SwipeRefreshLayoutManager.kt @@ -0,0 +1,153 @@ +/* + * Copyright (c) Meta Platforms, Inc. and 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.views.swiperefresh + +import android.graphics.Color +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout +import com.facebook.react.bridge.ColorPropConverter +import com.facebook.react.bridge.Dynamic +import com.facebook.react.bridge.ReadableArray +import com.facebook.react.bridge.ReadableType +import com.facebook.react.module.annotations.ReactModule +import com.facebook.react.uimanager.ThemedReactContext +import com.facebook.react.uimanager.UIManagerHelper +import com.facebook.react.uimanager.ViewGroupManager +import com.facebook.react.uimanager.ViewManagerDelegate +import com.facebook.react.uimanager.ViewProps +import com.facebook.react.uimanager.annotations.ReactProp +import com.facebook.react.viewmanagers.AndroidSwipeRefreshLayoutManagerDelegate +import com.facebook.react.viewmanagers.AndroidSwipeRefreshLayoutManagerInterface +import java.util.HashMap + +/** + * ViewManager for [ReactSwipeRefreshLayout] which allows the user to "pull to refresh" a child + * view. Emits an `onRefresh` event when this happens. + */ +@ReactModule(name = SwipeRefreshLayoutManager.REACT_CLASS) +internal open class SwipeRefreshLayoutManager : + ViewGroupManager(), + AndroidSwipeRefreshLayoutManagerInterface { + + private val delegate: ViewManagerDelegate = + AndroidSwipeRefreshLayoutManagerDelegate(this) + + override fun createViewInstance(reactContext: ThemedReactContext): ReactSwipeRefreshLayout = + ReactSwipeRefreshLayout(reactContext) + + override fun getName(): String = REACT_CLASS + + @ReactProp(name = ViewProps.ENABLED, defaultBoolean = true) + override fun setEnabled(view: ReactSwipeRefreshLayout, enabled: Boolean) { + view.isEnabled = enabled + } + + @ReactProp(name = "colors", customType = "ColorArray") + override fun setColors(view: ReactSwipeRefreshLayout, colors: ReadableArray?) { + if (colors != null) { + val colorValues = IntArray(colors.size()) + for (i in 0.. view.setSize(SwipeRefreshLayout.DEFAULT) + size.type == ReadableType.Number -> view.setSize(size.asInt()) + size.type == ReadableType.String -> this.setSize(view, size.asString()) + else -> throw IllegalArgumentException("Size must be 'default' or 'large'") + } + } + + @ReactProp(name = "refreshing") + override fun setRefreshing(view: ReactSwipeRefreshLayout, refreshing: Boolean) { + view.isRefreshing = refreshing + } + + @ReactProp(name = "progressViewOffset", defaultFloat = 0f) + override fun setProgressViewOffset(view: ReactSwipeRefreshLayout, offset: Float) { + view.setProgressViewOffset(offset) + } + + override fun setNativeRefreshing(view: ReactSwipeRefreshLayout, value: Boolean) { + setRefreshing(view, value) + } + + override fun addEventEmitters(reactContext: ThemedReactContext, view: ReactSwipeRefreshLayout) { + view.setOnRefreshListener { + val eventDispatcher = UIManagerHelper.getEventDispatcherForReactTag(reactContext, view.id) + eventDispatcher?.dispatchEvent(RefreshEvent(UIManagerHelper.getSurfaceId(view), view.id)) + } + } + + override fun receiveCommand( + root: ReactSwipeRefreshLayout, + commandId: String, + args: ReadableArray? + ) { + when (commandId) { + "setNativeRefreshing" -> + if (args != null) { + setRefreshing(root, args.getBoolean(0)) + } + else -> {} + } + } + + override fun getExportedViewConstants(): MutableMap = + mutableMapOf( + "SIZE" to + mutableMapOf( + "DEFAULT" to SwipeRefreshLayout.DEFAULT, "LARGE" to SwipeRefreshLayout.LARGE)) + + override fun getExportedCustomDirectEventTypeConstants(): MutableMap { + val baseEventTypeConstants = super.getExportedCustomDirectEventTypeConstants() + val eventTypeConstants: MutableMap = baseEventTypeConstants ?: HashMap() + eventTypeConstants.putAll( + mutableMapOf("topRefresh" to mutableMapOf("registrationName" to "onRefresh"))) + return eventTypeConstants + } + + override fun getDelegate(): ViewManagerDelegate = delegate + + companion object { + const val REACT_CLASS: String = "AndroidSwipeRefreshLayout" + } +} From 846c4b1ea2d139e3f3cbafa2f8ddbf159e3322e4 Mon Sep 17 00:00:00 2001 From: Arushi Kesarwani Date: Thu, 7 Nov 2024 15:32:43 -0800 Subject: [PATCH 122/220] Reducing visibility of ImageStoreManager (#47443) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47443 As part of sustainability week effort for switching to internal here: https://fb.workplace.com/groups/251759413609061/permalink/872342228217440/ Reducing visibility of ImageStoreManager from public to internal Changelog: [Android] [Breaking] - Stable API - Make ImageStoreManager internal Reviewed By: javache Differential Revision: D65520953 fbshipit-source-id: 0207be6a5e0b92dbbaee534735fc829e9202727d --- .../react-native/ReactAndroid/api/ReactAndroid.api | 10 ---------- .../facebook/react/modules/camera/ImageStoreManager.kt | 2 +- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index a9fb19df350f87..c6e0a011f3afef 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -3045,16 +3045,6 @@ public class com/facebook/react/modules/blob/FileReaderModule : com/facebook/fbr public fun readAsText (Lcom/facebook/react/bridge/ReadableMap;Ljava/lang/String;Lcom/facebook/react/bridge/Promise;)V } -public final class com/facebook/react/modules/camera/ImageStoreManager : com/facebook/fbreact/specs/NativeImageStoreAndroidSpec { - public static final field Companion Lcom/facebook/react/modules/camera/ImageStoreManager$Companion; - public static final field NAME Ljava/lang/String; - public fun (Lcom/facebook/react/bridge/ReactApplicationContext;)V - public fun getBase64ForTag (Ljava/lang/String;Lcom/facebook/react/bridge/Callback;Lcom/facebook/react/bridge/Callback;)V -} - -public final class com/facebook/react/modules/camera/ImageStoreManager$Companion { -} - public final class com/facebook/react/modules/common/ModuleDataCleaner { public static final field INSTANCE Lcom/facebook/react/modules/common/ModuleDataCleaner; public static final fun cleanDataFromModules (Lcom/facebook/react/bridge/ReactContext;)V diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/camera/ImageStoreManager.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/camera/ImageStoreManager.kt index d93e1903885de5..724b184fca501e 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/camera/ImageStoreManager.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/camera/ImageStoreManager.kt @@ -22,7 +22,7 @@ import java.io.InputStream import java.util.concurrent.Executors @ReactModule(name = NativeImageStoreAndroidSpec.NAME) -public class ImageStoreManager(reactContext: ReactApplicationContext) : +internal class ImageStoreManager(reactContext: ReactApplicationContext) : NativeImageStoreAndroidSpec(reactContext) { /** From cbab004eb94f8312e9b10dae1502d3ca8632a006 Mon Sep 17 00:00:00 2001 From: Joe Vilches Date: Thu, 7 Nov 2024 16:34:31 -0800 Subject: [PATCH 123/220] Remove position type override on scroll view sticky headers (#47498) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47498 I am trying to help someone with creating a sticky header on a scrollview, specifically one that floats on the side of the scrollview instead of the top Currently we can't really do that, since utilizing `position: absolute` to layout this properly will get overriden by the header styles changed in this diff This was only added since static was the default and we needed to apply zIndex. With proper static implementation that is no longer the case, so I think it makes sense to remove this to support this use case. Changelog: [General] [Breaking] - `position` of sticky headers on `ScrollView` will now be taken into account Reviewed By: rozele Differential Revision: D65626544 fbshipit-source-id: 8d650ca7654918e692435935e7c1094c412fd9f6 --- .../Libraries/Components/ScrollView/ScrollViewStickyHeader.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/react-native/Libraries/Components/ScrollView/ScrollViewStickyHeader.js b/packages/react-native/Libraries/Components/ScrollView/ScrollViewStickyHeader.js index d83abfe57a2b6e..1615f3fe0b9671 100644 --- a/packages/react-native/Libraries/Components/ScrollView/ScrollViewStickyHeader.js +++ b/packages/react-native/Libraries/Components/ScrollView/ScrollViewStickyHeader.js @@ -301,7 +301,6 @@ const ScrollViewStickyHeaderWithForwardedRef: component( const styles = StyleSheet.create({ header: { zIndex: 10, - position: 'relative', }, fill: { flex: 1, From f0ffcd4f5dfeab794fbfa3257bb9a8fd793ff2bc Mon Sep 17 00:00:00 2001 From: Tim Yung Date: Thu, 7 Nov 2024 23:43:30 -0800 Subject: [PATCH 124/220] RN: Enable `enableAnimatedAllowlist` and `enableAnimatedPropsMemo` (#47502) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47502 Enables the two following feature flags: - `enableAnimatedAllowlist` - `enableAnimatedPropsMemo` The former enables the use of an experimental optimization to provide `unstable_createAnimatedComponentWithAllowlist` and `useAnimatedProps` an allowlist of props that reduces the set of props iterated over by to find props with `AnimatedNode` (e.g. `Animated.Value`) instance values. The latter enables improved memoization logic in `Animated` so that its intenal state is invalidated less frequently, reducing the cost of updating `Animated` components. Changelog: [General][Changed] - Optimized the performance of updating `Animated` components. Reviewed By: rozele Differential Revision: D65645985 fbshipit-source-id: 85f9e53072f09a59589d76d0c096f4cedd17bb4b --- .../featureflags/ReactNativeFeatureFlags.config.js | 10 ++++------ .../private/featureflags/ReactNativeFeatureFlags.js | 6 +++--- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index fd6533860926b0..0aa841bcaafa21 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -519,12 +519,11 @@ const definitions: FeatureFlagDefinitions = { }, }, enableAnimatedAllowlist: { - defaultValue: false, + defaultValue: true, metadata: { - dateAdded: '2024-09-10', description: 'Enables Animated to skip non-allowlisted props and styles.', - purpose: 'experimentation', + purpose: 'release', }, }, enableAnimatedClearImmediateFix: { @@ -537,12 +536,11 @@ const definitions: FeatureFlagDefinitions = { }, }, enableAnimatedPropsMemo: { - defaultValue: false, + defaultValue: true, metadata: { - dateAdded: '2024-09-11', description: 'Enables Animated to analyze props to minimize invalidating `AnimatedProps`.', - purpose: 'experimentation', + purpose: 'release', }, }, enableOptimisedVirtualizedCells: { diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index b43a170addc67c..7d796d7984642b 100644 --- a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<141c9d17083660b8726d2780813168dd>> + * @generated SignedSource<<650ba11a0ac49b9779c6c98f57f7369f>> * @flow strict */ @@ -132,7 +132,7 @@ export const enableAccessToHostTreeInFabric: Getter = createJavaScriptF /** * Enables Animated to skip non-allowlisted props and styles. */ -export const enableAnimatedAllowlist: Getter = createJavaScriptFlagGetter('enableAnimatedAllowlist', false); +export const enableAnimatedAllowlist: Getter = createJavaScriptFlagGetter('enableAnimatedAllowlist', true); /** * Enables an experimental to use the proper clearIntermediate instead of calling the wrong clearTimeout and canceling another timer. @@ -142,7 +142,7 @@ export const enableAnimatedClearImmediateFix: Getter = createJavaScript /** * Enables Animated to analyze props to minimize invalidating `AnimatedProps`. */ -export const enableAnimatedPropsMemo: Getter = createJavaScriptFlagGetter('enableAnimatedPropsMemo', false); +export const enableAnimatedPropsMemo: Getter = createJavaScriptFlagGetter('enableAnimatedPropsMemo', true); /** * Removing unnecessary rerenders Virtualized cells after any rerenders of Virualized list. Works with strict=true option From 12180ca1538ea55e3a1fc002c02947464a4d0934 Mon Sep 17 00:00:00 2001 From: Fabrizio Cucci Date: Fri, 8 Nov 2024 04:03:46 -0800 Subject: [PATCH 125/220] Migrate com.facebook.react.views.text.ReactTypefaceUtils to Kotlin (#47505) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47505 As per title. Changelog: [Internal] Reviewed By: tdn120 Differential Revision: D65596132 fbshipit-source-id: d08aea48ff293cc7f20ebc40a1d289dcb8158dcb --- .../ReactAndroid/api/ReactAndroid.api | 12 +- .../react/views/text/ReactTypefaceUtils.java | 198 ------------------ .../react/views/text/ReactTypefaceUtils.kt | 114 ++++++++++ 3 files changed, 120 insertions(+), 204 deletions(-) delete mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTypefaceUtils.java create mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTypefaceUtils.kt diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index c6e0a011f3afef..2d65e0e33c6574 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -7418,12 +7418,12 @@ public abstract interface class com/facebook/react/views/text/ReactTextViewManag public abstract fun onPostProcessSpannable (Landroid/text/Spannable;)V } -public class com/facebook/react/views/text/ReactTypefaceUtils { - public fun ()V - public static fun applyStyles (Landroid/graphics/Typeface;IILjava/lang/String;Landroid/content/res/AssetManager;)Landroid/graphics/Typeface; - public static fun parseFontStyle (Ljava/lang/String;)I - public static fun parseFontVariant (Lcom/facebook/react/bridge/ReadableArray;)Ljava/lang/String; - public static fun parseFontWeight (Ljava/lang/String;)I +public final class com/facebook/react/views/text/ReactTypefaceUtils { + public static final field INSTANCE Lcom/facebook/react/views/text/ReactTypefaceUtils; + public static final fun applyStyles (Landroid/graphics/Typeface;IILjava/lang/String;Landroid/content/res/AssetManager;)Landroid/graphics/Typeface; + public static final fun parseFontStyle (Ljava/lang/String;)I + public static final fun parseFontVariant (Lcom/facebook/react/bridge/ReadableArray;)Ljava/lang/String; + public static final fun parseFontWeight (Ljava/lang/String;)I } public class com/facebook/react/views/text/TextAttributeProps { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTypefaceUtils.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTypefaceUtils.java deleted file mode 100644 index 061db50fcf0d59..00000000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTypefaceUtils.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and 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.views.text; - -import android.content.res.AssetManager; -import android.graphics.Typeface; -import android.text.TextUtils; -import androidx.annotation.Nullable; -import com.facebook.infer.annotation.Nullsafe; -import com.facebook.react.bridge.ReadableArray; -import com.facebook.react.common.ReactConstants; -import com.facebook.react.common.assets.ReactFontManager; -import java.util.ArrayList; -import java.util.List; - -@Nullsafe(Nullsafe.Mode.LOCAL) -public class ReactTypefaceUtils { - - public static int parseFontWeight(@Nullable String fontWeightString) { - if (fontWeightString != null) { - switch (fontWeightString) { - case "100": - return 100; - case "200": - return 200; - case "300": - return 300; - case "normal": - case "400": - return 400; - case "500": - return 500; - case "600": - return 600; - case "bold": - case "700": - return 700; - case "800": - return 800; - case "900": - return 900; - } - } - return ReactConstants.UNSET; - } - - public static int parseFontStyle(@Nullable String fontStyleString) { - if (fontStyleString != null) { - if ("italic".equals(fontStyleString)) { - return Typeface.ITALIC; - } - if ("normal".equals(fontStyleString)) { - return Typeface.NORMAL; - } - } - return ReactConstants.UNSET; - } - - public static @Nullable String parseFontVariant(@Nullable ReadableArray fontVariantArray) { - if (fontVariantArray == null || fontVariantArray.size() == 0) { - return null; - } - - List features = new ArrayList<>(); - for (int i = 0; i < fontVariantArray.size(); i++) { - // see https://docs.microsoft.com/en-us/typography/opentype/spec/featurelist - String fontVariant = fontVariantArray.getString(i); - if (fontVariant != null) { - switch (fontVariant) { - case "small-caps": - features.add("'smcp'"); - break; - case "oldstyle-nums": - features.add("'onum'"); - break; - case "lining-nums": - features.add("'lnum'"); - break; - case "tabular-nums": - features.add("'tnum'"); - break; - case "proportional-nums": - features.add("'pnum'"); - break; - case "common-ligatures": - features.add("'liga'"); - features.add("'clig'"); - break; - case "no-common-ligatures": - features.add("'liga' off"); - features.add("'clig' off"); - break; - case "discretionary-ligatures": - features.add("'dlig'"); - break; - case "no-discretionary-ligatures": - features.add("'dlig' off"); - break; - case "historical-ligatures": - features.add("'hlig'"); - break; - case "no-historical-ligatures": - features.add("'hlig' off"); - break; - case "contextual": - features.add("'calt'"); - break; - case "no-contextual": - features.add("'calt' off"); - break; - case "stylistic-one": - features.add("'ss01'"); - break; - case "stylistic-two": - features.add("'ss02'"); - break; - case "stylistic-three": - features.add("'ss03'"); - break; - case "stylistic-four": - features.add("'ss04'"); - break; - case "stylistic-five": - features.add("'ss05'"); - break; - case "stylistic-six": - features.add("'ss06'"); - break; - case "stylistic-seven": - features.add("'ss07'"); - break; - case "stylistic-eight": - features.add("'ss08'"); - break; - case "stylistic-nine": - features.add("'ss09'"); - break; - case "stylistic-ten": - features.add("'ss10'"); - break; - case "stylistic-eleven": - features.add("'ss11'"); - break; - case "stylistic-twelve": - features.add("'ss12'"); - break; - case "stylistic-thirteen": - features.add("'ss13'"); - break; - case "stylistic-fourteen": - features.add("'ss14'"); - break; - case "stylistic-fifteen": - features.add("'ss15'"); - break; - case "stylistic-sixteen": - features.add("'ss16'"); - break; - case "stylistic-seventeen": - features.add("'ss17'"); - break; - case "stylistic-eighteen": - features.add("'ss18'"); - break; - case "stylistic-nineteen": - features.add("'ss19'"); - break; - case "stylistic-twenty": - features.add("'ss20'"); - break; - } - } - } - - return TextUtils.join(", ", features); - } - - public static Typeface applyStyles( - @Nullable Typeface typeface, - int style, - int weight, - @Nullable String fontFamilyName, - AssetManager assetManager) { - ReactFontManager.TypefaceStyle typefaceStyle = - new ReactFontManager.TypefaceStyle(style, weight); - if (fontFamilyName == null) { - return typefaceStyle.apply(typeface == null ? Typeface.DEFAULT : typeface); - } else { - return ReactFontManager.getInstance() - .getTypeface(fontFamilyName, typefaceStyle, assetManager); - } - } -} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTypefaceUtils.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTypefaceUtils.kt new file mode 100644 index 00000000000000..517466055c7217 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTypefaceUtils.kt @@ -0,0 +1,114 @@ +/* + * Copyright (c) Meta Platforms, Inc. and 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.views.text + +import android.content.res.AssetManager +import android.graphics.Typeface +import android.text.TextUtils +import com.facebook.react.bridge.ReadableArray +import com.facebook.react.common.ReactConstants +import com.facebook.react.common.assets.ReactFontManager + +public object ReactTypefaceUtils { + + @JvmStatic + public fun parseFontWeight(fontWeightString: String?): Int = + when (fontWeightString) { + "100" -> 100 + "200" -> 200 + "300" -> 300 + "normal", + "400" -> 400 + "500" -> 500 + "600" -> 600 + "bold", + "700" -> 700 + "800" -> 800 + "900" -> 900 + else -> ReactConstants.UNSET + } + + @JvmStatic + public fun parseFontStyle(fontStyleString: String?): Int = + when (fontStyleString) { + "italic" -> Typeface.ITALIC + "normal" -> Typeface.NORMAL + else -> ReactConstants.UNSET + } + + @JvmStatic + public fun parseFontVariant(fontVariantArray: ReadableArray?): String? { + if (fontVariantArray == null || fontVariantArray.size() == 0) { + return null + } + + val features = mutableListOf() + for (i in 0 until fontVariantArray.size()) { + // see https://docs.microsoft.com/en-us/typography/opentype/spec/featurelist + val fontVariant = fontVariantArray.getString(i) + when (fontVariant) { + "small-caps" -> features.add("'smcp'") + "oldstyle-nums" -> features.add("'onum'") + "lining-nums" -> features.add("'lnum'") + "tabular-nums" -> features.add("'tnum'") + "proportional-nums" -> features.add("'pnum'") + "common-ligatures" -> { + features.add("'liga'") + features.add("'clig'") + } + "no-common-ligatures" -> { + features.add("'liga' off") + features.add("'clig' off") + } + "discretionary-ligatures" -> features.add("'dlig'") + "no-discretionary-ligatures" -> features.add("'dlig' off") + "historical-ligatures" -> features.add("'hlig'") + "no-historical-ligatures" -> features.add("'hlig' off") + "contextual" -> features.add("'calt'") + "no-contextual" -> features.add("'calt' off") + "stylistic-one" -> features.add("'ss01'") + "stylistic-two" -> features.add("'ss02'") + "stylistic-three" -> features.add("'ss03'") + "stylistic-four" -> features.add("'ss04'") + "stylistic-five" -> features.add("'ss05'") + "stylistic-six" -> features.add("'ss06'") + "stylistic-seven" -> features.add("'ss07'") + "stylistic-eight" -> features.add("'ss08'") + "stylistic-nine" -> features.add("'ss09'") + "stylistic-ten" -> features.add("'ss10'") + "stylistic-eleven" -> features.add("'ss11'") + "stylistic-twelve" -> features.add("'ss12'") + "stylistic-thirteen" -> features.add("'ss13'") + "stylistic-fourteen" -> features.add("'ss14'") + "stylistic-fifteen" -> features.add("'ss15'") + "stylistic-sixteen" -> features.add("'ss16'") + "stylistic-seventeen" -> features.add("'ss17'") + "stylistic-eighteen" -> features.add("'ss18'") + "stylistic-nineteen" -> features.add("'ss19'") + "stylistic-twenty" -> features.add("'ss20'") + } + } + return TextUtils.join(", ", features) + } + + @JvmStatic + public fun applyStyles( + typeface: Typeface?, + style: Int, + weight: Int, + fontFamilyName: String?, + assetManager: AssetManager + ): Typeface { + val typefaceStyle = ReactFontManager.TypefaceStyle(style, weight) + return if (fontFamilyName == null) { + typefaceStyle.apply(typeface ?: Typeface.DEFAULT) + } else { + ReactFontManager.getInstance().getTypeface(fontFamilyName, typefaceStyle, assetManager) + } + } +} From b32335c29984c4ec9e0f80fadd8b78cd0ee1862f Mon Sep 17 00:00:00 2001 From: Riccardo Cipolleschi Date: Fri, 8 Nov 2024 04:28:32 -0800 Subject: [PATCH 126/220] Only build ios in check nightlies (#47506) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47506 The Check nightlies job prepare a new nightly app with additional libraries and on iOS it builds with `yarn ios`. The command tries to launch the app on the simulator which sometimes fails and this can make the jobs keep running for hours. This change make sure that we only build the app ## Changelog: [Internal] - Only build iOS in CI for Check Nightlies Reviewed By: blakef Differential Revision: D65656812 fbshipit-source-id: 14db3738f33f8024c9e99fe206b170209154bac7 --- .github/actions/test-library-on-nightly/action.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/actions/test-library-on-nightly/action.yml b/.github/actions/test-library-on-nightly/action.yml index 1d59aec18fa44f..f6fdaa21446cd4 100644 --- a/.github/actions/test-library-on-nightly/action.yml +++ b/.github/actions/test-library-on-nightly/action.yml @@ -28,8 +28,10 @@ runs: cd /tmp/RNApp/ios bundle install bundle exec pod install - cd .. - yarn ios + xcodebuild build \ + -workspace RNApp.xcworkspace \ + -scheme RNApp \ + -sdk iphonesimulator - name: Setup Java for Android if: ${{ inputs.platform == 'android' }} uses: actions/setup-java@v2 From fd725372026748034b5e16543a323ae116abef2e Mon Sep 17 00:00:00 2001 From: Pieter De Baets Date: Fri, 8 Nov 2024 04:31:46 -0800 Subject: [PATCH 127/220] Convert com.facebook.react.bridge.JavaOnlyArray to Kotlin (#47424) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47424 Changelog: [Internal] Reviewed By: cortinico Differential Revision: D65479614 fbshipit-source-id: d2ab86eb0e8c68a5733c602652b4b8dccc09a0a1 --- .../ReactAndroid/api/ReactAndroid.api | 17 +- .../facebook/react/bridge/JavaOnlyArray.java | 219 ------------------ .../facebook/react/bridge/JavaOnlyArray.kt | 148 ++++++++++++ .../facebook/react/bridge/ReadableArray.kt | 2 +- 4 files changed, 162 insertions(+), 224 deletions(-) delete mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaOnlyArray.java create mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaOnlyArray.kt diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 2d65e0e33c6574..3a8e8ca785b54d 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -896,11 +896,14 @@ public final class com/facebook/react/bridge/JavaJSExecutor$ProxyExecutorExcepti public fun (Ljava/lang/Throwable;)V } -public class com/facebook/react/bridge/JavaOnlyArray : com/facebook/react/bridge/ReadableArray, com/facebook/react/bridge/WritableArray { +public final class com/facebook/react/bridge/JavaOnlyArray : com/facebook/react/bridge/ReadableArray, com/facebook/react/bridge/WritableArray { + public static final field Companion Lcom/facebook/react/bridge/JavaOnlyArray$Companion; public fun ()V - public static fun deepClone (Lcom/facebook/react/bridge/ReadableArray;)Lcom/facebook/react/bridge/JavaOnlyArray; + public synthetic fun (Ljava/util/List;Lkotlin/jvm/internal/DefaultConstructorMarker;)V + public synthetic fun ([Ljava/lang/Object;Lkotlin/jvm/internal/DefaultConstructorMarker;)V + public static final fun deepClone (Lcom/facebook/react/bridge/ReadableArray;)Lcom/facebook/react/bridge/JavaOnlyArray; public fun equals (Ljava/lang/Object;)Z - public static fun from (Ljava/util/List;)Lcom/facebook/react/bridge/JavaOnlyArray; + public static final fun from (Ljava/util/List;)Lcom/facebook/react/bridge/JavaOnlyArray; public fun getArray (I)Lcom/facebook/react/bridge/ReadableArray; public fun getBoolean (I)Z public fun getDouble (I)D @@ -912,7 +915,7 @@ public class com/facebook/react/bridge/JavaOnlyArray : com/facebook/react/bridge public fun getType (I)Lcom/facebook/react/bridge/ReadableType; public fun hashCode ()I public fun isNull (I)Z - public static fun of ([Ljava/lang/Object;)Lcom/facebook/react/bridge/JavaOnlyArray; + public static final fun of ([Ljava/lang/Object;)Lcom/facebook/react/bridge/JavaOnlyArray; public fun pushArray (Lcom/facebook/react/bridge/ReadableArray;)V public fun pushBoolean (Z)V public fun pushDouble (D)V @@ -926,6 +929,12 @@ public class com/facebook/react/bridge/JavaOnlyArray : com/facebook/react/bridge public fun toString ()Ljava/lang/String; } +public final class com/facebook/react/bridge/JavaOnlyArray$Companion { + public final fun deepClone (Lcom/facebook/react/bridge/ReadableArray;)Lcom/facebook/react/bridge/JavaOnlyArray; + public final fun from (Ljava/util/List;)Lcom/facebook/react/bridge/JavaOnlyArray; + public final fun of ([Ljava/lang/Object;)Lcom/facebook/react/bridge/JavaOnlyArray; +} + public final class com/facebook/react/bridge/JavaOnlyMap : com/facebook/react/bridge/ReadableMap, com/facebook/react/bridge/WritableMap { public static final field Companion Lcom/facebook/react/bridge/JavaOnlyMap$Companion; public fun ()V diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaOnlyArray.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaOnlyArray.java deleted file mode 100644 index 8f63d7a2add58d..00000000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaOnlyArray.java +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and 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.bridge; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -/** - * Java {@link ArrayList} backed implementation of {@link ReadableArray} and {@link WritableArray} - * Instances of this class SHOULD NOT be used for communication between java and JS, use instances - * of {@link WritableNativeArray} created via {@link Arguments#createArray} or just {@link - * ReadableArray} interface if you want your "native" module method to take an array from JS as an - * argument. - * - *

Main purpose for this class is to be used in java-only unit tests, but could also be used - * outside of tests in the code that operates only in java and needs to communicate with RN modules - * via their JS-exposed API. - */ -public class JavaOnlyArray implements ReadableArray, WritableArray { - - private final List mBackingList; - - public static JavaOnlyArray from(List list) { - return new JavaOnlyArray(list); - } - - public static JavaOnlyArray of(Object... values) { - return new JavaOnlyArray(values); - } - - public static JavaOnlyArray deepClone(ReadableArray ary) { - JavaOnlyArray res = new JavaOnlyArray(); - for (int i = 0, size = ary.size(); i < size; i++) { - ReadableType type = ary.getType(i); - switch (type) { - case Null: - res.pushNull(); - break; - case Boolean: - res.pushBoolean(ary.getBoolean(i)); - break; - case Number: - res.pushDouble(ary.getDouble(i)); - break; - case String: - res.pushString(ary.getString(i)); - break; - case Map: - res.pushMap(JavaOnlyMap.deepClone(ary.getMap(i))); - break; - case Array: - res.pushArray(deepClone(ary.getArray(i))); - break; - } - } - return res; - } - - private JavaOnlyArray(Object... values) { - mBackingList = Arrays.asList(values); - } - - private JavaOnlyArray(List list) { - mBackingList = new ArrayList(list); - } - - public JavaOnlyArray() { - mBackingList = new ArrayList(); - } - - @Override - public int size() { - return mBackingList.size(); - } - - @Override - public boolean isNull(int index) { - return mBackingList.get(index) == null; - } - - @Override - public double getDouble(int index) { - return ((Number) mBackingList.get(index)).doubleValue(); - } - - @Override - public int getInt(int index) { - return ((Number) mBackingList.get(index)).intValue(); - } - - @Override - public long getLong(int index) { - return ((Number) mBackingList.get(index)).longValue(); - } - - @Override - public @Nullable String getString(int index) { - return (String) mBackingList.get(index); - } - - @Override - public ReadableArray getArray(int index) { - return (ReadableArray) mBackingList.get(index); - } - - @Override - public boolean getBoolean(int index) { - return (Boolean) mBackingList.get(index); - } - - @Override - public ReadableMap getMap(int index) { - return (ReadableMap) mBackingList.get(index); - } - - @Override - public @NonNull Dynamic getDynamic(int index) { - return DynamicFromArray.create(this, index); - } - - @Override - public @NonNull ReadableType getType(int index) { - Object object = mBackingList.get(index); - - if (object == null) { - return ReadableType.Null; - } else if (object instanceof Boolean) { - return ReadableType.Boolean; - } else if (object instanceof Double - || object instanceof Float - || object instanceof Integer - || object instanceof Long) { - return ReadableType.Number; - } else if (object instanceof String) { - return ReadableType.String; - } else if (object instanceof ReadableArray) { - return ReadableType.Array; - } else if (object instanceof ReadableMap) { - return ReadableType.Map; - } - return null; - } - - @Override - public void pushBoolean(boolean value) { - mBackingList.add(value); - } - - @Override - public void pushDouble(double value) { - mBackingList.add(value); - } - - @Override - public void pushInt(int value) { - mBackingList.add(new Double(value)); - } - - @Override - public void pushLong(long value) { - mBackingList.add(value); - } - - @Override - public void pushString(@Nullable String value) { - mBackingList.add(value); - } - - @Override - public void pushArray(@Nullable ReadableArray array) { - mBackingList.add(array); - } - - @Override - public void pushMap(@Nullable ReadableMap map) { - mBackingList.add(map); - } - - @Override - public void pushNull() { - mBackingList.add(null); - } - - @Override - public @NonNull ArrayList toArrayList() { - return new ArrayList(mBackingList); - } - - @Override - public String toString() { - return mBackingList.toString(); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - JavaOnlyArray that = (JavaOnlyArray) o; - - if (mBackingList != null ? !mBackingList.equals(that.mBackingList) : that.mBackingList != null) - return false; - - return true; - } - - @Override - public int hashCode() { - return mBackingList != null ? mBackingList.hashCode() : 0; - } -} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaOnlyArray.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaOnlyArray.kt new file mode 100644 index 00000000000000..9728d488ad6ad6 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaOnlyArray.kt @@ -0,0 +1,148 @@ +/* + * Copyright (c) Meta Platforms, Inc. and 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.bridge + +import com.facebook.react.bridge.JavaOnlyMap.Companion.deepClone +import java.util.ArrayList + +/** + * Java [ArrayList] backed implementation of [ReadableArray] and [WritableArray] Instances of this + * class SHOULD NOT be used for communication between java and JS, use instances of + * [WritableNativeArray] created via [Arguments#createArray] or just [ReadableArray] interface if + * you want your "native" module method to take an array from JS as an argument. + * + * Main purpose for this class is to be used in java-only unit tests, but could also be used outside + * of tests in the code that operates only in java and needs to communicate with RN modules via + * their JS-exposed API. + */ +public class JavaOnlyArray : ReadableArray, WritableArray { + + public companion object { + @JvmStatic public fun from(list: List<*>): JavaOnlyArray = JavaOnlyArray(list) + + @JvmStatic public fun of(vararg values: Any?): JavaOnlyArray = JavaOnlyArray(*values) + + @JvmStatic + public fun deepClone(array: ReadableArray?): JavaOnlyArray { + val res = JavaOnlyArray() + if (array == null) { + return res + } + + repeat(array.size()) { i -> + val type = array.getType(i) + when (type) { + ReadableType.Null -> res.pushNull() + ReadableType.Boolean -> res.pushBoolean(array.getBoolean(i)) + ReadableType.Number -> res.pushDouble(array.getDouble(i)) + ReadableType.String -> res.pushString(array.getString(i)) + ReadableType.Map -> res.pushMap(deepClone(array.getMap(i))) + ReadableType.Array -> res.pushArray(deepClone(array.getArray(i))) + } + } + return res + } + } + + private val backingList: MutableList + + private constructor(vararg values: Any?) { + backingList = mutableListOf(*values) + } + + private constructor(list: List<*>) { + backingList = ArrayList(list) + } + + public constructor() { + backingList = mutableListOf() + } + + override fun size(): Int = backingList.size + + override fun isNull(index: Int): Boolean = backingList[index] == null + + override fun getDouble(index: Int): Double = (backingList[index] as Number).toDouble() + + override fun getInt(index: Int): Int = (backingList[index] as Number).toInt() + + override fun getLong(index: Int): Long = (backingList[index] as Number).toLong() + + override fun getString(index: Int): String = backingList[index] as String + + override fun getArray(index: Int): ReadableArray = backingList[index] as ReadableArray + + override fun getBoolean(index: Int): Boolean = backingList[index] as Boolean + + override fun getMap(index: Int): ReadableMap = backingList[index] as ReadableMap + + override fun getDynamic(index: Int): Dynamic = DynamicFromArray.create(this, index) + + override fun getType(index: Int): ReadableType { + return when (val value = backingList[index]) { + null -> ReadableType.Null + is Boolean -> ReadableType.Boolean + is Double, + is Float, + is Int, + is Long -> ReadableType.Number + is String -> ReadableType.String + is ReadableArray -> ReadableType.Array + is ReadableMap -> ReadableType.Map + else -> throw IllegalStateException("Invalid type ${value.javaClass})") + } + } + + override fun pushBoolean(value: Boolean) { + backingList.add(value) + } + + override fun pushDouble(value: Double) { + backingList.add(value) + } + + override fun pushInt(value: Int) { + backingList.add(value.toDouble()) + } + + override fun pushLong(value: Long) { + backingList.add(value.toDouble()) + } + + override fun pushString(value: String?) { + backingList.add(value) + } + + override fun pushArray(array: ReadableArray?) { + backingList.add(array) + } + + override fun pushMap(map: ReadableMap?) { + backingList.add(map) + } + + override fun pushNull() { + backingList.add(null) + } + + override fun toArrayList(): ArrayList = ArrayList(backingList) + + override fun toString(): String = backingList.toString() + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } else if (other == null || javaClass != other.javaClass) { + return false + } else { + return backingList == (other as JavaOnlyArray).backingList + } + } + + override fun hashCode(): Int = backingList.hashCode() +} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableArray.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableArray.kt index de59f930ad5829..8d024a81b8e052 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableArray.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableArray.kt @@ -36,5 +36,5 @@ public interface ReadableArray { public fun size(): Int - public fun toArrayList(): ArrayList + public fun toArrayList(): ArrayList } From 3c32da5bfeb9b284b5b8a0a2a92f02bd1430aa3e Mon Sep 17 00:00:00 2001 From: Pieter De Baets Date: Fri, 8 Nov 2024 04:31:46 -0800 Subject: [PATCH 128/220] Convert com.facebook.react.bridge.NativeArray to Kotlin (#47456) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47456 Changelog: [Internal] Reviewed By: tdn120 Differential Revision: D65486257 fbshipit-source-id: d18d38fd7e605918d79e370dda7df51abac2f23c --- .../facebook/react/bridge/NativeArray.java | 24 ------------------ .../com/facebook/react/bridge/NativeArray.kt | 25 +++++++++++++++++++ 2 files changed, 25 insertions(+), 24 deletions(-) delete mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/NativeArray.java create mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/NativeArray.kt diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/NativeArray.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/NativeArray.java deleted file mode 100644 index 2a5233427ab614..00000000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/NativeArray.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and 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.bridge; - -import com.facebook.jni.HybridClassBase; -import com.facebook.proguard.annotations.DoNotStrip; - -/** Base class for an array whose members are stored in native code (C++). */ -@DoNotStrip -public abstract class NativeArray extends HybridClassBase implements NativeArrayInterface { - static { - ReactBridge.staticInit(); - } - - protected NativeArray() {} - - @Override - public native String toString(); -} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/NativeArray.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/NativeArray.kt new file mode 100644 index 00000000000000..e70f2d76eec4e0 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/NativeArray.kt @@ -0,0 +1,25 @@ +/* + * Copyright (c) Meta Platforms, Inc. and 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.bridge + +import com.facebook.jni.HybridClassBase +import com.facebook.proguard.annotations.DoNotStrip + +/** Base class for an array whose members are stored in native code (C++). */ +@DoNotStrip +public abstract class NativeArray protected constructor() : + HybridClassBase(), NativeArrayInterface { + + external override fun toString(): String + + private companion object { + init { + ReactBridge.staticInit() + } + } +} From e64513bf4ecce60aff5c04e3bed91b203429d12f Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Fri, 8 Nov 2024 04:57:15 -0800 Subject: [PATCH 129/220] RNGP - Do not attempt to substring to 1024 while logging. (#47509) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47509 Fixes https://github.com/facebook/react-native/issues/47504 Changelog: [Android] [Fixed] - RNGP - Do not attempt to substring to 1024 while logging Reviewed By: javache Differential Revision: D65659586 fbshipit-source-id: 8fa16131cea96b8b6aa9c0224c7b990a4f51175f --- .../kotlin/com/facebook/react/ReactSettingsExtension.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/gradle-plugin/settings-plugin/src/main/kotlin/com/facebook/react/ReactSettingsExtension.kt b/packages/gradle-plugin/settings-plugin/src/main/kotlin/com/facebook/react/ReactSettingsExtension.kt index be26a2233799ef..aea525747e08b8 100644 --- a/packages/gradle-plugin/settings-plugin/src/main/kotlin/com/facebook/react/ReactSettingsExtension.kt +++ b/packages/gradle-plugin/settings-plugin/src/main/kotlin/com/facebook/react/ReactSettingsExtension.kt @@ -15,6 +15,7 @@ import java.math.BigInteger import java.security.MessageDigest import java.util.concurrent.TimeUnit import javax.inject.Inject +import kotlin.math.min import org.gradle.api.GradleException import org.gradle.api.file.FileCollection import org.gradle.api.initialization.Settings @@ -159,7 +160,10 @@ abstract class ReactSettingsExtension @Inject constructor(val settings: Settings val logger = Logging.getLogger("ReactSettingsExtension") logger.error(message) if (cacheJsonConfig.length() != 0L) { - logger.error(cacheJsonConfig.readText().substring(0, 1024)) + logger.error( + cacheJsonConfig + .readText() + .substring(0, min(1024, cacheJsonConfig.length().toInt()))) } cacheJsonConfig.delete() throw GradleException(message) From 697a422bf55b58b11499a40c6d4923deb646ce56 Mon Sep 17 00:00:00 2001 From: Fabrizio Cucci Date: Fri, 8 Nov 2024 06:10:22 -0800 Subject: [PATCH 130/220] Migrate com.facebook.react.views.text.FontMetricsUtil to Kotlin (#47510) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47510 As per title. Changelog: [Internal] Reviewed By: tdn120 Differential Revision: D65598073 fbshipit-source-id: 401750f2df9bd434a8310f107f46a686bfa6601c --- .../ReactAndroid/api/ReactAndroid.api | 6 +- .../react/views/text/FontMetricsUtil.java | 65 ----------------- .../react/views/text/FontMetricsUtil.kt | 72 +++++++++++++++++++ 3 files changed, 75 insertions(+), 68 deletions(-) delete mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/FontMetricsUtil.java create mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/FontMetricsUtil.kt diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 3a8e8ca785b54d..1585de5f1e42c9 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -7200,9 +7200,9 @@ public final class com/facebook/react/views/text/DefaultStyleValuesUtil { public static final fun getDefaultTextColorHint (Landroid/content/Context;)Landroid/content/res/ColorStateList; } -public class com/facebook/react/views/text/FontMetricsUtil { - public fun ()V - public static fun getFontMetrics (Ljava/lang/CharSequence;Landroid/text/Layout;Landroid/text/TextPaint;Landroid/content/Context;)Lcom/facebook/react/bridge/WritableArray; +public final class com/facebook/react/views/text/FontMetricsUtil { + public static final field INSTANCE Lcom/facebook/react/views/text/FontMetricsUtil; + public static final fun getFontMetrics (Ljava/lang/CharSequence;Landroid/text/Layout;Landroid/text/TextPaint;Landroid/content/Context;)Lcom/facebook/react/bridge/WritableArray; } public abstract class com/facebook/react/views/text/ReactBaseTextShadowNode : com/facebook/react/uimanager/LayoutShadowNode { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/FontMetricsUtil.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/FontMetricsUtil.java deleted file mode 100644 index 84dc328edab3af..00000000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/FontMetricsUtil.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and 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.views.text; - -import android.content.Context; -import android.graphics.Rect; -import android.text.Layout; -import android.text.TextPaint; -import android.util.DisplayMetrics; -import com.facebook.react.bridge.Arguments; -import com.facebook.react.bridge.WritableArray; -import com.facebook.react.bridge.WritableMap; - -public class FontMetricsUtil { - - private static final String CAP_HEIGHT_MEASUREMENT_TEXT = "T"; - private static final String X_HEIGHT_MEASUREMENT_TEXT = "x"; - private static final float AMPLIFICATION_FACTOR = 100; - - public static WritableArray getFontMetrics( - CharSequence text, Layout layout, TextPaint paint, Context context) { - DisplayMetrics dm = context.getResources().getDisplayMetrics(); - WritableArray lines = Arguments.createArray(); - // To calculate xHeight and capHeight we have to render an "x" and "T" and manually measure - // their height. - // In order to get more precision than Android offers, we blow up the text size by 100 and - // measure it. - // Luckily, text size affects rendering linearly, so we can do this trick. - TextPaint paintCopy = new TextPaint(paint); - paintCopy.setTextSize(paintCopy.getTextSize() * AMPLIFICATION_FACTOR); - Rect capHeightBounds = new Rect(); - paintCopy.getTextBounds( - CAP_HEIGHT_MEASUREMENT_TEXT, 0, CAP_HEIGHT_MEASUREMENT_TEXT.length(), capHeightBounds); - double capHeight = capHeightBounds.height() / AMPLIFICATION_FACTOR / dm.density; - Rect xHeightBounds = new Rect(); - paintCopy.getTextBounds( - X_HEIGHT_MEASUREMENT_TEXT, 0, X_HEIGHT_MEASUREMENT_TEXT.length(), xHeightBounds); - double xHeight = xHeightBounds.height() / AMPLIFICATION_FACTOR / dm.density; - for (int i = 0; i < layout.getLineCount(); i++) { - boolean endsWithNewLine = text.length() > 0 && text.charAt(layout.getLineEnd(i) - 1) == '\n'; - float lineWidth = endsWithNewLine ? layout.getLineMax(i) : layout.getLineWidth(i); - Rect bounds = new Rect(); - layout.getLineBounds(i, bounds); - WritableMap line = Arguments.createMap(); - line.putDouble("x", layout.getLineLeft(i) / dm.density); - line.putDouble("y", bounds.top / dm.density); - line.putDouble("width", lineWidth / dm.density); - line.putDouble("height", bounds.height() / dm.density); - line.putDouble("descender", layout.getLineDescent(i) / dm.density); - line.putDouble("ascender", -layout.getLineAscent(i) / dm.density); - line.putDouble("baseline", layout.getLineBaseline(i) / dm.density); - line.putDouble("capHeight", capHeight); - line.putDouble("xHeight", xHeight); - line.putString( - "text", text.subSequence(layout.getLineStart(i), layout.getLineEnd(i)).toString()); - lines.pushMap(line); - } - return lines; - } -} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/FontMetricsUtil.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/FontMetricsUtil.kt new file mode 100644 index 00000000000000..f9446d08a93a20 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/FontMetricsUtil.kt @@ -0,0 +1,72 @@ +/* + * Copyright (c) Meta Platforms, Inc. and 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.views.text + +import android.content.Context +import android.graphics.Rect +import android.text.Layout +import android.text.TextPaint +import com.facebook.react.bridge.Arguments +import com.facebook.react.bridge.WritableArray + +public object FontMetricsUtil { + + private const val CAP_HEIGHT_MEASUREMENT_TEXT = "T" + private const val X_HEIGHT_MEASUREMENT_TEXT = "x" + private const val AMPLIFICATION_FACTOR = 100f + + @JvmStatic + public fun getFontMetrics( + text: CharSequence, + layout: Layout, + paint: TextPaint, + context: Context + ): WritableArray { + val dm = context.resources.displayMetrics + val lines = Arguments.createArray() + + // To calculate xHeight and capHeight we have to render an "x" and "T" and manually measure + // their height. In order to get more precision than Android offers, we blow up the text size by + // 100 and + // measure it. Luckily, text size affects rendering linearly, so we can do this trick. + val paintCopy = TextPaint(paint).apply { textSize *= AMPLIFICATION_FACTOR } + + val capHeightBounds = Rect() + paintCopy.getTextBounds( + CAP_HEIGHT_MEASUREMENT_TEXT, 0, CAP_HEIGHT_MEASUREMENT_TEXT.length, capHeightBounds) + val capHeight = capHeightBounds.height() / AMPLIFICATION_FACTOR / dm.density + + val xHeightBounds = Rect() + paintCopy.getTextBounds( + X_HEIGHT_MEASUREMENT_TEXT, 0, X_HEIGHT_MEASUREMENT_TEXT.length, xHeightBounds) + val xHeight = xHeightBounds.height() / AMPLIFICATION_FACTOR / dm.density + + for (i in 0 until layout.lineCount) { + val endsWithNewLine = text.isNotEmpty() && text[layout.getLineEnd(i) - 1] == '\n' + val lineWidth = if (endsWithNewLine) layout.getLineMax(i) else layout.getLineWidth(i) + val bounds = Rect() + layout.getLineBounds(i, bounds) + val line = + Arguments.createMap().apply { + putDouble("x", (layout.getLineLeft(i) / dm.density).toDouble()) + putDouble("y", (bounds.top / dm.density).toDouble()) + putDouble("width", (lineWidth / dm.density).toDouble()) + putDouble("height", (bounds.height() / dm.density).toDouble()) + putDouble("descender", (layout.getLineDescent(i) / dm.density).toDouble()) + putDouble("ascender", (-layout.getLineAscent(i) / dm.density).toDouble()) + putDouble("baseline", (layout.getLineBaseline(i) / dm.density).toDouble()) + putDouble("capHeight", capHeight.toDouble()) + putDouble("xHeight", xHeight.toDouble()) + putString( + "text", text.subSequence(layout.getLineStart(i), layout.getLineEnd(i)).toString()) + } + lines.pushMap(line) + } + return lines + } +} From 8cb2ad672525824e6695f6fe59075c54acd164a6 Mon Sep 17 00:00:00 2001 From: Pieter De Baets Date: Fri, 8 Nov 2024 06:14:13 -0800 Subject: [PATCH 131/220] Improve robolectric shadows (#47460) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47460 Changelog: [Internal] Reviewed By: cortinico Differential Revision: D65538979 fbshipit-source-id: 7a0b0f701968a9af9197246e6e89e0ccfd55653d --- .../testutils/shadows/ShadowNativeMap.kt | 29 +++++ .../shadows/ShadowReadableNativeArray.java | 90 +++++++++++++++ .../shadows/ShadowReadableNativeMap.java | 104 ++++++++++++++++++ .../shadows/ShadowWritableNativeArray.java | 65 +++++++++++ .../shadows/ShadowWritableNativeMap.java | 76 +++++++++++++ 5 files changed, 364 insertions(+) create mode 100644 packages/react-native/ReactAndroid/src/test/java/com/facebook/testutils/shadows/ShadowNativeMap.kt create mode 100644 packages/react-native/ReactAndroid/src/test/java/com/facebook/testutils/shadows/ShadowReadableNativeArray.java create mode 100644 packages/react-native/ReactAndroid/src/test/java/com/facebook/testutils/shadows/ShadowReadableNativeMap.java create mode 100644 packages/react-native/ReactAndroid/src/test/java/com/facebook/testutils/shadows/ShadowWritableNativeArray.java create mode 100644 packages/react-native/ReactAndroid/src/test/java/com/facebook/testutils/shadows/ShadowWritableNativeMap.java diff --git a/packages/react-native/ReactAndroid/src/test/java/com/facebook/testutils/shadows/ShadowNativeMap.kt b/packages/react-native/ReactAndroid/src/test/java/com/facebook/testutils/shadows/ShadowNativeMap.kt new file mode 100644 index 00000000000000..d0092045c874e1 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/test/java/com/facebook/testutils/shadows/ShadowNativeMap.kt @@ -0,0 +1,29 @@ +/* + * Copyright (c) Meta Platforms, Inc. and 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.testutils.shadows + +import com.facebook.react.bridge.NativeMap +import com.facebook.react.bridge.ReadableNativeMap +import com.facebook.react.bridge.WritableNativeMap +import org.robolectric.annotation.Implements +import org.robolectric.shadow.api.Shadow + +// Mockito can't mock native methods, so shadow the entire class instead +@Implements(NativeMap::class) +public open class ShadowNativeMap { + public var contents: Map = HashMap() + + @Implements(ReadableNativeMap::class) public class Readable : ShadowNativeMap() {} + + @Implements(WritableNativeMap::class) public class Writable : ShadowNativeMap() {} + + public companion object { + public fun getContents(map: NativeMap): Map = + (Shadow.extract(map) as ShadowNativeMap).contents + } +} diff --git a/packages/react-native/ReactAndroid/src/test/java/com/facebook/testutils/shadows/ShadowReadableNativeArray.java b/packages/react-native/ReactAndroid/src/test/java/com/facebook/testutils/shadows/ShadowReadableNativeArray.java new file mode 100644 index 00000000000000..2c7aaccb1a40c8 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/test/java/com/facebook/testutils/shadows/ShadowReadableNativeArray.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) Meta Platforms, Inc. and 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.testutils.shadows; + +import androidx.annotation.NonNull; +import com.facebook.react.bridge.Dynamic; +import com.facebook.react.bridge.JavaOnlyArray; +import com.facebook.react.bridge.ReadableArray; +import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.bridge.ReadableNativeArray; +import com.facebook.react.bridge.ReadableType; +import java.util.ArrayList; +import org.robolectric.annotation.Implementation; +import org.robolectric.annotation.Implements; + +@Implements(ReadableNativeArray.class) +public class ShadowReadableNativeArray extends ShadowNativeArray implements ReadableArray { + + protected JavaOnlyArray backingArray; + + @Implementation + protected void __constructor__() { + this.backingArray = new JavaOnlyArray(); + } + + @Implementation + public int size() { + return this.backingArray.size(); + } + + @Implementation + public boolean isNull(int index) { + return this.backingArray.isNull(index); + } + + @Implementation + public boolean getBoolean(int index) { + return this.backingArray.getBoolean(index); + } + + @Implementation + public double getDouble(int index) { + return this.backingArray.getDouble(index); + } + + @Implementation + public int getInt(int index) { + return this.backingArray.getInt(index); + } + + @Implementation + public long getLong(int index) { + return this.backingArray.getLong(index); + } + + @Implementation + public @NonNull String getString(int index) { + return this.backingArray.getString(index); + } + + @Implementation + public @NonNull ReadableArray getArray(int index) { + return this.backingArray.getArray(index); + } + + @Implementation + public @NonNull ReadableMap getMap(int index) { + return this.backingArray.getMap(index); + } + + @Implementation + public @NonNull Dynamic getDynamic(int index) { + return this.backingArray.getDynamic(index); + } + + @Implementation + public @NonNull ReadableType getType(int index) { + return this.backingArray.getType(index); + } + + @Implementation + public @NonNull ArrayList toArrayList() { + return this.backingArray.toArrayList(); + } +} diff --git a/packages/react-native/ReactAndroid/src/test/java/com/facebook/testutils/shadows/ShadowReadableNativeMap.java b/packages/react-native/ReactAndroid/src/test/java/com/facebook/testutils/shadows/ShadowReadableNativeMap.java new file mode 100644 index 00000000000000..1599e51bd84434 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/test/java/com/facebook/testutils/shadows/ShadowReadableNativeMap.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) Meta Platforms, Inc. and 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.testutils.shadows; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import com.facebook.react.bridge.Dynamic; +import com.facebook.react.bridge.JavaOnlyMap; +import com.facebook.react.bridge.ReadableArray; +import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.bridge.ReadableMapKeySetIterator; +import com.facebook.react.bridge.ReadableNativeMap; +import com.facebook.react.bridge.ReadableType; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import org.robolectric.annotation.Implementation; +import org.robolectric.annotation.Implements; + +@Implements(ReadableNativeMap.class) +public class ShadowReadableNativeMap extends ShadowNativeMap implements ReadableMap { + + protected JavaOnlyMap backingMap; + + @Implementation + protected void __constructor__() { + this.backingMap = new JavaOnlyMap(); + } + + @Implementation + public boolean hasKey(@NonNull String name) { + return backingMap.hasKey(name); + } + + @Implementation + public boolean isNull(@NonNull String name) { + return backingMap.isNull(name); + } + + @Implementation + public boolean getBoolean(@NonNull String name) { + return backingMap.getBoolean(name); + } + + @Implementation + public double getDouble(@NonNull String name) { + return backingMap.getDouble(name); + } + + @Implementation + public int getInt(@NonNull String name) { + return backingMap.getInt(name); + } + + @Implementation + public long getLong(@NonNull String name) { + return backingMap.getLong(name); + } + + @Implementation + public @Nullable String getString(@NonNull String name) { + return backingMap.getString(name); + } + + @Implementation + public @Nullable ReadableArray getArray(@NonNull String name) { + return backingMap.getArray(name); + } + + @Implementation + public @Nullable ReadableMap getMap(@NonNull String name) { + return backingMap.getMap(name); + } + + @Implementation + public @NonNull Dynamic getDynamic(@NonNull String name) { + return backingMap.getDynamic(name); + } + + @Implementation + public @NonNull ReadableType getType(@NonNull String name) { + return backingMap.getType(name); + } + + @Implementation + public @NonNull Iterator> getEntryIterator() { + return backingMap.getEntryIterator(); + } + + @Implementation + public @NonNull ReadableMapKeySetIterator keySetIterator() { + return backingMap.keySetIterator(); + } + + @Implementation + public @NonNull HashMap toHashMap() { + return backingMap.toHashMap(); + } +} diff --git a/packages/react-native/ReactAndroid/src/test/java/com/facebook/testutils/shadows/ShadowWritableNativeArray.java b/packages/react-native/ReactAndroid/src/test/java/com/facebook/testutils/shadows/ShadowWritableNativeArray.java new file mode 100644 index 00000000000000..0dfa2f3917ed67 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/test/java/com/facebook/testutils/shadows/ShadowWritableNativeArray.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) Meta Platforms, Inc. and 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.testutils.shadows; + +import androidx.annotation.Nullable; +import com.facebook.react.bridge.ReadableArray; +import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.bridge.WritableArray; +import com.facebook.react.bridge.WritableNativeArray; +import org.robolectric.annotation.Implementation; +import org.robolectric.annotation.Implements; + +@Implements(WritableNativeArray.class) +public class ShadowWritableNativeArray extends ShadowReadableNativeArray implements WritableArray { + + @Implementation + protected void __constructor__() { + super.__constructor__(); + } + + @Implementation + public void pushNull() { + super.backingArray.pushNull(); + } + + @Implementation + public void pushBoolean(boolean value) { + super.backingArray.pushBoolean(value); + } + + @Implementation + public void pushDouble(double value) { + super.backingArray.pushDouble(value); + } + + @Implementation + public void pushInt(int value) { + super.backingArray.pushInt(value); + } + + @Implementation + public void pushLong(long value) { + super.backingArray.pushLong(value); + } + + @Implementation + public void pushString(@Nullable String value) { + super.backingArray.pushString(value); + } + + @Implementation + public void pushArray(@Nullable ReadableArray array) { + super.backingArray.pushArray(array); + } + + @Implementation + public void pushMap(@Nullable ReadableMap map) { + super.backingArray.pushMap(map); + } +} diff --git a/packages/react-native/ReactAndroid/src/test/java/com/facebook/testutils/shadows/ShadowWritableNativeMap.java b/packages/react-native/ReactAndroid/src/test/java/com/facebook/testutils/shadows/ShadowWritableNativeMap.java new file mode 100644 index 00000000000000..754aef3d936522 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/test/java/com/facebook/testutils/shadows/ShadowWritableNativeMap.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) Meta Platforms, Inc. and 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.testutils.shadows; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import com.facebook.react.bridge.ReadableArray; +import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.bridge.WritableMap; +import com.facebook.react.bridge.WritableNativeMap; +import org.robolectric.annotation.Implementation; +import org.robolectric.annotation.Implements; + +@Implements(WritableNativeMap.class) +public class ShadowWritableNativeMap extends ShadowReadableNativeMap implements WritableMap { + + @Implementation + protected void __constructor__() { + super.__constructor__(); + } + + @Implementation + public void putNull(@NonNull String key) { + super.backingMap.putNull(key); + } + + @Implementation + public void putBoolean(@NonNull String key, boolean value) { + super.backingMap.putBoolean(key, value); + } + + @Implementation + public void putDouble(@NonNull String key, double value) { + super.backingMap.putDouble(key, value); + } + + @Implementation + public void putInt(@NonNull String key, int value) { + super.backingMap.putInt(key, value); + } + + @Implementation + public void putLong(@NonNull String key, long value) { + super.backingMap.putLong(key, value); + } + + @Implementation + public void putString(@NonNull String key, @Nullable String value) { + super.backingMap.putString(key, value); + } + + @Implementation + public void putArray(@NonNull String key, @Nullable ReadableArray value) { + super.backingMap.putArray(key, value); + } + + @Implementation + public void putMap(@NonNull String key, @Nullable ReadableMap value) { + super.backingMap.putMap(key, value); + } + + @Implementation + public void merge(@NonNull ReadableMap source) { + super.backingMap.merge(source); + } + + @Implementation + public WritableMap copy() { + return super.backingMap.copy(); + } +} From 7e268c9d52c99ed5af7b57158bcf9bdaeea68d11 Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Fri, 8 Nov 2024 08:27:37 -0800 Subject: [PATCH 132/220] Revert React 19RC to React 18.3.1 (#47380) Summary: While we're waiting for 19 stable, let's bring main back to 18.3.1 ahead of the 0.77 branch cut. We'll land this change just after 19 stable lands. This is a cherry pick of b93b378fa03e4e85a9e32c651f2f1f6d54033af4 which landed in 0.76 already bypass-github-export-checks ## Changelog: [INTERNAL] - Revert React 19RC to React 18.3.1 Pull Request resolved: https://github.com/facebook/react-native/pull/47380 Test Plan: CI Reviewed By: cipolleschi Differential Revision: D65430775 Pulled By: cortinico fbshipit-source-id: f0f211754c8ffe5d037fd299e4de52c29d1d7913 --- package.json | 6 +- packages/helloworld/package.json | 4 +- .../__tests__/LogBox-integration-test.js | 24 +- .../implementations/ReactFabric-dev.js | 41583 +++++++++------ .../implementations/ReactFabric-prod.js | 4305 +- .../implementations/ReactFabric-profiling.js | 4645 +- .../ReactNativeRenderer-dev.js | 43261 ++++++++++------ .../ReactNativeRenderer-prod.js | 4371 +- .../ReactNativeRenderer-profiling.js | 4713 +- packages/react-native/package.json | 4 +- .../__tests__/new_architecture-test.rb | 12 - .../scripts/cocoapods/__tests__/utils-test.rb | 3 - packages/rn-tester/package.json | 2 +- packages/virtualized-lists/package.json | 2 +- .../react-native/template/package.json | 2 +- yarn.lock | 58 +- 16 files changed, 59993 insertions(+), 43002 deletions(-) diff --git a/package.json b/package.json index fa80c94ff1d9e7..e76423582e2462 100644 --- a/package.json +++ b/package.json @@ -93,8 +93,8 @@ "nullthrows": "^1.1.1", "prettier": "2.8.8", "prettier-plugin-hermes-parser": "0.24.0", - "react": "19.0.0-rc-fb9a90fa48-20240614", - "react-test-renderer": "19.0.0-rc-fb9a90fa48-20240614", + "react": "18.3.1", + "react-test-renderer": "18.3.1", "rimraf": "^3.0.2", "shelljs": "^0.8.5", "signedsource": "^1.0.0", @@ -103,6 +103,6 @@ "ws": "^6.2.3" }, "resolutions": { - "react-is": "19.0.0-rc-fb9a90fa48-20240614" + "react-is": "18.3.1" } } diff --git a/packages/helloworld/package.json b/packages/helloworld/package.json index be722e4fd9cba4..a5a2d6a751fb20 100644 --- a/packages/helloworld/package.json +++ b/packages/helloworld/package.json @@ -12,7 +12,7 @@ "test": "jest" }, "dependencies": { - "react": "19.0.0-rc-fb9a90fa48-20240614", + "react": "18.3.1", "react-native": "1000.0.0" }, "devDependencies": { @@ -28,7 +28,7 @@ "eslint": "^8.19.0", "jest": "^29.6.3", "listr2": "^8.2.1", - "react-test-renderer": "19.0.0-rc-fb9a90fa48-20240614", + "react-test-renderer": "18.3.1", "rxjs": "^7.8.1" }, "engines": { diff --git a/packages/react-native/Libraries/LogBox/__tests__/LogBox-integration-test.js b/packages/react-native/Libraries/LogBox/__tests__/LogBox-integration-test.js index 00dd5859fc228e..81f56cad14766e 100644 --- a/packages/react-native/Libraries/LogBox/__tests__/LogBox-integration-test.js +++ b/packages/react-native/Libraries/LogBox/__tests__/LogBox-integration-test.js @@ -80,21 +80,24 @@ describe('LogBox', () => { expect(mockWarn).not.toBeCalled(); expect(console.error).toBeCalledTimes(1); expect(console.error.mock.calls[0]).toEqual([ - 'Each child in a list should have a unique "key" prop.%s%s See https://react.dev/link/warning-keys for more information.%s', - '\n\nCheck the render method of `DoesNotUseKey`.', + expect.stringMatching( + 'Each child in a list should have a unique "key" prop', + ), + expect.stringMatching('Check the render method of `DoesNotUseKey`'), '', expect.stringMatching('at DoesNotUseKey'), ]); expect(spy).toHaveBeenCalledWith({ level: 'error', category: expect.stringContaining( - 'Warning: Each child in a list should have a unique', + 'Each child in a list should have a unique', ), componentStack: expect.anything(), componentStackType: 'stack', message: { - content: - 'Warning: Each child in a list should have a unique "key" prop.\n\nCheck the render method of `DoesNotUseKey`. See https://react.dev/link/warning-keys for more information.', + content: expect.stringContaining( + 'Each child in a list should have a unique "key" prop', + ), substitutions: [ {length: 45, offset: 62}, {length: 0, offset: 107}, @@ -106,7 +109,7 @@ describe('LogBox', () => { // We also interpolate the string before passing to the underlying console method. expect(mockError.mock.calls[0]).toEqual([ expect.stringMatching( - 'Warning: Each child in a list should have a unique "key" prop.\n\nCheck the render method of `DoesNotUseKey`. See https://react.dev/link/warning-keys for more information.\n at ', + 'Each child in a list should have a unique "key" prop', ), ]); }); @@ -134,7 +137,9 @@ describe('LogBox', () => { expect(mockWarn).not.toBeCalled(); expect(console.error).toBeCalledTimes(1); expect(console.error.mock.calls[0]).toEqual([ - 'Invalid prop `%s` supplied to `React.Fragment`. React.Fragment can only have `key` and `children` props.%s', + expect.stringMatching( + 'Invalid prop `%s` supplied to `React.Fragment`. React.Fragment can only have `key` and `children` props.%s', + ), 'invalid', expect.stringMatching('at FragmentWithProp'), ]); @@ -144,8 +149,9 @@ describe('LogBox', () => { componentStack: expect.anything(), componentStackType: expect.stringMatching(/(stack|legacy)/), message: { - content: - 'Warning: Invalid prop `invalid` supplied to `React.Fragment`. React.Fragment can only have `key` and `children` props.', + content: expect.stringMatching( + 'Invalid prop `invalid` supplied to `React.Fragment`. React.Fragment can only have `key` and `children` props.', + ), substitutions: [{length: 7, offset: 23}], }, }); diff --git a/packages/react-native/Libraries/Renderer/implementations/ReactFabric-dev.js b/packages/react-native/Libraries/Renderer/implementations/ReactFabric-dev.js index bc3567199be769..4d49bcd510e76a 100644 --- a/packages/react-native/Libraries/Renderer/implementations/ReactFabric-dev.js +++ b/packages/react-native/Libraries/Renderer/implementations/ReactFabric-dev.js @@ -6,839 +6,605 @@ * * @noflow * @nolint + * @providesModule ReactFabric-dev * @preventMunge - * @generated SignedSource<<37dbeed0bd5ee462a000bd6f9329a267>> - * - * This file was sync'd from the facebook/react repository. + * @generated SignedSource<> */ "use strict"; -__DEV__ && + +if (__DEV__) { (function () { - function findHook(fiber, id) { - for (fiber = fiber.memoizedState; null !== fiber && 0 < id; ) - (fiber = fiber.next), id--; - return fiber; - } - function copyWithSetImpl(obj, path, index, value) { - if (index >= path.length) return value; - var key = path[index], - updated = isArrayImpl(obj) ? obj.slice() : assign({}, obj); - updated[key] = copyWithSetImpl(obj[key], path, index + 1, value); - return updated; - } - function copyWithRename(obj, oldPath, newPath) { - if (oldPath.length !== newPath.length) - warn("copyWithRename() expects paths of the same length"); - else { - for (var i = 0; i < newPath.length - 1; i++) - if (oldPath[i] !== newPath[i]) { - warn( - "copyWithRename() expects paths to be the same except for the deepest key" - ); - return; - } - return copyWithRenameImpl(obj, oldPath, newPath, 0); - } - } - function copyWithRenameImpl(obj, oldPath, newPath, index) { - var oldKey = oldPath[index], - updated = isArrayImpl(obj) ? obj.slice() : assign({}, obj); - index + 1 === oldPath.length - ? ((updated[newPath[index]] = updated[oldKey]), - isArrayImpl(updated) - ? updated.splice(oldKey, 1) - : delete updated[oldKey]) - : (updated[oldKey] = copyWithRenameImpl( - obj[oldKey], - oldPath, - newPath, - index + 1 - )); - return updated; - } - function copyWithDeleteImpl(obj, path, index) { - var key = path[index], - updated = isArrayImpl(obj) ? obj.slice() : assign({}, obj); - if (index + 1 === path.length) - return ( - isArrayImpl(updated) ? updated.splice(key, 1) : delete updated[key], - updated - ); - updated[key] = copyWithDeleteImpl(obj[key], path, index + 1); - return updated; - } - function shouldSuspendImpl() { - return !1; - } - function shouldErrorImpl() { - return null; - } - function findHostInstancesForRefresh(root, families) { - var hostInstances = new Set(); - families = new Set( - families.map(function (family) { - return family.current; - }) - ); - findHostInstancesForMatchingFibersRecursively( - root.current, - families, - hostInstances - ); - return hostInstances; - } - function scheduleRoot(root, element) { - root.context === emptyContextObject && - (0 === root.tag && flushPassiveEffects(), - updateContainerImpl(root.current, SyncLane, element, root, null, null), - flushSyncWork()); - } - function scheduleRefresh(root, update) { - if (null !== resolveFamily) { - var staleFamilies = update.staleFamilies; - update = update.updatedFamilies; - flushPassiveEffects(); - scheduleFibersWithFamiliesRecursively( - root.current, - update, - staleFamilies - ); - flushSyncWork(); - } - } - function setRefreshHandler(handler) { - resolveFamily = handler; - } - function warnInvalidHookAccess() { - error$jscomp$0( - "Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. You can only call Hooks at the top level of your React function. For more information, see https://react.dev/link/rules-of-hooks" - ); - } - function warnInvalidContextAccess() { - error$jscomp$0( - "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()." - ); - } - function warnForMissingKey() {} - function setToSortedString(set) { - var array = []; - set.forEach(function (value) { - array.push(value); - }); - return array.sort().join(", "); - } - function batchedUpdatesImpl(fn, bookkeeping) { - return fn(bookkeeping); - } - function warn(format) { - if (!suppressWarning) { - for ( - var _len = arguments.length, - args = Array(1 < _len ? _len - 1 : 0), - _key = 1; - _key < _len; - _key++ - ) - args[_key - 1] = arguments[_key]; - printWarning("warn", format, args, Error("react-stack-top-frame")); - } - } - function error$jscomp$0(format) { - if (!suppressWarning) { - for ( - var _len2 = arguments.length, - args = Array(1 < _len2 ? _len2 - 1 : 0), - _key2 = 1; - _key2 < _len2; - _key2++ - ) - args[_key2 - 1] = arguments[_key2]; - printWarning("error", format, args, Error("react-stack-top-frame")); - } - } - function printWarning(level, format, args, currentStack) { - !supportsCreateTask && - ReactSharedInternals.getCurrentStack && - ((currentStack = ReactSharedInternals.getCurrentStack(currentStack)), - "" !== currentStack && - ((format += "%s"), (args = args.concat([currentStack])))); - args.unshift(format); - Function.prototype.apply.call(console[level], console, args); - } - function getIteratorFn(maybeIterable) { - if (null === maybeIterable || "object" !== typeof maybeIterable) - return null; - maybeIterable = - (MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL]) || - maybeIterable["@@iterator"]; - return "function" === typeof maybeIterable ? maybeIterable : null; - } - function disabledLog() {} - function disableLogs() { - if (0 === disabledDepth) { - prevLog = console.log; - prevInfo = console.info; - prevWarn = console.warn; - prevError = console.error; - prevGroup = console.group; - prevGroupCollapsed = console.groupCollapsed; - prevGroupEnd = console.groupEnd; - var props = { - configurable: !0, - enumerable: !0, - value: disabledLog, - writable: !0 - }; - Object.defineProperties(console, { - info: props, - log: props, - warn: props, - error: props, - group: props, - groupCollapsed: props, - groupEnd: props - }); - } - disabledDepth++; - } - function reenableLogs() { - disabledDepth--; - if (0 === disabledDepth) { - var props = { configurable: !0, enumerable: !0, writable: !0 }; - Object.defineProperties(console, { - log: assign({}, props, { value: prevLog }), - info: assign({}, props, { value: prevInfo }), - warn: assign({}, props, { value: prevWarn }), - error: assign({}, props, { value: prevError }), - group: assign({}, props, { value: prevGroup }), - groupCollapsed: assign({}, props, { value: prevGroupCollapsed }), - groupEnd: assign({}, props, { value: prevGroupEnd }) - }); - } - 0 > disabledDepth && - error$jscomp$0( - "disabledDepth fell below zero. This is a bug in React. Please file an issue." - ); + "use strict"; + + /* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */ + if ( + typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined" && + typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart === + "function" + ) { + __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error()); } - function describeBuiltInComponentFrame(name) { - if (void 0 === prefix) - try { - throw Error(); - } catch (x) { - var match = x.stack.trim().match(/\n( *(at )?)/); - prefix = (match && match[1]) || ""; - } - return "\n" + prefix + name; - } - function describeNativeComponentFrame(fn, construct) { - if (!fn || reentry) return ""; - var frame = componentFrameCache.get(fn); - if (void 0 !== frame) return frame; - reentry = !0; - frame = Error.prepareStackTrace; - Error.prepareStackTrace = void 0; - var previousDispatcher = null; - previousDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = null; - disableLogs(); - var RunInRootFrame = { - DetermineComponentFrameRoot: function () { - try { - if (construct) { - var Fake = function () { - throw Error(); - }; - Object.defineProperty(Fake.prototype, "props", { - set: function () { - throw Error(); - } - }); - if ("object" === typeof Reflect && Reflect.construct) { - try { - Reflect.construct(Fake, []); - } catch (x) { - var control = x; - } - Reflect.construct(fn, [], Fake); - } else { - try { - Fake.call(); - } catch (x$0) { - control = x$0; - } - fn.call(Fake.prototype); - } - } else { - try { - throw Error(); - } catch (x$1) { - control = x$1; - } - (Fake = fn()) && - "function" === typeof Fake.catch && - Fake.catch(function () {}); - } - } catch (sample) { - if (sample && control && "string" === typeof sample.stack) - return [sample.stack, control.stack]; - } - return [null, null]; - } - }; - RunInRootFrame.DetermineComponentFrameRoot.displayName = - "DetermineComponentFrameRoot"; - var namePropDescriptor = Object.getOwnPropertyDescriptor( - RunInRootFrame.DetermineComponentFrameRoot, - "name" - ); - namePropDescriptor && - namePropDescriptor.configurable && - Object.defineProperty( - RunInRootFrame.DetermineComponentFrameRoot, - "name", - { value: "DetermineComponentFrameRoot" } - ); - try { - var _RunInRootFrame$Deter = - RunInRootFrame.DetermineComponentFrameRoot(), - sampleStack = _RunInRootFrame$Deter[0], - controlStack = _RunInRootFrame$Deter[1]; - if (sampleStack && controlStack) { - var sampleLines = sampleStack.split("\n"), - controlLines = controlStack.split("\n"); - for ( - sampleStack = _RunInRootFrame$Deter = 0; - _RunInRootFrame$Deter < sampleLines.length && - !sampleLines[_RunInRootFrame$Deter].includes( - "DetermineComponentFrameRoot" - ); + var React = require("react"); + require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); + var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"); + var Scheduler = require("scheduler"); - ) - _RunInRootFrame$Deter++; - for ( - ; - sampleStack < controlLines.length && - !controlLines[sampleStack].includes("DetermineComponentFrameRoot"); + var ReactSharedInternals = + React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; - ) - sampleStack++; - if ( - _RunInRootFrame$Deter === sampleLines.length || - sampleStack === controlLines.length - ) - for ( - _RunInRootFrame$Deter = sampleLines.length - 1, - sampleStack = controlLines.length - 1; - 1 <= _RunInRootFrame$Deter && - 0 <= sampleStack && - sampleLines[_RunInRootFrame$Deter] !== controlLines[sampleStack]; + // by calls to these methods by a Babel plugin. + // + // In PROD (or in packages without access to React internals), + // they are left as they are instead. - ) - sampleStack--; + function warn(format) { + { + { for ( - ; - 1 <= _RunInRootFrame$Deter && 0 <= sampleStack; - _RunInRootFrame$Deter--, sampleStack-- - ) - if ( - sampleLines[_RunInRootFrame$Deter] !== controlLines[sampleStack] - ) { - if (1 !== _RunInRootFrame$Deter || 1 !== sampleStack) { - do - if ( - (_RunInRootFrame$Deter--, - sampleStack--, - 0 > sampleStack || - sampleLines[_RunInRootFrame$Deter] !== - controlLines[sampleStack]) - ) { - var _frame = - "\n" + - sampleLines[_RunInRootFrame$Deter].replace( - " at new ", - " at " - ); - fn.displayName && - _frame.includes("") && - (_frame = _frame.replace("", fn.displayName)); - "function" === typeof fn && - componentFrameCache.set(fn, _frame); - return _frame; - } - while (1 <= _RunInRootFrame$Deter && 0 <= sampleStack); - } - break; - } + var _len = arguments.length, + args = new Array(_len > 1 ? _len - 1 : 0), + _key = 1; + _key < _len; + _key++ + ) { + args[_key - 1] = arguments[_key]; + } + + printWarning("warn", format, args); } - } finally { - (reentry = !1), - (ReactSharedInternals.H = previousDispatcher), - reenableLogs(), - (Error.prepareStackTrace = frame); - } - sampleLines = (sampleLines = fn ? fn.displayName || fn.name : "") - ? describeBuiltInComponentFrame(sampleLines) - : ""; - "function" === typeof fn && componentFrameCache.set(fn, sampleLines); - return sampleLines; - } - function callComponentInDEV(Component, props, secondArg) { - var wasRendering = isRendering; - isRendering = !0; - try { - return Component(props, secondArg); - } finally { - isRendering = wasRendering; } } - function callRenderInDEV(instance) { - var wasRendering = isRendering; - isRendering = !0; - try { - return instance.render(); - } finally { - isRendering = wasRendering; - } - } - function callLazyInitInDEV(lazy) { - var init = lazy._init; - return init(lazy._payload); - } - function isNotExternal(stackFrame) { - return !externalRegExp.test(stackFrame); - } - function filterDebugStack(error) { - error = error.stack; - error.startsWith("Error: react-stack-top-frame\n") && - (error = error.slice(29)); - error = error.split("\n").slice(1); - if (null === callComponentFrame) { - var stack = callComponentInDEV( - Error, - "react-stack-top-frame", - {} - ).stack, - startIdx = stack.startsWith("Error: react-stack-top-frame\n") - ? 29 - : 0, - endIdx = stack.indexOf("\n", startIdx); - callComponentFrame = - -1 === endIdx ? stack.slice(startIdx) : stack.slice(startIdx, endIdx); - } - stack = error.indexOf(callComponentFrame); - if ( - -1 === stack && - (null === callLazyInitFrame && - ((stack = callLazyInitInDEV({ - $$typeof: REACT_LAZY_TYPE, - _init: Error, - _payload: "react-stack-top-frame" - }).stack), - (startIdx = stack.startsWith("Error: react-stack-top-frame\n") - ? 29 - : 0), - (endIdx = stack.indexOf("\n", startIdx)), - (callLazyInitFrame = - -1 === endIdx - ? stack.slice(startIdx) - : stack.slice(startIdx, endIdx))), - (stack = error.indexOf(callLazyInitFrame)), - -1 === stack) - ) { - if (null === callIteratorFrame) - try { - callRenderInDEV({ render: null }), (callIteratorFrame = ""); - } catch (error$2) { - (stack = error$2.stack), - (startIdx = stack.startsWith("TypeError: ") - ? stack.indexOf("\n") + 1 - : 0), - (endIdx = stack.indexOf("\n", startIdx)), - (callIteratorFrame = - -1 === endIdx - ? stack.slice(startIdx) - : stack.slice(startIdx, endIdx)); - } - stack = error.indexOf(callIteratorFrame); - } - if (-1 !== stack) error.length = stack; - else return ""; - return error.filter(isNotExternal).join("\n"); - } - function describeFiber(fiber) { - switch (fiber.tag) { - case 26: - case 27: - case 5: - return describeBuiltInComponentFrame(fiber.type); - case 16: - return describeBuiltInComponentFrame("Lazy"); - case 13: - return describeBuiltInComponentFrame("Suspense"); - case 19: - return describeBuiltInComponentFrame("SuspenseList"); - case 0: - case 15: - return (fiber = describeNativeComponentFrame(fiber.type, !1)), fiber; - case 11: - return ( - (fiber = describeNativeComponentFrame(fiber.type.render, !1)), fiber - ); - case 1: - return (fiber = describeNativeComponentFrame(fiber.type, !0)), fiber; - default: - return ""; + function error(format) { + { + { + for ( + var _len2 = arguments.length, + args = new Array(_len2 > 1 ? _len2 - 1 : 0), + _key2 = 1; + _key2 < _len2; + _key2++ + ) { + args[_key2 - 1] = arguments[_key2]; + } + + printWarning("error", format, args); + } } } - function getStackByFiberInDevAndProd(workInProgress) { - try { - var info = ""; - do { - info += describeFiber(workInProgress); - var debugInfo = workInProgress._debugInfo; - if (debugInfo) - for (var i = debugInfo.length - 1; 0 <= i; i--) { - var entry = debugInfo[i]; - if ("string" === typeof entry.name) { - var JSCompiler_temp_const = info, - env = entry.env; - var JSCompiler_inline_result = describeBuiltInComponentFrame( - entry.name + (env ? " (" + env + ")" : "") - ); - info = JSCompiler_temp_const + JSCompiler_inline_result; - } - } - workInProgress = workInProgress.return; - } while (workInProgress); - return info; - } catch (x) { - return "\nError generating stack: " + x.message + "\n" + x.stack; + + function printWarning(level, format, args) { + // When changing this logic, you might want to also + // update consoleWithStackDev.www.js as well. + { + var ReactDebugCurrentFrame = + ReactSharedInternals.ReactDebugCurrentFrame; + var stack = ReactDebugCurrentFrame.getStackAddendum(); + + if (stack !== "") { + format += "%s"; + args = args.concat([stack]); + } // eslint-disable-next-line react-internal/safe-string-coercion + + var argsWithFormat = args.map(function (item) { + return String(item); + }); // Careful: RN currently depends on this prefix + + argsWithFormat.unshift("Warning: " + format); // We intentionally don't use spread (or .apply) directly because it + // breaks IE9: https://github.com/facebook/react/issues/13610 + // eslint-disable-next-line react-internal/no-production-logging + + Function.prototype.apply.call(console[level], console, argsWithFormat); } } - function describeFunctionComponentFrameWithoutLineNumber(fn) { - return (fn = fn ? fn.displayName || fn.name : "") - ? describeBuiltInComponentFrame(fn) - : ""; - } - function getComponentNameFromType(type) { - if (null == type) return null; - if ("function" === typeof type) - return type.$$typeof === REACT_CLIENT_REFERENCE - ? null - : type.displayName || type.name || null; - if ("string" === typeof type) return type; - switch (type) { - case REACT_FRAGMENT_TYPE: - return "Fragment"; - case REACT_PORTAL_TYPE: - return "Portal"; - case REACT_PROFILER_TYPE: - return "Profiler"; - case REACT_STRICT_MODE_TYPE: - return "StrictMode"; - case REACT_SUSPENSE_TYPE: - return "Suspense"; - case REACT_SUSPENSE_LIST_TYPE: - return "SuspenseList"; - } - if ("object" === typeof type) - switch ( - ("number" === typeof type.tag && - error$jscomp$0( - "Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue." - ), - type.$$typeof) - ) { - case REACT_CONTEXT_TYPE: - return (type.displayName || "Context") + ".Provider"; - case REACT_CONSUMER_TYPE: - return (type._context.displayName || "Context") + ".Consumer"; - case REACT_FORWARD_REF_TYPE: - var innerType = type.render; - type = type.displayName; - type || - ((type = innerType.displayName || innerType.name || ""), - (type = "" !== type ? "ForwardRef(" + type + ")" : "ForwardRef")); - return type; - case REACT_MEMO_TYPE: - return ( - (innerType = type.displayName || null), - null !== innerType - ? innerType - : getComponentNameFromType(type.type) || "Memo" - ); - case REACT_LAZY_TYPE: - innerType = type._payload; - type = type._init; - try { - return getComponentNameFromType(type(innerType)); - } catch (x) {} - } - return null; + + var isArrayImpl = Array.isArray; // eslint-disable-next-line no-redeclare + + function isArray(a) { + return isArrayImpl(a); } - function getComponentNameFromFiber(fiber) { - var type = fiber.type; - switch (fiber.tag) { - case 24: - return "Cache"; - case 9: - return (type._context.displayName || "Context") + ".Consumer"; - case 10: - return (type.displayName || "Context") + ".Provider"; - case 18: - return "DehydratedFragment"; - case 11: - return ( - (fiber = type.render), - (fiber = fiber.displayName || fiber.name || ""), - type.displayName || - ("" !== fiber ? "ForwardRef(" + fiber + ")" : "ForwardRef") + + var hasError = false; + var caughtError = null; + var getFiberCurrentPropsFromNode$1 = null; + var getInstanceFromNode$1 = null; + var getNodeFromInstance$1 = null; + function setComponentTree( + getFiberCurrentPropsFromNodeImpl, + getInstanceFromNodeImpl, + getNodeFromInstanceImpl + ) { + getFiberCurrentPropsFromNode$1 = getFiberCurrentPropsFromNodeImpl; + getInstanceFromNode$1 = getInstanceFromNodeImpl; + getNodeFromInstance$1 = getNodeFromInstanceImpl; + + { + if (!getNodeFromInstance$1 || !getInstanceFromNode$1) { + error( + "Injected " + + "module is missing getNodeFromInstance or getInstanceFromNode." ); - case 7: - return "Fragment"; - case 26: - case 27: - case 5: - return type; - case 4: - return "Portal"; - case 3: - return "Root"; - case 6: - return "Text"; - case 16: - return getComponentNameFromType(type); - 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 25: - return "TracingMarker"; - case 17: - case 28: - case 1: - case 0: - case 14: - case 15: - if ("function" === typeof type) - return type.displayName || type.name || null; - if ("string" === typeof type) return type; - break; - case 29: - type = fiber._debugInfo; - if (null != type) - for (var i = type.length - 1; 0 <= i; i--) - if ("string" === typeof type[i].name) return type[i].name; - if (null !== fiber.return) - return getComponentNameFromFiber(fiber.return); - } - return null; - } - function getCurrentFiberStackInDev(stack) { - if (null === current) return ""; - var workInProgress = current; - try { - var info = ""; - if (stack) { - var formattedTopStack = filterDebugStack(stack); - "" !== formattedTopStack && (info += "\n" + formattedTopStack); } - 6 === workInProgress.tag && (workInProgress = workInProgress.return); - switch (workInProgress.tag) { - case 26: - case 27: - case 5: - info += describeBuiltInComponentFrame(workInProgress.type); - break; - case 13: - info += describeBuiltInComponentFrame("Suspense"); - break; - case 19: - info += describeBuiltInComponentFrame("SuspenseList"); - break; - case 0: - case 15: - case 1: - workInProgress._debugOwner || - "" !== info || - (info += describeFunctionComponentFrameWithoutLineNumber( - workInProgress.type - )); - break; - case 11: - workInProgress._debugOwner || - "" !== info || - (info += describeFunctionComponentFrameWithoutLineNumber( - workInProgress.type.render - )); - } - for (stack = workInProgress; stack; ) - if ("number" === typeof stack.tag) { - workInProgress = stack; - stack = workInProgress._debugOwner; - var debugStack = workInProgress._debugStack; - stack && - debugStack && - ("string" !== typeof debugStack && - (workInProgress._debugStack = debugStack = - filterDebugStack(debugStack)), - "" !== debugStack && (info += "\n" + debugStack)); - } else if ("string" === typeof stack.stack) - "" !== stack.stack && (info += "\n" + stack.stack), - (stack = stack.owner); - else break; - var JSCompiler_inline_result = info; - } catch (x) { - JSCompiler_inline_result = - "\nError generating stack: " + x.message + "\n" + x.stack; - } - return JSCompiler_inline_result; - } - function runWithFiberInDEV(fiber, callback, arg0, arg1, arg2, arg3, arg4) { - var previousFiber = current; - ReactSharedInternals.getCurrentStack = - null === fiber ? null : getCurrentFiberStackInDev; - isRendering = !1; - current = fiber; - try { - return null !== fiber && fiber._debugTask - ? fiber._debugTask.run( - callback.bind(null, arg0, arg1, arg2, arg3, arg4) - ) - : callback(arg0, arg1, arg2, arg3, arg4); - } finally { - current = previousFiber; } - throw Error( - "runWithFiberInDEV should never be called in production. This is a bug in React." - ); } + function validateEventDispatches(event) { - var dispatchListeners = event._dispatchListeners, - dispatchInstances = event._dispatchInstances; - dispatchListeners = (event = isArrayImpl(dispatchListeners)) - ? dispatchListeners.length - : dispatchListeners - ? 1 - : 0; - var instancesIsArr = isArrayImpl(dispatchInstances); - dispatchInstances = instancesIsArr - ? dispatchInstances.length - : dispatchInstances - ? 1 - : 0; - (instancesIsArr === event && dispatchInstances === dispatchListeners) || - error$jscomp$0("EventPluginUtils: Invalid `event`."); + { + var dispatchListeners = event._dispatchListeners; + var dispatchInstances = event._dispatchInstances; + var listenersIsArr = isArray(dispatchListeners); + var listenersLen = listenersIsArr + ? dispatchListeners.length + : dispatchListeners + ? 1 + : 0; + var instancesIsArr = isArray(dispatchInstances); + var instancesLen = instancesIsArr + ? dispatchInstances.length + : dispatchInstances + ? 1 + : 0; + + if ( + instancesIsArr !== listenersIsArr || + instancesLen !== listenersLen + ) { + error("EventPluginUtils: Invalid `event`."); + } + } } + /** + * Dispatch the event to the listener. + * @param {SyntheticEvent} event SyntheticEvent to handle + * @param {function} listener Application-level callback + * @param {*} inst Internal component instance + */ + function executeDispatch(event, listener, inst) { event.currentTarget = getNodeFromInstance$1(inst); + try { listener(event); - } catch (error$3) { - hasError || ((hasError = !0), (caughtError = error$3)); + } catch (error) { + if (!hasError) { + hasError = true; + caughtError = error; + } } + event.currentTarget = null; } - function executeDirectDispatch(event) { - validateEventDispatches(event); - var dispatchListener = event._dispatchListeners, - dispatchInstance = event._dispatchInstances; - if (isArrayImpl(dispatchListener)) throw Error("Invalid `event`."); - event.currentTarget = dispatchListener - ? getNodeFromInstance$1(dispatchInstance) - : null; - dispatchListener = dispatchListener ? dispatchListener(event) : null; - event.currentTarget = null; + /** + * Standard/simple iteration through an event's collected dispatches. + */ + + function executeDispatchesInOrder(event) { + var dispatchListeners = event._dispatchListeners; + var dispatchInstances = event._dispatchInstances; + + { + validateEventDispatches(event); + } + + if (isArray(dispatchListeners)) { + for (var i = 0; i < dispatchListeners.length; i++) { + if (event.isPropagationStopped()) { + break; + } // Listeners and Instances are two parallel arrays that are always in sync. + + executeDispatch(event, dispatchListeners[i], dispatchInstances[i]); + } + } else if (dispatchListeners) { + executeDispatch(event, dispatchListeners, dispatchInstances); + } + event._dispatchListeners = null; event._dispatchInstances = null; - return dispatchListener; - } - function functionThatReturnsTrue() { - return !0; } - function functionThatReturnsFalse() { - return !1; + /** + * Standard/simple iteration through an event's collected dispatches, but stops + * at the first dispatch execution returning true, and returns that id. + * + * @return {?string} id of the first dispatch execution who's listener returns + * true, or null if no listener returned true. + */ + + function executeDispatchesInOrderStopAtTrueImpl(event) { + var dispatchListeners = event._dispatchListeners; + var dispatchInstances = event._dispatchInstances; + + { + validateEventDispatches(event); + } + + if (isArray(dispatchListeners)) { + for (var i = 0; i < dispatchListeners.length; i++) { + if (event.isPropagationStopped()) { + break; + } // Listeners and Instances are two parallel arrays that are always in sync. + + if (dispatchListeners[i](event, dispatchInstances[i])) { + return dispatchInstances[i]; + } + } + } else if (dispatchListeners) { + if (dispatchListeners(event, dispatchInstances)) { + return dispatchInstances; + } + } + + return null; } - function SyntheticEvent( - dispatchConfig, + /** + * @see executeDispatchesInOrderStopAtTrueImpl + */ + + function executeDispatchesInOrderStopAtTrue(event) { + var ret = executeDispatchesInOrderStopAtTrueImpl(event); + event._dispatchInstances = null; + event._dispatchListeners = null; + return ret; + } + /** + * Execution of a "direct" dispatch - there must be at most one dispatch + * accumulated on the event or it is considered an error. It doesn't really make + * sense for an event with multiple dispatches (bubbled) to keep track of the + * return values at each dispatch execution, but it does tend to make sense when + * dealing with "direct" dispatches. + * + * @return {*} The return value of executing the single dispatch. + */ + + function executeDirectDispatch(event) { + { + validateEventDispatches(event); + } + + var dispatchListener = event._dispatchListeners; + var dispatchInstance = event._dispatchInstances; + + if (isArray(dispatchListener)) { + throw new Error("Invalid `event`."); + } + + event.currentTarget = dispatchListener + ? getNodeFromInstance$1(dispatchInstance) + : null; + var res = dispatchListener ? dispatchListener(event) : null; + event.currentTarget = null; + event._dispatchListeners = null; + event._dispatchInstances = null; + return res; + } + /** + * @param {SyntheticEvent} event + * @return {boolean} True iff number of dispatches accumulated is greater than 0. + */ + + function hasDispatches(event) { + return !!event._dispatchListeners; + } + function rethrowCaughtError() { + if (hasError) { + var error = caughtError; + hasError = false; + caughtError = null; + throw error; + } + } + + var assign = Object.assign; + + var EVENT_POOL_SIZE = 10; + /** + * @interface Event + * @see http://www.w3.org/TR/DOM-Level-3-Events/ + */ + + var EventInterface = { + type: null, + target: null, + // currentTarget is set when dispatching; no use in copying it here + currentTarget: function () { + return null; + }, + eventPhase: null, + bubbles: null, + cancelable: null, + timeStamp: function (event) { + return event.timeStamp || Date.now(); + }, + defaultPrevented: null, + isTrusted: null + }; + + function functionThatReturnsTrue() { + return true; + } + + function functionThatReturnsFalse() { + return false; + } + /** + * Synthetic events are dispatched by event plugins, typically in response to a + * top-level event delegation handler. + * + * These systems should generally use pooling to reduce the frequency of garbage + * collection. The system should check `isPersistent` to determine whether the + * event should be released into the pool after being dispatched. Users that + * need a persisted event should invoke `persist`. + * + * Synthetic events (and subclasses) implement the DOM Level 3 Events API by + * normalizing browser quirks. Subclasses do not necessarily have to implement a + * DOM interface; custom application-specific events can also subclass this. + * + * @param {object} dispatchConfig Configuration used to dispatch this event. + * @param {*} targetInst Marker identifying the event target. + * @param {object} nativeEvent Native browser event. + * @param {DOMEventTarget} nativeEventTarget Target node. + */ + + function SyntheticEvent( + dispatchConfig, targetInst, nativeEvent, nativeEventTarget ) { - delete this.nativeEvent; - delete this.preventDefault; - delete this.stopPropagation; - delete this.isDefaultPrevented; - delete this.isPropagationStopped; + { + // these have a getter/setter for warnings + delete this.nativeEvent; + delete this.preventDefault; + delete this.stopPropagation; + delete this.isDefaultPrevented; + delete this.isPropagationStopped; + } + this.dispatchConfig = dispatchConfig; this._targetInst = targetInst; this.nativeEvent = nativeEvent; - this._dispatchInstances = this._dispatchListeners = null; - dispatchConfig = this.constructor.Interface; - for (var propName in dispatchConfig) - dispatchConfig.hasOwnProperty(propName) && - (delete this[propName], - (targetInst = dispatchConfig[propName]) - ? (this[propName] = targetInst(nativeEvent)) - : "target" === propName - ? (this.target = nativeEventTarget) - : (this[propName] = nativeEvent[propName])); - this.isDefaultPrevented = ( - null != nativeEvent.defaultPrevented + this._dispatchListeners = null; + this._dispatchInstances = null; + var Interface = this.constructor.Interface; + + for (var propName in Interface) { + if (!Interface.hasOwnProperty(propName)) { + continue; + } + + { + delete this[propName]; // this has a getter/setter for warnings + } + + var normalize = Interface[propName]; + + if (normalize) { + this[propName] = normalize(nativeEvent); + } else { + if (propName === "target") { + this.target = nativeEventTarget; + } else { + this[propName] = nativeEvent[propName]; + } + } + } + + var defaultPrevented = + nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented - : !1 === nativeEvent.returnValue - ) - ? functionThatReturnsTrue - : functionThatReturnsFalse; + : nativeEvent.returnValue === false; + + if (defaultPrevented) { + this.isDefaultPrevented = functionThatReturnsTrue; + } else { + this.isDefaultPrevented = functionThatReturnsFalse; + } + this.isPropagationStopped = functionThatReturnsFalse; return this; } + + assign(SyntheticEvent.prototype, { + preventDefault: function () { + this.defaultPrevented = true; + var event = this.nativeEvent; + + if (!event) { + return; + } + + if (event.preventDefault) { + event.preventDefault(); + } else if (typeof event.returnValue !== "unknown") { + event.returnValue = false; + } + + this.isDefaultPrevented = functionThatReturnsTrue; + }, + stopPropagation: function () { + var event = this.nativeEvent; + + if (!event) { + return; + } + + if (event.stopPropagation) { + event.stopPropagation(); + } else if (typeof event.cancelBubble !== "unknown") { + // The ChangeEventPlugin registers a "propertychange" event for + // IE. This event does not support bubbling or cancelling, and + // any references to cancelBubble throw "Member not found". A + // typeof check of "unknown" circumvents this issue (and is also + // IE specific). + event.cancelBubble = true; + } + + this.isPropagationStopped = functionThatReturnsTrue; + }, + + /** + * We release all dispatched `SyntheticEvent`s after each event loop, adding + * them back into the pool. This allows a way to hold onto a reference that + * won't be added back into the pool. + */ + persist: function () { + this.isPersistent = functionThatReturnsTrue; + }, + + /** + * Checks if this event should be released back into the pool. + * + * @return {boolean} True if this should not be released, false otherwise. + */ + isPersistent: functionThatReturnsFalse, + + /** + * `PooledClass` looks for `destructor` on each instance it releases. + */ + destructor: function () { + var Interface = this.constructor.Interface; + + for (var propName in Interface) { + { + Object.defineProperty( + this, + propName, + getPooledWarningPropertyDefinition(propName, Interface[propName]) + ); + } + } + + this.dispatchConfig = null; + this._targetInst = null; + this.nativeEvent = null; + this.isDefaultPrevented = functionThatReturnsFalse; + this.isPropagationStopped = functionThatReturnsFalse; + this._dispatchListeners = null; + this._dispatchInstances = null; + + { + Object.defineProperty( + this, + "nativeEvent", + getPooledWarningPropertyDefinition("nativeEvent", null) + ); + Object.defineProperty( + this, + "isDefaultPrevented", + getPooledWarningPropertyDefinition( + "isDefaultPrevented", + functionThatReturnsFalse + ) + ); + Object.defineProperty( + this, + "isPropagationStopped", + getPooledWarningPropertyDefinition( + "isPropagationStopped", + functionThatReturnsFalse + ) + ); + Object.defineProperty( + this, + "preventDefault", + getPooledWarningPropertyDefinition("preventDefault", function () {}) + ); + Object.defineProperty( + this, + "stopPropagation", + getPooledWarningPropertyDefinition( + "stopPropagation", + function () {} + ) + ); + } + } + }); + SyntheticEvent.Interface = EventInterface; + /** + * Helper to reduce boilerplate when creating subclasses. + */ + + SyntheticEvent.extend = function (Interface) { + var Super = this; + + var E = function () {}; + + E.prototype = Super.prototype; + var prototype = new E(); + + function Class() { + return Super.apply(this, arguments); + } + + assign(prototype, Class.prototype); + Class.prototype = prototype; + Class.prototype.constructor = Class; + Class.Interface = assign({}, Super.Interface, Interface); + Class.extend = Super.extend; + addEventPoolingTo(Class); + return Class; + }; + + addEventPoolingTo(SyntheticEvent); + /** + * Helper to nullify syntheticEvent instance properties when destructing + * + * @param {String} propName + * @param {?object} getVal + * @return {object} defineProperty object + */ + function getPooledWarningPropertyDefinition(propName, getVal) { - function warn(action, result) { - error$jscomp$0( - "This synthetic event is reused for performance reasons. If you're seeing this, you're %s `%s` on a released/nullified synthetic event. %s. If you must keep the original synthetic event around, use event.persist(). See https://react.dev/link/event-pooling for more information.", - action, - propName, - result - ); + function set(val) { + var action = isFunction ? "setting the method" : "setting the property"; + warn(action, "This is effectively a no-op"); + return val; } - var isFunction = "function" === typeof getVal; - return { - configurable: !0, - set: function (val) { - warn( - isFunction ? "setting the method" : "setting the property", - "This is effectively a no-op" - ); - return val; - }, - get: function () { - warn( - isFunction ? "accessing the method" : "accessing the property", - isFunction ? "This is a no-op function" : "This is set to null" + + function get() { + var action = isFunction + ? "accessing the method" + : "accessing the property"; + var result = isFunction + ? "This is a no-op function" + : "This is set to null"; + warn(action, result); + return getVal; + } + + function warn(action, result) { + { + error( + "This synthetic event is reused for performance reasons. If you're seeing this, " + + "you're %s `%s` on a released/nullified synthetic event. %s. " + + "If you must keep the original synthetic event around, use event.persist(). " + + "See https://react.dev/link/event-pooling for more information.", + action, + propName, + result ); - return getVal; } + } + + var isFunction = typeof getVal === "function"; + return { + configurable: true, + set: set, + get: get }; } + function createOrGetPooledEvent( dispatchConfig, targetInst, nativeEvent, nativeInst ) { - if (this.eventPool.length) { - var instance = this.eventPool.pop(); - this.call( + var EventConstructor = this; + + if (EventConstructor.eventPool.length) { + var instance = EventConstructor.eventPool.pop(); + EventConstructor.call( instance, dispatchConfig, targetInst, @@ -847,104 +613,211 @@ __DEV__ && ); return instance; } - return new this(dispatchConfig, targetInst, nativeEvent, nativeInst); + + return new EventConstructor( + dispatchConfig, + targetInst, + nativeEvent, + nativeInst + ); } + function releasePooledEvent(event) { - if (!(event instanceof this)) - throw Error( + var EventConstructor = this; + + if (!(event instanceof EventConstructor)) { + throw new Error( "Trying to release an event instance into a pool of a different type." ); + } + event.destructor(); - 10 > this.eventPool.length && this.eventPool.push(event); + + if (EventConstructor.eventPool.length < EVENT_POOL_SIZE) { + EventConstructor.eventPool.push(event); + } } + function addEventPoolingTo(EventConstructor) { EventConstructor.getPooled = createOrGetPooledEvent; EventConstructor.eventPool = []; EventConstructor.release = releasePooledEvent; } + + /** + * `touchHistory` isn't actually on the native event, but putting it in the + * interface will ensure that it is cleaned up when pooled/destroyed. The + * `ResponderEventPlugin` will populate it appropriately. + */ + + var ResponderSyntheticEvent = SyntheticEvent.extend({ + touchHistory: function (nativeEvent) { + return null; // Actually doesn't even look at the native event. + } + }); + + var TOP_TOUCH_START = "topTouchStart"; + var TOP_TOUCH_MOVE = "topTouchMove"; + var TOP_TOUCH_END = "topTouchEnd"; + var TOP_TOUCH_CANCEL = "topTouchCancel"; + var TOP_SCROLL = "topScroll"; + var TOP_SELECTION_CHANGE = "topSelectionChange"; function isStartish(topLevelType) { - return "topTouchStart" === topLevelType; + return topLevelType === TOP_TOUCH_START; } function isMoveish(topLevelType) { - return "topTouchMove" === topLevelType; + return topLevelType === TOP_TOUCH_MOVE; } + function isEndish(topLevelType) { + return ( + topLevelType === TOP_TOUCH_END || topLevelType === TOP_TOUCH_CANCEL + ); + } + var startDependencies = [TOP_TOUCH_START]; + var moveDependencies = [TOP_TOUCH_MOVE]; + var endDependencies = [TOP_TOUCH_CANCEL, TOP_TOUCH_END]; + + /** + * Tracks the position and time of each active touch by `touch.identifier`. We + * should typically only see IDs in the range of 1-20 because IDs get recycled + * when touches end and start again. + */ + + var MAX_TOUCH_BANK = 20; + var touchBank = []; + var touchHistory = { + touchBank: touchBank, + numberActiveTouches: 0, + // If there is only one active touch, we remember its location. This prevents + // us having to loop through all of the touches all the time in the most + // common case. + indexOfSingleActiveTouch: -1, + mostRecentTimeStamp: 0 + }; + function timestampForTouch(touch) { + // The legacy internal implementation provides "timeStamp", which has been + // renamed to "timestamp". Let both work for now while we iron it out + // TODO (evv): rename timeStamp to timestamp in internal code return touch.timeStamp || touch.timestamp; } + /** + * TODO: Instead of making gestures recompute filtered velocity, we could + * include a built in velocity computation that can be reused globally. + */ + + function createTouchRecord(touch) { + return { + touchActive: true, + startPageX: touch.pageX, + startPageY: touch.pageY, + startTimeStamp: timestampForTouch(touch), + currentPageX: touch.pageX, + currentPageY: touch.pageY, + currentTimeStamp: timestampForTouch(touch), + previousPageX: touch.pageX, + previousPageY: touch.pageY, + previousTimeStamp: timestampForTouch(touch) + }; + } + + function resetTouchRecord(touchRecord, touch) { + touchRecord.touchActive = true; + touchRecord.startPageX = touch.pageX; + touchRecord.startPageY = touch.pageY; + touchRecord.startTimeStamp = timestampForTouch(touch); + touchRecord.currentPageX = touch.pageX; + touchRecord.currentPageY = touch.pageY; + touchRecord.currentTimeStamp = timestampForTouch(touch); + touchRecord.previousPageX = touch.pageX; + touchRecord.previousPageY = touch.pageY; + touchRecord.previousTimeStamp = timestampForTouch(touch); + } + function getTouchIdentifier(_ref) { - _ref = _ref.identifier; - if (null == _ref) throw Error("Touch object is missing identifier."); - 20 < _ref && - error$jscomp$0( - "Touch identifier %s is greater than maximum supported %s which causes performance issues backfilling array locations for all of the indices.", - _ref, - 20 - ); - return _ref; + var identifier = _ref.identifier; + + if (identifier == null) { + throw new Error("Touch object is missing identifier."); + } + + { + if (identifier > MAX_TOUCH_BANK) { + error( + "Touch identifier %s is greater than maximum supported %s which causes " + + "performance issues backfilling array locations for all of the indices.", + identifier, + MAX_TOUCH_BANK + ); + } + } + + return identifier; } + function recordTouchStart(touch) { - var identifier = getTouchIdentifier(touch), - touchRecord = touchBank[identifier]; - touchRecord - ? ((touchRecord.touchActive = !0), - (touchRecord.startPageX = touch.pageX), - (touchRecord.startPageY = touch.pageY), - (touchRecord.startTimeStamp = timestampForTouch(touch)), - (touchRecord.currentPageX = touch.pageX), - (touchRecord.currentPageY = touch.pageY), - (touchRecord.currentTimeStamp = timestampForTouch(touch)), - (touchRecord.previousPageX = touch.pageX), - (touchRecord.previousPageY = touch.pageY), - (touchRecord.previousTimeStamp = timestampForTouch(touch))) - : ((touchRecord = { - touchActive: !0, - startPageX: touch.pageX, - startPageY: touch.pageY, - startTimeStamp: timestampForTouch(touch), - currentPageX: touch.pageX, - currentPageY: touch.pageY, - currentTimeStamp: timestampForTouch(touch), - previousPageX: touch.pageX, - previousPageY: touch.pageY, - previousTimeStamp: timestampForTouch(touch) - }), - (touchBank[identifier] = touchRecord)); + var identifier = getTouchIdentifier(touch); + var touchRecord = touchBank[identifier]; + + if (touchRecord) { + resetTouchRecord(touchRecord, touch); + } else { + touchBank[identifier] = createTouchRecord(touch); + } + touchHistory.mostRecentTimeStamp = timestampForTouch(touch); } + function recordTouchMove(touch) { var touchRecord = touchBank[getTouchIdentifier(touch)]; - touchRecord - ? ((touchRecord.touchActive = !0), - (touchRecord.previousPageX = touchRecord.currentPageX), - (touchRecord.previousPageY = touchRecord.currentPageY), - (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), - (touchRecord.currentPageX = touch.pageX), - (touchRecord.currentPageY = touch.pageY), - (touchRecord.currentTimeStamp = timestampForTouch(touch)), - (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) - : warn( - "Cannot record touch move without a touch start.\nTouch Move: %s\nTouch Bank: %s", + + if (touchRecord) { + touchRecord.touchActive = true; + touchRecord.previousPageX = touchRecord.currentPageX; + touchRecord.previousPageY = touchRecord.currentPageY; + touchRecord.previousTimeStamp = touchRecord.currentTimeStamp; + touchRecord.currentPageX = touch.pageX; + touchRecord.currentPageY = touch.pageY; + touchRecord.currentTimeStamp = timestampForTouch(touch); + touchHistory.mostRecentTimeStamp = timestampForTouch(touch); + } else { + { + warn( + "Cannot record touch move without a touch start.\n" + + "Touch Move: %s\n" + + "Touch Bank: %s", printTouch(touch), printTouchBank() ); + } + } } + function recordTouchEnd(touch) { var touchRecord = touchBank[getTouchIdentifier(touch)]; - touchRecord - ? ((touchRecord.touchActive = !1), - (touchRecord.previousPageX = touchRecord.currentPageX), - (touchRecord.previousPageY = touchRecord.currentPageY), - (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), - (touchRecord.currentPageX = touch.pageX), - (touchRecord.currentPageY = touch.pageY), - (touchRecord.currentTimeStamp = timestampForTouch(touch)), - (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) - : warn( - "Cannot record touch end without a touch start.\nTouch End: %s\nTouch Bank: %s", + + if (touchRecord) { + touchRecord.touchActive = false; + touchRecord.previousPageX = touchRecord.currentPageX; + touchRecord.previousPageY = touchRecord.currentPageY; + touchRecord.previousTimeStamp = touchRecord.currentTimeStamp; + touchRecord.currentPageX = touch.pageX; + touchRecord.currentPageY = touch.pageY; + touchRecord.currentTimeStamp = timestampForTouch(touch); + touchHistory.mostRecentTimeStamp = timestampForTouch(touch); + } else { + { + warn( + "Cannot record touch end without a touch start.\n" + + "Touch End: %s\n" + + "Touch Bank: %s", printTouch(touch), printTouchBank() ); + } + } } + function printTouch(touch) { return JSON.stringify({ identifier: touch.identifier, @@ -953,9902 +826,20665 @@ __DEV__ && timestamp: timestampForTouch(touch) }); } + function printTouchBank() { - var printed = JSON.stringify(touchBank.slice(0, 20)); - 20 < touchBank.length && - (printed += " (original size: " + touchBank.length + ")"); + var printed = JSON.stringify(touchBank.slice(0, MAX_TOUCH_BANK)); + + if (touchBank.length > MAX_TOUCH_BANK) { + printed += " (original size: " + touchBank.length + ")"; + } + 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)) { + nativeEvent.changedTouches.forEach(recordTouchStart); + touchHistory.numberActiveTouches = nativeEvent.touches.length; + + if (touchHistory.numberActiveTouches === 1) { + touchHistory.indexOfSingleActiveTouch = + nativeEvent.touches[0].identifier; + } + } else if (isEndish(topLevelType)) { + nativeEvent.changedTouches.forEach(recordTouchEnd); + touchHistory.numberActiveTouches = nativeEvent.touches.length; + + if (touchHistory.numberActiveTouches === 1) { + for (var i = 0; i < touchBank.length; i++) { + var touchTrackToCheck = touchBank[i]; + + if (touchTrackToCheck != null && touchTrackToCheck.touchActive) { + touchHistory.indexOfSingleActiveTouch = i; + break; + } + } + + { + var activeRecord = + touchBank[touchHistory.indexOfSingleActiveTouch]; + + if (activeRecord == null || !activeRecord.touchActive) { + error("Cannot find single active touch."); + } + } + } + } + }, + touchHistory: touchHistory + }; + + /** + * Accumulates items that must not be null or undefined. + * + * This is used to conserve memory by avoiding array allocations. + * + * @return {*|array<*>} An accumulation of items. + */ + function accumulate(current, next) { - if (null == next) - throw Error("Accumulated items must not be null or undefined."); - return null == current - ? next - : isArrayImpl(current) - ? current.concat(next) - : isArrayImpl(next) - ? [current].concat(next) - : [current, next]; + if (next == null) { + throw new Error("Accumulated items must not be null or undefined."); + } + + if (current == null) { + return 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 (isArray(current)) { + /* $FlowFixMe[incompatible-return] if `current` is `T` and `T` an array, + * `isArray` might refine to the array element type of `T` */ + return current.concat(next); + } + + if (isArray(next)) { + /* $FlowFixMe[incompatible-return] unsound if `next` is `T` and `T` an array, + * `isArray` might refine to the array element type of `T` */ + return [current].concat(next); + } + + return [current, next]; } + + /** + * Accumulates items that must not be null or undefined into the first one. This + * is used to conserve memory by avoiding array allocations, and thus sacrifices + * API cleanness. Since `current` can be null before being passed in and not + * null after this function, make sure to assign it back to `current`: + * + * `a = accumulateInto(a, b);` + * + * This API should be sparingly used. Try `accumulate` for something cleaner. + * + * @return {*|array<*>} An accumulation of items. + */ + function accumulateInto(current, next) { - if (null == next) - throw Error("Accumulated items must not be null or undefined."); - if (null == current) return next; - if (isArrayImpl(current)) { - if (isArrayImpl(next)) - return current.push.apply(current, next), current; + if (next == null) { + throw new Error("Accumulated items must not be null or undefined."); + } + + if (current == null) { + return 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 (isArray(current)) { + if (isArray(next)) { + // $FlowFixMe[prop-missing] `isArray` does not ensure array is mutable + // $FlowFixMe[method-unbinding] + current.push.apply(current, next); + return current; + } // $FlowFixMe[prop-missing] `isArray` does not ensure array is mutable + current.push(next); return current; } - return isArrayImpl(next) ? [current].concat(next) : [current, next]; - } + + if (isArray(next)) { + // A bit too dangerous to mutate `next`. + + /* $FlowFixMe[incompatible-return] unsound if `next` is `T` and `T` an array, + * `isArray` might refine to the array element type of `T` */ + return [current].concat(next); + } + + return [current, next]; + } + + /** + * @param {array} arr an "accumulation" of items which is either an Array or + * a single item. Useful when paired with the `accumulate` module. This is a + * simple utility that allows us to reason about a collection of items, but + * handling the case when there is exactly one item (and we do not need to + * allocate an array). + * @param {function} cb Callback invoked with each element or a collection. + * @param {?} [scope] Scope used as `this` in a callback. + */ function forEachAccumulated(arr, cb, scope) { - Array.isArray(arr) ? arr.forEach(cb, scope) : arr && cb.call(scope, arr); + if (Array.isArray(arr)) { + // $FlowFixMe[incompatible-call] if `T` is an array, `cb` cannot be called + arr.forEach(cb, scope); + } else if (arr) { + cb.call(scope, arr); + } } + + var FunctionComponent = 0; + var ClassComponent = 1; + var IndeterminateComponent = 2; // Before we know whether it is function or class + + var HostRoot = 3; // Root of a host tree. Could be nested inside another node. + + var HostPortal = 4; // A subtree. Could be an entry point to a different renderer. + + var HostComponent = 5; + var HostText = 6; + var Fragment = 7; + var Mode = 8; + var ContextConsumer = 9; + var ContextProvider = 10; + var ForwardRef = 11; + var Profiler = 12; + var SuspenseComponent = 13; + var MemoComponent = 14; + var SimpleMemoComponent = 15; + var LazyComponent = 16; + var IncompleteClassComponent = 17; + var DehydratedFragment = 18; + var SuspenseListComponent = 19; + var ScopeComponent = 21; + var OffscreenComponent = 22; + var LegacyHiddenComponent = 23; + var CacheComponent = 24; + var TracingMarkerComponent = 25; + var HostHoistable = 26; + var HostSingleton = 27; + + /** + * Instance of element that should respond to touch/move types of interactions, + * as indicated explicitly by relevant callbacks. + */ + + var responderInst = null; + /** + * Count of current touches. A textInput should become responder iff the + * selection changes while there is a touch on the screen. + */ + + var trackedTouchCount = 0; + function changeResponder(nextResponderInst, blockHostResponder) { var oldResponderInst = responderInst; responderInst = nextResponderInst; - if (null !== ResponderEventPlugin.GlobalResponderHandler) + + if (ResponderEventPlugin.GlobalResponderHandler !== null) { ResponderEventPlugin.GlobalResponderHandler.onChange( oldResponderInst, nextResponderInst, blockHostResponder ); + } } + + var eventTypes = { + /** + * On a `touchStart`/`mouseDown`, is it desired that this element become the + * responder? + */ + startShouldSetResponder: { + phasedRegistrationNames: { + bubbled: "onStartShouldSetResponder", + captured: "onStartShouldSetResponderCapture" + }, + dependencies: startDependencies + }, + + /** + * On a `scroll`, is it desired that this element become the responder? This + * is usually not needed, but should be used to retroactively infer that a + * `touchStart` had occurred during momentum scroll. During a momentum scroll, + * a touch start will be immediately followed by a scroll event if the view is + * currently scrolling. + * + * TODO: This shouldn't bubble. + */ + scrollShouldSetResponder: { + phasedRegistrationNames: { + bubbled: "onScrollShouldSetResponder", + captured: "onScrollShouldSetResponderCapture" + }, + dependencies: [TOP_SCROLL] + }, + + /** + * On text selection change, should this element become the responder? This + * is needed for text inputs or other views with native selection, so the + * JS view can claim the responder. + * + * TODO: This shouldn't bubble. + */ + selectionChangeShouldSetResponder: { + phasedRegistrationNames: { + bubbled: "onSelectionChangeShouldSetResponder", + captured: "onSelectionChangeShouldSetResponderCapture" + }, + dependencies: [TOP_SELECTION_CHANGE] + }, + + /** + * On a `touchMove`/`mouseMove`, is it desired that this element become the + * responder? + */ + moveShouldSetResponder: { + phasedRegistrationNames: { + bubbled: "onMoveShouldSetResponder", + captured: "onMoveShouldSetResponderCapture" + }, + dependencies: moveDependencies + }, + + /** + * Direct responder events dispatched directly to responder. Do not bubble. + */ + responderStart: { + registrationName: "onResponderStart", + dependencies: startDependencies + }, + responderMove: { + registrationName: "onResponderMove", + dependencies: moveDependencies + }, + responderEnd: { + registrationName: "onResponderEnd", + dependencies: endDependencies + }, + responderRelease: { + registrationName: "onResponderRelease", + dependencies: endDependencies + }, + responderTerminationRequest: { + registrationName: "onResponderTerminationRequest", + dependencies: [] + }, + responderGrant: { + registrationName: "onResponderGrant", + dependencies: [] + }, + responderReject: { + registrationName: "onResponderReject", + dependencies: [] + }, + responderTerminate: { + registrationName: "onResponderTerminate", + dependencies: [] + } + }; // Start of inline: the below functions were inlined from + // EventPropagator.js, as they deviated from ReactDOM's newer + // implementations. + function getParent$1(inst) { - do inst = inst.return; - while (inst && 5 !== inst.tag); - return inst ? inst : null; + do { + inst = inst.return; // TODO: If this is a HostRoot we might want to bail out. + // That is depending on if we want nested subtrees (layers) to bubble + // events to their parent. We could also go through parentNode on the + // host node but that wouldn't work for React Native and doesn't let us + // do the portal feature. + } while (inst && inst.tag !== HostComponent); + + if (inst) { + return inst; + } + + return null; + } + /** + * Return the lowest common ancestor of A and B, or null if they are in + * different trees. + */ + + function getLowestCommonAncestor(instA, instB) { + var depthA = 0; + + for (var tempA = instA; tempA; tempA = getParent$1(tempA)) { + depthA++; + } + + var depthB = 0; + + for (var tempB = instB; tempB; tempB = getParent$1(tempB)) { + depthB++; + } // If A is deeper, crawl up. + + while (depthA - depthB > 0) { + instA = getParent$1(instA); + depthA--; + } // If B is deeper, crawl up. + + while (depthB - depthA > 0) { + instB = getParent$1(instB); + depthB--; + } // Walk in lockstep until we find a match. + + var depth = depthA; + + while (depth--) { + if (instA === instB || instA === instB.alternate) { + return instA; + } + + instA = getParent$1(instA); + instB = getParent$1(instB); + } + + return null; + } + /** + * Return if A is an ancestor of B. + */ + + function isAncestor(instA, instB) { + while (instB) { + if (instA === instB || instA === instB.alternate) { + return true; + } + + instB = getParent$1(instB); + } + + return false; } + /** + * Simulates the traversal of a two-phase, capture/bubble event dispatch. + */ + function traverseTwoPhase$1(inst, fn, arg) { - for (var path = []; inst; ) path.push(inst), (inst = getParent$1(inst)); - for (inst = path.length; 0 < inst--; ) fn(path[inst], "captured", arg); - for (inst = 0; inst < path.length; inst++) fn(path[inst], "bubbled", arg); + var path = []; + + while (inst) { + path.push(inst); + inst = getParent$1(inst); + } + + var i; + + for (i = path.length; i-- > 0; ) { + fn(path[i], "captured", arg); + } + + for (i = 0; i < path.length; i++) { + fn(path[i], "bubbled", arg); + } } + function getListener$1(inst, registrationName) { - inst = inst.stateNode; - if (null === inst) return null; - inst = getFiberCurrentPropsFromNode$1(inst); - if (null === inst) return null; - if ((inst = inst[registrationName]) && "function" !== typeof inst) - throw Error( + var stateNode = inst.stateNode; + + if (stateNode === null) { + // Work in progress (ex: onload events in incremental mode). + return null; + } + + var props = getFiberCurrentPropsFromNode$1(stateNode); + + if (props === null) { + // Work in progress. + return null; + } + + var listener = props[registrationName]; + + if (listener && typeof listener !== "function") { + throw new Error( "Expected `" + registrationName + "` listener to be a function, instead got a value of `" + - typeof inst + + typeof listener + "` type." ); - return inst; + } + + return listener; + } + + function listenerAtPhase$1(inst, event, propagationPhase) { + var registrationName = + event.dispatchConfig.phasedRegistrationNames[propagationPhase]; + return getListener$1(inst, registrationName); } + function accumulateDirectionalDispatches$1(inst, phase, event) { - inst || error$jscomp$0("Dispatching inst must not be null"); - if ( - (phase = getListener$1( - inst, - event.dispatchConfig.phasedRegistrationNames[phase] - )) - ) - (event._dispatchListeners = accumulateInto( + { + if (!inst) { + error("Dispatching inst must not be null"); + } + } + + var listener = listenerAtPhase$1(inst, event, phase); + + if (listener) { + event._dispatchListeners = accumulateInto( event._dispatchListeners, - phase - )), - (event._dispatchInstances = accumulateInto( + listener + ); + event._dispatchInstances = accumulateInto( + event._dispatchInstances, + inst + ); + } + } + /** + * Accumulates without regard to direction, does not look for phased + * registration names. Same as `accumulateDirectDispatchesSingle` but without + * requiring that the `dispatchMarker` be the same as the dispatched ID. + */ + + function accumulateDispatches$1(inst, ignoredDirection, event) { + if (inst && event && event.dispatchConfig.registrationName) { + var registrationName = event.dispatchConfig.registrationName; + var listener = getListener$1(inst, registrationName); + + if (listener) { + event._dispatchListeners = accumulateInto( + event._dispatchListeners, + listener + ); + event._dispatchInstances = accumulateInto( event._dispatchInstances, inst - )); + ); + } + } } + /** + * Accumulates dispatches on an `SyntheticEvent`, but only for the + * `dispatchMarker`. + * @param {SyntheticEvent} event + */ + function accumulateDirectDispatchesSingle$1(event) { if (event && event.dispatchConfig.registrationName) { - var inst = event._targetInst; - if (inst && event && event.dispatchConfig.registrationName) { - var listener = getListener$1( - inst, - event.dispatchConfig.registrationName - ); - listener && - ((event._dispatchListeners = accumulateInto( - event._dispatchListeners, - listener - )), - (event._dispatchInstances = accumulateInto( - event._dispatchInstances, - inst - ))); - } + accumulateDispatches$1(event._targetInst, null, event); } } + + function accumulateDirectDispatches$1(events) { + forEachAccumulated(events, accumulateDirectDispatchesSingle$1); + } + function accumulateTwoPhaseDispatchesSingleSkipTarget(event) { if (event && event.dispatchConfig.phasedRegistrationNames) { var targetInst = event._targetInst; - targetInst = targetInst ? getParent$1(targetInst) : null; + var parentInst = targetInst ? getParent$1(targetInst) : null; traverseTwoPhase$1( - targetInst, + parentInst, accumulateDirectionalDispatches$1, event ); } } + + function accumulateTwoPhaseDispatchesSkipTarget(events) { + forEachAccumulated(events, accumulateTwoPhaseDispatchesSingleSkipTarget); + } + function accumulateTwoPhaseDispatchesSingle$1(event) { - event && - event.dispatchConfig.phasedRegistrationNames && + if (event && event.dispatchConfig.phasedRegistrationNames) { traverseTwoPhase$1( event._targetInst, accumulateDirectionalDispatches$1, event ); - } - function recomputePluginOrdering() { - if (eventPluginOrder) - for (var pluginName in namesToPlugins) { - var pluginModule = namesToPlugins[pluginName], - pluginIndex = eventPluginOrder.indexOf(pluginName); - if (-1 >= pluginIndex) - throw Error( - "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + - (pluginName + "`.") - ); - if (!plugins[pluginIndex]) { - if (!pluginModule.extractEvents) - throw Error( - "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + - (pluginName + "` does not.") - ); - plugins[pluginIndex] = pluginModule; - pluginIndex = pluginModule.eventTypes; - for (var eventName in pluginIndex) { - var JSCompiler_inline_result = void 0; - var dispatchConfig = pluginIndex[eventName], - pluginModule$jscomp$0 = pluginModule, - eventName$jscomp$0 = eventName; - if (eventNameDispatchConfigs.hasOwnProperty(eventName$jscomp$0)) - throw Error( - "EventPluginRegistry: More than one plugin attempted to publish the same event name, `" + - (eventName$jscomp$0 + "`.") - ); - eventNameDispatchConfigs[eventName$jscomp$0] = dispatchConfig; - if ( - (eventName$jscomp$0 = dispatchConfig.phasedRegistrationNames) - ) { - for (JSCompiler_inline_result in eventName$jscomp$0) - eventName$jscomp$0.hasOwnProperty(JSCompiler_inline_result) && - publishRegistrationName( - eventName$jscomp$0[JSCompiler_inline_result], - pluginModule$jscomp$0 - ); - JSCompiler_inline_result = !0; - } else - dispatchConfig.registrationName - ? (publishRegistrationName( - dispatchConfig.registrationName, - pluginModule$jscomp$0 - ), - (JSCompiler_inline_result = !0)) - : (JSCompiler_inline_result = !1); - if (!JSCompiler_inline_result) - throw Error( - "EventPluginRegistry: Failed to publish event `" + - eventName + - "` for plugin `" + - pluginName + - "`." - ); - } - } - } - } - function publishRegistrationName(registrationName, pluginModule) { - if (registrationNameModules[registrationName]) - throw Error( - "EventPluginRegistry: More than one plugin attempted to publish the same registration name, `" + - (registrationName + "`.") - ); - registrationNameModules[registrationName] = pluginModule; - registrationName.toLowerCase(); - } - function getListener(inst, registrationName) { - inst = inst.stateNode; - if (null === inst) return null; - inst = getFiberCurrentPropsFromNode$1(inst); - if (null === inst) return null; - if ((inst = inst[registrationName]) && "function" !== typeof inst) - throw Error( - "Expected `" + - registrationName + - "` listener to be a function, instead got a value of `" + - typeof inst + - "` type." - ); - return inst; - } - function accumulateDirectionalDispatches(inst, phase, event) { - inst || error$jscomp$0("Dispatching inst must not be null"); - if ( - (phase = getListener( - inst, - event.dispatchConfig.phasedRegistrationNames[phase] - )) - ) - (event._dispatchListeners = accumulateInto( - event._dispatchListeners, - phase - )), - (event._dispatchInstances = accumulateInto( - event._dispatchInstances, - inst - )); - } - function traverseTwoPhase(inst, fn, arg, skipBubbling) { - for (var path = []; inst; ) { - path.push(inst); - do inst = inst.return; - while (inst && 5 !== inst.tag); - inst = inst ? inst : null; } - for (inst = path.length; 0 < inst--; ) fn(path[inst], "captured", arg); - if (skipBubbling) fn(path[0], "bubbled", arg); - else - for (inst = 0; inst < path.length; inst++) - fn(path[inst], "bubbled", arg); } - function accumulateTwoPhaseDispatchesSingle(event) { - event && - event.dispatchConfig.phasedRegistrationNames && - traverseTwoPhase( - event._targetInst, - accumulateDirectionalDispatches, - event, - !1 + + function accumulateTwoPhaseDispatches$1(events) { + forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle$1); + } // End of inline + + /** + * + * Responder System: + * ---------------- + * + * - A global, solitary "interaction lock" on a view. + * - If a node becomes the responder, it should convey visual feedback + * immediately to indicate so, either by highlighting or moving accordingly. + * - To be the responder means, that touches are exclusively important to that + * responder view, and no other view. + * - While touches are still occurring, the responder lock can be transferred to + * a new view, but only to increasingly "higher" views (meaning ancestors of + * the current responder). + * + * Responder being granted: + * ------------------------ + * + * - Touch starts, moves, and scrolls can cause an ID to become the responder. + * - We capture/bubble `startShouldSetResponder`/`moveShouldSetResponder` to + * the "appropriate place". + * - If nothing is currently the responder, the "appropriate place" is the + * initiating event's `targetID`. + * - If something *is* already the responder, the "appropriate place" is the + * first common ancestor of the event target and the current `responderInst`. + * - Some negotiation happens: See the timing diagram below. + * - Scrolled views automatically become responder. The reasoning is that a + * platform scroll view that isn't built on top of the responder system has + * began scrolling, and the active responder must now be notified that the + * interaction is no longer locked to it - the system has taken over. + * + * - Responder being released: + * As soon as no more touches that *started* inside of descendants of the + * *current* responderInst, an `onResponderRelease` event is dispatched to the + * current responder, and the responder lock is released. + * + * TODO: + * - on "end", a callback hook for `onResponderEndShouldRemainResponder` that + * determines if the responder lock should remain. + * - If a view shouldn't "remain" the responder, any active touches should by + * default be considered "dead" and do not influence future negotiations or + * bubble paths. It should be as if those touches do not exist. + * -- For multitouch: Usually a translate-z will choose to "remain" responder + * after one out of many touches ended. For translate-y, usually the view + * doesn't wish to "remain" responder after one of many touches end. + * - Consider building this on top of a `stopPropagation` model similar to + * `W3C` events. + * - Ensure that `onResponderTerminate` is called on touch cancels, whether or + * not `onResponderTerminationRequest` returns `true` or `false`. + * + */ + + /* Negotiation Performed + +-----------------------+ + / \ +Process low level events to + Current Responder + wantsResponderID +determine who to perform negot-| (if any exists at all) | +iation/transition | Otherwise just pass through| +-------------------------------+----------------------------+------------------+ +Bubble to find first ID | | +to return true:wantsResponderID| | + | | + +-------------+ | | + | onTouchStart| | | + +------+------+ none | | + | return| | ++-----------v-------------+true| +------------------------+ | +|onStartShouldSetResponder|----->|onResponderStart (cur) |<-----------+ ++-----------+-------------+ | +------------------------+ | | + | | | +--------+-------+ + | returned true for| false:REJECT +-------->|onResponderReject + | wantsResponderID | | | +----------------+ + | (now attempt | +------------------+-----+ | + | handoff) | | onResponder | | + +------------------->| TerminationRequest| | + | +------------------+-----+ | + | | | +----------------+ + | true:GRANT +-------->|onResponderGrant| + | | +--------+-------+ + | +------------------------+ | | + | | onResponderTerminate |<-----------+ + | +------------------+-----+ | + | | | +----------------+ + | +-------->|onResponderStart| + | | +----------------+ +Bubble to find first ID | | +to return true:wantsResponderID| | + | | + +-------------+ | | + | onTouchMove | | | + +------+------+ none | | + | return| | ++-----------v-------------+true| +------------------------+ | +|onMoveShouldSetResponder |----->|onResponderMove (cur) |<-----------+ ++-----------+-------------+ | +------------------------+ | | + | | | +--------+-------+ + | returned true for| false:REJECT +-------->|onResponderRejec| + | wantsResponderID | | | +----------------+ + | (now attempt | +------------------+-----+ | + | handoff) | | onResponder | | + +------------------->| TerminationRequest| | + | +------------------+-----+ | + | | | +----------------+ + | true:GRANT +-------->|onResponderGrant| + | | +--------+-------+ + | +------------------------+ | | + | | onResponderTerminate |<-----------+ + | +------------------+-----+ | + | | | +----------------+ + | +-------->|onResponderMove | + | | +----------------+ + | | + | | + Some active touch started| | + inside current responder | +------------------------+ | + +------------------------->| onResponderEnd | | + | | +------------------------+ | + +---+---------+ | | + | onTouchEnd | | | + +---+---------+ | | + | | +------------------------+ | + +------------------------->| onResponderEnd | | + No active touches started| +-----------+------------+ | + inside current responder | | | + | v | + | +------------------------+ | + | | onResponderRelease | | + | +------------------------+ | + | | + + + */ + + /** + * A note about event ordering in the `EventPluginRegistry`. + * + * Suppose plugins are injected in the following order: + * + * `[R, S, C]` + * + * To help illustrate the example, assume `S` is `SimpleEventPlugin` (for + * `onClick` etc) and `R` is `ResponderEventPlugin`. + * + * "Deferred-Dispatched Events": + * + * - The current event plugin system will traverse the list of injected plugins, + * in order, and extract events by collecting the plugin's return value of + * `extractEvents()`. + * - These events that are returned from `extractEvents` are "deferred + * dispatched events". + * - When returned from `extractEvents`, deferred-dispatched events contain an + * "accumulation" of deferred dispatches. + * - These deferred dispatches are accumulated/collected before they are + * returned, but processed at a later time by the `EventPluginRegistry` (hence the + * name deferred). + * + * In the process of returning their deferred-dispatched events, event plugins + * themselves can dispatch events on-demand without returning them from + * `extractEvents`. Plugins might want to do this, so that they can use event + * dispatching as a tool that helps them decide which events should be extracted + * in the first place. + * + * "On-Demand-Dispatched Events": + * + * - On-demand-dispatched events are not returned from `extractEvents`. + * - On-demand-dispatched events are dispatched during the process of returning + * the deferred-dispatched events. + * - They should not have side effects. + * - They should be avoided, and/or eventually be replaced with another + * abstraction that allows event plugins to perform multiple "rounds" of event + * extraction. + * + * Therefore, the sequence of event dispatches becomes: + * + * - `R`s on-demand events (if any) (dispatched by `R` on-demand) + * - `S`s on-demand events (if any) (dispatched by `S` on-demand) + * - `C`s on-demand events (if any) (dispatched by `C` on-demand) + * - `R`s extracted events (if any) (dispatched by `EventPluginRegistry`) + * - `S`s extracted events (if any) (dispatched by `EventPluginRegistry`) + * - `C`s extracted events (if any) (dispatched by `EventPluginRegistry`) + * + * In the case of `ResponderEventPlugin`: If the `startShouldSetResponder` + * on-demand dispatch returns `true` (and some other details are satisfied) the + * `onResponderGrant` deferred dispatched event is returned from + * `extractEvents`. The sequence of dispatch executions in this case + * will appear as follows: + * + * - `startShouldSetResponder` (`ResponderEventPlugin` dispatches on-demand) + * - `touchStartCapture` (`EventPluginRegistry` dispatches as usual) + * - `touchStart` (`EventPluginRegistry` dispatches as usual) + * - `responderGrant/Reject` (`EventPluginRegistry` dispatches as usual) + */ + + function setResponderAndExtractTransfer( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget + ) { + var shouldSetEventType = isStartish(topLevelType) + ? eventTypes.startShouldSetResponder + : isMoveish(topLevelType) + ? eventTypes.moveShouldSetResponder + : topLevelType === TOP_SELECTION_CHANGE + ? eventTypes.selectionChangeShouldSetResponder + : eventTypes.scrollShouldSetResponder; // TODO: stop one short of the current responder. + + var bubbleShouldSetFrom = !responderInst + ? targetInst + : getLowestCommonAncestor(responderInst, targetInst); // When capturing/bubbling the "shouldSet" event, we want to skip the target + // (deepest ID) if it happens to be the current responder. The reasoning: + // It's strange to get an `onMoveShouldSetResponder` when you're *already* + // the responder. + + var skipOverBubbleShouldSetFrom = bubbleShouldSetFrom === responderInst; + var shouldSetEvent = ResponderSyntheticEvent.getPooled( + shouldSetEventType, + bubbleShouldSetFrom, + nativeEvent, + nativeEventTarget + ); + shouldSetEvent.touchHistory = ResponderTouchHistoryStore.touchHistory; + + if (skipOverBubbleShouldSetFrom) { + accumulateTwoPhaseDispatchesSkipTarget(shouldSetEvent); + } else { + accumulateTwoPhaseDispatches$1(shouldSetEvent); + } + + var wantsResponderInst = + executeDispatchesInOrderStopAtTrue(shouldSetEvent); + + if (!shouldSetEvent.isPersistent()) { + shouldSetEvent.constructor.release(shouldSetEvent); + } + + if (!wantsResponderInst || wantsResponderInst === responderInst) { + return null; + } + + var extracted; + var grantEvent = ResponderSyntheticEvent.getPooled( + eventTypes.responderGrant, + wantsResponderInst, + nativeEvent, + nativeEventTarget + ); + grantEvent.touchHistory = ResponderTouchHistoryStore.touchHistory; + accumulateDirectDispatches$1(grantEvent); + var blockHostResponder = executeDirectDispatch(grantEvent) === true; + + if (responderInst) { + var terminationRequestEvent = ResponderSyntheticEvent.getPooled( + eventTypes.responderTerminationRequest, + responderInst, + nativeEvent, + nativeEventTarget ); - } - function accumulateDirectDispatchesSingle(event) { - if (event && event.dispatchConfig.registrationName) { - var inst = event._targetInst; - if (inst && event && event.dispatchConfig.registrationName) { - var listener = getListener( - inst, - event.dispatchConfig.registrationName + terminationRequestEvent.touchHistory = + ResponderTouchHistoryStore.touchHistory; + accumulateDirectDispatches$1(terminationRequestEvent); + var shouldSwitch = + !hasDispatches(terminationRequestEvent) || + executeDirectDispatch(terminationRequestEvent); + + if (!terminationRequestEvent.isPersistent()) { + terminationRequestEvent.constructor.release(terminationRequestEvent); + } + + if (shouldSwitch) { + var terminateEvent = ResponderSyntheticEvent.getPooled( + eventTypes.responderTerminate, + responderInst, + nativeEvent, + nativeEventTarget + ); + terminateEvent.touchHistory = ResponderTouchHistoryStore.touchHistory; + accumulateDirectDispatches$1(terminateEvent); + extracted = accumulate(extracted, [grantEvent, terminateEvent]); + changeResponder(wantsResponderInst, blockHostResponder); + } else { + var rejectEvent = ResponderSyntheticEvent.getPooled( + eventTypes.responderReject, + wantsResponderInst, + nativeEvent, + nativeEventTarget ); - listener && - ((event._dispatchListeners = accumulateInto( - event._dispatchListeners, - listener - )), - (event._dispatchInstances = accumulateInto( - event._dispatchInstances, - inst - ))); + rejectEvent.touchHistory = ResponderTouchHistoryStore.touchHistory; + accumulateDirectDispatches$1(rejectEvent); + extracted = accumulate(extracted, rejectEvent); } + } else { + extracted = accumulate(extracted, grantEvent); + changeResponder(wantsResponderInst, blockHostResponder); } + + return extracted; + } + /** + * A transfer is a negotiation between a currently set responder and the next + * element to claim responder status. Any start event could trigger a transfer + * of responderInst. Any move event could trigger a transfer. + * + * @param {string} topLevelType Record from `BrowserEventConstants`. + * @return {boolean} True if a transfer of responder could possibly occur. + */ + + function canTriggerTransfer(topLevelType, topLevelInst, nativeEvent) { + return ( + topLevelInst && // responderIgnoreScroll: We are trying to migrate away from specifically + // tracking native scroll events here and responderIgnoreScroll indicates we + // will send topTouchCancel to handle canceling touch events instead + ((topLevelType === TOP_SCROLL && !nativeEvent.responderIgnoreScroll) || + (trackedTouchCount > 0 && topLevelType === TOP_SELECTION_CHANGE) || + isStartish(topLevelType) || + isMoveish(topLevelType)) + ); } - function defaultDiffer(prevProp, nextProp) { - return "object" !== typeof nextProp || null === nextProp - ? !0 - : ReactNativePrivateInterface.deepDiffer( - prevProp, - nextProp, - deepDifferOptions - ); - } - function restoreDeletedValuesInNestedArray( - updatePayload, - node, - validAttributes - ) { - if (isArrayImpl(node)) - for (var i = node.length; i-- && 0 < removedKeyCount; ) - restoreDeletedValuesInNestedArray( - updatePayload, - node[i], - validAttributes - ); - else if (node && 0 < removedKeyCount) - for (i in removedKeys) - if (removedKeys[i]) { - var nextProp = node[i]; - if (void 0 !== nextProp) { - var attributeConfig = validAttributes[i]; - if (attributeConfig) { - "function" === typeof nextProp && (nextProp = !0); - "undefined" === typeof nextProp && (nextProp = null); - if ("object" !== typeof attributeConfig) - updatePayload[i] = nextProp; - else if ( - "function" === typeof attributeConfig.diff || - "function" === typeof attributeConfig.process - ) - (nextProp = - "function" === typeof attributeConfig.process - ? attributeConfig.process(nextProp) - : nextProp), - (updatePayload[i] = nextProp); - removedKeys[i] = !1; - removedKeyCount--; - } - } + /** + * Returns whether or not this touch end event makes it such that there are no + * longer any touches that started inside of the current `responderInst`. + * + * @param {NativeEvent} nativeEvent Native touch end event. + * @return {boolean} Whether or not this touch end event ends the responder. + */ + + function noResponderTouches(nativeEvent) { + var touches = nativeEvent.touches; + + if (!touches || touches.length === 0) { + return true; + } + + for (var i = 0; i < touches.length; i++) { + var activeTouch = touches[i]; + var target = activeTouch.target; + + if (target !== null && target !== undefined && target !== 0) { + // Is the original touch location inside of the current responder? + var targetInst = getInstanceFromNode$1(target); + + if (isAncestor(responderInst, targetInst)) { + return false; } - } - function diffNestedProperty( - updatePayload, - prevProp, - nextProp, - validAttributes - ) { - if (!updatePayload && prevProp === nextProp) return updatePayload; - if (!prevProp || !nextProp) - return nextProp - ? addNestedProperty(updatePayload, nextProp, validAttributes) - : prevProp - ? clearNestedProperty(updatePayload, prevProp, validAttributes) - : updatePayload; - if (!isArrayImpl(prevProp) && !isArrayImpl(nextProp)) - return diffProperties( - updatePayload, - prevProp, - nextProp, - validAttributes - ); - if (isArrayImpl(prevProp) && isArrayImpl(nextProp)) { - var minLength = - prevProp.length < nextProp.length - ? prevProp.length - : nextProp.length, - i; - for (i = 0; i < minLength; i++) - updatePayload = diffNestedProperty( - updatePayload, - prevProp[i], - nextProp[i], - validAttributes - ); - for (; i < prevProp.length; i++) - updatePayload = clearNestedProperty( - updatePayload, - prevProp[i], - validAttributes - ); - for (; i < nextProp.length; i++) - updatePayload = addNestedProperty( - updatePayload, - nextProp[i], - validAttributes - ); - return updatePayload; + } } - return isArrayImpl(prevProp) - ? diffProperties( - updatePayload, - ReactNativePrivateInterface.flattenStyle(prevProp), - nextProp, - validAttributes - ) - : diffProperties( - updatePayload, - prevProp, - ReactNativePrivateInterface.flattenStyle(nextProp), - validAttributes - ); + + return true; } - function addNestedProperty(updatePayload, nextProp, validAttributes) { - if (!nextProp) return updatePayload; - if (!isArrayImpl(nextProp)) - return diffProperties( - updatePayload, - emptyObject$1, - nextProp, - validAttributes - ); - for (var i = 0; i < nextProp.length; i++) - updatePayload = addNestedProperty( - updatePayload, - nextProp[i], - validAttributes - ); - return updatePayload; - } - function clearNestedProperty(updatePayload, prevProp, validAttributes) { - if (!prevProp) return updatePayload; - if (!isArrayImpl(prevProp)) - return diffProperties( - updatePayload, - prevProp, - emptyObject$1, - validAttributes - ); - for (var i = 0; i < prevProp.length; i++) - updatePayload = clearNestedProperty( - updatePayload, - prevProp[i], - validAttributes - ); - return updatePayload; - } - function diffProperties( - updatePayload, - prevProps, - nextProps, - validAttributes - ) { - var attributeConfig, propKey; - for (propKey in nextProps) - if ((attributeConfig = validAttributes[propKey])) { - var prevProp = prevProps[propKey]; - var nextProp = nextProps[propKey]; - "function" === typeof nextProp && - ((nextProp = !0), - "function" === typeof prevProp && (prevProp = !0)); - "undefined" === typeof nextProp && - ((nextProp = null), - "undefined" === typeof prevProp && (prevProp = null)); - removedKeys && (removedKeys[propKey] = !1); - if (updatePayload && void 0 !== updatePayload[propKey]) - if ("object" !== typeof attributeConfig) - updatePayload[propKey] = nextProp; - else { - if ( - "function" === typeof attributeConfig.diff || - "function" === typeof attributeConfig.process - ) - (attributeConfig = - "function" === typeof attributeConfig.process - ? attributeConfig.process(nextProp) - : nextProp), - (updatePayload[propKey] = attributeConfig); + + var ResponderEventPlugin = { + /* For unit testing only */ + _getResponder: function () { + return responderInst; + }, + eventTypes: eventTypes, + + /** + * We must be resilient to `targetInst` being `null` on `touchMove` or + * `touchEnd`. On certain platforms, this means that a native scroll has + * assumed control and the original touch targets are destroyed. + */ + extractEvents: function ( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget, + eventSystemFlags + ) { + if (isStartish(topLevelType)) { + trackedTouchCount += 1; + } else if (isEndish(topLevelType)) { + if (trackedTouchCount >= 0) { + trackedTouchCount -= 1; + } else { + { + warn( + "Ended a touch event which was not counted in `trackedTouchCount`." + ); } - else if (prevProp !== nextProp) - if ("object" !== typeof attributeConfig) - defaultDiffer(prevProp, nextProp) && - ((updatePayload || (updatePayload = {}))[propKey] = nextProp); - else if ( - "function" === typeof attributeConfig.diff || - "function" === typeof attributeConfig.process - ) { - if ( - void 0 === prevProp || - ("function" === typeof attributeConfig.diff - ? attributeConfig.diff(prevProp, nextProp) - : defaultDiffer(prevProp, nextProp)) - ) - (attributeConfig = - "function" === typeof attributeConfig.process - ? attributeConfig.process(nextProp) - : nextProp), - ((updatePayload || (updatePayload = {}))[propKey] = - attributeConfig); - } else - (removedKeys = null), - (removedKeyCount = 0), - (updatePayload = diffNestedProperty( - updatePayload, - prevProp, - nextProp, - attributeConfig - )), - 0 < removedKeyCount && - updatePayload && - (restoreDeletedValuesInNestedArray( - updatePayload, - nextProp, - attributeConfig - ), - (removedKeys = null)); - } - for (var _propKey in prevProps) - void 0 === nextProps[_propKey] && - (!(attributeConfig = validAttributes[_propKey]) || - (updatePayload && void 0 !== updatePayload[_propKey]) || - ((prevProp = prevProps[_propKey]), - void 0 !== prevProp && - ("object" !== typeof attributeConfig || - "function" === typeof attributeConfig.diff || - "function" === typeof attributeConfig.process - ? (((updatePayload || (updatePayload = {}))[_propKey] = null), - removedKeys || (removedKeys = {}), - removedKeys[_propKey] || - ((removedKeys[_propKey] = !0), removedKeyCount++)) - : (updatePayload = clearNestedProperty( - updatePayload, - prevProp, - attributeConfig - ))))); - return updatePayload; - } - function batchedUpdates$1(fn, bookkeeping) { - if (isInsideEventHandler) return fn(bookkeeping); - isInsideEventHandler = !0; - try { - return batchedUpdatesImpl(fn, bookkeeping); - } finally { - isInsideEventHandler = !1; - } - } - function executeDispatchesAndReleaseTopLevel(e) { - if (e) { - var dispatchListeners = e._dispatchListeners, - dispatchInstances = e._dispatchInstances; - validateEventDispatches(e); - if (isArrayImpl(dispatchListeners)) - for ( - var i = 0; - i < dispatchListeners.length && !e.isPropagationStopped(); - i++ - ) { - var listener = dispatchListeners[i], - instance = dispatchInstances[i]; - null !== instance - ? runWithFiberInDEV( - instance, - executeDispatch, - e, - listener, - instance - ) - : executeDispatch(e, listener, instance); - } - else - dispatchListeners && - (null !== dispatchInstances - ? runWithFiberInDEV( - dispatchInstances, - executeDispatch, - e, - dispatchListeners, - dispatchInstances - ) - : executeDispatch(e, dispatchListeners, dispatchInstances)); - e._dispatchListeners = null; - e._dispatchInstances = null; - e.isPersistent() || e.constructor.release(e); - } - } - function dispatchEvent(target, topLevelType, nativeEvent) { - var eventTarget = null; - if (null != target) { - var stateNode = target.stateNode; - null != stateNode && (eventTarget = getPublicInstance(stateNode)); - } - batchedUpdates$1(function () { - var event = { eventName: topLevelType, nativeEvent: nativeEvent }; - ReactNativePrivateInterface.RawEventEmitter.emit(topLevelType, event); - ReactNativePrivateInterface.RawEventEmitter.emit("*", event); - event = eventTarget; - for ( - var events = null, legacyPlugins = plugins, i = 0; - i < legacyPlugins.length; - i++ - ) { - var possiblePlugin = legacyPlugins[i]; - possiblePlugin && - (possiblePlugin = possiblePlugin.extractEvents( + + return null; + } + } + + ResponderTouchHistoryStore.recordTouchTrack(topLevelType, nativeEvent); + var extracted = canTriggerTransfer( + topLevelType, + targetInst, + nativeEvent + ) + ? setResponderAndExtractTransfer( topLevelType, - target, + targetInst, nativeEvent, - event - )) && - (events = accumulateInto(events, possiblePlugin)); - } - event = events; - null !== event && (eventQueue = accumulateInto(eventQueue, event)); - event = eventQueue; - eventQueue = null; - if (event) { - forEachAccumulated(event, executeDispatchesAndReleaseTopLevel); - if (eventQueue) - throw Error( - "processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented." - ); - if (hasError) - throw ( - ((event = caughtError), - (hasError = !1), - (caughtError = null), - event) - ); + nativeEventTarget + ) + : null; // Responder may or may not have transferred on a new touch start/move. + // Regardless, whoever is the responder after any potential transfer, we + // direct all touch start/move/ends to them in the form of + // `onResponderMove/Start/End`. These will be called for *every* additional + // finger that move/start/end, dispatched directly to whoever is the + // current responder at that moment, until the responder is "released". + // + // These multiple individual change touch events are are always bookended + // by `onResponderGrant`, and one of + // (`onResponderRelease/onResponderTerminate`). + + var isResponderTouchStart = responderInst && isStartish(topLevelType); + var isResponderTouchMove = responderInst && isMoveish(topLevelType); + var isResponderTouchEnd = responderInst && isEndish(topLevelType); + var incrementalTouch = isResponderTouchStart + ? eventTypes.responderStart + : isResponderTouchMove + ? eventTypes.responderMove + : isResponderTouchEnd + ? eventTypes.responderEnd + : null; + + if (incrementalTouch) { + var gesture = ResponderSyntheticEvent.getPooled( + incrementalTouch, + responderInst, + nativeEvent, + nativeEventTarget + ); + gesture.touchHistory = ResponderTouchHistoryStore.touchHistory; + accumulateDirectDispatches$1(gesture); + extracted = accumulate(extracted, gesture); + } + + var isResponderTerminate = + responderInst && topLevelType === TOP_TOUCH_CANCEL; + var isResponderRelease = + responderInst && + !isResponderTerminate && + isEndish(topLevelType) && + noResponderTouches(nativeEvent); + var finalTouch = isResponderTerminate + ? eventTypes.responderTerminate + : isResponderRelease + ? eventTypes.responderRelease + : null; + + if (finalTouch) { + var finalEvent = ResponderSyntheticEvent.getPooled( + finalTouch, + responderInst, + nativeEvent, + nativeEventTarget + ); + finalEvent.touchHistory = ResponderTouchHistoryStore.touchHistory; + accumulateDirectDispatches$1(finalEvent); + extracted = accumulate(extracted, finalEvent); + changeResponder(null); + } + + return extracted; + }, + GlobalResponderHandler: null, + injection: { + /** + * @param {{onChange: (ReactID, ReactID) => void} GlobalResponderHandler + * Object that handles any change in responder. Use this to inject + * integration with an existing touch handling system etc. + */ + injectGlobalResponderHandler: function (GlobalResponderHandler) { + ResponderEventPlugin.GlobalResponderHandler = GlobalResponderHandler; } - }); - } - function injectInternals(internals) { - if ("undefined" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) return !1; - var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; - if (hook.isDisabled) return !0; - if (!hook.supportsFiber) - return ( - error$jscomp$0( - "The installed version of React DevTools is too old and will not work with the current version of React. Please update React DevTools. https://react.dev/link/react-devtools" - ), - !0 - ); - try { - (internals = assign({}, internals, { - getLaneLabelMap: getLaneLabelMap, - injectProfilingHooks: injectProfilingHooks - })), - (rendererID = hook.inject(internals)), - (injectedHook = hook); - } catch (err) { - error$jscomp$0("React instrumentation encountered an error: %s.", err); } - return hook.checkDCE ? !0 : !1; - } - function onCommitRoot(root, eventPriority) { - if (injectedHook && "function" === typeof injectedHook.onCommitFiberRoot) - try { - var didError = 128 === (root.current.flags & 128); - switch (eventPriority) { - case DiscreteEventPriority: - var schedulerPriority = ImmediatePriority; - break; - case ContinuousEventPriority: - schedulerPriority = UserBlockingPriority; - break; - case DefaultEventPriority: - schedulerPriority = NormalPriority$1; - break; - case IdleEventPriority: - schedulerPriority = IdlePriority; - break; - default: - schedulerPriority = NormalPriority$1; - } - injectedHook.onCommitFiberRoot( - rendererID, - root, - schedulerPriority, - didError + }; + + /** + * Injectable ordering of event plugins. + */ + var eventPluginOrder = null; + /** + * Injectable mapping from names to event plugin modules. + */ + + var namesToPlugins = {}; + /** + * Recomputes the plugin list using the injected plugins and plugin ordering. + * + * @private + */ + + function recomputePluginOrdering() { + if (!eventPluginOrder) { + // Wait until an `eventPluginOrder` is injected. + return; + } + + for (var pluginName in namesToPlugins) { + var pluginModule = namesToPlugins[pluginName]; // $FlowFixMe[incompatible-use] found when upgrading Flow + + var pluginIndex = eventPluginOrder.indexOf(pluginName); + + if (pluginIndex <= -1) { + throw new Error( + "EventPluginRegistry: Cannot inject event plugins that do not exist in " + + ("the plugin ordering, `" + pluginName + "`.") ); - } catch (err) { - hasLoggedError || - ((hasLoggedError = !0), - error$jscomp$0( - "React instrumentation encountered an error: %s", - err - )); } - } - function setIsStrictModeForDevtools(newIsStrictMode) { - "function" === typeof log$1 && - (unstable_setDisableYieldValue(newIsStrictMode), - (suppressWarning = newIsStrictMode)); - if (injectedHook && "function" === typeof injectedHook.setStrictMode) - try { - injectedHook.setStrictMode(rendererID, newIsStrictMode); - } catch (err) { - hasLoggedError || - ((hasLoggedError = !0), - error$jscomp$0( - "React instrumentation encountered an error: %s", - err - )); + + if (plugins[pluginIndex]) { + continue; } - } - function injectProfilingHooks(profilingHooks) { - injectedProfilingHooks = profilingHooks; - } - function getLaneLabelMap() { - for ( - var map = new Map(), lane = 1, index = 0; - index < TotalLanes; - index++ - ) { - var label = getLabelForLane(lane); - map.set(lane, label); - lane *= 2; - } - return map; - } - function markCommitStopped() { - null !== injectedProfilingHooks && - "function" === typeof injectedProfilingHooks.markCommitStopped && - injectedProfilingHooks.markCommitStopped(); - } - function markComponentRenderStarted(fiber) { - null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markComponentRenderStarted && - injectedProfilingHooks.markComponentRenderStarted(fiber); - } - function markComponentRenderStopped() { - null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markComponentRenderStopped && - injectedProfilingHooks.markComponentRenderStopped(); - } - function markComponentLayoutEffectUnmountStarted(fiber) { - null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markComponentLayoutEffectUnmountStarted && - injectedProfilingHooks.markComponentLayoutEffectUnmountStarted(fiber); - } - function markComponentLayoutEffectUnmountStopped() { - null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markComponentLayoutEffectUnmountStopped && - injectedProfilingHooks.markComponentLayoutEffectUnmountStopped(); - } - function markRenderStarted(lanes) { - null !== injectedProfilingHooks && - "function" === typeof injectedProfilingHooks.markRenderStarted && - injectedProfilingHooks.markRenderStarted(lanes); - } - function markRenderStopped() { - null !== injectedProfilingHooks && - "function" === typeof injectedProfilingHooks.markRenderStopped && - injectedProfilingHooks.markRenderStopped(); - } - function markStateUpdateScheduled(fiber, lane) { - null !== injectedProfilingHooks && - "function" === typeof injectedProfilingHooks.markStateUpdateScheduled && - injectedProfilingHooks.markStateUpdateScheduled(fiber, lane); - } - function clz32Fallback(x) { - x >>>= 0; - return 0 === x ? 32 : (31 - ((log(x) / LN2) | 0)) | 0; - } - function getLabelForLane(lane) { - if (lane & SyncHydrationLane) return "SyncHydrationLane"; - if (lane & SyncLane) return "Sync"; - if (lane & InputContinuousHydrationLane) - return "InputContinuousHydration"; - if (lane & InputContinuousLane) return "InputContinuous"; - if (lane & DefaultHydrationLane) return "DefaultHydration"; - if (lane & DefaultLane) return "Default"; - if (lane & TransitionHydrationLane) return "TransitionHydration"; - if (lane & TransitionLanes) return "Transition"; - if (lane & RetryLanes) return "Retry"; - if (lane & SelectiveHydrationLane) return "SelectiveHydration"; - if (lane & IdleHydrationLane) return "IdleHydration"; - if (lane & IdleLane) return "Idle"; - if (lane & OffscreenLane) return "Offscreen"; - if (lane & DeferredLane) return "Deferred"; - } - function getHighestPriorityLanes(lanes) { - var pendingSyncLanes = lanes & SyncUpdateLanes; - if (0 !== pendingSyncLanes) return pendingSyncLanes; - switch (lanes & -lanes) { - case SyncHydrationLane: - return SyncHydrationLane; - case SyncLane: - return SyncLane; - case InputContinuousHydrationLane: - return InputContinuousHydrationLane; - case InputContinuousLane: - return InputContinuousLane; - case DefaultHydrationLane: - return DefaultHydrationLane; - case DefaultLane: - return DefaultLane; - case TransitionHydrationLane: - return TransitionHydrationLane; - 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 & TransitionLanes; - case 4194304: - case 8388608: - case 16777216: - case 33554432: - return lanes & RetryLanes; - case SelectiveHydrationLane: - return SelectiveHydrationLane; - case IdleHydrationLane: - return IdleHydrationLane; - case IdleLane: - return IdleLane; - case OffscreenLane: - return OffscreenLane; - case DeferredLane: - return 0; - default: - return ( - error$jscomp$0( - "Should have found matching lanes. This is a bug in React." - ), - lanes + + if (!pluginModule.extractEvents) { + throw new Error( + "EventPluginRegistry: Event plugins must implement an `extractEvents` " + + ("method, but `" + pluginName + "` does not.") ); + } + + plugins[pluginIndex] = pluginModule; + var publishedEvents = pluginModule.eventTypes; + + for (var eventName in publishedEvents) { + if ( + !publishEventForPlugin( + publishedEvents[eventName], + pluginModule, + eventName + ) + ) { + throw new Error( + "EventPluginRegistry: Failed to publish event `" + + eventName + + "` for plugin `" + + pluginName + + "`." + ); + } + } } } - function getNextLanes(root, wipLanes) { - var pendingLanes = root.pendingLanes; - if (0 === pendingLanes) return 0; - var nextLanes = 0, - suspendedLanes = root.suspendedLanes; - root = root.pingedLanes; - var nonIdlePendingLanes = pendingLanes & 134217727; - 0 !== nonIdlePendingLanes - ? ((pendingLanes = nonIdlePendingLanes & ~suspendedLanes), - 0 !== pendingLanes - ? (nextLanes = getHighestPriorityLanes(pendingLanes)) - : ((root &= nonIdlePendingLanes), - 0 !== root && (nextLanes = getHighestPriorityLanes(root)))) - : ((pendingLanes &= ~suspendedLanes), - 0 !== pendingLanes - ? (nextLanes = getHighestPriorityLanes(pendingLanes)) - : 0 !== root && (nextLanes = getHighestPriorityLanes(root))); - return 0 === nextLanes - ? 0 - : 0 !== wipLanes && - wipLanes !== nextLanes && - 0 === (wipLanes & suspendedLanes) && - ((suspendedLanes = nextLanes & -nextLanes), - (root = wipLanes & -wipLanes), - suspendedLanes >= root || - (suspendedLanes === DefaultLane && 0 !== (root & TransitionLanes))) - ? wipLanes - : nextLanes; - } - function computeExpirationTime(lane, currentTime) { - switch (lane) { - case SyncHydrationLane: - case SyncLane: - case InputContinuousHydrationLane: - case InputContinuousLane: - return currentTime + 250; - case DefaultHydrationLane: - case DefaultLane: - case TransitionHydrationLane: - 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: - return -1; - case SelectiveHydrationLane: - case IdleHydrationLane: - case IdleLane: - case OffscreenLane: - case DeferredLane: - return -1; - default: - return ( - error$jscomp$0( - "Should have found matching lanes. This is a bug in React." - ), - -1 - ); + /** + * Publishes an event so that it can be dispatched by the supplied plugin. + * + * @param {object} dispatchConfig Dispatch configuration for the event. + * @param {object} PluginModule Plugin publishing the event. + * @return {boolean} True if the event was successfully published. + * @private + */ + + function publishEventForPlugin(dispatchConfig, pluginModule, eventName) { + if (eventNameDispatchConfigs.hasOwnProperty(eventName)) { + throw new Error( + "EventPluginRegistry: More than one plugin attempted to publish the same " + + ("event name, `" + eventName + "`.") + ); } - } - function getLanesToRetrySynchronouslyOnError( - root, - originallyAttemptedLanes - ) { - if (root.errorRecoveryDisabledLanes & originallyAttemptedLanes) return 0; - root = root.pendingLanes & ~OffscreenLane; - return 0 !== root ? root : root & OffscreenLane ? OffscreenLane : 0; - } - function claimNextTransitionLane() { - var lane = nextTransitionLane; - nextTransitionLane <<= 1; - 0 === (nextTransitionLane & TransitionLanes) && - (nextTransitionLane = 128); - return lane; - } - function claimNextRetryLane() { - var lane = nextRetryLane; - nextRetryLane <<= 1; - 0 === (nextRetryLane & RetryLanes) && (nextRetryLane = 4194304); - return lane; - } - function createLaneMap(initial) { - for (var laneMap = [], i = 0; i < TotalLanes; i++) laneMap.push(initial); - return laneMap; - } - function markRootFinished(root, remainingLanes, spawnedLane) { - var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; - root.pendingLanes = remainingLanes; - root.suspendedLanes = 0; - root.pingedLanes = 0; - root.expiredLanes &= remainingLanes; - root.entangledLanes &= remainingLanes; - root.errorRecoveryDisabledLanes &= remainingLanes; - root.shellSuspendCounter = 0; - remainingLanes = root.entanglements; - for ( - var expirationTimes = root.expirationTimes, - hiddenUpdates = root.hiddenUpdates; - 0 < noLongerPendingLanes; - ) { - var index = 31 - clz32(noLongerPendingLanes), - lane = 1 << index; - remainingLanes[index] = 0; - expirationTimes[index] = -1; - var hiddenUpdatesForLane = hiddenUpdates[index]; - if (null !== hiddenUpdatesForLane) - for ( - hiddenUpdates[index] = null, index = 0; - index < hiddenUpdatesForLane.length; - index++ - ) { - var update = hiddenUpdatesForLane[index]; - null !== update && (update.lane &= ~OffscreenLane); + eventNameDispatchConfigs[eventName] = dispatchConfig; + var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; + + if (phasedRegistrationNames) { + for (var phaseName in phasedRegistrationNames) { + if (phasedRegistrationNames.hasOwnProperty(phaseName)) { + var phasedRegistrationName = phasedRegistrationNames[phaseName]; + publishRegistrationName(phasedRegistrationName, pluginModule); } - noLongerPendingLanes &= ~lane; + } + + return true; + } else if (dispatchConfig.registrationName) { + publishRegistrationName(dispatchConfig.registrationName, pluginModule); + return true; } - 0 !== spawnedLane && markSpawnedDeferredLane(root, spawnedLane, 0); - } - function markSpawnedDeferredLane(root, spawnedLane, entangledLanes) { - root.pendingLanes |= spawnedLane; - root.suspendedLanes &= ~spawnedLane; - var spawnedLaneIndex = 31 - clz32(spawnedLane); - root.entangledLanes |= spawnedLane; - root.entanglements[spawnedLaneIndex] = - root.entanglements[spawnedLaneIndex] | - DeferredLane | - (entangledLanes & UpdateLanes); - } - function markRootEntangled(root, entangledLanes) { - var rootEntangledLanes = (root.entangledLanes |= entangledLanes); - for (root = root.entanglements; rootEntangledLanes; ) { - var index = 31 - clz32(rootEntangledLanes), - lane = 1 << index; - (lane & entangledLanes) | (root[index] & entangledLanes) && - (root[index] |= entangledLanes); - rootEntangledLanes &= ~lane; + + return false; + } + /** + * Publishes a registration name that is used to identify dispatched events. + * + * @param {string} registrationName Registration name to add. + * @param {object} PluginModule Plugin publishing the event. + * @private + */ + + function publishRegistrationName( + registrationName, + pluginModule, + eventName + ) { + if (registrationNameModules[registrationName]) { + throw new Error( + "EventPluginRegistry: More than one plugin attempted to publish the same " + + ("registration name, `" + registrationName + "`.") + ); + } + + registrationNameModules[registrationName] = pluginModule; + + { + registrationName.toLowerCase(); } } - function addFiberToLanesMap(root, fiber, lanes) { - if (isDevToolsPresent) - for (root = root.pendingUpdatersLaneMap; 0 < lanes; ) { - var index = 31 - clz32(lanes), - lane = 1 << index; - root[index].add(fiber); - lanes &= ~lane; + /** + * Registers plugins so that they can extract and dispatch events. + */ + + /** + * Ordered list of injected plugins. + */ + + var plugins = []; + /** + * Mapping from event name to dispatch config + */ + + var eventNameDispatchConfigs = {}; + /** + * Mapping from registration name to plugin module + */ + + var registrationNameModules = {}; + + /** + * Injects an ordering of plugins (by plugin name). This allows the ordering + * to be decoupled from injection of the actual plugins so that ordering is + * always deterministic regardless of packaging, on-the-fly injection, etc. + * + * @param {array} InjectedEventPluginOrder + * @internal + */ + + function injectEventPluginOrder(injectedEventPluginOrder) { + if (eventPluginOrder) { + throw new Error( + "EventPluginRegistry: Cannot inject event plugin ordering more than " + + "once. You are likely trying to load more than one copy of React." + ); + } // Clone the ordering so it cannot be dynamically mutated. + // $FlowFixMe[method-unbinding] found when upgrading Flow + + eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder); + recomputePluginOrdering(); + } + /** + * Injects plugins to be used by plugin event system. The plugin names must be + * in the ordering injected by `injectEventPluginOrder`. + * + * Plugins can be injected as part of page initialization or on-the-fly. + * + * @param {object} injectedNamesToPlugins Map from names to plugin modules. + * @internal + */ + + function injectEventPluginsByName(injectedNamesToPlugins) { + var isOrderingDirty = false; + + for (var pluginName in injectedNamesToPlugins) { + if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) { + continue; } - } - function movePendingFibersToMemoized(root, lanes) { - if (isDevToolsPresent) - for ( - var pendingUpdatersLaneMap = root.pendingUpdatersLaneMap, - memoizedUpdaters = root.memoizedUpdaters; - 0 < lanes; + var pluginModule = injectedNamesToPlugins[pluginName]; + + if ( + !namesToPlugins.hasOwnProperty(pluginName) || + namesToPlugins[pluginName] !== pluginModule ) { - var index = 31 - clz32(lanes); - root = 1 << index; - index = pendingUpdatersLaneMap[index]; - 0 < index.size && - (index.forEach(function (fiber) { - var alternate = fiber.alternate; - (null !== alternate && memoizedUpdaters.has(alternate)) || - memoizedUpdaters.add(fiber); - }), - index.clear()); - lanes &= ~root; + if (namesToPlugins[pluginName]) { + throw new Error( + "EventPluginRegistry: Cannot inject two different event plugins " + + ("using the same name, `" + pluginName + "`.") + ); + } + + namesToPlugins[pluginName] = pluginModule; + isOrderingDirty = true; } + } + + if (isOrderingDirty) { + recomputePluginOrdering(); + } } - function lanesToEventPriority(lanes) { - lanes &= -lanes; - return 0 !== DiscreteEventPriority && DiscreteEventPriority < lanes - ? 0 !== ContinuousEventPriority && ContinuousEventPriority < lanes - ? 0 !== (lanes & 134217727) - ? DefaultEventPriority - : IdleEventPriority - : ContinuousEventPriority - : DiscreteEventPriority; - } - 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." - ); - } - function shim() { - throw Error( - "The current renderer does not support Resources. This error is likely caused by a bug in React. Please file an issue." - ); - } - function createTextInstance( - text, - rootContainerInstance, - hostContext, - internalInstanceHandle - ) { - hostContext.isInAParentText || - error$jscomp$0( - "Text strings must be rendered within a component." + + function getListener(inst, registrationName) { + var stateNode = inst.stateNode; + + if (stateNode === null) { + // Work in progress (ex: onload events in incremental mode). + return null; + } + + var props = getFiberCurrentPropsFromNode$1(stateNode); + + if (props === null) { + // Work in progress. + return null; + } + + var listener = props[registrationName]; + + if (listener && typeof listener !== "function") { + throw new Error( + "Expected `" + + registrationName + + "` listener to be a function, instead got a value of `" + + typeof listener + + "` type." ); - hostContext = nextReactTag; - nextReactTag += 2; - return { - node: createNode( - hostContext, - "RCTRawText", - rootContainerInstance, - { text: text }, - internalInstanceHandle - ) - }; - } - function getPublicInstance(instance) { - return null != instance.canonical && - null != instance.canonical.publicInstance - ? instance.canonical.publicInstance - : null != instance._nativeTag - ? instance - : null; - } - function resolveUpdatePriority() { - if (0 !== currentUpdatePriority) return currentUpdatePriority; - var currentEventPriority = fabricGetCurrentEventPriority - ? fabricGetCurrentEventPriority() - : null; - if (null != currentEventPriority) - switch (currentEventPriority) { - case FabricDiscretePriority: - return DiscreteEventPriority; - } - return DefaultEventPriority; - } - function cloneHiddenInstance(instance) { - var node = instance.node; - var updatePayload = diffProperties( - null, - emptyObject$1, - { style: { display: "none" } }, - instance.canonical.viewConfig.validAttributes - ); - return { - node: cloneNodeWithNewProps(node, updatePayload), - canonical: instance.canonical - }; - } - function getInstanceFromNode(node) { - return null != node.canonical && - null != node.canonical.internalInstanceHandle - ? node.canonical.internalInstanceHandle - : node; - } - function getNearestMountedFiber(fiber) { - var node = fiber, - nearestMounted = fiber; - if (fiber.alternate) for (; node.return; ) node = node.return; - else { - fiber = node; - do - (node = fiber), - 0 !== (node.flags & 4098) && (nearestMounted = node.return), - (fiber = node.return); - while (fiber); } - return 3 === node.tag ? nearestMounted : null; - } - function assertIsMounted(fiber) { - if (getNearestMountedFiber(fiber) !== fiber) - throw Error("Unable to find node on an unmounted component."); + + return listener; } - function findCurrentFiberUsingSlowPath(fiber) { - var alternate = fiber.alternate; - if (!alternate) { - alternate = getNearestMountedFiber(fiber); - if (null === alternate) - throw Error("Unable to find node on an unmounted component."); - return alternate !== fiber ? null : fiber; - } - for (var a = fiber, b = alternate; ; ) { - var parentA = a.return; - if (null === parentA) break; - var parentB = parentA.alternate; - if (null === parentB) { - b = parentA.return; - if (null !== b) { - a = b; - continue; - } - break; - } - if (parentA.child === parentB.child) { - for (parentB = parentA.child; parentB; ) { - if (parentB === a) return assertIsMounted(parentA), fiber; - if (parentB === b) return assertIsMounted(parentA), alternate; - parentB = parentB.sibling; - } - throw Error("Unable to find node on an unmounted component."); - } - if (a.return !== b.return) (a = parentA), (b = parentB); - else { - for (var didFindChild = !1, _child = parentA.child; _child; ) { - if (_child === a) { - didFindChild = !0; - a = parentA; - b = parentB; - break; - } - if (_child === b) { - didFindChild = !0; - b = parentA; - a = parentB; - break; - } - _child = _child.sibling; - } - if (!didFindChild) { - for (_child = parentB.child; _child; ) { - if (_child === a) { - didFindChild = !0; - a = parentB; - b = parentA; - break; - } - if (_child === b) { - didFindChild = !0; - b = parentB; - a = parentA; - break; - } - _child = _child.sibling; - } - if (!didFindChild) - throw Error( - "Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue." - ); - } + + var customBubblingEventTypes = + ReactNativePrivateInterface.ReactNativeViewConfigRegistry + .customBubblingEventTypes, + customDirectEventTypes = + ReactNativePrivateInterface.ReactNativeViewConfigRegistry + .customDirectEventTypes; // Start of inline: the below functions were inlined from + // EventPropagator.js, as they deviated from ReactDOM's newer + // implementations. + // $FlowFixMe[missing-local-annot] + + function listenerAtPhase(inst, event, propagationPhase) { + var registrationName = + event.dispatchConfig.phasedRegistrationNames[propagationPhase]; + return getListener(inst, registrationName); + } // $FlowFixMe[missing-local-annot] + + function accumulateDirectionalDispatches(inst, phase, event) { + { + if (!inst) { + error("Dispatching inst must not be null"); } - if (a.alternate !== b) - throw Error( - "Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue." - ); } - if (3 !== a.tag) - throw Error("Unable to find node on an unmounted component."); - return a.stateNode.current === a ? fiber : alternate; - } - function findCurrentHostFiber(parent) { - parent = findCurrentFiberUsingSlowPath(parent); - return null !== parent ? findCurrentHostFiberImpl(parent) : null; - } - function findCurrentHostFiberImpl(node) { - var tag = node.tag; - if (5 === tag || 26 === tag || 27 === tag || 6 === tag) return node; - for (node = node.child; null !== node; ) { - tag = findCurrentHostFiberImpl(node); - if (null !== tag) return tag; - node = node.sibling; + + var listener = listenerAtPhase(inst, event, phase); + + if (listener) { + event._dispatchListeners = accumulateInto( + event._dispatchListeners, + listener + ); + event._dispatchInstances = accumulateInto( + event._dispatchInstances, + inst + ); + } + } // $FlowFixMe[missing-local-annot] + + function getParent(inst) { + do { + inst = inst.return; // TODO: If this is a HostRoot we might want to bail out. + // That is depending on if we want nested subtrees (layers) to bubble + // events to their parent. We could also go through parentNode on the + // host node but that wouldn't work for React Native and doesn't let us + // do the portal feature. + } while (inst && inst.tag !== HostComponent); + + if (inst) { + return inst; } + return null; } - function doesFiberContain(parentFiber, childFiber) { - for ( - var parentFiberAlternate = parentFiber.alternate; - null !== childFiber; + /** + * Simulates the traversal of a two-phase, capture/bubble event dispatch. + */ - ) { - if (childFiber === parentFiber || childFiber === parentFiberAlternate) - return !0; - childFiber = childFiber.return; + function traverseTwoPhase(inst, fn, arg, skipBubbling) { + var path = []; + + while (inst) { + path.push(inst); + inst = getParent(inst); } - return !1; - } - function createCursor(defaultValue) { - return { current: defaultValue }; - } - function pop(cursor, fiber) { - 0 > index$jscomp$0 - ? error$jscomp$0("Unexpected pop.") - : (fiber !== fiberStack[index$jscomp$0] && - error$jscomp$0("Unexpected Fiber popped."), - (cursor.current = valueStack[index$jscomp$0]), - (valueStack[index$jscomp$0] = null), - (fiberStack[index$jscomp$0] = null), - index$jscomp$0--); - } - function push(cursor, value, fiber) { - index$jscomp$0++; - valueStack[index$jscomp$0] = cursor.current; - fiberStack[index$jscomp$0] = fiber; - cursor.current = value; - } - function is(x, y) { - return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y); - } - function createCapturedValueAtFiber(value, source) { - if ("object" === typeof value && null !== value) { - var stack = CapturedStacks.get(value); - "string" !== typeof stack && - ((stack = getStackByFiberInDevAndProd(source)), - CapturedStacks.set(value, stack)); - } else stack = getStackByFiberInDevAndProd(source); - return { value: value, source: source, stack: stack }; - } - function requiredContext(c) { - null === c && - error$jscomp$0( - "Expected host context to exist. This error is likely caused by a bug in React. Please file an issue." - ); - return c; - } - function pushHostContainer(fiber, nextRootInstance) { - push(rootInstanceStackCursor, nextRootInstance, fiber); - push(contextFiberStackCursor, fiber, fiber); - push(contextStackCursor, null, fiber); - nextRootInstance = { isInAParentText: !1 }; - pop(contextStackCursor, fiber); - push(contextStackCursor, nextRootInstance, fiber); - } - function popHostContainer(fiber) { - pop(contextStackCursor, fiber); - pop(contextFiberStackCursor, fiber); - pop(rootInstanceStackCursor, fiber); - } - function pushHostContext(fiber) { - null !== fiber.memoizedState && - push(hostTransitionProviderCursor, fiber, fiber); - var context = requiredContext(contextStackCursor.current); - var nextContext = fiber.type; - nextContext = - "AndroidTextInput" === nextContext || - "RCTMultilineTextInputView" === nextContext || - "RCTSinglelineTextInputView" === nextContext || - "RCTText" === nextContext || - "RCTVirtualText" === nextContext; - nextContext = - context.isInAParentText !== nextContext - ? { isInAParentText: nextContext } - : context; - context !== nextContext && - (push(contextFiberStackCursor, fiber, fiber), - push(contextStackCursor, nextContext, fiber)); - } - function popHostContext(fiber) { - contextFiberStackCursor.current === fiber && - (pop(contextStackCursor, fiber), pop(contextFiberStackCursor, fiber)); - hostTransitionProviderCursor.current === fiber && - (pop(hostTransitionProviderCursor, fiber), - (HostTransitionContext._currentValue2 = null)); - } - function findNotableNode(node, indent) { - return void 0 === node.serverProps && - 0 === node.serverTail.length && - 1 === node.children.length && - 3 < node.distanceFromLeaf && - node.distanceFromLeaf > 15 - indent - ? findNotableNode(node.children[0], indent) - : node; - } - function indentation(indent) { - return " " + " ".repeat(indent); - } - function added(indent) { - return "+ " + " ".repeat(indent); - } - function removed(indent) { - return "- " + " ".repeat(indent); - } - function describeFiberType(fiber) { - switch (fiber.tag) { - case 26: - case 27: - case 5: - return fiber.type; - case 16: - return "Lazy"; - case 13: - return "Suspense"; - case 19: - return "SuspenseList"; - case 0: - case 15: - return (fiber = fiber.type), fiber.displayName || fiber.name || null; - case 11: - return ( - (fiber = fiber.type.render), fiber.displayName || fiber.name || null - ); - case 1: - return (fiber = fiber.type), fiber.displayName || fiber.name || null; - default: - return null; + + var i; + + for (i = path.length; i-- > 0; ) { + fn(path[i], "captured", arg); } - } - function describeTextNode(content, maxLength) { - return needsEscaping.test(content) - ? ((content = JSON.stringify(content)), - content.length > maxLength - 2 - ? 8 > maxLength - ? '{"..."}' - : "{" + content.slice(0, maxLength - 7) + '..."}' - : "{" + content + "}") - : content.length > maxLength - ? 5 > maxLength - ? '{"..."}' - : content.slice(0, maxLength - 3) + "..." - : content; - } - function describeTextDiff(clientText, serverProps, indent) { - var maxLength = 120 - 2 * indent; - if (null === serverProps) - return added(indent) + describeTextNode(clientText, maxLength) + "\n"; - if ("string" === typeof serverProps) { - for ( - var firstDiff = 0; - firstDiff < serverProps.length && - firstDiff < clientText.length && - serverProps.charCodeAt(firstDiff) === - clientText.charCodeAt(firstDiff); - firstDiff++ + + if (skipBubbling) { + // Dispatch on target only + fn(path[0], "bubbled", arg); + } else { + for (i = 0; i < path.length; i++) { + fn(path[i], "bubbled", arg); + } + } + } // $FlowFixMe[missing-local-annot] + + function accumulateTwoPhaseDispatchesSingle(event) { + if (event && event.dispatchConfig.phasedRegistrationNames) { + traverseTwoPhase( + event._targetInst, + accumulateDirectionalDispatches, + event, + false ); - firstDiff > maxLength - 8 && - 10 < firstDiff && - ((clientText = "..." + clientText.slice(firstDiff - 8)), - (serverProps = "..." + serverProps.slice(firstDiff - 8))); - return ( - added(indent) + - describeTextNode(clientText, maxLength) + - "\n" + - removed(indent) + - describeTextNode(serverProps, maxLength) + - "\n" + } + } // $FlowFixMe[missing-local-annot] + + function accumulateTwoPhaseDispatches(events) { + forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle); + } // $FlowFixMe[missing-local-annot] + + function accumulateCapturePhaseDispatches(event) { + if (event && event.dispatchConfig.phasedRegistrationNames) { + traverseTwoPhase( + event._targetInst, + accumulateDirectionalDispatches, + event, + true ); } - return ( - indentation(indent) + describeTextNode(clientText, maxLength) + "\n" - ); } - function objectName(object) { - return Object.prototype.toString - .call(object) - .replace(/^\[object (.*)\]$/, function (m, p0) { - return p0; - }); - } - function describeValue(value, maxLength) { - switch (typeof value) { - case "string": - return ( - (value = JSON.stringify(value)), - value.length > maxLength - ? 5 > maxLength - ? '"..."' - : value.slice(0, maxLength - 4) + '..."' - : value - ); - case "object": - if (null === value) return "null"; - if (isArrayImpl(value)) return "[...]"; - if (value.$$typeof === REACT_ELEMENT_TYPE) - return (maxLength = getComponentNameFromType(value.type)) - ? "<" + maxLength + ">" - : "<...>"; - var name = objectName(value); - if ("Object" === name) { - name = ""; - maxLength -= 2; - for (var propName in value) - if (value.hasOwnProperty(propName)) { - var jsonPropName = JSON.stringify(propName); - jsonPropName !== '"' + propName + '"' && - (propName = jsonPropName); - maxLength -= propName.length - 2; - jsonPropName = describeValue( - value[propName], - 15 > maxLength ? maxLength : 15 - ); - maxLength -= jsonPropName.length; - if (0 > maxLength) { - name += "" === name ? "..." : ", ..."; - break; - } - name += - ("" === name ? "" : ",") + propName + ":" + jsonPropName; - } - return "{" + name + "}"; - } - return name; - case "function": - return (maxLength = value.displayName || value.name) - ? "function " + maxLength - : "function"; - default: - return String(value); - } - } - function describePropValue(value, maxLength) { - return "string" !== typeof value || needsEscaping.test(value) - ? "{" + describeValue(value, maxLength - 2) + "}" - : value.length > maxLength - 2 - ? 5 > maxLength - ? '"..."' - : '"' + value.slice(0, maxLength - 5) + '..."' - : '"' + value + '"'; - } - function describeExpandedElement(type, props, rowPrefix) { - var remainingRowLength = 120 - rowPrefix.length - type.length, - properties = [], - propName; - for (propName in props) - if (props.hasOwnProperty(propName) && "children" !== propName) { - var propValue = describePropValue( - props[propName], - 120 - rowPrefix.length - propName.length - 1 + /** + * Accumulates without regard to direction, does not look for phased + * registration names. Same as `accumulateDirectDispatchesSingle` but without + * requiring that the `dispatchMarker` be the same as the dispatched ID. + */ + + function accumulateDispatches(inst, ignoredDirection, event) { + if (inst && event && event.dispatchConfig.registrationName) { + var registrationName = event.dispatchConfig.registrationName; + var listener = getListener(inst, registrationName); + + if (listener) { + event._dispatchListeners = accumulateInto( + event._dispatchListeners, + listener ); - remainingRowLength -= propName.length + propValue.length + 2; - properties.push(propName + "=" + propValue); - } - return 0 === properties.length - ? rowPrefix + "<" + type + ">\n" - : 0 < remainingRowLength - ? rowPrefix + "<" + type + " " + properties.join(" ") + ">\n" - : rowPrefix + - "<" + - type + - "\n" + - rowPrefix + - " " + - properties.join("\n" + rowPrefix + " ") + - "\n" + - rowPrefix + - ">\n"; - } - function describePropertiesDiff(clientObject, serverObject, indent) { - var properties = "", - remainingServerProperties = assign({}, serverObject), - propName; - for (propName in clientObject) - if (clientObject.hasOwnProperty(propName)) { - delete remainingServerProperties[propName]; - var maxLength = 120 - 2 * indent - propName.length - 2, - clientPropValue = describeValue(clientObject[propName], maxLength); - serverObject.hasOwnProperty(propName) - ? ((maxLength = describeValue(serverObject[propName], maxLength)), - (properties += - added(indent) + propName + ": " + clientPropValue + "\n"), - (properties += - removed(indent) + propName + ": " + maxLength + "\n")) - : (properties += - added(indent) + propName + ": " + clientPropValue + "\n"); - } - for (var _propName in remainingServerProperties) - remainingServerProperties.hasOwnProperty(_propName) && - ((clientObject = describeValue( - remainingServerProperties[_propName], - 120 - 2 * indent - _propName.length - 2 - )), - (properties += - removed(indent) + _propName + ": " + clientObject + "\n")); - return properties; - } - function describeElementDiff(type, clientProps, serverProps, indent) { - var content = "", - serverPropNames = new Map(); - for (propName$jscomp$0 in serverProps) - serverProps.hasOwnProperty(propName$jscomp$0) && - serverPropNames.set( - propName$jscomp$0.toLowerCase(), - propName$jscomp$0 + event._dispatchInstances = accumulateInto( + event._dispatchInstances, + inst ); - if (1 === serverPropNames.size && serverPropNames.has("children")) - content += describeExpandedElement( - type, - clientProps, - indentation(indent) - ); - else { - for (var _propName2 in clientProps) - if ( - clientProps.hasOwnProperty(_propName2) && - "children" !== _propName2 - ) { - var maxLength$jscomp$0 = - 120 - 2 * (indent + 1) - _propName2.length - 1, - serverPropName = serverPropNames.get(_propName2.toLowerCase()); - if (void 0 !== serverPropName) { - serverPropNames.delete(_propName2.toLowerCase()); - var propName$jscomp$0 = clientProps[_propName2]; - serverPropName = serverProps[serverPropName]; - var clientPropValue = describePropValue( - propName$jscomp$0, - maxLength$jscomp$0 - ); - maxLength$jscomp$0 = describePropValue( - serverPropName, - maxLength$jscomp$0 - ); - "object" === typeof propName$jscomp$0 && - null !== propName$jscomp$0 && - "object" === typeof serverPropName && - null !== serverPropName && - "Object" === objectName(propName$jscomp$0) && - "Object" === objectName(serverPropName) && - (2 < Object.keys(propName$jscomp$0).length || - 2 < Object.keys(serverPropName).length || - -1 < clientPropValue.indexOf("...") || - -1 < maxLength$jscomp$0.indexOf("...")) - ? (content += - indentation(indent + 1) + - _propName2 + - "={{\n" + - describePropertiesDiff( - propName$jscomp$0, - serverPropName, - indent + 2 - ) + - indentation(indent + 1) + - "}}\n") - : ((content += - added(indent + 1) + - _propName2 + - "=" + - clientPropValue + - "\n"), - (content += - removed(indent + 1) + - _propName2 + - "=" + - maxLength$jscomp$0 + - "\n")); - } else - content += - indentation(indent + 1) + - _propName2 + - "=" + - describePropValue(clientProps[_propName2], maxLength$jscomp$0) + - "\n"; - } - serverPropNames.forEach(function (propName) { - if ("children" !== propName) { - var maxLength = 120 - 2 * (indent + 1) - propName.length - 1; - content += - removed(indent + 1) + - propName + - "=" + - describePropValue(serverProps[propName], maxLength) + - "\n"; - } - }); - content = - "" === content - ? indentation(indent) + "<" + type + ">\n" - : indentation(indent) + - "<" + - type + - "\n" + - content + - indentation(indent) + - ">\n"; - } - type = serverProps.children; - clientProps = clientProps.children; - if ( - "string" === typeof type || - "number" === typeof type || - "bigint" === typeof type - ) { - serverPropNames = ""; - if ( - "string" === typeof clientProps || - "number" === typeof clientProps || - "bigint" === typeof clientProps - ) - serverPropNames = "" + clientProps; - content += describeTextDiff(serverPropNames, "" + type, indent + 1); - } else if ( - "string" === typeof clientProps || - "number" === typeof clientProps || - "bigint" === typeof clientProps - ) - content += describeTextDiff("" + clientProps, void 0, indent + 1); - return content; - } - function describeSiblingFiber(fiber, indent) { - var type = describeFiberType(fiber); - if (null === type) { - type = ""; - for (fiber = fiber.child; fiber; ) - (type += describeSiblingFiber(fiber, indent)), - (fiber = fiber.sibling); - return type; + } } - return indentation(indent) + "<" + type + ">\n"; } - function describeNode(node, indent) { - var skipToNode = findNotableNode(node, indent); - if ( - skipToNode !== node && - (1 !== node.children.length || node.children[0] !== skipToNode) - ) - return ( - indentation(indent) + "...\n" + describeNode(skipToNode, indent + 1) - ); - skipToNode = ""; - var debugInfo = node.fiber._debugInfo; - if (debugInfo) - for (var i = 0; i < debugInfo.length; i++) { - var serverComponentName = debugInfo[i].name; - "string" === typeof serverComponentName && - ((skipToNode += - indentation(indent) + "<" + serverComponentName + ">\n"), - indent++); - } - debugInfo = ""; - i = node.fiber.pendingProps; - if (6 === node.fiber.tag) - debugInfo = describeTextDiff(i, node.serverProps, indent); - else if ( - ((serverComponentName = describeFiberType(node.fiber)), - null !== serverComponentName) - ) - if (void 0 === node.serverProps) { - debugInfo = indent; - var maxLength = 120 - 2 * debugInfo - serverComponentName.length - 2, - content = ""; - for (propName in i) - if (i.hasOwnProperty(propName) && "children" !== propName) { - var propValue = describePropValue(i[propName], 15); - maxLength -= propName.length + propValue.length + 2; - if (0 > maxLength) { - content += " ..."; - break; - } - content += " " + propName + "=" + propValue; - } - debugInfo = - indentation(debugInfo) + - "<" + - serverComponentName + - content + - ">\n"; - indent++; - } else - null === node.serverProps - ? (debugInfo = describeExpandedElement( - serverComponentName, - i, - added(indent) - )) - : "string" === typeof node.serverProps - ? error$jscomp$0( - "Should not have matched a non HostText fiber to a Text node. This is a bug in React." - ) - : ((debugInfo = describeElementDiff( - serverComponentName, - i, - node.serverProps, - indent - )), - indent++); - var propName = ""; - i = node.fiber.child; - for ( - serverComponentName = 0; - i && serverComponentName < node.children.length; - - ) - (maxLength = node.children[serverComponentName]), - maxLength.fiber === i - ? ((propName += describeNode(maxLength, indent)), - serverComponentName++) - : (propName += describeSiblingFiber(i, indent)), - (i = i.sibling); - i && - 0 < node.children.length && - (propName += indentation(indent) + "...\n"); - node = node.serverTail; - for (i = 0; i < node.length; i++) - (serverComponentName = node[i]), - (propName = - "string" === typeof serverComponentName - ? propName + - (removed(indent) + - describeTextNode(serverComponentName, 120 - 2 * indent) + - "\n") - : propName + - describeExpandedElement( - serverComponentName.type, - serverComponentName.props, - removed(indent) - )); - return skipToNode + debugInfo + propName; + /** + * Accumulates dispatches on an `SyntheticEvent`, but only for the + * `dispatchMarker`. + * @param {SyntheticEvent} event + */ + + function accumulateDirectDispatchesSingle(event) { + if (event && event.dispatchConfig.registrationName) { + accumulateDispatches(event._targetInst, null, event); + } } - function finishQueueingConcurrentUpdates() { - for ( - var endIndex = concurrentQueuesIndex, - i = (concurrentlyUpdatedLanes = concurrentQueuesIndex = 0); - i < endIndex; + function accumulateDirectDispatches(events) { + forEachAccumulated(events, accumulateDirectDispatchesSingle); + } // End of inline + + var ReactNativeBridgeEventPlugin = { + eventTypes: {}, + extractEvents: function ( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget ) { - var fiber = concurrentQueues[i]; - concurrentQueues[i++] = null; - var queue = concurrentQueues[i]; - concurrentQueues[i++] = null; - var update = concurrentQueues[i]; - concurrentQueues[i++] = null; - var lane = concurrentQueues[i]; - concurrentQueues[i++] = null; - if (null !== queue && null !== update) { - var pending = queue.pending; - null === pending - ? (update.next = update) - : ((update.next = pending.next), (pending.next = update)); - queue.pending = update; + if (targetInst == null) { + // Probably a node belonging to another renderer's tree. + return null; } - 0 !== lane && markUpdateLaneFromFiberToRoot(fiber, update, lane); - } - } - function enqueueUpdate$1(fiber, queue, update, lane) { - concurrentQueues[concurrentQueuesIndex++] = fiber; - concurrentQueues[concurrentQueuesIndex++] = queue; - concurrentQueues[concurrentQueuesIndex++] = update; - concurrentQueues[concurrentQueuesIndex++] = lane; - concurrentlyUpdatedLanes |= lane; - fiber.lanes |= lane; - fiber = fiber.alternate; - null !== fiber && (fiber.lanes |= lane); - } - function enqueueConcurrentHookUpdate(fiber, queue, update, lane) { - enqueueUpdate$1(fiber, queue, update, lane); - return getRootForUpdatedFiber(fiber); - } - function enqueueConcurrentRenderForLane(fiber, lane) { - enqueueUpdate$1(fiber, null, null, lane); - return getRootForUpdatedFiber(fiber); - } - function markUpdateLaneFromFiberToRoot(sourceFiber, update, lane) { - sourceFiber.lanes |= lane; - var alternate = sourceFiber.alternate; - null !== alternate && (alternate.lanes |= lane); - for (var isHidden = !1, parent = sourceFiber.return; null !== parent; ) - (parent.childLanes |= lane), - (alternate = parent.alternate), - null !== alternate && (alternate.childLanes |= lane), - 22 === parent.tag && - ((sourceFiber = parent.stateNode), - null === sourceFiber || - sourceFiber._visibility & 1 || - (isHidden = !0)), - (sourceFiber = parent), - (parent = parent.return); - isHidden && - null !== update && - 3 === sourceFiber.tag && - ((parent = sourceFiber.stateNode), - (isHidden = 31 - clz32(lane)), - (parent = parent.hiddenUpdates), - (sourceFiber = parent[isHidden]), - null === sourceFiber - ? (parent[isHidden] = [update]) - : sourceFiber.push(update), - (update.lane = lane | OffscreenLane)); - } - function getRootForUpdatedFiber(sourceFiber) { - throwIfInfiniteUpdateLoopDetected(); - null === sourceFiber.alternate && - 0 !== (sourceFiber.flags & 4098) && - warnAboutUpdateOnNotYetMountedFiberInDEV(sourceFiber); - for (var node = sourceFiber, parent = node.return; null !== parent; ) - null === node.alternate && - 0 !== (node.flags & 4098) && - warnAboutUpdateOnNotYetMountedFiberInDEV(sourceFiber), - (node = parent), - (parent = node.return); - return 3 === node.tag ? node.stateNode : null; - } - function ensureRootIsScheduled(root) { - root !== lastScheduledRoot && - null === root.next && - (null === lastScheduledRoot - ? (firstScheduledRoot = lastScheduledRoot = root) - : (lastScheduledRoot = lastScheduledRoot.next = root)); - mightHavePendingSyncWork = !0; - null !== ReactSharedInternals.actQueue - ? didScheduleMicrotask_act || - ((didScheduleMicrotask_act = !0), - scheduleImmediateTask(processRootScheduleInMicrotask)) - : didScheduleMicrotask || - ((didScheduleMicrotask = !0), - scheduleImmediateTask(processRootScheduleInMicrotask)); - ReactSharedInternals.isBatchingLegacy && - 0 === root.tag && - (ReactSharedInternals.didScheduleLegacyUpdate = !0); - } - function flushSyncWorkAcrossRoots_impl(onlyLegacy) { - if (!isFlushingWork && mightHavePendingSyncWork) { - isFlushingWork = !0; - do { - var didPerformSomeWork = !1; - for (var root = firstScheduledRoot; null !== root; ) { - if (!onlyLegacy || 0 === root.tag) { - var workInProgressRootRenderLanes$jscomp$0 = - workInProgressRootRenderLanes; - workInProgressRootRenderLanes$jscomp$0 = getNextLanes( - root, - root === workInProgressRoot - ? workInProgressRootRenderLanes$jscomp$0 - : 0 - ); - 0 !== - (workInProgressRootRenderLanes$jscomp$0 & - (SyncLane | SyncHydrationLane)) && - ((didPerformSomeWork = !0), - performSyncWorkOnRoot( - root, - workInProgressRootRenderLanes$jscomp$0 - )); - } - root = root.next; + + var bubbleDispatchConfig = customBubblingEventTypes[topLevelType]; + var directDispatchConfig = customDirectEventTypes[topLevelType]; + + if (!bubbleDispatchConfig && !directDispatchConfig) { + throw new Error( // $FlowFixMe[incompatible-type] - Flow doesn't like this string coercion because DOMTopLevelEventType is opaque + 'Unsupported top level event type "' + topLevelType + '" dispatched' + ); + } + + var event = SyntheticEvent.getPooled( + bubbleDispatchConfig || directDispatchConfig, + targetInst, + nativeEvent, + nativeEventTarget + ); + + if (bubbleDispatchConfig) { + var skipBubbling = + event != null && + event.dispatchConfig.phasedRegistrationNames != null && + event.dispatchConfig.phasedRegistrationNames.skipBubbling; + + if (skipBubbling) { + accumulateCapturePhaseDispatches(event); + } else { + accumulateTwoPhaseDispatches(event); } - } while (didPerformSomeWork); - isFlushingWork = !1; + } else if (directDispatchConfig) { + accumulateDirectDispatches(event); + } else { + return null; + } + + return event; } - } - function processRootScheduleInMicrotask() { - mightHavePendingSyncWork = - didScheduleMicrotask_act = - didScheduleMicrotask = - !1; - for ( - var currentTime = now$1(), prev = null, root = firstScheduledRoot; - null !== root; + }; - ) { - var next = root.next, - nextLanes = scheduleTaskForRootDuringMicrotask(root, currentTime); - 0 === nextLanes - ? ((root.next = null), - null === prev ? (firstScheduledRoot = next) : (prev.next = next), - null === next && (lastScheduledRoot = prev)) - : ((prev = root), - 0 !== (nextLanes & (SyncLane | SyncHydrationLane)) && - (mightHavePendingSyncWork = !0)); - root = next; + var ReactNativeEventPluginOrder = [ + "ResponderEventPlugin", + "ReactNativeBridgeEventPlugin" + ]; + + /** + * Make sure essential globals are available and are patched correctly. Please don't remove this + * line. Bundles created by react-packager `require` it before executing any application code. This + * ensures it exists in the dependency graph and can be `require`d. + * TODO: require this in packager, not in React #10932517 + */ + /** + * Inject module for resolving DOM hierarchy and plugin ordering. + */ + + injectEventPluginOrder(ReactNativeEventPluginOrder); + /** + * Some important event plugins included by default (without having to require + * them). + */ + + injectEventPluginsByName({ + ResponderEventPlugin: ResponderEventPlugin, + ReactNativeBridgeEventPlugin: ReactNativeBridgeEventPlugin + }); + + // Modules provided by RN: + var emptyObject$1 = {}; + /** + * Create a payload that contains all the updates between two sets of props. + * + * These helpers are all encapsulated into a single module, because they use + * mutation as a performance optimization which leads to subtle shared + * dependencies between the code paths. To avoid this mutable state leaking + * across modules, I've kept them isolated to this module. + */ + // Tracks removed keys + + var removedKeys = null; + var removedKeyCount = 0; + var deepDifferOptions = { + unsafelyIgnoreFunctions: true + }; + + function defaultDiffer(prevProp, nextProp) { + if (typeof nextProp !== "object" || nextProp === null) { + // Scalars have already been checked for equality + return true; + } else { + // For objects and arrays, the default diffing algorithm is a deep compare + return ReactNativePrivateInterface.deepDiffer( + prevProp, + nextProp, + deepDifferOptions + ); } - currentEventTransitionLane = 0; - flushSyncWorkAcrossRoots_impl(!1); } - function scheduleTaskForRootDuringMicrotask(root, currentTime) { - for ( - var suspendedLanes = root.suspendedLanes, - pingedLanes = root.pingedLanes, - expirationTimes = root.expirationTimes, - lanes = root.pendingLanes & ~RetryLanes; - 0 < lanes; - ) { - var index = 31 - clz32(lanes), - lane = 1 << index, - expirationTime = expirationTimes[index]; - if (-1 === expirationTime) { - if (0 === (lane & suspendedLanes) || 0 !== (lane & pingedLanes)) - expirationTimes[index] = computeExpirationTime(lane, currentTime); - } else expirationTime <= currentTime && (root.expiredLanes |= lane); - lanes &= ~lane; + function restoreDeletedValuesInNestedArray( + updatePayload, + node, + validAttributes + ) { + if (isArray(node)) { + var i = node.length; + + while (i-- && removedKeyCount > 0) { + restoreDeletedValuesInNestedArray( + updatePayload, + node[i], + validAttributes + ); + } + } else if (node && removedKeyCount > 0) { + var obj = node; + + for (var propKey in removedKeys) { + // $FlowFixMe[incompatible-use] found when upgrading Flow + if (!removedKeys[propKey]) { + continue; + } + + var nextProp = obj[propKey]; + + if (nextProp === undefined) { + continue; + } + + var attributeConfig = validAttributes[propKey]; + + if (!attributeConfig) { + continue; // not a valid native prop + } + + if (typeof nextProp === "function") { + // $FlowFixMe[incompatible-type] found when upgrading Flow + nextProp = true; + } + + if (typeof nextProp === "undefined") { + // $FlowFixMe[incompatible-type] found when upgrading Flow + nextProp = null; + } + + if (typeof attributeConfig !== "object") { + // case: !Object is the default case + updatePayload[propKey] = nextProp; + } else if ( + typeof attributeConfig.diff === "function" || + typeof attributeConfig.process === "function" + ) { + // case: CustomAttributeConfiguration + var nextValue = + typeof attributeConfig.process === "function" + ? attributeConfig.process(nextProp) + : nextProp; + updatePayload[propKey] = nextValue; + } // $FlowFixMe[incompatible-use] found when upgrading Flow + + removedKeys[propKey] = false; + removedKeyCount--; + } } - currentTime = workInProgressRoot; - suspendedLanes = workInProgressRootRenderLanes; - suspendedLanes = getNextLanes( - root, - root === currentTime ? suspendedLanes : 0 - ); - pingedLanes = root.callbackNode; - if ( - 0 === suspendedLanes || - (root === currentTime && - workInProgressSuspendedReason === SuspendedOnData) || - null !== root.cancelPendingCommit - ) - return ( - null !== pingedLanes && cancelCallback(pingedLanes), - (root.callbackNode = null), - (root.callbackPriority = 0) + } + + function diffNestedArrayProperty( + updatePayload, + prevArray, + nextArray, + validAttributes + ) { + var minLength = + prevArray.length < nextArray.length + ? prevArray.length + : nextArray.length; + var i; + + for (i = 0; i < minLength; i++) { + // Diff any items in the array in the forward direction. Repeated keys + // will be overwritten by later values. + updatePayload = diffNestedProperty( + updatePayload, + prevArray[i], + nextArray[i], + validAttributes ); - if (0 !== (suspendedLanes & (SyncLane | SyncHydrationLane))) - return ( - null !== pingedLanes && cancelCallback(pingedLanes), - (root.callbackPriority = SyncLane), - (root.callbackNode = null), - SyncLane + } + + for (; i < prevArray.length; i++) { + // Clear out all remaining properties. + updatePayload = clearNestedProperty( + updatePayload, + prevArray[i], + validAttributes ); - currentTime = suspendedLanes & -suspendedLanes; - if ( - currentTime !== root.callbackPriority || - (null !== ReactSharedInternals.actQueue && - pingedLanes !== fakeActCallbackNode$1) - ) - cancelCallback(pingedLanes); - else return currentTime; - switch (lanesToEventPriority(suspendedLanes)) { - case DiscreteEventPriority: - suspendedLanes = ImmediatePriority; - break; - case ContinuousEventPriority: - suspendedLanes = UserBlockingPriority; - break; - case DefaultEventPriority: - suspendedLanes = NormalPriority$1; - break; - case IdleEventPriority: - suspendedLanes = IdlePriority; - break; - default: - suspendedLanes = NormalPriority$1; } - pingedLanes = performConcurrentWorkOnRoot.bind(null, root); - null !== ReactSharedInternals.actQueue - ? (ReactSharedInternals.actQueue.push(pingedLanes), - (suspendedLanes = fakeActCallbackNode$1)) - : (suspendedLanes = scheduleCallback$3(suspendedLanes, pingedLanes)); - root.callbackPriority = currentTime; - root.callbackNode = suspendedLanes; - return currentTime; - } - function cancelCallback(callbackNode) { - callbackNode !== fakeActCallbackNode$1 && - null !== callbackNode && - cancelCallback$1(callbackNode); - } - function scheduleImmediateTask(cb) { - null !== ReactSharedInternals.actQueue && - ReactSharedInternals.actQueue.push(function () { - cb(); - return null; - }); - supportsMicrotasks - ? scheduleMicrotask(function () { - (executionContext & (RenderContext | CommitContext)) !== NoContext - ? scheduleCallback$3(ImmediatePriority, cb) - : cb(); - }) - : scheduleCallback$3(ImmediatePriority, cb); - } - function requestTransitionLane() { - 0 === currentEventTransitionLane && - (currentEventTransitionLane = claimNextTransitionLane()); - return currentEventTransitionLane; - } - function entangleAsyncAction(transition, thenable) { - if (null === currentEntangledListeners) { - var entangledListeners = (currentEntangledListeners = []); - currentEntangledPendingCount = 0; - currentEntangledLane = requestTransitionLane(); - currentEntangledActionThenable = { - status: "pending", - value: void 0, - then: function (resolve) { - entangledListeners.push(resolve); - } - }; + + for (; i < nextArray.length; i++) { + // Add all remaining properties. + updatePayload = addNestedProperty( + updatePayload, + nextArray[i], + validAttributes + ); } - currentEntangledPendingCount++; - thenable.then(pingEngtangledActionScope, pingEngtangledActionScope); - return thenable; + + return updatePayload; } - function pingEngtangledActionScope() { - if ( - null !== currentEntangledListeners && - 0 === --currentEntangledPendingCount - ) { - null !== currentEntangledActionThenable && - (currentEntangledActionThenable.status = "fulfilled"); - var listeners = currentEntangledListeners; - currentEntangledListeners = null; - currentEntangledLane = 0; - currentEntangledActionThenable = null; - for (var i = 0; i < listeners.length; i++) (0, listeners[i])(); + + function diffNestedProperty( + updatePayload, + prevProp, + nextProp, + validAttributes + ) { + if (!updatePayload && prevProp === nextProp) { + // If no properties have been added, then we can bail out quickly on object + // equality. + return updatePayload; } - } - function chainThenableValue(thenable, result) { - var listeners = [], - thenableWithOverride = { - status: "pending", - value: null, - reason: null, - then: function (resolve) { - listeners.push(resolve); - } - }; - thenable.then( - function () { - thenableWithOverride.status = "fulfilled"; - thenableWithOverride.value = result; - for (var i = 0; i < listeners.length; i++) (0, listeners[i])(result); - }, - function (error) { - thenableWithOverride.status = "rejected"; - thenableWithOverride.reason = error; - for (error = 0; error < listeners.length; error++) - (0, listeners[error])(void 0); + + if (!prevProp || !nextProp) { + if (nextProp) { + return addNestedProperty(updatePayload, nextProp, validAttributes); } - ); - return thenableWithOverride; - } - function initializeUpdateQueue(fiber) { - fiber.updateQueue = { - baseState: fiber.memoizedState, - firstBaseUpdate: null, - lastBaseUpdate: null, - shared: { pending: null, lanes: 0, hiddenCallbacks: null }, - callbacks: null - }; - } - function cloneUpdateQueue(current, workInProgress) { - current = current.updateQueue; - workInProgress.updateQueue === current && - (workInProgress.updateQueue = { - baseState: current.baseState, - firstBaseUpdate: current.firstBaseUpdate, - lastBaseUpdate: current.lastBaseUpdate, - shared: current.shared, - callbacks: null - }); - } - function createUpdate(lane) { - return { - lane: lane, - tag: UpdateState, - payload: null, - callback: null, - next: null - }; - } - function enqueueUpdate(fiber, update, lane) { - var updateQueue = fiber.updateQueue; - if (null === updateQueue) return null; - updateQueue = updateQueue.shared; - if ( - currentlyProcessingQueue === updateQueue && - !didWarnUpdateInsideUpdate - ) { - var componentName = getComponentNameFromFiber(fiber); - error$jscomp$0( - "An update (setState, replaceState, or forceUpdate) was scheduled from inside an update function. Update functions should be pure, with zero side-effects. Consider using componentDidUpdate or a callback.\n\nPlease update the following component: %s", - componentName + + if (prevProp) { + return clearNestedProperty(updatePayload, prevProp, validAttributes); + } + + return updatePayload; + } + + if (!isArray(prevProp) && !isArray(nextProp)) { + // Both are leaves, we can diff the leaves. + return diffProperties( + updatePayload, + prevProp, + nextProp, + validAttributes ); - didWarnUpdateInsideUpdate = !0; } - if ((executionContext & RenderContext) !== NoContext) - return ( - (componentName = updateQueue.pending), - null === componentName - ? (update.next = update) - : ((update.next = componentName.next), - (componentName.next = update)), - (updateQueue.pending = update), - (update = getRootForUpdatedFiber(fiber)), - markUpdateLaneFromFiberToRoot(fiber, null, lane), - update + + if (isArray(prevProp) && isArray(nextProp)) { + // Both are arrays, we can diff the arrays. + return diffNestedArrayProperty( + updatePayload, + prevProp, + nextProp, + validAttributes ); - enqueueUpdate$1(fiber, updateQueue, update, lane); - return getRootForUpdatedFiber(fiber); - } - function entangleTransitions(root, fiber, lane) { - fiber = fiber.updateQueue; - if ( - null !== fiber && - ((fiber = fiber.shared), 0 !== (lane & TransitionLanes)) - ) { - var queueLanes = fiber.lanes; - queueLanes &= root.pendingLanes; - lane |= queueLanes; - fiber.lanes = lane; - markRootEntangled(root, lane); } - } - function enqueueCapturedUpdate(workInProgress, capturedUpdate) { - var queue = workInProgress.updateQueue, - current = workInProgress.alternate; - if ( - null !== current && - ((current = current.updateQueue), queue === current) - ) { - var newFirst = null, - newLast = null; - queue = queue.firstBaseUpdate; - if (null !== queue) { - do { - var clone = { - lane: queue.lane, - tag: queue.tag, - payload: queue.payload, - callback: null, - next: null - }; - null === newLast - ? (newFirst = newLast = clone) - : (newLast = newLast.next = clone); - queue = queue.next; - } while (null !== queue); - null === newLast - ? (newFirst = newLast = capturedUpdate) - : (newLast = newLast.next = capturedUpdate); - } else newFirst = newLast = capturedUpdate; - queue = { - baseState: current.baseState, - firstBaseUpdate: newFirst, - lastBaseUpdate: newLast, - shared: current.shared, - callbacks: current.callbacks - }; - workInProgress.updateQueue = queue; - return; + + if (isArray(prevProp)) { + return diffProperties( + updatePayload, + ReactNativePrivateInterface.flattenStyle(prevProp), + nextProp, + validAttributes + ); } - workInProgress = queue.lastBaseUpdate; - null === workInProgress - ? (queue.firstBaseUpdate = capturedUpdate) - : (workInProgress.next = capturedUpdate); - queue.lastBaseUpdate = capturedUpdate; + + return diffProperties( + updatePayload, + prevProp, + ReactNativePrivateInterface.flattenStyle(nextProp), + validAttributes + ); } - function suspendIfUpdateReadFromEntangledAsyncAction() { - if (didReadFromEntangledAsyncAction) { - var entangledActionThenable = currentEntangledActionThenable; - if (null !== entangledActionThenable) throw entangledActionThenable; + /** + * addNestedProperty takes a single set of props and valid attribute + * attribute configurations. It processes each prop and adds it to the + * updatePayload. + */ + + function addNestedProperty(updatePayload, nextProp, validAttributes) { + if (!nextProp) { + return updatePayload; + } + + if (!isArray(nextProp)) { + // Add each property of the leaf. + return addProperties(updatePayload, nextProp, validAttributes); + } + + for (var i = 0; i < nextProp.length; i++) { + // Add all the properties of the array. + updatePayload = addNestedProperty( + updatePayload, + nextProp[i], + validAttributes + ); } + + return updatePayload; } - function processUpdateQueue( - workInProgress, - props, - instance$jscomp$0, - renderLanes - ) { - didReadFromEntangledAsyncAction = !1; - var queue = workInProgress.updateQueue; - hasForceUpdate = !1; - currentlyProcessingQueue = queue.shared; - var firstBaseUpdate = queue.firstBaseUpdate, - lastBaseUpdate = queue.lastBaseUpdate, - pendingQueue = queue.shared.pending; - if (null !== pendingQueue) { - queue.shared.pending = null; - var lastPendingUpdate = pendingQueue, - firstPendingUpdate = lastPendingUpdate.next; - lastPendingUpdate.next = null; - null === lastBaseUpdate - ? (firstBaseUpdate = firstPendingUpdate) - : (lastBaseUpdate.next = firstPendingUpdate); - lastBaseUpdate = lastPendingUpdate; - var current = workInProgress.alternate; - null !== current && - ((current = current.updateQueue), - (pendingQueue = current.lastBaseUpdate), - pendingQueue !== lastBaseUpdate && - (null === pendingQueue - ? (current.firstBaseUpdate = firstPendingUpdate) - : (pendingQueue.next = firstPendingUpdate), - (current.lastBaseUpdate = lastPendingUpdate))); - } - if (null !== firstBaseUpdate) { - var newState = queue.baseState; - lastBaseUpdate = 0; - current = firstPendingUpdate = lastPendingUpdate = null; - pendingQueue = firstBaseUpdate; - do { - var updateLane = pendingQueue.lane & ~OffscreenLane, - isHiddenUpdate = updateLane !== pendingQueue.lane; - if ( - isHiddenUpdate - ? (workInProgressRootRenderLanes & updateLane) === updateLane - : (renderLanes & updateLane) === updateLane - ) { - 0 !== updateLane && - updateLane === currentEntangledLane && - (didReadFromEntangledAsyncAction = !0); - null !== current && - (current = current.next = - { - lane: 0, - tag: pendingQueue.tag, - payload: pendingQueue.payload, - callback: null, - next: null - }); - a: { - updateLane = workInProgress; - var partialState = pendingQueue; - var nextProps = props, - instance = instance$jscomp$0; - switch (partialState.tag) { - case ReplaceState: - partialState = partialState.payload; - if ("function" === typeof partialState) { - isDisallowedContextReadInDEV = !0; - var nextState = partialState.call( - instance, - newState, - nextProps - ); - if (updateLane.mode & 8) { - setIsStrictModeForDevtools(!0); - try { - partialState.call(instance, newState, nextProps); - } finally { - setIsStrictModeForDevtools(!1); - } - } - isDisallowedContextReadInDEV = !1; - newState = nextState; - break a; - } - newState = partialState; - break a; - case CaptureUpdate: - updateLane.flags = (updateLane.flags & -65537) | 128; - case UpdateState: - nextState = partialState.payload; - if ("function" === typeof nextState) { - isDisallowedContextReadInDEV = !0; - partialState = nextState.call( - instance, - newState, - nextProps - ); - if (updateLane.mode & 8) { - setIsStrictModeForDevtools(!0); - try { - nextState.call(instance, newState, nextProps); - } finally { - setIsStrictModeForDevtools(!1); - } - } - isDisallowedContextReadInDEV = !1; - } else partialState = nextState; - if (null === partialState || void 0 === partialState) break a; - newState = assign({}, newState, partialState); - break a; - case ForceUpdate: - hasForceUpdate = !0; - } - } - updateLane = pendingQueue.callback; - null !== updateLane && - ((workInProgress.flags |= 64), - isHiddenUpdate && (workInProgress.flags |= 8192), - (isHiddenUpdate = queue.callbacks), - null === isHiddenUpdate - ? (queue.callbacks = [updateLane]) - : isHiddenUpdate.push(updateLane)); - } else - (isHiddenUpdate = { - lane: updateLane, - tag: pendingQueue.tag, - payload: pendingQueue.payload, - callback: pendingQueue.callback, - next: null - }), - null === current - ? ((firstPendingUpdate = current = isHiddenUpdate), - (lastPendingUpdate = newState)) - : (current = current.next = isHiddenUpdate), - (lastBaseUpdate |= updateLane); - pendingQueue = pendingQueue.next; - if (null === pendingQueue) - if (((pendingQueue = queue.shared.pending), null === pendingQueue)) - break; - else - (isHiddenUpdate = pendingQueue), - (pendingQueue = isHiddenUpdate.next), - (isHiddenUpdate.next = null), - (queue.lastBaseUpdate = isHiddenUpdate), - (queue.shared.pending = null); - } while (1); - null === current && (lastPendingUpdate = newState); - queue.baseState = lastPendingUpdate; - queue.firstBaseUpdate = firstPendingUpdate; - queue.lastBaseUpdate = current; - null === firstBaseUpdate && (queue.shared.lanes = 0); - workInProgressRootSkippedLanes |= lastBaseUpdate; - workInProgress.lanes = lastBaseUpdate; - workInProgress.memoizedState = newState; + /** + * clearNestedProperty takes a single set of props and valid attributes. It + * adds a null sentinel to the updatePayload, for each prop key. + */ + + function clearNestedProperty(updatePayload, prevProp, validAttributes) { + if (!prevProp) { + return updatePayload; } - currentlyProcessingQueue = null; - } - function callCallback(callback, context) { - if ("function" !== typeof callback) - throw Error( - "Invalid argument passed as callback. Expected a function. Instead received: " + - callback + + if (!isArray(prevProp)) { + // Add each property of the leaf. + return clearProperties(updatePayload, prevProp, validAttributes); + } + + for (var i = 0; i < prevProp.length; i++) { + // Add all the properties of the array. + updatePayload = clearNestedProperty( + updatePayload, + prevProp[i], + validAttributes ); - callback.call(context); - } - function commitCallbacks(updateQueue, context) { - var callbacks = updateQueue.callbacks; - if (null !== callbacks) - for ( - updateQueue.callbacks = null, updateQueue = 0; - updateQueue < callbacks.length; - updateQueue++ - ) - callCallback(callbacks[updateQueue], context); - } - 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++) { - var currentKey = keysA[keysB]; - if ( - !hasOwnProperty.call(objB, currentKey) || - !objectIs(objA[currentKey], objB[currentKey]) - ) - return !1; } - return !0; - } - function createThenableState() { - return { didWarnAboutUncachedPromise: !1, thenables: [] }; - } - function isThenableResolved(thenable) { - thenable = thenable.status; - return "fulfilled" === thenable || "rejected" === thenable; + + return updatePayload; } - function noop() {} - function trackUsedThenable(thenableState, thenable, index) { - null !== ReactSharedInternals.actQueue && - (ReactSharedInternals.didUsePromise = !0); - var trackedThenables = thenableState.thenables; - index = trackedThenables[index]; - void 0 === index - ? trackedThenables.push(thenable) - : index !== thenable && - (thenableState.didWarnAboutUncachedPromise || - ((thenableState.didWarnAboutUncachedPromise = !0), - error$jscomp$0( - "A component was suspended by an uncached promise. Creating promises inside a Client Component or hook is not yet supported, except via a Suspense-compatible library or framework." - )), - thenable.then(noop, noop), - (thenable = index)); - switch (thenable.status) { - case "fulfilled": - return thenable.value; - case "rejected": - throw ( - ((thenableState = thenable.reason), - checkIfUseWrappedInAsyncCatch(thenableState), - thenableState) + /** + * diffProperties takes two sets of props and a set of valid attributes + * and write to updatePayload the values that changed or were deleted. + * If no updatePayload is provided, a new one is created and returned if + * anything changed. + */ + + function diffProperties( + updatePayload, + prevProps, + nextProps, + validAttributes + ) { + var attributeConfig; + var nextProp; + var prevProp; + + for (var propKey in nextProps) { + attributeConfig = validAttributes[propKey]; + + if (!attributeConfig) { + continue; // not a valid native prop + } + + prevProp = prevProps[propKey]; + nextProp = nextProps[propKey]; // functions are converted to booleans as markers that the associated + // events should be sent from native. + + if (typeof nextProp === "function") { + nextProp = true; // If nextProp is not a function, then don't bother changing prevProp + // since nextProp will win and go into the updatePayload regardless. + + if (typeof prevProp === "function") { + prevProp = true; + } + } // An explicit value of undefined is treated as a null because it overrides + // any other preceding value. + + if (typeof nextProp === "undefined") { + nextProp = null; + + if (typeof prevProp === "undefined") { + prevProp = null; + } + } + + if (removedKeys) { + removedKeys[propKey] = false; + } + + if (updatePayload && updatePayload[propKey] !== undefined) { + // Something else already triggered an update to this key because another + // value diffed. Since we're now later in the nested arrays our value is + // more important so we need to calculate it and override the existing + // value. It doesn't matter if nothing changed, we'll set it anyway. + // Pattern match on: attributeConfig + if (typeof attributeConfig !== "object") { + // case: !Object is the default case + updatePayload[propKey] = nextProp; + } else if ( + typeof attributeConfig.diff === "function" || + typeof attributeConfig.process === "function" + ) { + // case: CustomAttributeConfiguration + var nextValue = + typeof attributeConfig.process === "function" + ? attributeConfig.process(nextProp) + : nextProp; + updatePayload[propKey] = nextValue; + } + + continue; + } + + if (prevProp === nextProp) { + continue; // nothing changed + } // Pattern match on: attributeConfig + + if (typeof attributeConfig !== "object") { + // case: !Object is the default case + if (defaultDiffer(prevProp, nextProp)) { + // a normal leaf has changed + (updatePayload || (updatePayload = {}))[propKey] = nextProp; + } + } else if ( + typeof attributeConfig.diff === "function" || + typeof attributeConfig.process === "function" + ) { + // case: CustomAttributeConfiguration + var shouldUpdate = + prevProp === undefined || + (typeof attributeConfig.diff === "function" + ? attributeConfig.diff(prevProp, nextProp) + : defaultDiffer(prevProp, nextProp)); + + if (shouldUpdate) { + var _nextValue = + typeof attributeConfig.process === "function" // $FlowFixMe[incompatible-use] found when upgrading Flow + ? attributeConfig.process(nextProp) + : nextProp; + + (updatePayload || (updatePayload = {}))[propKey] = _nextValue; + } + } else { + // default: fallthrough case when nested properties are defined + removedKeys = null; + removedKeyCount = 0; // We think that attributeConfig is not CustomAttributeConfiguration at + // this point so we assume it must be AttributeConfiguration. + + updatePayload = diffNestedProperty( + updatePayload, + prevProp, + nextProp, + attributeConfig ); - default: - if ("string" === typeof thenable.status) thenable.then(noop, noop); - else { - thenableState = workInProgressRoot; - if ( - null !== thenableState && - 100 < thenableState.shellSuspendCounter - ) - throw Error( - "async/await is not yet supported in Client Components, only Server Components. This error is often caused by accidentally adding `'use client'` to a module that was originally written for the server." - ); - thenableState = thenable; - thenableState.status = "pending"; - thenableState.then( - function (fulfilledValue) { - if ("pending" === thenable.status) { - var fulfilledThenable = thenable; - fulfilledThenable.status = "fulfilled"; - fulfilledThenable.value = fulfilledValue; - } - }, - function (error) { - if ("pending" === thenable.status) { - var rejectedThenable = thenable; - rejectedThenable.status = "rejected"; - rejectedThenable.reason = error; - } - } + + if (removedKeyCount > 0 && updatePayload) { + restoreDeletedValuesInNestedArray( + updatePayload, + nextProp, + attributeConfig ); + removedKeys = null; } - switch (thenable.status) { - case "fulfilled": - return thenable.value; - case "rejected": - throw ( - ((thenableState = thenable.reason), - checkIfUseWrappedInAsyncCatch(thenableState), - thenableState) - ); + } + } // Also iterate through all the previous props to catch any that have been + // removed and make sure native gets the signal so it can reset them to the + // default. + + for (var _propKey in prevProps) { + if (nextProps[_propKey] !== undefined) { + continue; // we've already covered this key in the previous pass + } + + attributeConfig = validAttributes[_propKey]; + + if (!attributeConfig) { + continue; // not a valid native prop + } + + if (updatePayload && updatePayload[_propKey] !== undefined) { + // This was already updated to a diff result earlier. + continue; + } + + prevProp = prevProps[_propKey]; + + if (prevProp === undefined) { + continue; // was already empty anyway + } // Pattern match on: attributeConfig + + if ( + typeof attributeConfig !== "object" || + typeof attributeConfig.diff === "function" || + typeof attributeConfig.process === "function" + ) { + // case: CustomAttributeConfiguration | !Object + // Flag the leaf property for removal by sending a sentinel. + (updatePayload || (updatePayload = {}))[_propKey] = null; + + if (!removedKeys) { + removedKeys = {}; } - suspendedThenable = thenable; - needsToResetSuspendedThenableDEV = !0; - throw SuspenseException; - } - } - function getSuspendedThenable() { - if (null === suspendedThenable) - throw Error( - "Expected a suspended thenable. This is a bug in React. Please file an issue." - ); - var thenable = suspendedThenable; - suspendedThenable = null; - needsToResetSuspendedThenableDEV = !1; - return thenable; - } - function checkIfUseWrappedInAsyncCatch(rejectedReason) { - if (rejectedReason === SuspenseException) - throw Error( - "Hooks are not supported inside an async component. This error is often caused by accidentally adding `'use client'` to a module that was originally written for the server." - ); - } - function pushDebugInfo(debugInfo) { - var previousDebugInfo = currentDebugInfo; - null != debugInfo && - (currentDebugInfo = - null === previousDebugInfo - ? debugInfo - : previousDebugInfo.concat(debugInfo)); - return previousDebugInfo; - } - function validateFragmentProps(element, fiber, returnFiber) { - for (var keys = Object.keys(element.props), i = 0; i < keys.length; i++) { - var key = keys[i]; - if ("children" !== key && "key" !== key) { - null === fiber && - ((fiber = createFiberFromElement(element, returnFiber.mode, 0)), - (fiber.return = returnFiber)); - runWithFiberInDEV( - fiber, - function (erroredKey) { - error$jscomp$0( - "Invalid prop `%s` supplied to `React.Fragment`. React.Fragment can only have `key` and `children` props.", - erroredKey - ); - }, - key + + if (!removedKeys[_propKey]) { + removedKeys[_propKey] = true; + removedKeyCount++; + } + } else { + // default: + // This is a nested attribute configuration where all the properties + // were removed so we need to go through and clear out all of them. + updatePayload = clearNestedProperty( + updatePayload, + prevProp, + attributeConfig ); - break; } } + + return updatePayload; } - function unwrapThenable(thenable) { - var index = thenableIndexCounter$1; - thenableIndexCounter$1 += 1; - null === thenableState$1 && (thenableState$1 = createThenableState()); - return trackUsedThenable(thenableState$1, thenable, index); - } - function coerceRef(returnFiber, current, workInProgress, element) { - returnFiber = element.props.ref; - workInProgress.ref = void 0 !== returnFiber ? returnFiber : null; + /** + * addProperties adds all the valid props to the payload after being processed. + */ + + function addProperties(updatePayload, props, validAttributes) { + // TODO: Fast path + return diffProperties( + updatePayload, + emptyObject$1, + props, + validAttributes + ); } - function throwOnInvalidObjectType(returnFiber, newChild) { - if (newChild.$$typeof === REACT_LEGACY_ELEMENT_TYPE) - throw Error( - 'A React Element from an older version of React was rendered. This is not supported. It can happen if:\n- Multiple copies of the "react" package is used.\n- A library pre-bundled an old copy of "react" or "react/jsx-runtime".\n- A compiler tries to "inline" JSX instead of using the runtime.' - ); - 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." + /** + * clearProperties clears all the previous props by adding a null sentinel + * to the payload for each valid key. + */ + + function clearProperties(updatePayload, prevProps, validAttributes) { + // TODO: Fast path + return diffProperties( + updatePayload, + prevProps, + emptyObject$1, + validAttributes ); } - function warnOnFunctionType(returnFiber, invalidChild) { - var parentName = getComponentNameFromFiber(returnFiber) || "Component"; - ownerHasFunctionTypeWarning[parentName] || - ((ownerHasFunctionTypeWarning[parentName] = !0), - (invalidChild = - invalidChild.displayName || invalidChild.name || "Component"), - 3 === returnFiber.tag - ? error$jscomp$0( - "Functions are not valid as a React child. This may happen if you return %s instead of <%s /> from render. Or maybe you meant to call this function rather than return it.\n root.render(%s)", - invalidChild, - invalidChild, - invalidChild - ) - : error$jscomp$0( - "Functions are not valid as a React child. This may happen if you return %s instead of <%s /> from render. Or maybe you meant to call this function rather than return it.\n <%s>{%s}", - invalidChild, - invalidChild, - parentName, - invalidChild, - parentName - )); + + function create(props, validAttributes) { + return addProperties( + null, // updatePayload + props, + validAttributes + ); } - function warnOnSymbolType(returnFiber, invalidChild) { - var parentName = getComponentNameFromFiber(returnFiber) || "Component"; - ownerHasSymbolTypeWarning[parentName] || - ((ownerHasSymbolTypeWarning[parentName] = !0), - (invalidChild = String(invalidChild)), - 3 === returnFiber.tag - ? error$jscomp$0( - "Symbols are not valid as a React child.\n root.render(%s)", - invalidChild - ) - : error$jscomp$0( - "Symbols are not valid as a React child.\n <%s>%s", - parentName, - invalidChild, - parentName - )); + function diff(prevProps, nextProps, validAttributes) { + return diffProperties( + null, // updatePayload + prevProps, + nextProps, + validAttributes + ); } - function createChildReconciler(shouldTrackSideEffects) { - function deleteChild(returnFiber, childToDelete) { - if (shouldTrackSideEffects) { - var deletions = returnFiber.deletions; - null === deletions - ? ((returnFiber.deletions = [childToDelete]), - (returnFiber.flags |= 16)) - : deletions.push(childToDelete); - } + + // Used as a way to call batchedUpdates when we don't have a reference to + // the renderer. Such as when we're dispatching events or if third party + // libraries need to call batchedUpdates. Eventually, this API will go away when + // everything is batched by default. We'll then have a similar API to opt-out of + // scheduled work and instead do synchronous work. + // Defaults + var batchedUpdatesImpl = function (fn, bookkeeping) { + return fn(bookkeeping); + }; + + var isInsideEventHandler = false; + function batchedUpdates$1(fn, bookkeeping) { + if (isInsideEventHandler) { + // If we are currently inside another batch, we need to wait until it + // fully completes before restoring state. + return fn(bookkeeping); } - function deleteRemainingChildren(returnFiber, currentFirstChild) { - if (!shouldTrackSideEffects) return null; - for (; null !== currentFirstChild; ) - deleteChild(returnFiber, currentFirstChild), - (currentFirstChild = currentFirstChild.sibling); - return null; + + isInsideEventHandler = true; + + try { + return batchedUpdatesImpl(fn, bookkeeping); + } finally { + isInsideEventHandler = false; } - function mapRemainingChildren(currentFirstChild) { - for (var existingChildren = new Map(); null !== currentFirstChild; ) - null !== currentFirstChild.key - ? existingChildren.set(currentFirstChild.key, currentFirstChild) - : existingChildren.set(currentFirstChild.index, currentFirstChild), - (currentFirstChild = currentFirstChild.sibling); - return existingChildren; + } + function setBatchingImplementation( + _batchedUpdatesImpl, + _discreteUpdatesImpl + ) { + batchedUpdatesImpl = _batchedUpdatesImpl; + } + + /** + * Internal queue of events that have accumulated their dispatches and are + * waiting to have their dispatches executed. + */ + + var eventQueue = null; + /** + * Dispatches an event and releases it back into the pool, unless persistent. + * + * @param {?object} event Synthetic event to be dispatched. + * @private + */ + + function executeDispatchesAndRelease(event) { + if (event) { + executeDispatchesInOrder(event); + + if (!event.isPersistent()) { + event.constructor.release(event); + } } - function useFiber(fiber, pendingProps) { - fiber = createWorkInProgress(fiber, pendingProps); - fiber.index = 0; - fiber.sibling = null; - return fiber; + } // $FlowFixMe[missing-local-annot] + + function executeDispatchesAndReleaseTopLevel(e) { + return executeDispatchesAndRelease(e); + } + + function runEventsInBatch(events) { + if (events !== null) { + eventQueue = accumulateInto(eventQueue, events); + } // Set `eventQueue` to null before processing it so that we can tell if more + // events get enqueued while processing. + + var processingEventQueue = eventQueue; + eventQueue = null; + + if (!processingEventQueue) { + return; } - function placeChild(newFiber, lastPlacedIndex, newIndex) { - newFiber.index = newIndex; - if (!shouldTrackSideEffects) - return (newFiber.flags |= 1048576), lastPlacedIndex; - newIndex = newFiber.alternate; - if (null !== newIndex) - return ( - (newIndex = newIndex.index), - newIndex < lastPlacedIndex - ? ((newFiber.flags |= 33554434), lastPlacedIndex) - : newIndex + + forEachAccumulated( + processingEventQueue, + executeDispatchesAndReleaseTopLevel + ); + + if (eventQueue) { + throw new Error( + "processEventQueue(): Additional events were enqueued while processing " + + "an event queue. Support for this has not yet been implemented." + ); + } // This would be a good time to rethrow if any of the event handlers threw. + + rethrowCaughtError(); + } + + /** + * Allows registered plugins an opportunity to extract events from top-level + * native browser events. + * + * @return {*} An accumulation of synthetic events. + * @internal + */ + + function extractPluginEvents( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget + ) { + var events = null; + var legacyPlugins = plugins; + + for (var i = 0; i < legacyPlugins.length; i++) { + // Not every plugin in the ordering may be loaded at runtime. + var possiblePlugin = legacyPlugins[i]; + + if (possiblePlugin) { + var extractedEvents = possiblePlugin.extractEvents( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget ); - newFiber.flags |= 33554434; - return lastPlacedIndex; - } - function placeSingleChild(newFiber) { - shouldTrackSideEffects && - null === newFiber.alternate && - (newFiber.flags |= 33554434); - return newFiber; + + if (extractedEvents) { + events = accumulateInto(events, extractedEvents); + } + } } - function updateTextNode(returnFiber, current, textContent, lanes) { - if (null === current || 6 !== current.tag) - return ( - (current = createFiberFromText( - textContent, - returnFiber.mode, - lanes - )), - (current.return = returnFiber), - (current._debugInfo = currentDebugInfo), - current - ); - current = useFiber(current, textContent); - current.return = returnFiber; - current._debugInfo = currentDebugInfo; - return current; + + return events; + } + + function runExtractedPluginEventsInBatch( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget + ) { + var events = extractPluginEvents( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget + ); + runEventsInBatch(events); + } + + function dispatchEvent(target, topLevelType, nativeEvent) { + var targetFiber = target; + var eventTarget = null; + + if (targetFiber != null) { + var stateNode = targetFiber.stateNode; // Guard against Fiber being unmounted + + if (stateNode != null) { + // $FlowExpectedError[incompatible-cast] public instances in Fabric do not implement `EventTarget` yet. + eventTarget = getPublicInstance(stateNode); + } } - function updateElement(returnFiber, current, element, lanes) { - var elementType = element.type; - if (elementType === REACT_FRAGMENT_TYPE) - return ( - (current = updateFragment( - returnFiber, - current, - element.props.children, - lanes, - element.key - )), - validateFragmentProps(element, current, returnFiber), - current - ); - if ( - null !== current && - (current.elementType === elementType || - isCompatibleFamilyForHotReloading(current, element) || - ("object" === typeof elementType && - null !== elementType && - elementType.$$typeof === REACT_LAZY_TYPE && - callLazyInitInDEV(elementType) === current.type)) - ) - return ( - (lanes = useFiber(current, element.props)), - coerceRef(returnFiber, current, lanes, element), - (lanes.return = returnFiber), - (lanes._debugOwner = element._owner), - (lanes._debugInfo = currentDebugInfo), - lanes - ); - lanes = createFiberFromElement(element, returnFiber.mode, lanes); - coerceRef(returnFiber, current, lanes, element); - lanes.return = returnFiber; - lanes._debugInfo = currentDebugInfo; - return lanes; + + batchedUpdates$1(function () { + // Emit event to the RawEventEmitter. This is an unused-by-default EventEmitter + // that can be used to instrument event performance monitoring (primarily - could be useful + // for other things too). + // + // NOTE: this merely emits events into the EventEmitter below. + // If *you* do not add listeners to the `RawEventEmitter`, + // then all of these emitted events will just blackhole and are no-ops. + // It is available (although not officially supported... yet) if you want to collect + // perf data on event latency in your application, and could also be useful for debugging + // low-level events issues. + // + // If you do not have any event perf monitoring and are extremely concerned about event perf, + // it is safe to disable these "emit" statements; it will prevent checking the size of + // an empty array twice and prevent two no-ops. Practically the overhead is so low that + // we don't think it's worth thinking about in prod; your perf issues probably lie elsewhere. + // + // We emit two events here: one for listeners to this specific event, + // and one for the catchall listener '*', for any listeners that want + // to be notified for all events. + // Note that extracted events are *not* emitted, + // only events that have a 1:1 mapping with a native event, at least for now. + var event = { + eventName: topLevelType, + nativeEvent: nativeEvent + }; // $FlowFixMe[class-object-subtyping] found when upgrading Flow + + ReactNativePrivateInterface.RawEventEmitter.emit(topLevelType, event); // $FlowFixMe[class-object-subtyping] found when upgrading Flow + + ReactNativePrivateInterface.RawEventEmitter.emit("*", event); // Heritage plugin event system + + runExtractedPluginEventsInBatch( + topLevelType, + targetFiber, + nativeEvent, + eventTarget + ); + }); // React Native doesn't use ReactControlledComponent but if it did, here's + // where it would do it. + } + + // ----------------------------------------------------------------------------- + var enableSchedulingProfiler = false; + var enableProfilerTimer = true; + var enableProfilerCommitHooks = true; + var enableProfilerNestedUpdatePhase = true; + var syncLaneExpirationMs = 250; + var transitionLaneExpirationMs = 5000; + var enableLazyContextPropagation = false; + var enableLegacyHidden = false; + var enableAsyncActions = false; + var passChildrenWhenCloningPersistedNodes = false; + var enableBigIntSupport = false; + + var NoFlags$1 = + /* */ + 0; + var PerformedWork = + /* */ + 1; + var Placement = + /* */ + 2; + var DidCapture = + /* */ + 128; + var Hydrating = + /* */ + 4096; // You can change the rest (and add more). + + var Update = + /* */ + 4; + /* Skipped value: 0b0000000000000000000000001000; */ + + var ChildDeletion = + /* */ + 16; + var ContentReset = + /* */ + 32; + var Callback = + /* */ + 64; + /* Used by DidCapture: 0b0000000000000000000010000000; */ + + var ForceClientRender = + /* */ + 256; + var Ref = + /* */ + 512; + var Snapshot = + /* */ + 1024; + var Passive$1 = + /* */ + 2048; + /* Used by Hydrating: 0b0000000000000001000000000000; */ + + var Visibility = + /* */ + 8192; + var StoreConsistency = + /* */ + 16384; // It's OK to reuse these bits because these flags are mutually exclusive for + // different fiber types. We should really be doing this for as many flags as + // possible, because we're about to run out of bits. + + var ScheduleRetry = StoreConsistency; + var ShouldSuspendCommit = Visibility; + var DidDefer = ContentReset; + var LifecycleEffectMask = + Passive$1 | Update | Callback | Ref | Snapshot | StoreConsistency; // Union of all commit flags (flags with the lifetime of a particular commit) + + var HostEffectMask = + /* */ + 32767; // These are not really side effects, but we still reuse this field. + + var Incomplete = + /* */ + 32768; + var ShouldCapture = + /* */ + 65536; + var ForceUpdateForLegacySuspense = + /* */ + 131072; + var Forked = + /* */ + 1048576; // Static tags describe aspects of a fiber that are not specific to a render, + // e.g. a fiber uses a passive effect (even if there are no updates on this particular render). + // This enables us to defer more work in the unmount case, + // since we can defer traversing the tree during layout to look for Passive effects, + // and instead rely on the static flag as a signal that there may be cleanup work. + + var RefStatic = + /* */ + 2097152; + var LayoutStatic = + /* */ + 4194304; + var PassiveStatic = + /* */ + 8388608; + var MaySuspendCommit = + /* */ + 16777216; // Flag used to identify newly inserted fibers. It isn't reset after commit unlike `Placement`. + + var PlacementDEV = + /* */ + 33554432; + var MountLayoutDev = + /* */ + 67108864; + var MountPassiveDev = + /* */ + 134217728; // 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 Visibility + // flag logic (see #20043) + Update | Snapshot | 0; + var MutationMask = + Placement | + Update | + ChildDeletion | + ContentReset | + Ref | + Hydrating | + Visibility; + var LayoutMask = Update | Callback | Ref | Visibility; // TODO: Split into PassiveMountMask and PassiveUnmountMask + + var PassiveMask = Passive$1 | Visibility | ChildDeletion; // Union of tags that don't get reset on clones. + // This allows certain concepts to persist without recalculating them, + // e.g. whether a subtree contains passive effects or portals. + + var StaticMask = + LayoutStatic | PassiveStatic | RefStatic | MaySuspendCommit; + + // This module only exists as an ESM wrapper around the external CommonJS + var scheduleCallback$2 = Scheduler.unstable_scheduleCallback; + var cancelCallback$1 = Scheduler.unstable_cancelCallback; + var shouldYield = Scheduler.unstable_shouldYield; + var requestPaint = Scheduler.unstable_requestPaint; + var now$1 = Scheduler.unstable_now; + var ImmediatePriority = Scheduler.unstable_ImmediatePriority; + var UserBlockingPriority = Scheduler.unstable_UserBlockingPriority; + var NormalPriority = Scheduler.unstable_NormalPriority; + var IdlePriority = Scheduler.unstable_IdlePriority; // this doesn't actually exist on the scheduler, but it *does* + + // Helpers to patch console.logs to avoid logging during side-effect free + // replaying on render function. This currently only patches the object + // lazily which won't cover if the log function was extracted eagerly. + // We could also eagerly patch the method. + var disabledDepth = 0; + var prevLog; + var prevInfo; + var prevWarn; + var prevError; + var prevGroup; + var prevGroupCollapsed; + var prevGroupEnd; + + function disabledLog() {} + + disabledLog.__reactDisabledLog = true; + function disableLogs() { + { + if (disabledDepth === 0) { + /* eslint-disable react-internal/no-production-logging */ + prevLog = console.log; + prevInfo = console.info; + prevWarn = console.warn; + prevError = console.error; + prevGroup = console.group; + prevGroupCollapsed = console.groupCollapsed; + prevGroupEnd = console.groupEnd; // https://github.com/facebook/react/issues/19099 + + var props = { + configurable: true, + enumerable: true, + value: disabledLog, + writable: true + }; // $FlowFixMe[cannot-write] Flow thinks console is immutable. + + Object.defineProperties(console, { + info: props, + log: props, + warn: props, + error: props, + group: props, + groupCollapsed: props, + groupEnd: props + }); + /* eslint-enable react-internal/no-production-logging */ + } + + disabledDepth++; } - function updatePortal(returnFiber, current, portal, lanes) { - if ( - null === current || - 4 !== current.tag || - current.stateNode.containerInfo !== portal.containerInfo || - current.stateNode.implementation !== portal.implementation - ) - return ( - (current = createFiberFromPortal(portal, returnFiber.mode, lanes)), - (current.return = returnFiber), - (current._debugInfo = currentDebugInfo), - current + } + function reenableLogs() { + { + disabledDepth--; + + if (disabledDepth === 0) { + /* eslint-disable react-internal/no-production-logging */ + var props = { + configurable: true, + enumerable: true, + writable: true + }; // $FlowFixMe[cannot-write] Flow thinks console is immutable. + + Object.defineProperties(console, { + log: assign({}, props, { + value: prevLog + }), + info: assign({}, props, { + value: prevInfo + }), + warn: assign({}, props, { + value: prevWarn + }), + error: assign({}, props, { + value: prevError + }), + group: assign({}, props, { + value: prevGroup + }), + groupCollapsed: assign({}, props, { + value: prevGroupCollapsed + }), + groupEnd: assign({}, props, { + value: prevGroupEnd + }) + }); + /* eslint-enable react-internal/no-production-logging */ + } + + if (disabledDepth < 0) { + error( + "disabledDepth fell below zero. " + + "This is a bug in React. Please file an issue." ); - current = useFiber(current, portal.children || []); - current.return = returnFiber; - current._debugInfo = currentDebugInfo; - return current; + } } - function updateFragment(returnFiber, current, fragment, lanes, key) { - if (null === current || 7 !== current.tag) - return ( - (current = createFiberFromFragment( - fragment, - returnFiber.mode, - lanes, - key - )), - (current.return = returnFiber), - (current._debugInfo = currentDebugInfo), - current - ); - current = useFiber(current, fragment); - current.return = returnFiber; - current._debugInfo = currentDebugInfo; - return current; + } + + var rendererID = null; + var injectedHook = null; + var hasLoggedError = false; + var isDevToolsPresent = + typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined"; + function injectInternals(internals) { + if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === "undefined") { + // No DevTools + return false; } - function createChild(returnFiber, newChild, lanes) { - if ( - ("string" === typeof newChild && "" !== newChild) || - "number" === typeof newChild || - "bigint" === typeof newChild - ) - return ( - (newChild = createFiberFromText( - "" + newChild, - returnFiber.mode, - lanes - )), - (newChild.return = returnFiber), - (newChild._debugInfo = currentDebugInfo), - newChild + + 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://react.dev/link/react-devtools" ); - if ("object" === typeof newChild && null !== newChild) { - switch (newChild.$$typeof) { - case REACT_ELEMENT_TYPE: - return ( - (lanes = createFiberFromElement( - newChild, - returnFiber.mode, - lanes - )), - coerceRef(returnFiber, null, lanes, newChild), - (lanes.return = returnFiber), - (returnFiber = pushDebugInfo(newChild._debugInfo)), - (lanes._debugInfo = currentDebugInfo), - (currentDebugInfo = returnFiber), - lanes - ); - case REACT_PORTAL_TYPE: - return ( - (newChild = createFiberFromPortal( - newChild, - returnFiber.mode, - lanes - )), - (newChild.return = returnFiber), - (newChild._debugInfo = currentDebugInfo), - newChild - ); - case REACT_LAZY_TYPE: - var _prevDebugInfo = pushDebugInfo(newChild._debugInfo); - newChild = callLazyInitInDEV(newChild); - returnFiber = createChild(returnFiber, newChild, lanes); - currentDebugInfo = _prevDebugInfo; - return returnFiber; - } - if (isArrayImpl(newChild) || getIteratorFn(newChild)) - return ( - (lanes = createFiberFromFragment( - newChild, - returnFiber.mode, - lanes, - null - )), - (lanes.return = returnFiber), - (returnFiber = pushDebugInfo(newChild._debugInfo)), - (lanes._debugInfo = currentDebugInfo), - (currentDebugInfo = returnFiber), - lanes - ); - if ("function" === typeof newChild.then) - return ( - (_prevDebugInfo = pushDebugInfo(newChild._debugInfo)), - (returnFiber = createChild( - returnFiber, - unwrapThenable(newChild), - lanes - )), - (currentDebugInfo = _prevDebugInfo), - returnFiber - ); - if (newChild.$$typeof === REACT_CONTEXT_TYPE) - return createChild( - returnFiber, - readContextDuringReconciliation(returnFiber, newChild, lanes), - lanes - ); - throwOnInvalidObjectType(returnFiber, newChild); + } // DevTools exists, even though it doesn't support Fiber. + + return true; + } + + try { + if (enableSchedulingProfiler); + + 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); } - "function" === typeof newChild && - warnOnFunctionType(returnFiber, newChild); - "symbol" === typeof newChild && warnOnSymbolType(returnFiber, newChild); - return null; } - function updateSlot(returnFiber, oldFiber, newChild, lanes) { - var key = null !== oldFiber ? oldFiber.key : null; + + if (hook.checkDCE) { + // This is the real DevTools. + return true; + } else { + // This is likely a hook installed by Fast Refresh runtime. + return false; + } + } + function onScheduleRoot(root, children) { + { if ( - ("string" === typeof newChild && "" !== newChild) || - "number" === typeof newChild || - "bigint" === typeof newChild - ) - return null !== key - ? null - : updateTextNode(returnFiber, oldFiber, "" + newChild, lanes); - if ("object" === typeof newChild && null !== newChild) { - switch (newChild.$$typeof) { - case REACT_ELEMENT_TYPE: - return newChild.key === key - ? ((key = pushDebugInfo(newChild._debugInfo)), - (returnFiber = updateElement( - returnFiber, - oldFiber, - newChild, - lanes - )), - (currentDebugInfo = key), - returnFiber) - : null; - case REACT_PORTAL_TYPE: - return newChild.key === key - ? updatePortal(returnFiber, oldFiber, newChild, lanes) - : null; - case REACT_LAZY_TYPE: - return ( - (key = pushDebugInfo(newChild._debugInfo)), - (newChild = callLazyInitInDEV(newChild)), - (returnFiber = updateSlot( - returnFiber, - oldFiber, - newChild, - lanes - )), - (currentDebugInfo = key), - returnFiber - ); - } - if (isArrayImpl(newChild) || getIteratorFn(newChild)) { - if (null !== key) return null; - key = pushDebugInfo(newChild._debugInfo); - returnFiber = updateFragment( - returnFiber, - oldFiber, - newChild, - lanes, - null - ); - currentDebugInfo = key; - return returnFiber; + 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); + } } - if ("function" === typeof newChild.then) - return ( - (key = pushDebugInfo(newChild._debugInfo)), - (returnFiber = updateSlot( - returnFiber, - oldFiber, - unwrapThenable(newChild), - lanes - )), - (currentDebugInfo = key), - returnFiber - ); - if (newChild.$$typeof === REACT_CONTEXT_TYPE) - return updateSlot( - returnFiber, - oldFiber, - readContextDuringReconciliation(returnFiber, newChild, lanes), - lanes - ); - throwOnInvalidObjectType(returnFiber, newChild); } - "function" === typeof newChild && - warnOnFunctionType(returnFiber, newChild); - "symbol" === typeof newChild && warnOnSymbolType(returnFiber, newChild); - return null; } - function updateFromMap( - existingChildren, - returnFiber, - newIdx, - newChild, - lanes + } + function onCommitRoot(root, eventPriority) { + if ( + injectedHook && + typeof injectedHook.onCommitFiberRoot === "function" ) { - if ( - ("string" === typeof newChild && "" !== newChild) || - "number" === typeof newChild || - "bigint" === typeof newChild - ) - return ( - (existingChildren = existingChildren.get(newIdx) || null), - updateTextNode(returnFiber, existingChildren, "" + newChild, lanes) - ); - if ("object" === typeof newChild && null !== newChild) { - switch (newChild.$$typeof) { - case REACT_ELEMENT_TYPE: - return ( - (newIdx = - existingChildren.get( - null === newChild.key ? newIdx : newChild.key - ) || null), - (existingChildren = pushDebugInfo(newChild._debugInfo)), - (returnFiber = updateElement( - returnFiber, - newIdx, - newChild, - lanes - )), - (currentDebugInfo = existingChildren), - returnFiber - ); - case REACT_PORTAL_TYPE: - return ( - (existingChildren = - existingChildren.get( - null === newChild.key ? newIdx : newChild.key - ) || null), - updatePortal(returnFiber, existingChildren, newChild, lanes) - ); - case REACT_LAZY_TYPE: - var _prevDebugInfo7 = pushDebugInfo(newChild._debugInfo); - newChild = callLazyInitInDEV(newChild); - returnFiber = updateFromMap( - existingChildren, - returnFiber, - newIdx, - newChild, - lanes - ); - currentDebugInfo = _prevDebugInfo7; - return returnFiber; - } - if (isArrayImpl(newChild) || getIteratorFn(newChild)) - return ( - (newIdx = existingChildren.get(newIdx) || null), - (existingChildren = pushDebugInfo(newChild._debugInfo)), - (returnFiber = updateFragment( - returnFiber, - newIdx, - newChild, - lanes, - null - )), - (currentDebugInfo = existingChildren), - returnFiber - ); - if ("function" === typeof newChild.then) - return ( - (_prevDebugInfo7 = pushDebugInfo(newChild._debugInfo)), - (returnFiber = updateFromMap( - existingChildren, - returnFiber, - newIdx, - unwrapThenable(newChild), - lanes - )), - (currentDebugInfo = _prevDebugInfo7), - returnFiber - ); - if (newChild.$$typeof === REACT_CONTEXT_TYPE) - return updateFromMap( - existingChildren, - returnFiber, - newIdx, - readContextDuringReconciliation(returnFiber, newChild, lanes), - lanes + 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 ); - throwOnInvalidObjectType(returnFiber, newChild); + } + } catch (err) { + { + if (!hasLoggedError) { + hasLoggedError = true; + + error("React instrumentation encountered an error: %s", err); + } + } } - "function" === typeof newChild && - warnOnFunctionType(returnFiber, newChild); - "symbol" === typeof newChild && warnOnSymbolType(returnFiber, newChild); - return null; } - function warnOnInvalidKey(returnFiber, workInProgress, child, knownKeys) { - if ("object" !== typeof child || null === child) return knownKeys; - switch (child.$$typeof) { - case REACT_ELEMENT_TYPE: - case REACT_PORTAL_TYPE: - warnForMissingKey(returnFiber, workInProgress, child); - var key = child.key; - if ("string" !== typeof key) break; - if (null === knownKeys) { - knownKeys = new Set(); - knownKeys.add(key); - break; - } - if (!knownKeys.has(key)) { - knownKeys.add(key); - break; + } + 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); } - runWithFiberInDEV(workInProgress, function () { - error$jscomp$0( - "Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted \u2014 the behavior is unsupported and could change in a future version.", - key - ); - }); - break; - case REACT_LAZY_TYPE: - (child = callLazyInitInDEV(child)), - warnOnInvalidKey(returnFiber, workInProgress, child, knownKeys); + } } - return knownKeys; } - function reconcileChildrenArray( - returnFiber, - currentFirstChild, - newChildren, - lanes + } + function onCommitUnmount(fiber) { + if ( + injectedHook && + typeof injectedHook.onCommitFiberUnmount === "function" ) { - for ( - var knownKeys = null, - resultingFirstChild = null, - previousNewFiber = null, - oldFiber = currentFirstChild, - newIdx = (currentFirstChild = 0), - nextOldFiber = null; - null !== oldFiber && newIdx < newChildren.length; - newIdx++ - ) { - oldFiber.index > newIdx - ? ((nextOldFiber = oldFiber), (oldFiber = null)) - : (nextOldFiber = oldFiber.sibling); - var newFiber = updateSlot( - returnFiber, - oldFiber, - newChildren[newIdx], - lanes - ); - if (null === newFiber) { - null === oldFiber && (oldFiber = nextOldFiber); - break; + try { + injectedHook.onCommitFiberUnmount(rendererID, fiber); + } catch (err) { + { + if (!hasLoggedError) { + hasLoggedError = true; + + error("React instrumentation encountered an error: %s", err); + } } - knownKeys = warnOnInvalidKey( - returnFiber, - newFiber, - newChildren[newIdx], - knownKeys - ); - shouldTrackSideEffects && - oldFiber && - null === newFiber.alternate && - deleteChild(returnFiber, oldFiber); - currentFirstChild = placeChild(newFiber, currentFirstChild, newIdx); - null === previousNewFiber - ? (resultingFirstChild = newFiber) - : (previousNewFiber.sibling = newFiber); - previousNewFiber = newFiber; - oldFiber = nextOldFiber; } - if (newIdx === newChildren.length) - return ( - deleteRemainingChildren(returnFiber, oldFiber), resultingFirstChild - ); - if (null === oldFiber) { - for (; newIdx < newChildren.length; newIdx++) - (oldFiber = createChild(returnFiber, newChildren[newIdx], lanes)), - null !== oldFiber && - ((knownKeys = warnOnInvalidKey( - returnFiber, - oldFiber, - newChildren[newIdx], - knownKeys - )), - (currentFirstChild = placeChild( - oldFiber, - currentFirstChild, - newIdx - )), - null === previousNewFiber - ? (resultingFirstChild = oldFiber) - : (previousNewFiber.sibling = oldFiber), - (previousNewFiber = oldFiber)); - return resultingFirstChild; - } - for ( - oldFiber = mapRemainingChildren(oldFiber); - newIdx < newChildren.length; - newIdx++ - ) - (nextOldFiber = updateFromMap( - oldFiber, - returnFiber, - newIdx, - newChildren[newIdx], - lanes - )), - null !== nextOldFiber && - ((knownKeys = warnOnInvalidKey( - returnFiber, - nextOldFiber, - newChildren[newIdx], - knownKeys - )), - shouldTrackSideEffects && - null !== nextOldFiber.alternate && - oldFiber.delete( - null === nextOldFiber.key ? newIdx : nextOldFiber.key - ), - (currentFirstChild = placeChild( - nextOldFiber, - currentFirstChild, - newIdx - )), - null === previousNewFiber - ? (resultingFirstChild = nextOldFiber) - : (previousNewFiber.sibling = nextOldFiber), - (previousNewFiber = nextOldFiber)); - shouldTrackSideEffects && - oldFiber.forEach(function (child) { - return deleteChild(returnFiber, child); - }); - return resultingFirstChild; } - function reconcileChildrenIterator( - returnFiber, - currentFirstChild, - newChildren, - lanes - ) { - if (null == newChildren) - throw Error("An iterable object provided no iterator."); - for ( - var resultingFirstChild = null, - previousNewFiber = null, - oldFiber = currentFirstChild, - newIdx = (currentFirstChild = 0), - nextOldFiber = null, - knownKeys = null, - step = newChildren.next(); - null !== oldFiber && !step.done; - newIdx++, step = newChildren.next() - ) { - oldFiber.index > newIdx - ? ((nextOldFiber = oldFiber), (oldFiber = null)) - : (nextOldFiber = oldFiber.sibling); - var newFiber = updateSlot(returnFiber, oldFiber, step.value, lanes); - if (null === newFiber) { - null === oldFiber && (oldFiber = nextOldFiber); - break; - } - knownKeys = warnOnInvalidKey( - returnFiber, - newFiber, - step.value, - knownKeys - ); - shouldTrackSideEffects && - oldFiber && - null === newFiber.alternate && - deleteChild(returnFiber, oldFiber); - currentFirstChild = placeChild(newFiber, currentFirstChild, newIdx); - null === previousNewFiber - ? (resultingFirstChild = newFiber) - : (previousNewFiber.sibling = newFiber); - previousNewFiber = newFiber; - oldFiber = nextOldFiber; + } + function setIsStrictModeForDevtools(newIsStrictMode) { + { + if (newIsStrictMode) { + disableLogs(); + } else { + reenableLogs(); } - if (step.done) - return ( - deleteRemainingChildren(returnFiber, oldFiber), resultingFirstChild - ); - if (null === oldFiber) { - for (; !step.done; newIdx++, step = newChildren.next()) - (oldFiber = createChild(returnFiber, step.value, lanes)), - null !== oldFiber && - ((knownKeys = warnOnInvalidKey( - returnFiber, - oldFiber, - step.value, - knownKeys - )), - (currentFirstChild = placeChild( - oldFiber, - currentFirstChild, - newIdx - )), - null === previousNewFiber - ? (resultingFirstChild = oldFiber) - : (previousNewFiber.sibling = oldFiber), - (previousNewFiber = oldFiber)); - return resultingFirstChild; + } + } // Profiler API hooks + + function injectProfilingHooks(profilingHooks) {} + + function getLaneLabelMap() { + { + return null; + } + } + + var NoMode = + /* */ + 0; // TODO: Remove ConcurrentMode by reading from the root tag instead + + var ConcurrentMode = + /* */ + 1; + var ProfileMode = + /* */ + 2; + var StrictLegacyMode = + /* */ + 8; + var StrictEffectsMode = + /* */ + 16; + var NoStrictPassiveEffectsMode = + /* */ + 64; + + // TODO: This is pretty well supported by browsers. Maybe we can drop it. + var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback; // Count leading zeros. + // 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 clz32Fallback(x) { + var asUint = x >>> 0; + + if (asUint === 0) { + return 32; + } + + return (31 - ((log(asUint) / LN2) | 0)) | 0; + } + + // If those values are changed that package should be rebuilt and redeployed. + + var TotalLanes = 31; + var NoLanes = + /* */ + 0; + var NoLane = + /* */ + 0; + var SyncHydrationLane = + /* */ + 1; + var SyncLane = + /* */ + 2; + var SyncLaneIndex = 1; + var InputContinuousHydrationLane = + /* */ + 4; + var InputContinuousLane = + /* */ + 8; + var DefaultHydrationLane = + /* */ + 16; + var DefaultLane = + /* */ + 32; + var SyncUpdateLanes = SyncLane | InputContinuousLane | DefaultLane; + var TransitionHydrationLane = + /* */ + 64; + var TransitionLanes = + /* */ + 4194176; + var TransitionLane1 = + /* */ + 128; + var TransitionLane2 = + /* */ + 256; + var TransitionLane3 = + /* */ + 512; + var TransitionLane4 = + /* */ + 1024; + var TransitionLane5 = + /* */ + 2048; + var TransitionLane6 = + /* */ + 4096; + var TransitionLane7 = + /* */ + 8192; + var TransitionLane8 = + /* */ + 16384; + var TransitionLane9 = + /* */ + 32768; + var TransitionLane10 = + /* */ + 65536; + var TransitionLane11 = + /* */ + 131072; + var TransitionLane12 = + /* */ + 262144; + var TransitionLane13 = + /* */ + 524288; + var TransitionLane14 = + /* */ + 1048576; + var TransitionLane15 = + /* */ + 2097152; + var RetryLanes = + /* */ + 62914560; + var RetryLane1 = + /* */ + 4194304; + var RetryLane2 = + /* */ + 8388608; + var RetryLane3 = + /* */ + 16777216; + var RetryLane4 = + /* */ + 33554432; + var SomeRetryLane = RetryLane1; + var SelectiveHydrationLane = + /* */ + 67108864; + var NonIdleLanes = + /* */ + 134217727; + var IdleHydrationLane = + /* */ + 134217728; + var IdleLane = + /* */ + 268435456; + var OffscreenLane = + /* */ + 536870912; + var DeferredLane = + /* */ + 1073741824; // Any lane that might schedule an update. This is used to detect infinite + // update loops, so it doesn't include hydration lanes or retries. + + var UpdateLanes = + SyncLane | InputContinuousLane | DefaultLane | TransitionLanes; // This function is used for the experimental timeline (react-devtools-timeline) + var NoTimestamp = -1; + var nextTransitionLane = TransitionLane1; + var nextRetryLane = RetryLane1; + + function getHighestPriorityLanes(lanes) { + { + var pendingSyncLanes = lanes & SyncUpdateLanes; + + if (pendingSyncLanes !== 0) { + return pendingSyncLanes; } - for ( - oldFiber = mapRemainingChildren(oldFiber); - !step.done; - newIdx++, step = newChildren.next() - ) - (nextOldFiber = updateFromMap( - oldFiber, - returnFiber, - newIdx, - step.value, - lanes - )), - null !== nextOldFiber && - ((knownKeys = warnOnInvalidKey( - returnFiber, - nextOldFiber, - step.value, - knownKeys - )), - shouldTrackSideEffects && - null !== nextOldFiber.alternate && - oldFiber.delete( - null === nextOldFiber.key ? newIdx : nextOldFiber.key - ), - (currentFirstChild = placeChild( - nextOldFiber, - currentFirstChild, - newIdx - )), - null === previousNewFiber - ? (resultingFirstChild = nextOldFiber) - : (previousNewFiber.sibling = nextOldFiber), - (previousNewFiber = nextOldFiber)); - shouldTrackSideEffects && - oldFiber.forEach(function (child) { - return deleteChild(returnFiber, child); - }); - return resultingFirstChild; } - function reconcileChildFibersImpl( - returnFiber, - currentFirstChild, - newChild, - lanes - ) { - "object" === typeof newChild && - null !== newChild && - newChild.type === REACT_FRAGMENT_TYPE && - null === newChild.key && - (validateFragmentProps(newChild, null, returnFiber), - (newChild = newChild.props.children)); - if ("object" === typeof newChild && null !== newChild) { - switch (newChild.$$typeof) { - case REACT_ELEMENT_TYPE: - var prevDebugInfo = pushDebugInfo(newChild._debugInfo); - a: { - for ( - var key = newChild.key, child = currentFirstChild; - null !== child; - ) { - if (child.key === key) { - key = newChild.type; - if (key === REACT_FRAGMENT_TYPE) { - if (7 === child.tag) { - deleteRemainingChildren(returnFiber, child.sibling); - currentFirstChild = useFiber( - child, - newChild.props.children - ); - currentFirstChild.return = returnFiber; - currentFirstChild._debugOwner = newChild._owner; - currentFirstChild._debugInfo = currentDebugInfo; - validateFragmentProps( - newChild, - currentFirstChild, - returnFiber - ); - returnFiber = currentFirstChild; - break a; - } - } else if ( - child.elementType === key || - isCompatibleFamilyForHotReloading(child, newChild) || - ("object" === typeof key && - null !== key && - key.$$typeof === REACT_LAZY_TYPE && - callLazyInitInDEV(key) === child.type) - ) { - deleteRemainingChildren(returnFiber, child.sibling); - currentFirstChild = useFiber(child, newChild.props); - coerceRef( - returnFiber, - child, - currentFirstChild, - newChild - ); - currentFirstChild.return = returnFiber; - currentFirstChild._debugOwner = newChild._owner; - currentFirstChild._debugInfo = currentDebugInfo; - returnFiber = currentFirstChild; - break a; - } - deleteRemainingChildren(returnFiber, child); - break; - } else deleteChild(returnFiber, child); - child = child.sibling; - } - newChild.type === REACT_FRAGMENT_TYPE - ? ((currentFirstChild = createFiberFromFragment( - newChild.props.children, - returnFiber.mode, - lanes, - newChild.key - )), - (currentFirstChild.return = returnFiber), - (currentFirstChild._debugInfo = currentDebugInfo), - validateFragmentProps( - newChild, - currentFirstChild, - returnFiber - ), - (returnFiber = currentFirstChild)) - : ((lanes = createFiberFromElement( - newChild, - returnFiber.mode, - lanes - )), - coerceRef(returnFiber, currentFirstChild, lanes, newChild), - (lanes.return = returnFiber), - (lanes._debugInfo = currentDebugInfo), - (returnFiber = lanes)); - } - returnFiber = placeSingleChild(returnFiber); - currentDebugInfo = prevDebugInfo; - return returnFiber; - case REACT_PORTAL_TYPE: - a: { - prevDebugInfo = newChild; - for ( - newChild = prevDebugInfo.key; - null !== currentFirstChild; + switch (getHighestPriorityLane(lanes)) { + case SyncHydrationLane: + return SyncHydrationLane; - ) { - if (currentFirstChild.key === newChild) - if ( - 4 === currentFirstChild.tag && - currentFirstChild.stateNode.containerInfo === - prevDebugInfo.containerInfo && - currentFirstChild.stateNode.implementation === - prevDebugInfo.implementation - ) { - deleteRemainingChildren( - returnFiber, - currentFirstChild.sibling - ); - currentFirstChild = useFiber( - currentFirstChild, - prevDebugInfo.children || [] - ); - currentFirstChild.return = returnFiber; - returnFiber = currentFirstChild; - break a; - } else { - deleteRemainingChildren(returnFiber, currentFirstChild); - break; - } - else deleteChild(returnFiber, currentFirstChild); - currentFirstChild = currentFirstChild.sibling; - } - currentFirstChild = createFiberFromPortal( - prevDebugInfo, - returnFiber.mode, - lanes - ); - currentFirstChild.return = returnFiber; - returnFiber = currentFirstChild; - } - return placeSingleChild(returnFiber); - case REACT_LAZY_TYPE: - return ( - (prevDebugInfo = pushDebugInfo(newChild._debugInfo)), - (newChild = callLazyInitInDEV(newChild)), - (returnFiber = reconcileChildFibersImpl( - returnFiber, - currentFirstChild, - newChild, - lanes - )), - (currentDebugInfo = prevDebugInfo), - returnFiber - ); + case SyncLane: + return SyncLane; + + 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: + return lanes & TransitionLanes; + + case RetryLane1: + case RetryLane2: + case RetryLane3: + case RetryLane4: + return lanes & RetryLanes; + + case SelectiveHydrationLane: + return SelectiveHydrationLane; + + case IdleHydrationLane: + return IdleHydrationLane; + + case IdleLane: + return IdleLane; + + case OffscreenLane: + return OffscreenLane; + + case DeferredLane: + // This shouldn't be reachable because deferred work is always entangled + // with something else. + return NoLanes; + + 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; + } + } + + function getNextLanes(root, wipLanes) { + // Early bailout if there's no pending work left. + var pendingLanes = root.pendingLanes; + + if (pendingLanes === NoLanes) { + return NoLanes; + } + + 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. + + var nonIdlePendingLanes = pendingLanes & NonIdleLanes; + + if (nonIdlePendingLanes !== NoLanes) { + var nonIdleUnblockedLanes = nonIdlePendingLanes & ~suspendedLanes; + + if (nonIdleUnblockedLanes !== NoLanes) { + nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes); + } else { + var nonIdlePingedLanes = nonIdlePendingLanes & pingedLanes; + + if (nonIdlePingedLanes !== NoLanes) { + nextLanes = getHighestPriorityLanes(nonIdlePingedLanes); } - if (isArrayImpl(newChild)) - return ( - (prevDebugInfo = pushDebugInfo(newChild._debugInfo)), - (returnFiber = reconcileChildrenArray( - returnFiber, - currentFirstChild, - newChild, - lanes - )), - (currentDebugInfo = prevDebugInfo), - returnFiber - ); - if (getIteratorFn(newChild)) { - prevDebugInfo = pushDebugInfo(newChild._debugInfo); - child = getIteratorFn(newChild); - if ("function" !== typeof child) - throw Error( - "An object is not an iterable. This error is likely caused by a bug in React. Please file an issue." - ); - key = child.call(newChild); - if (key === newChild) { - if ( - 0 !== returnFiber.tag || - "[object GeneratorFunction]" !== - Object.prototype.toString.call(returnFiber.type) || - "[object Generator]" !== Object.prototype.toString.call(key) - ) - didWarnAboutGenerators || - error$jscomp$0( - "Using Iterators as children is unsupported and will likely yield unexpected results because enumerating a generator mutates it. You may convert it to an array with `Array.from()` or the `[...spread]` operator before rendering. You can also use an Iterable that can iterate multiple times over the same items." - ), - (didWarnAboutGenerators = !0); - } else - newChild.entries !== child || - didWarnAboutMaps || - (error$jscomp$0( - "Using Maps as children is not supported. Use an array of keyed ReactElements instead." - ), - (didWarnAboutMaps = !0)); - returnFiber = reconcileChildrenIterator( - returnFiber, - currentFirstChild, - key, - lanes - ); - currentDebugInfo = prevDebugInfo; - return returnFiber; + } + } else { + // The only remaining work is Idle. + var unblockedLanes = pendingLanes & ~suspendedLanes; + + if (unblockedLanes !== NoLanes) { + nextLanes = getHighestPriorityLanes(unblockedLanes); + } else { + if (pingedLanes !== NoLanes) { + nextLanes = getHighestPriorityLanes(pingedLanes); } - if ("function" === typeof newChild.then) - return ( - (prevDebugInfo = pushDebugInfo(newChild._debugInfo)), - (returnFiber = reconcileChildFibersImpl( - returnFiber, - currentFirstChild, - unwrapThenable(newChild), - lanes - )), - (currentDebugInfo = prevDebugInfo), - returnFiber - ); - if (newChild.$$typeof === REACT_CONTEXT_TYPE) - return reconcileChildFibersImpl( - returnFiber, - currentFirstChild, - readContextDuringReconciliation(returnFiber, newChild, lanes), - lanes - ); - throwOnInvalidObjectType(returnFiber, newChild); } - if ( - ("string" === typeof newChild && "" !== newChild) || - "number" === typeof newChild || - "bigint" === typeof newChild - ) - return ( - (prevDebugInfo = "" + newChild), - null !== currentFirstChild && 6 === currentFirstChild.tag - ? (deleteRemainingChildren( - returnFiber, - currentFirstChild.sibling - ), - (currentFirstChild = useFiber( - currentFirstChild, - prevDebugInfo - )), - (currentFirstChild.return = returnFiber), - (returnFiber = currentFirstChild)) - : (deleteRemainingChildren(returnFiber, currentFirstChild), - (currentFirstChild = createFiberFromText( - prevDebugInfo, - returnFiber.mode, - lanes - )), - (currentFirstChild.return = returnFiber), - (returnFiber = currentFirstChild)), - placeSingleChild(returnFiber) - ); - "function" === typeof newChild && - warnOnFunctionType(returnFiber, newChild); - "symbol" === typeof newChild && warnOnSymbolType(returnFiber, newChild); - return deleteRemainingChildren(returnFiber, currentFirstChild); } - return function (returnFiber, currentFirstChild, newChild, lanes) { - var prevDebugInfo = currentDebugInfo; - currentDebugInfo = null; - try { - thenableIndexCounter$1 = 0; - var firstChildFiber = reconcileChildFibersImpl( - returnFiber, - currentFirstChild, - newChild, - lanes - ); - thenableState$1 = null; - return firstChildFiber; - } catch (x) { - if ( - x === SuspenseException || - (0 === (returnFiber.mode & 1) && - "object" === typeof x && - null !== x && - "function" === typeof x.then) - ) - throw x; - var fiber = createFiber(29, x, null, returnFiber.mode); - fiber.lanes = lanes; - fiber.return = returnFiber; - var debugInfo = (fiber._debugInfo = currentDebugInfo); - fiber._debugOwner = returnFiber._debugOwner; - fiber._debugTask = returnFiber._debugTask; - if (null != debugInfo) - for (var i = debugInfo.length - 1; 0 <= i; i--) - if ("string" === typeof debugInfo[i].stack) { - fiber._debugOwner = debugInfo[i]; - fiber._debugTask = debugInfo[i].task; - break; - } - return fiber; - } finally { - currentDebugInfo = prevDebugInfo; - } - }; - } - function pushHiddenContext(fiber, context) { - var prevEntangledRenderLanes = entangledRenderLanes; - push(prevEntangledRenderLanesCursor, prevEntangledRenderLanes, fiber); - push(currentTreeHiddenStackCursor, context, fiber); - entangledRenderLanes = prevEntangledRenderLanes | context.baseLanes; - } - function reuseHiddenContextOnStack(fiber) { - push(prevEntangledRenderLanesCursor, entangledRenderLanes, fiber); - push( - currentTreeHiddenStackCursor, - currentTreeHiddenStackCursor.current, - fiber - ); - } - function popHiddenContext(fiber) { - entangledRenderLanes = prevEntangledRenderLanesCursor.current; - pop(currentTreeHiddenStackCursor, fiber); - pop(prevEntangledRenderLanesCursor, fiber); - } - function pushPrimaryTreeSuspenseHandler(handler) { - var current = handler.alternate; - push( - suspenseStackCursor, - suspenseStackCursor.current & SubtreeSuspenseContextMask, - handler - ); - push(suspenseHandlerStackCursor, handler, handler); - null === shellBoundary && - (null === current || null !== currentTreeHiddenStackCursor.current - ? (shellBoundary = handler) - : null !== current.memoizedState && (shellBoundary = handler)); - } - function pushOffscreenSuspenseHandler(fiber) { - if (22 === fiber.tag) { + + 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. + + 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 ( - (push(suspenseStackCursor, suspenseStackCursor.current, fiber), - push(suspenseHandlerStackCursor, fiber, fiber), - null === shellBoundary) + // 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) ) { - var current = fiber.alternate; - null !== current && - null !== current.memoizedState && - (shellBoundary = fiber); + // Keep working on the existing in-progress tree. Do not interrupt. + return wipLanes; } - } else reuseSuspenseHandlerOnStack(fiber); - } - function reuseSuspenseHandlerOnStack(fiber) { - push(suspenseStackCursor, suspenseStackCursor.current, fiber); - push( - suspenseHandlerStackCursor, - suspenseHandlerStackCursor.current, - fiber - ); + } + + return nextLanes; } - function popSuspenseHandler(fiber) { - pop(suspenseHandlerStackCursor, fiber); - shellBoundary === fiber && (shellBoundary = null); - pop(suspenseStackCursor, fiber); + function getEntangledLanes(root, renderLanes) { + var entangledLanes = renderLanes; + + if ((entangledLanes & 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. + entangledLanes |= entangledLanes & 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, + // we should ensure that there is no partial work at the + // time we apply the entanglement. + + var allEntangledLanes = root.entangledLanes; + + if (allEntangledLanes !== NoLanes) { + var entanglements = root.entanglements; + var lanes = entangledLanes & allEntangledLanes; + + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + entangledLanes |= entanglements[index]; + lanes &= ~lane; + } + } + + return entangledLanes; } - function findFirstSuspended(row) { - for (var node = row; null !== node; ) { - if (13 === node.tag) { - var state = node.memoizedState; - if ( - null !== state && - (null === state.dehydrated || - isSuspenseInstancePending() || - isSuspenseInstanceFallback()) - ) - return node; - } else if ( - 19 === node.tag && - void 0 !== node.memoizedProps.revealOrder - ) { - if (0 !== (node.flags & 128)) return node; - } else if (null !== node.child) { - node.child.return = node; - node = node.child; - continue; - } - if (node === row) break; - for (; null === node.sibling; ) { - if (null === node.return || node.return === row) return null; - node = node.return; - } - node.sibling.return = node.return; - node = node.sibling; + + function computeExpirationTime(lane, currentTime) { + switch (lane) { + case SyncHydrationLane: + 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 + syncLaneExpirationMs; + + 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: + return currentTime + transitionLaneExpirationMs; + + case RetryLane1: + case RetryLane2: + case RetryLane3: + case RetryLane4: + // 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: + case DeferredLane: + // Anything idle priority or lower should never expire. + return NoTimestamp; + + default: + { + error("Should have found matching lanes. This is a bug in React."); + } + + return NoTimestamp; } - return null; - } - function mountHookTypesDev() { - var hookName = currentHookNameInDev; - null === hookTypesDev - ? (hookTypesDev = [hookName]) - : hookTypesDev.push(hookName); } - function updateHookTypesDev() { - var hookName = currentHookNameInDev; - if ( - null !== hookTypesDev && - (hookTypesUpdateIndexDev++, - hookTypesDev[hookTypesUpdateIndexDev] !== hookName) - ) { - var componentName = getComponentNameFromFiber( - currentlyRenderingFiber$1 - ); - if ( - !didWarnAboutMismatchedHooksForComponent.has(componentName) && - (didWarnAboutMismatchedHooksForComponent.add(componentName), - null !== hookTypesDev) - ) { - for (var table = "", i = 0; i <= hookTypesUpdateIndexDev; i++) { - var oldHookName = hookTypesDev[i], - newHookName = - i === hookTypesUpdateIndexDev ? hookName : oldHookName; - for ( - oldHookName = i + 1 + ". " + oldHookName; - 30 > oldHookName.length; - ) - oldHookName += " "; - oldHookName += newHookName + "\n"; - table += oldHookName; - } - error$jscomp$0( - "React has detected a change in the order of Hooks called by %s. This will lead to bugs and errors if not fixed. For more information, read the Rules of Hooks: https://react.dev/link/rules-of-hooks\n\n Previous render Next render\n ------------------------------------------------------\n%s ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", - componentName, - table - ); + 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. + // TODO: We should be able to replace this with upgradePendingLanesToSync + // + // We exclude retry lanes because those must always be time sliced, in order + // to unwrap uncached promises. + // TODO: Write a test for this + + var lanes = pendingLanes & ~RetryLanes; + + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + var expirationTime = expirationTimes[index]; + + if (expirationTime === NoTimestamp) { + // Found a pending lane with no expiration time. If it's not suspended, or + // if it's pinged, assume it's CPU-bound. Compute a new expiration time + // using the current time. + if ( + (lane & suspendedLanes) === NoLanes || + (lane & pingedLanes) !== NoLanes + ) { + // Assumes timestamps are monotonically increasing. + expirationTimes[index] = computeExpirationTime(lane, currentTime); + } + } else if (expirationTime <= currentTime) { + // This lane expired + root.expiredLanes |= lane; } + + lanes &= ~lane; + } + } // This returns the highest priority pending lanes regardless of whether they + function getLanesToRetrySynchronouslyOnError( + root, + originallyAttemptedLanes + ) { + if (root.errorRecoveryDisabledLanes & originallyAttemptedLanes) { + // The error recovery mechanism is disabled until these lanes are cleared. + return NoLanes; + } + + var everythingButOffscreen = root.pendingLanes & ~OffscreenLane; + + if (everythingButOffscreen !== NoLanes) { + return everythingButOffscreen; + } + + if (everythingButOffscreen & OffscreenLane) { + return OffscreenLane; } + + return NoLanes; } - function checkDepsAreArrayDev(deps) { - void 0 === deps || - null === deps || - isArrayImpl(deps) || - error$jscomp$0( - "%s received a final argument that is not an array (instead, received `%s`). When specified, the final argument must be an array.", - currentHookNameInDev, - typeof deps - ); + function includesSyncLane(lanes) { + return (lanes & (SyncLane | SyncHydrationLane)) !== NoLanes; } - function warnOnUseFormStateInDev() { - var componentName = getComponentNameFromFiber(currentlyRenderingFiber$1); - didWarnAboutUseFormState.has(componentName) || - (didWarnAboutUseFormState.add(componentName), - error$jscomp$0( - "ReactDOM.useFormState has been renamed to React.useActionState. Please update %s to use React.useActionState.", - componentName - )); + function includesNonIdleWork(lanes) { + return (lanes & NonIdleLanes) !== NoLanes; } - function throwInvalidHookError() { - throw Error( - "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://react.dev/link/invalid-hook-call for tips about how to debug and fix this problem." - ); + function includesOnlyRetries(lanes) { + return (lanes & RetryLanes) === lanes; } - function areHookInputsEqual(nextDeps, prevDeps) { - if (ignorePreviousDependencies) return !1; - if (null === prevDeps) - return ( - error$jscomp$0( - "%s received a final argument during this render, but not during the previous render. Even though the final argument is optional, its type cannot change between renders.", - currentHookNameInDev - ), - !1 - ); - nextDeps.length !== prevDeps.length && - error$jscomp$0( - "The final argument passed to %s changed size between renders. The order and size of this array must remain constant.\n\nPrevious: %s\nIncoming: %s", - currentHookNameInDev, - "[" + prevDeps.join(", ") + "]", - "[" + nextDeps.join(", ") + "]" - ); - for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) - if (!objectIs(nextDeps[i], prevDeps[i])) return !1; - return !0; + function includesOnlyNonUrgentLanes(lanes) { + // TODO: Should hydration lanes be included here? This function is only + // used in `updateDeferredValueImpl`. + var UrgentLanes = SyncLane | InputContinuousLane | DefaultLane; + return (lanes & UrgentLanes) === NoLanes; } - function renderWithHooks( - current, - workInProgress, - Component, - props, - secondArg, - nextRenderLanes - ) { - renderLanes = nextRenderLanes; - currentlyRenderingFiber$1 = workInProgress; - hookTypesDev = null !== current ? current._debugHookTypes : null; - hookTypesUpdateIndexDev = -1; - ignorePreviousDependencies = - null !== current && current.type !== workInProgress.type; - if ( - "[object AsyncFunction]" === - Object.prototype.toString.call(Component) || - "[object AsyncGeneratorFunction]" === - Object.prototype.toString.call(Component) - ) - (nextRenderLanes = getComponentNameFromFiber( - currentlyRenderingFiber$1 - )), - didWarnAboutAsyncClientComponent.has(nextRenderLanes) || - (didWarnAboutAsyncClientComponent.add(nextRenderLanes), - error$jscomp$0( - "async/await is not yet supported in Client Components, only Server Components. This error is often caused by accidentally adding `'use client'` to a module that was originally written for the server." - )); - workInProgress.memoizedState = null; - workInProgress.updateQueue = null; - workInProgress.lanes = 0; - ReactSharedInternals.H = - null !== current && null !== current.memoizedState - ? HooksDispatcherOnUpdateInDEV - : null !== hookTypesDev - ? HooksDispatcherOnMountWithHookTypesInDEV - : HooksDispatcherOnMountInDEV; - shouldDoubleInvokeUserFnsInHooksDEV = nextRenderLanes = - 0 !== (workInProgress.mode & 8); - var children = callComponentInDEV(Component, props, secondArg); - shouldDoubleInvokeUserFnsInHooksDEV = !1; - didScheduleRenderPhaseUpdateDuringThisPass && - (children = renderWithHooksAgain( - workInProgress, - Component, - props, - secondArg - )); - if (nextRenderLanes) { - setIsStrictModeForDevtools(!0); - try { - children = renderWithHooksAgain( - workInProgress, - Component, - props, - secondArg - ); - } finally { - setIsStrictModeForDevtools(!1); - } - } - finishRenderingHooks(current, workInProgress); - return children; + function includesOnlyTransitions(lanes) { + return (lanes & TransitionLanes) === lanes; } - function finishRenderingHooks(current, workInProgress) { - workInProgress._debugHookTypes = hookTypesDev; - ReactSharedInternals.H = ContextOnlyDispatcher; - var didRenderTooFewHooks = - null !== currentHook && null !== currentHook.next; - renderLanes = 0; - hookTypesDev = - currentHookNameInDev = - workInProgressHook = - currentHook = - currentlyRenderingFiber$1 = - null; - hookTypesUpdateIndexDev = -1; - null !== current && - (current.flags & 31457280) !== (workInProgress.flags & 31457280) && - 0 !== (current.mode & 1) && - error$jscomp$0( - "Internal React error: Expected static flag was missing. Please notify the React team." - ); - didScheduleRenderPhaseUpdate = !1; - thenableIndexCounter = 0; - thenableState = null; - if (didRenderTooFewHooks) - throw Error( - "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." - ); - needsToResetSuspendedThenableDEV - ? ((needsToResetSuspendedThenableDEV = !1), (current = !0)) - : (current = !1); - current && - ((workInProgress = - getComponentNameFromFiber(workInProgress) || "Unknown"), - didWarnAboutUseWrappedInTryCatch.has(workInProgress) || - didWarnAboutAsyncClientComponent.has(workInProgress) || - (didWarnAboutUseWrappedInTryCatch.add(workInProgress), - error$jscomp$0( - "`use` was called from inside a try/catch block. This is not allowed and can lead to unexpected behavior. To handle errors triggered by `use`, wrap your component in a error boundary." - ))); + function includesBlockingLane(root, lanes) { + var SyncDefaultLanes = + InputContinuousHydrationLane | + InputContinuousLane | + DefaultHydrationLane | + DefaultLane; + return (lanes & SyncDefaultLanes) !== NoLanes; } - function renderWithHooksAgain(workInProgress, Component, props, secondArg) { - currentlyRenderingFiber$1 = workInProgress; - var numberOfReRenders = 0; - do { - didScheduleRenderPhaseUpdateDuringThisPass && (thenableState = null); - thenableIndexCounter = 0; - didScheduleRenderPhaseUpdateDuringThisPass = !1; - if (numberOfReRenders >= RE_RENDER_LIMIT) - throw Error( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." - ); - numberOfReRenders += 1; - ignorePreviousDependencies = !1; - workInProgressHook = currentHook = null; - workInProgress.updateQueue = null; - hookTypesUpdateIndexDev = -1; - ReactSharedInternals.H = HooksDispatcherOnRerenderInDEV; - var children = callComponentInDEV(Component, props, secondArg); - } while (didScheduleRenderPhaseUpdateDuringThisPass); - return children; + function includesExpiredLane(root, lanes) { + // This is a separate check from includesBlockingLane because a lane can + // expire after a render has already started. + return (lanes & root.expiredLanes) !== NoLanes; } - function TransitionAwareHostComponent() { - var dispatcher = ReactSharedInternals.H, - maybeThenable = dispatcher.useState()[0]; - maybeThenable = - "function" === typeof maybeThenable.then - ? useThenable(maybeThenable) - : maybeThenable; - dispatcher = dispatcher.useState()[0]; - (null !== currentHook ? currentHook.memoizedState : null) !== - dispatcher && (currentlyRenderingFiber$1.flags |= 1024); - return maybeThenable; + function isTransitionLane(lane) { + return (lane & TransitionLanes) !== NoLanes; } - function bailoutHooks(current, workInProgress, lanes) { - workInProgress.updateQueue = current.updateQueue; - workInProgress.flags = - 0 !== (workInProgress.mode & 16) - ? workInProgress.flags & -201328645 - : workInProgress.flags & -2053; - current.lanes &= ~lanes; + 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; + + if ((nextTransitionLane & TransitionLanes) === NoLanes) { + nextTransitionLane = TransitionLane1; + } + + return lane; } - function resetHooksOnUnwind(workInProgress) { - if (didScheduleRenderPhaseUpdate) { - for ( - workInProgress = workInProgress.memoizedState; - null !== workInProgress; + function claimNextRetryLane() { + var lane = nextRetryLane; + nextRetryLane <<= 1; - ) { - var queue = workInProgress.queue; - null !== queue && (queue.pending = null); - workInProgress = workInProgress.next; - } - didScheduleRenderPhaseUpdate = !1; - } - renderLanes = 0; - hookTypesDev = - workInProgressHook = - currentHook = - currentlyRenderingFiber$1 = - null; - hookTypesUpdateIndexDev = -1; - currentHookNameInDev = null; - didScheduleRenderPhaseUpdateDuringThisPass = !1; - thenableIndexCounter = 0; - thenableState = null; + if ((nextRetryLane & RetryLanes) === NoLanes) { + nextRetryLane = RetryLane1; + } + + return lane; } - function mountWorkInProgressHook() { - var hook = { - memoizedState: null, - baseState: null, - baseQueue: null, - queue: null, - next: null - }; - null === workInProgressHook - ? (currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook) - : (workInProgressHook = workInProgressHook.next = hook); - return workInProgressHook; + function getHighestPriorityLane(lanes) { + return lanes & -lanes; } - function updateWorkInProgressHook() { - if (null === currentHook) { - var nextCurrentHook = currentlyRenderingFiber$1.alternate; - nextCurrentHook = - null !== nextCurrentHook ? nextCurrentHook.memoizedState : null; - } else nextCurrentHook = currentHook.next; - var nextWorkInProgressHook = - null === workInProgressHook - ? currentlyRenderingFiber$1.memoizedState - : workInProgressHook.next; - if (null !== nextWorkInProgressHook) - (workInProgressHook = nextWorkInProgressHook), - (currentHook = nextCurrentHook); - else { - if (null === nextCurrentHook) { - if (null === currentlyRenderingFiber$1.alternate) - throw Error( - "Update hook called on initial render. This is likely a bug in React. Please file an issue." - ); - throw Error("Rendered more hooks than during the previous render."); - } - currentHook = nextCurrentHook; - nextCurrentHook = { - memoizedState: currentHook.memoizedState, - baseState: currentHook.baseState, - baseQueue: currentHook.baseQueue, - queue: currentHook.queue, - next: null - }; - null === workInProgressHook - ? (currentlyRenderingFiber$1.memoizedState = workInProgressHook = - nextCurrentHook) - : (workInProgressHook = workInProgressHook.next = nextCurrentHook); - } - return workInProgressHook; + 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); } - function useThenable(thenable) { - var index = thenableIndexCounter; - thenableIndexCounter += 1; - null === thenableState && (thenableState = createThenableState()); - thenable = trackUsedThenable(thenableState, thenable, index); - index = currentlyRenderingFiber$1; - null === - (null === workInProgressHook - ? index.memoizedState - : workInProgressHook.next) && - ((index = index.alternate), - (ReactSharedInternals.H = - null !== index && null !== index.memoizedState - ? HooksDispatcherOnUpdateInDEV - : HooksDispatcherOnMountInDEV)); - return thenable; + + function pickArbitraryLaneIndex(lanes) { + return 31 - clz32(lanes); } - function use(usable) { - if (null !== usable && "object" === typeof usable) { - if ("function" === typeof usable.then) return useThenable(usable); - if (usable.$$typeof === REACT_CONTEXT_TYPE) return readContext(usable); - } - throw Error("An unsupported type was passed to use(): " + String(usable)); + + function laneToIndex(lane) { + return pickArbitraryLaneIndex(lane); } - function useMemoCache(size) { - var memoCache = null, - updateQueue = currentlyRenderingFiber$1.updateQueue; - null !== updateQueue && (memoCache = updateQueue.memoCache); - if (null == memoCache) { - var current = currentlyRenderingFiber$1.alternate; - null !== current && - ((current = current.updateQueue), - null !== current && - ((current = current.memoCache), - null != current && - (memoCache = { - data: current.data.map(function (array) { - return array.slice(); - }), - index: 0 - }))); - } - null == memoCache && (memoCache = { data: [], index: 0 }); - null === updateQueue && - ((updateQueue = createFunctionComponentUpdateQueue()), - (currentlyRenderingFiber$1.updateQueue = updateQueue)); - updateQueue.memoCache = memoCache; - updateQueue = memoCache.data[memoCache.index]; - if (void 0 === updateQueue) - for ( - updateQueue = memoCache.data[memoCache.index] = Array(size), - current = 0; - current < size; - current++ - ) - updateQueue[current] = REACT_MEMO_CACHE_SENTINEL; - else - updateQueue.length !== size && - error$jscomp$0( - "Expected a constant size argument for each invocation of useMemoCache. The previous cache was allocated with size %s but size %s was requested.", - updateQueue.length, - size - ); - memoCache.index++; - return updateQueue; + + function includesSomeLane(a, b) { + return (a & b) !== NoLanes; } - function basicStateReducer(state, action) { - return "function" === typeof action ? action(state) : action; + function isSubsetOfLanes(set, subset) { + return (set & subset) === subset; } - function mountReducer(reducer, initialArg, init) { - var hook = mountWorkInProgressHook(); - if (void 0 !== init) { - var initialState = init(initialArg); - shouldDoubleInvokeUserFnsInHooksDEV && - (setIsStrictModeForDevtools(!0), - init(initialArg), - setIsStrictModeForDevtools(!1)); - } else initialState = initialArg; - hook.memoizedState = hook.baseState = initialState; - reducer = { - pending: null, - lanes: 0, - dispatch: null, - lastRenderedReducer: reducer, - lastRenderedState: initialState - }; - hook.queue = reducer; - reducer = reducer.dispatch = dispatchReducerAction.bind( - null, - currentlyRenderingFiber$1, - reducer - ); - return [hook.memoizedState, reducer]; + function mergeLanes(a, b) { + return a | b; } - function updateReducer(reducer) { - var hook = updateWorkInProgressHook(); - return updateReducerImpl(hook, currentHook, reducer); + function removeLanes(set, subset) { + return set & ~subset; } - function updateReducerImpl(hook, current, reducer) { - var queue = hook.queue; - if (null === queue) - throw Error( - "Should have a queue. You are likely calling Hooks conditionally, which is not allowed. (https://react.dev/link/invalid-hook-call)" - ); - queue.lastRenderedReducer = reducer; - var baseQueue = hook.baseQueue, - pendingQueue = queue.pending; - if (null !== pendingQueue) { - if (null !== baseQueue) { - var baseFirst = baseQueue.next; - baseQueue.next = pendingQueue.next; - pendingQueue.next = baseFirst; - } - current.baseQueue !== baseQueue && - error$jscomp$0( - "Internal error: Expected work-in-progress queue to be a clone. This is a bug in React." - ); - current.baseQueue = baseQueue = pendingQueue; - queue.pending = null; - } - pendingQueue = hook.baseState; - if (null === baseQueue) hook.memoizedState = pendingQueue; - else { - current = baseQueue.next; - var newBaseQueueFirst = (baseFirst = null), - newBaseQueueLast = null, - update = current, - didReadFromEntangledAsyncAction = !1; - do { - var updateLane = update.lane & ~OffscreenLane; - if ( - updateLane !== update.lane - ? (workInProgressRootRenderLanes & updateLane) === updateLane - : (renderLanes & updateLane) === updateLane - ) { - var revertLane = update.revertLane; - if (0 === revertLane) - null !== newBaseQueueLast && - (newBaseQueueLast = newBaseQueueLast.next = - { - lane: 0, - revertLane: 0, - action: update.action, - hasEagerState: update.hasEagerState, - eagerState: update.eagerState, - next: null - }), - updateLane === currentEntangledLane && - (didReadFromEntangledAsyncAction = !0); - else if ((renderLanes & revertLane) === revertLane) { - update = update.next; - revertLane === currentEntangledLane && - (didReadFromEntangledAsyncAction = !0); - continue; - } else - (updateLane = { - lane: 0, - revertLane: update.revertLane, - action: update.action, - hasEagerState: update.hasEagerState, - eagerState: update.eagerState, - next: null - }), - null === newBaseQueueLast - ? ((newBaseQueueFirst = newBaseQueueLast = updateLane), - (baseFirst = pendingQueue)) - : (newBaseQueueLast = newBaseQueueLast.next = updateLane), - (currentlyRenderingFiber$1.lanes |= revertLane), - (workInProgressRootSkippedLanes |= revertLane); - updateLane = update.action; - shouldDoubleInvokeUserFnsInHooksDEV && - reducer(pendingQueue, updateLane); - pendingQueue = update.hasEagerState - ? update.eagerState - : reducer(pendingQueue, updateLane); - } else - (revertLane = { - lane: updateLane, - revertLane: update.revertLane, - action: update.action, - hasEagerState: update.hasEagerState, - eagerState: update.eagerState, - next: null - }), - null === newBaseQueueLast - ? ((newBaseQueueFirst = newBaseQueueLast = revertLane), - (baseFirst = pendingQueue)) - : (newBaseQueueLast = newBaseQueueLast.next = revertLane), - (currentlyRenderingFiber$1.lanes |= updateLane), - (workInProgressRootSkippedLanes |= updateLane); - update = update.next; - } while (null !== update && update !== current); - null === newBaseQueueLast - ? (baseFirst = pendingQueue) - : (newBaseQueueLast.next = newBaseQueueFirst); - if ( - !objectIs(pendingQueue, hook.memoizedState) && - ((didReceiveUpdate = !0), - didReadFromEntangledAsyncAction && - ((reducer = currentEntangledActionThenable), null !== reducer)) - ) - throw reducer; - hook.memoizedState = pendingQueue; - hook.baseState = baseFirst; - hook.baseQueue = newBaseQueueLast; - queue.lastRenderedState = pendingQueue; - } - null === baseQueue && (queue.lanes = 0); - return [hook.memoizedState, queue.dispatch]; + 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 laneToLanes(lane) { + return lane; } - function rerenderReducer(reducer) { - var hook = updateWorkInProgressHook(), - queue = hook.queue; - if (null === queue) - throw Error( - "Should have a queue. You are likely calling Hooks conditionally, which is not allowed. (https://react.dev/link/invalid-hook-call)" - ); - queue.lastRenderedReducer = reducer; - var dispatch = queue.dispatch, - lastRenderPhaseUpdate = queue.pending, - newState = hook.memoizedState; - if (null !== lastRenderPhaseUpdate) { - queue.pending = null; - var update = (lastRenderPhaseUpdate = lastRenderPhaseUpdate.next); - do - (newState = reducer(newState, update.action)), (update = update.next); - while (update !== lastRenderPhaseUpdate); - objectIs(newState, hook.memoizedState) || (didReceiveUpdate = !0); - hook.memoizedState = newState; - null === hook.baseQueue && (hook.baseState = newState); - queue.lastRenderedState = newState; + 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); } - return [newState, dispatch]; + + return laneMap; } - function mountSyncExternalStore(subscribe, getSnapshot) { - var fiber = currentlyRenderingFiber$1, - hook = mountWorkInProgressHook(); - var nextSnapshot = getSnapshot(); - if (!didWarnUncachedGetSnapshot) { - var cachedSnapshot = getSnapshot(); - objectIs(nextSnapshot, cachedSnapshot) || - (error$jscomp$0( - "The result of getSnapshot should be cached to avoid an infinite loop" - ), - (didWarnUncachedGetSnapshot = !0)); + function markRootUpdated$1(root, updateLane) { + root.pendingLanes |= updateLane; // If there are any suspended transitions, it's possible this new update + // could unblock them. Clear the suspended lanes so that we can try rendering + // them again. + // + // 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. + + if (updateLane !== IdleLane) { + root.suspendedLanes = NoLanes; + root.pingedLanes = NoLanes; } - if (null === workInProgressRoot) - throw Error( - "Expected a work-in-progress root. This is a bug in React. Please file an issue." - ); - 0 !== - (workInProgressRootRenderLanes & - (InputContinuousHydrationLane | - InputContinuousLane | - DefaultHydrationLane | - DefaultLane)) || - pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot); - hook.memoizedState = nextSnapshot; - cachedSnapshot = { value: nextSnapshot, getSnapshot: getSnapshot }; - hook.queue = cachedSnapshot; - mountEffect( - subscribeToStore.bind(null, fiber, cachedSnapshot, subscribe), - [subscribe] - ); - fiber.flags |= 2048; - pushEffect( - HasEffect | Passive, - updateStoreInstance.bind( - null, - fiber, - cachedSnapshot, - nextSnapshot, - getSnapshot - ), - { destroy: void 0 }, - null - ); - return nextSnapshot; } - function updateSyncExternalStore(subscribe, getSnapshot) { - var fiber = currentlyRenderingFiber$1, - hook = updateWorkInProgressHook(); - var nextSnapshot = getSnapshot(); - if (!didWarnUncachedGetSnapshot) { - var cachedSnapshot = getSnapshot(); - objectIs(nextSnapshot, cachedSnapshot) || - (error$jscomp$0( - "The result of getSnapshot should be cached to avoid an infinite loop" - ), - (didWarnUncachedGetSnapshot = !0)); + function markRootSuspended$1(root, suspendedLanes, spawnedLane) { + 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; } - if ( - (cachedSnapshot = !objectIs( - (currentHook || hook).memoizedState, - nextSnapshot - )) - ) - (hook.memoizedState = nextSnapshot), (didReceiveUpdate = !0); - hook = hook.queue; - var create = subscribeToStore.bind(null, fiber, hook, subscribe); - updateEffectImpl(2048, Passive, create, [subscribe]); - if ( - hook.getSnapshot !== getSnapshot || - cachedSnapshot || - (null !== workInProgressHook && - workInProgressHook.memoizedState.tag & HasEffect) - ) { - fiber.flags |= 2048; - pushEffect( - HasEffect | Passive, - updateStoreInstance.bind( - null, - fiber, - hook, - nextSnapshot, - getSnapshot - ), - { destroy: void 0 }, - null + + if (spawnedLane !== NoLane) { + markSpawnedDeferredLane(root, spawnedLane, suspendedLanes); + } + } + function markRootPinged$1(root, pingedLanes) { + root.pingedLanes |= root.suspendedLanes & pingedLanes; + } + function markRootFinished(root, remainingLanes, spawnedLane) { + var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; + root.pendingLanes = remainingLanes; // Let's try everything again + + root.suspendedLanes = NoLanes; + root.pingedLanes = NoLanes; + root.expiredLanes &= remainingLanes; + root.entangledLanes &= remainingLanes; + root.errorRecoveryDisabledLanes &= remainingLanes; + root.shellSuspendCounter = 0; + var entanglements = root.entanglements; + var expirationTimes = root.expirationTimes; + var hiddenUpdates = root.hiddenUpdates; // Clear the lanes that no longer have pending work + + var lanes = noLongerPendingLanes; + + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + entanglements[index] = NoLanes; + expirationTimes[index] = NoTimestamp; + var hiddenUpdatesForLane = hiddenUpdates[index]; + + if (hiddenUpdatesForLane !== null) { + hiddenUpdates[index] = null; // "Hidden" updates are updates that were made to a hidden component. They + // have special logic associated with them because they may be entangled + // with updates that occur outside that tree. But once the outer tree + // commits, they behave like regular updates. + + for (var i = 0; i < hiddenUpdatesForLane.length; i++) { + var update = hiddenUpdatesForLane[i]; + + if (update !== null) { + update.lane &= ~OffscreenLane; + } + } + } + + lanes &= ~lane; + } + + if (spawnedLane !== NoLane) { + markSpawnedDeferredLane( + root, + spawnedLane, // This render finished successfully without suspending, so we don't need + // to entangle the spawned task with the parent task. + NoLanes ); - if (null === workInProgressRoot) - throw Error( - "Expected a work-in-progress root. This is a bug in React. Please file an issue." - ); - 0 !== - (renderLanes & - (InputContinuousHydrationLane | - InputContinuousLane | - DefaultHydrationLane | - DefaultLane)) || - pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot); } - return nextSnapshot; } - function pushStoreConsistencyCheck(fiber, getSnapshot, renderedSnapshot) { - fiber.flags |= 16384; - fiber = { getSnapshot: getSnapshot, value: renderedSnapshot }; - getSnapshot = currentlyRenderingFiber$1.updateQueue; - null === getSnapshot - ? ((getSnapshot = createFunctionComponentUpdateQueue()), - (currentlyRenderingFiber$1.updateQueue = getSnapshot), - (getSnapshot.stores = [fiber])) - : ((renderedSnapshot = getSnapshot.stores), - null === renderedSnapshot - ? (getSnapshot.stores = [fiber]) - : renderedSnapshot.push(fiber)); + + function markSpawnedDeferredLane(root, spawnedLane, entangledLanes) { + // This render spawned a deferred task. Mark it as pending. + root.pendingLanes |= spawnedLane; + root.suspendedLanes &= ~spawnedLane; // Entangle the spawned lane with the DeferredLane bit so that we know it + // was the result of another render. This lets us avoid a useDeferredValue + // waterfall — only the first level will defer. + + var spawnedLaneIndex = laneToIndex(spawnedLane); + root.entangledLanes |= spawnedLane; + root.entanglements[spawnedLaneIndex] |= + DeferredLane | // If the parent render task suspended, we must also entangle those lanes + // with the spawned task, so that the deferred task includes all the same + // updates that the parent task did. We can exclude any lane that is not + // used for updates (e.g. Offscreen). + (entangledLanes & UpdateLanes); } - function updateStoreInstance(fiber, inst, nextSnapshot, getSnapshot) { - inst.value = nextSnapshot; - inst.getSnapshot = getSnapshot; - checkIfSnapshotChanged(inst) && forceStoreRerender(fiber); + + 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; + + while (lanes) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + + if ( + // Is this one of the newly entangled lanes? + (lane & entangledLanes) | // Is this lane transitively entangled with the newly entangled lanes? + (entanglements[index] & entangledLanes) + ) { + entanglements[index] |= entangledLanes; + } + + lanes &= ~lane; + } } - function subscribeToStore(fiber, inst, subscribe) { - return subscribe(function () { - checkIfSnapshotChanged(inst) && forceStoreRerender(fiber); - }); + function upgradePendingLaneToSync(root, lane) { + // Since we're upgrading the priority of the given lane, there is now pending + // sync work. + root.pendingLanes |= SyncLane; // Entangle the sync lane with the lane we're upgrading. This means SyncLane + // will not be allowed to finish without also finishing the given lane. + + root.entangledLanes |= SyncLane; + root.entanglements[SyncLaneIndex] |= lane; } - function checkIfSnapshotChanged(inst) { - var latestGetSnapshot = inst.getSnapshot; - inst = inst.value; - try { - var nextValue = latestGetSnapshot(); - return !objectIs(inst, nextValue); - } catch (error$4) { - return !0; + function markHiddenUpdate(root, update, lane) { + var index = laneToIndex(lane); + var hiddenUpdates = root.hiddenUpdates; + var hiddenUpdatesForLane = hiddenUpdates[index]; + + if (hiddenUpdatesForLane === null) { + hiddenUpdates[index] = [update]; + } else { + hiddenUpdatesForLane.push(update); } + + update.lane = lane | OffscreenLane; } - function forceStoreRerender(fiber) { - var root = enqueueConcurrentRenderForLane(fiber, SyncLane); - null !== root && scheduleUpdateOnFiber(root, fiber, SyncLane); + function getBumpedLaneForHydration(root, renderLanes) { + var renderLane = getHighestPriorityLane(renderLanes); + var lane; + + if ((renderLane & SyncUpdateLanes) !== NoLane) { + lane = SyncHydrationLane; + } else { + switch (renderLane) { + case SyncLane: + lane = SyncHydrationLane; + break; + + case InputContinuousLane: + lane = InputContinuousHydrationLane; + break; + + case DefaultLane: + lane = DefaultHydrationLane; + break; + + case TransitionLane1: + case TransitionLane2: + case TransitionLane3: + case TransitionLane4: + case TransitionLane5: + case TransitionLane6: + case TransitionLane7: + case TransitionLane8: + case TransitionLane9: + case TransitionLane10: + case TransitionLane11: + case TransitionLane12: + case TransitionLane13: + case TransitionLane14: + case TransitionLane15: + case RetryLane1: + case RetryLane2: + case RetryLane3: + case RetryLane4: + lane = TransitionHydrationLane; + break; + + case IdleLane: + lane = IdleHydrationLane; + break; + + default: + // Everything else is already either a hydration lane, or shouldn't + // be retried at a hydration lane. + lane = NoLane; + break; + } + } // Check if the lane we chose is suspended. If so, that indicates that we + // already attempted and failed to hydrate at that level. Also check if we're + // already rendering that lane, which is rare but could happen. + + if ((lane & (root.suspendedLanes | renderLanes)) !== NoLane) { + // Give up trying to hydrate and fall back to client render. + return NoLane; + } + + return lane; } - function mountStateImpl(initialState) { - var hook = mountWorkInProgressHook(); - if ("function" === typeof initialState) { - var initialStateInitializer = initialState; - initialState = initialStateInitializer(); - shouldDoubleInvokeUserFnsInHooksDEV && - (setIsStrictModeForDevtools(!0), - initialStateInitializer(), - setIsStrictModeForDevtools(!1)); + function addFiberToLanesMap(root, fiber, lanes) { + if (!isDevToolsPresent) { + return; + } + + var pendingUpdatersLaneMap = root.pendingUpdatersLaneMap; + + while (lanes > 0) { + var index = laneToIndex(lanes); + var lane = 1 << index; + var updaters = pendingUpdatersLaneMap[index]; + updaters.add(fiber); + lanes &= ~lane; } - hook.memoizedState = hook.baseState = initialState; - hook.queue = { - pending: null, - lanes: 0, - dispatch: null, - lastRenderedReducer: basicStateReducer, - lastRenderedState: initialState - }; - return hook; } - function mountState(initialState) { - initialState = mountStateImpl(initialState); - var queue = initialState.queue, - dispatch = dispatchSetState.bind( - null, - currentlyRenderingFiber$1, - queue - ); - queue.dispatch = dispatch; - return [initialState.memoizedState, dispatch]; + function movePendingFibersToMemoized(root, lanes) { + if (!isDevToolsPresent) { + return; + } + + var pendingUpdatersLaneMap = root.pendingUpdatersLaneMap; + var memoizedUpdaters = root.memoizedUpdaters; + + while (lanes > 0) { + var index = laneToIndex(lanes); + var lane = 1 << index; + var updaters = pendingUpdatersLaneMap[index]; + + if (updaters.size > 0) { + updaters.forEach(function (fiber) { + var alternate = fiber.alternate; + + if (alternate === null || !memoizedUpdaters.has(alternate)) { + memoizedUpdaters.add(fiber); + } + }); + updaters.clear(); + } + + lanes &= ~lane; + } } - function mountOptimistic(passthrough) { - var hook = mountWorkInProgressHook(); - hook.memoizedState = hook.baseState = passthrough; - var queue = { - pending: null, - lanes: 0, - dispatch: null, - lastRenderedReducer: null, - lastRenderedState: null - }; - hook.queue = queue; - hook = dispatchOptimisticSetState.bind( - null, - currentlyRenderingFiber$1, - !0, - queue - ); - queue.dispatch = hook; - return [passthrough, hook]; + function getTransitionsForLanes(root, lanes) { + { + return null; + } } - function updateOptimistic(passthrough, reducer) { - var hook = updateWorkInProgressHook(); - return updateOptimisticImpl(hook, currentHook, passthrough, reducer); - } - function updateOptimisticImpl(hook, current, passthrough, reducer) { - hook.baseState = passthrough; - return updateReducerImpl( - hook, - currentHook, - "function" === typeof reducer ? reducer : basicStateReducer + + 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); + + if (!isHigherEventPriority(DiscreteEventPriority, lane)) { + return DiscreteEventPriority; + } + + if (!isHigherEventPriority(ContinuousEventPriority, lane)) { + return ContinuousEventPriority; + } + + if (includesNonIdleWork(lane)) { + return DefaultEventPriority; + } + + return IdleEventPriority; + } + + // Renderers that don't support mutation + // can re-export everything from this module. + function shim$2() { + throw new Error( + "The current renderer does not support mutation. " + + "This error is likely caused by a bug in React. " + + "Please file an issue." + ); + } // Mutation (when unsupported) + var commitMount = shim$2; + + // Renderers that don't support hydration + // can re-export everything from this module. + function shim$1() { + throw new 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 getSuspenseInstanceFallbackErrorDetails = shim$1; + var registerSuspenseInstanceRetry = shim$1; + var errorHydratingContainer = shim$1; + + // Renderers that don't support hydration + // can re-export everything from this module. + function shim() { + throw new Error( + "The current renderer does not support Resources. " + + "This error is likely caused by a bug in React. " + + "Please file an issue." + ); + } // Resources (when unsupported) + var suspendResource = shim; + + var _nativeFabricUIManage = nativeFabricUIManager, + createNode = _nativeFabricUIManage.createNode, + cloneNodeWithNewChildren = _nativeFabricUIManage.cloneNodeWithNewChildren, + cloneNodeWithNewChildrenAndProps = + _nativeFabricUIManage.cloneNodeWithNewChildrenAndProps, + cloneNodeWithNewProps = _nativeFabricUIManage.cloneNodeWithNewProps, + createChildNodeSet = _nativeFabricUIManage.createChildSet, + appendChildNode = _nativeFabricUIManage.appendChild, + appendChildNodeToSet = _nativeFabricUIManage.appendChildToSet, + completeRoot = _nativeFabricUIManage.completeRoot, + registerEventHandler = _nativeFabricUIManage.registerEventHandler, + FabricDefaultPriority = + _nativeFabricUIManage.unstable_DefaultEventPriority, + FabricDiscretePriority = + _nativeFabricUIManage.unstable_DiscreteEventPriority, + fabricGetCurrentEventPriority = + _nativeFabricUIManage.unstable_getCurrentEventPriority; + 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); } - function rerenderOptimistic(passthrough, reducer) { - var hook = updateWorkInProgressHook(); - if (null !== currentHook) - return updateOptimisticImpl(hook, currentHook, passthrough, reducer); - hook.baseState = passthrough; - return [passthrough, hook.queue.dispatch]; + function appendInitialChild(parentInstance, child) { + appendChildNode(parentInstance.node, child.node); } - function dispatchActionState( - fiber, - actionQueue, - setPendingState, - setState, - payload + function createInstance( + type, + props, + rootContainerInstance, + hostContext, + internalInstanceHandle ) { - if (isRenderPhaseUpdate(fiber)) - throw Error("Cannot update form state while rendering."); - fiber = actionQueue.action; - if (null !== fiber) { - var actionNode = { - payload: payload, - action: fiber, - next: null, - isTransition: !0, - status: "pending", - value: null, - reason: null, - listeners: [], - then: function (listener) { - actionNode.listeners.push(listener); + var tag = nextReactTag; + nextReactTag += 2; + var viewConfig = getViewConfigForType(type); + + { + for (var key in viewConfig.validAttributes) { + if (props.hasOwnProperty(key)) { + ReactNativePrivateInterface.deepFreezeAndThrowOnMutationInDev( + props[key] + ); } - }; - null !== ReactSharedInternals.T - ? setPendingState(!0) - : (actionNode.isTransition = !1); - setState(actionNode); - setPendingState = actionQueue.pending; - null === setPendingState - ? ((actionNode.next = actionQueue.pending = actionNode), - runActionStateAction(actionQueue, actionNode)) - : ((actionNode.next = setPendingState.next), - (actionQueue.pending = setPendingState.next = actionNode)); - } - } - function runActionStateAction(actionQueue, node) { - var action = node.action, - payload = node.payload, - prevState = actionQueue.state; - if (node.isTransition) { - var prevTransition = ReactSharedInternals.T, - currentTransition = {}; - ReactSharedInternals.T = currentTransition; - ReactSharedInternals.T._updatedFibers = new Set(); - try { - var returnValue = action(prevState, payload), - onStartTransitionFinish = ReactSharedInternals.S; - null !== onStartTransitionFinish && - onStartTransitionFinish(currentTransition, returnValue); - handleActionReturnValue(actionQueue, node, returnValue); - } catch (error$5) { - onActionError(actionQueue, node, error$5); - } finally { - (ReactSharedInternals.T = prevTransition), - null === prevTransition && - currentTransition._updatedFibers && - ((actionQueue = currentTransition._updatedFibers.size), - currentTransition._updatedFibers.clear(), - 10 < actionQueue && - warn( - "Detected a large number of updates inside startTransition. If this is due to a subscription please re-write it to use React provided hooks. Otherwise concurrent mode guarantees are off the table." - )); - } - } else - try { - (currentTransition = action(prevState, payload)), - handleActionReturnValue(actionQueue, node, currentTransition); - } catch (error$6) { - onActionError(actionQueue, node, error$6); - } - } - function handleActionReturnValue(actionQueue, node, returnValue) { - null !== returnValue && - "object" === typeof returnValue && - "function" === typeof returnValue.then - ? (returnValue.then( - function (nextState) { - onActionSuccess(actionQueue, node, nextState); - }, - function (error) { - return onActionError(actionQueue, node, error); - } - ), - node.isTransition || - error$jscomp$0( - "An async function was passed to useActionState, but it was dispatched outside of an action context. This is likely not what you intended. Either pass the dispatch function to an `action` prop, or dispatch manually inside `startTransition`" - )) - : onActionSuccess(actionQueue, node, returnValue); - } - function onActionSuccess(actionQueue, actionNode, nextState) { - actionNode.status = "fulfilled"; - actionNode.value = nextState; - notifyActionListeners(actionNode); - actionQueue.state = nextState; - actionNode = actionQueue.pending; - null !== actionNode && - ((nextState = actionNode.next), - nextState === actionNode - ? (actionQueue.pending = null) - : ((nextState = nextState.next), - (actionNode.next = nextState), - runActionStateAction(actionQueue, nextState))); - } - function onActionError(actionQueue, actionNode, error) { - var last = actionQueue.pending; - actionQueue.pending = null; - if (null !== last) { - last = last.next; - do - (actionNode.status = "rejected"), - (actionNode.reason = error), - notifyActionListeners(actionNode), - (actionNode = actionNode.next); - while (actionNode !== last); - } - actionQueue.action = null; - } - function notifyActionListeners(actionNode) { - actionNode = actionNode.listeners; - for (var i = 0; i < actionNode.length; i++) (0, actionNode[i])(); - } - function actionStateReducer(oldState, newState) { - return newState; - } - function mountActionState(action, initialStateProp) { - var stateHook = mountWorkInProgressHook(); - stateHook.memoizedState = stateHook.baseState = initialStateProp; - var stateQueue = { - pending: null, - lanes: 0, - dispatch: null, - lastRenderedReducer: actionStateReducer, - lastRenderedState: initialStateProp - }; - stateHook.queue = stateQueue; - stateHook = dispatchSetState.bind( - null, - currentlyRenderingFiber$1, - stateQueue + } + } + + var updatePayload = create(props, viewConfig.validAttributes); + var node = createNode( + tag, // reactTag + viewConfig.uiViewClassName, // viewName + rootContainerInstance, // rootTag + updatePayload, // props + internalInstanceHandle // internalInstanceHandle ); - stateQueue.dispatch = stateHook; - stateQueue = mountStateImpl(!1); - var setPendingState = dispatchOptimisticSetState.bind( - null, - currentlyRenderingFiber$1, - !1, - stateQueue.queue + var component = ReactNativePrivateInterface.createPublicInstance( + tag, + viewConfig, + internalInstanceHandle ); - stateQueue = mountWorkInProgressHook(); - var actionQueue = { - state: initialStateProp, - dispatch: null, - action: action, - pending: null + return { + node: node, + canonical: { + nativeTag: tag, + viewConfig: viewConfig, + currentProps: props, + internalInstanceHandle: internalInstanceHandle, + publicInstance: component + } }; - stateQueue.queue = actionQueue; - stateHook = dispatchActionState.bind( - null, - currentlyRenderingFiber$1, - actionQueue, - setPendingState, - stateHook - ); - actionQueue.dispatch = stateHook; - stateQueue.memoizedState = action; - return [initialStateProp, stateHook, !1]; - } - function updateActionState(action) { - var stateHook = updateWorkInProgressHook(); - return updateActionStateImpl(stateHook, currentHook, action); - } - function updateActionStateImpl(stateHook, currentStateHook, action) { - currentStateHook = updateReducerImpl( - stateHook, - currentStateHook, - actionStateReducer - )[0]; - stateHook = updateReducer(basicStateReducer)[0]; - currentStateHook = - "object" === typeof currentStateHook && - null !== currentStateHook && - "function" === typeof currentStateHook.then - ? useThenable(currentStateHook) - : currentStateHook; - var actionQueueHook = updateWorkInProgressHook(), - actionQueue = actionQueueHook.queue, - dispatch = actionQueue.dispatch; - action !== actionQueueHook.memoizedState && - ((currentlyRenderingFiber$1.flags |= 2048), - pushEffect( - HasEffect | Passive, - actionStateActionEffect.bind(null, actionQueue, action), - { destroy: void 0 }, - null - )); - return [currentStateHook, dispatch, stateHook]; - } - function actionStateActionEffect(actionQueue, action) { - actionQueue.action = action; - } - function rerenderActionState(action) { - var stateHook = updateWorkInProgressHook(), - currentStateHook = currentHook; - if (null !== currentStateHook) - return updateActionStateImpl(stateHook, currentStateHook, action); - updateWorkInProgressHook(); - stateHook = stateHook.memoizedState; - currentStateHook = updateWorkInProgressHook(); - var dispatch = currentStateHook.queue.dispatch; - currentStateHook.memoizedState = action; - return [stateHook, dispatch, !1]; - } - function pushEffect(tag, create, inst, deps) { - tag = { tag: tag, create: create, inst: inst, deps: deps, next: null }; - create = currentlyRenderingFiber$1.updateQueue; - null === create - ? ((create = createFunctionComponentUpdateQueue()), - (currentlyRenderingFiber$1.updateQueue = create), - (create.lastEffect = tag.next = tag)) - : ((inst = create.lastEffect), - null === inst - ? (create.lastEffect = tag.next = tag) - : ((deps = inst.next), - (inst.next = tag), - (tag.next = deps), - (create.lastEffect = tag))); - return tag; - } - function mountRef(initialValue) { - var hook = mountWorkInProgressHook(); - initialValue = { current: initialValue }; - return (hook.memoizedState = initialValue); } - function mountEffectImpl(fiberFlags, hookFlags, create, deps) { - var hook = mountWorkInProgressHook(); - currentlyRenderingFiber$1.flags |= fiberFlags; - hook.memoizedState = pushEffect( - HasEffect | hookFlags, - create, - { destroy: void 0 }, - void 0 === deps ? null : deps + function createTextInstance( + text, + rootContainerInstance, + hostContext, + internalInstanceHandle + ) { + { + if (!hostContext.isInAParentText) { + error("Text strings must be rendered within a component."); + } + } + + var tag = nextReactTag; + nextReactTag += 2; + var node = createNode( + tag, // reactTag + "RCTRawText", // viewName + rootContainerInstance, // rootTag + { + text: text + }, // props + internalInstanceHandle // instance handle ); + return { + node: node + }; } - function updateEffectImpl(fiberFlags, hookFlags, create, deps) { - var hook = updateWorkInProgressHook(); - deps = void 0 === deps ? null : deps; - var inst = hook.memoizedState.inst; - null !== currentHook && - null !== deps && - areHookInputsEqual(deps, currentHook.memoizedState.deps) - ? (hook.memoizedState = pushEffect(hookFlags, create, inst, deps)) - : ((currentlyRenderingFiber$1.flags |= fiberFlags), - (hook.memoizedState = pushEffect( - HasEffect | hookFlags, - create, - inst, - deps - ))); - } - function mountEffect(create, deps) { - 0 !== (currentlyRenderingFiber$1.mode & 16) && - 0 === (currentlyRenderingFiber$1.mode & 64) - ? mountEffectImpl(142608384, Passive, create, deps) - : mountEffectImpl(8390656, Passive, create, deps); - } - function mountLayoutEffect(create, deps) { - var fiberFlags = 4194308; - 0 !== (currentlyRenderingFiber$1.mode & 16) && (fiberFlags |= 67108864); - return mountEffectImpl(fiberFlags, Layout, create, deps); + function getRootHostContext(rootContainerInstance) { + return { + isInAParentText: false + }; } - function imperativeHandleEffect(create, ref) { - if ("function" === typeof ref) { - create = create(); - var refCleanup = ref(create); - return function () { - "function" === typeof refCleanup ? refCleanup() : ref(null); + function getChildHostContext(parentHostContext, type) { + var prevIsInAParentText = parentHostContext.isInAParentText; + var isInAParentText = + type === "AndroidTextInput" || // Android + type === "RCTMultilineTextInputView" || // iOS + type === "RCTSinglelineTextInputView" || // iOS + type === "RCTText" || + type === "RCTVirtualText"; // TODO: If this is an offscreen host container, we should reuse the + // parent context. + + if (prevIsInAParentText !== isInAParentText) { + return { + isInAParentText: isInAParentText }; + } else { + return parentHostContext; } - if (null !== ref && void 0 !== ref) - return ( - ref.hasOwnProperty("current") || - error$jscomp$0( - "Expected useImperativeHandle() first argument to either be a ref callback or React.createRef() object. Instead received: %s.", - "an object with keys {" + Object.keys(ref).join(", ") + "}" - ), - (create = create()), - (ref.current = create), - function () { - ref.current = null; - } - ); } - function mountImperativeHandle(ref, create, deps) { - "function" !== typeof create && - error$jscomp$0( - "Expected useImperativeHandle() second argument to be a function that creates a handle. Instead received: %s.", - null !== create ? typeof create : "null" - ); - deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; - var fiberFlags = 4194308; - 0 !== (currentlyRenderingFiber$1.mode & 16) && (fiberFlags |= 67108864); - mountEffectImpl( - fiberFlags, - Layout, - imperativeHandleEffect.bind(null, create, ref), - deps - ); - } - function updateImperativeHandle(ref, create, deps) { - "function" !== typeof create && - error$jscomp$0( - "Expected useImperativeHandle() second argument to be a function that creates a handle. Instead received: %s.", - null !== create ? typeof create : "null" - ); - deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; - updateEffectImpl( - 4, - Layout, - imperativeHandleEffect.bind(null, create, ref), - deps - ); - } - function mountCallback(callback, deps) { - mountWorkInProgressHook().memoizedState = [ - callback, - void 0 === deps ? null : deps - ]; - return callback; - } - function updateCallback(callback, deps) { - var hook = updateWorkInProgressHook(); - deps = void 0 === deps ? null : deps; - var prevState = hook.memoizedState; - if (null !== deps && areHookInputsEqual(deps, prevState[1])) - return prevState[0]; - hook.memoizedState = [callback, deps]; - return callback; - } - function mountMemo(nextCreate, deps) { - var hook = mountWorkInProgressHook(); - deps = void 0 === deps ? null : deps; - var nextValue = nextCreate(); - shouldDoubleInvokeUserFnsInHooksDEV && - (setIsStrictModeForDevtools(!0), - nextCreate(), - setIsStrictModeForDevtools(!1)); - hook.memoizedState = [nextValue, deps]; - return nextValue; - } - function updateMemo(nextCreate, deps) { - var hook = updateWorkInProgressHook(); - deps = void 0 === deps ? null : deps; - var prevState = hook.memoizedState; - if (null !== deps && areHookInputsEqual(deps, prevState[1])) - return prevState[0]; - prevState = nextCreate(); - shouldDoubleInvokeUserFnsInHooksDEV && - (setIsStrictModeForDevtools(!0), - nextCreate(), - setIsStrictModeForDevtools(!1)); - hook.memoizedState = [prevState, deps]; - return prevState; - } - function mountDeferredValue(value, initialValue) { - var hook = mountWorkInProgressHook(); - return mountDeferredValueImpl(hook, value, initialValue); - } - function updateDeferredValue(value, initialValue) { - var hook = updateWorkInProgressHook(); - return updateDeferredValueImpl( - hook, - currentHook.memoizedState, - value, - initialValue - ); + function getPublicInstance(instance) { + if ( + instance.canonical != null && + instance.canonical.publicInstance != null + ) { + return instance.canonical.publicInstance; + } // For compatibility with the legacy renderer, in case it's used with Fabric + // in the same app. + // $FlowExpectedError[prop-missing] + + if (instance._nativeTag != null) { + // $FlowExpectedError[incompatible-return] + return instance; + } + + return null; } - function rerenderDeferredValue(value, initialValue) { - var hook = updateWorkInProgressHook(); - return null === currentHook - ? mountDeferredValueImpl(hook, value, initialValue) - : updateDeferredValueImpl( - hook, - currentHook.memoizedState, - value, - initialValue + + function getPublicTextInstance(textInstance, internalInstanceHandle) { + if (textInstance.publicInstance == null) { + textInstance.publicInstance = + ReactNativePrivateInterface.createPublicTextInstance( + internalInstanceHandle ); + } + + return textInstance.publicInstance; } - function mountDeferredValueImpl(hook, value, initialValue) { - if (void 0 === initialValue || 0 !== (renderLanes & DeferredLane)) - return (hook.memoizedState = value); - hook.memoizedState = initialValue; - hook = requestDeferredLane(); - currentlyRenderingFiber$1.lanes |= hook; - workInProgressRootSkippedLanes |= hook; - return initialValue; - } - function updateDeferredValueImpl(hook, prevValue, value, initialValue) { - if (objectIs(value, prevValue)) return value; - if (null !== currentTreeHiddenStackCursor.current) - return ( - (hook = mountDeferredValueImpl(hook, value, initialValue)), - objectIs(hook, prevValue) || (didReceiveUpdate = !0), - hook - ); - if (0 === (renderLanes & (SyncLane | InputContinuousLane | DefaultLane))) - return (didReceiveUpdate = !0), (hook.memoizedState = value); - hook = requestDeferredLane(); - currentlyRenderingFiber$1.lanes |= hook; - workInProgressRootSkippedLanes |= hook; - return prevValue; - } - function startTransition( - fiber, - queue, - pendingState, - finishedState, - callback + + function getPublicInstanceFromInternalInstanceHandle( + internalInstanceHandle ) { - var previousPriority = currentUpdatePriority; - currentUpdatePriority = - 0 !== previousPriority && previousPriority < ContinuousEventPriority - ? previousPriority - : ContinuousEventPriority; - var prevTransition = ReactSharedInternals.T, - currentTransition = {}; - ReactSharedInternals.T = currentTransition; - dispatchOptimisticSetState(fiber, !1, queue, pendingState); - currentTransition._updatedFibers = new Set(); - try { - var returnValue = callback(), - onStartTransitionFinish = ReactSharedInternals.S; - null !== onStartTransitionFinish && - onStartTransitionFinish(currentTransition, returnValue); - if ( - null !== returnValue && - "object" === typeof returnValue && - "function" === typeof returnValue.then - ) { - var thenableForFinishedState = chainThenableValue( - returnValue, - finishedState - ); - dispatchSetState(fiber, queue, thenableForFinishedState); - } else dispatchSetState(fiber, queue, finishedState); - } catch (error$7) { - dispatchSetState(fiber, queue, { - then: function () {}, - status: "rejected", - reason: error$7 - }); - } finally { - (currentUpdatePriority = previousPriority), - (ReactSharedInternals.T = prevTransition), - null === prevTransition && - currentTransition._updatedFibers && - ((fiber = currentTransition._updatedFibers.size), - currentTransition._updatedFibers.clear(), - 10 < fiber && - warn( - "Detected a large number of updates inside startTransition. If this is due to a subscription please re-write it to use React provided hooks. Otherwise concurrent mode guarantees are off the table." - )); + var instance = internalInstanceHandle.stateNode; // React resets all the fields in the fiber when the component is unmounted + // to prevent memory leaks. + + if (instance == null) { + return null; } - } - function mountTransition() { - var stateHook = mountStateImpl(!1); - stateHook = startTransition.bind( - null, - currentlyRenderingFiber$1, - stateHook.queue, - !0, - !1 - ); - mountWorkInProgressHook().memoizedState = stateHook; - return [!1, stateHook]; - } - function updateTransition() { - var booleanOrThenable = updateReducer(basicStateReducer)[0], - start = updateWorkInProgressHook().memoizedState; - return [ - "boolean" === typeof booleanOrThenable - ? booleanOrThenable - : useThenable(booleanOrThenable), - start - ]; - } - function rerenderTransition() { - var booleanOrThenable = rerenderReducer(basicStateReducer)[0], - start = updateWorkInProgressHook().memoizedState; - return [ - "boolean" === typeof booleanOrThenable - ? booleanOrThenable - : useThenable(booleanOrThenable), - start - ]; - } - function useHostTransitionStatus() { - var status = readContext(HostTransitionContext); - return null !== status ? status : null; - } - function mountId() { - var hook = mountWorkInProgressHook(), - identifierPrefix = workInProgressRoot.identifierPrefix, - globalClientId = globalClientIdCounter++; - identifierPrefix = - ":" + identifierPrefix + "r" + globalClientId.toString(32) + ":"; - return (hook.memoizedState = identifierPrefix); - } - function mountRefresh() { - return (mountWorkInProgressHook().memoizedState = refreshCache.bind( - null, - currentlyRenderingFiber$1 - )); - } - function refreshCache(fiber, seedKey) { - for (var provider = fiber.return; null !== provider; ) { - switch (provider.tag) { - case 24: - case 3: - var lane = requestUpdateLane(provider); - fiber = createUpdate(lane); - var root = enqueueUpdate(provider, fiber, lane); - null !== root && - (scheduleUpdateOnFiber(root, provider, lane), - entangleTransitions(root, provider, lane)); - provider = createCache(); - null !== seedKey && - void 0 !== seedKey && - null !== root && - error$jscomp$0( - "The seed argument is not enabled outside experimental channels." - ); - fiber.payload = { cache: provider }; - return; + + if (internalInstanceHandle.tag === HostText) { + var textInstance = instance; + return getPublicTextInstance(textInstance, internalInstanceHandle); + } + + var elementInstance = internalInstanceHandle.stateNode; + return getPublicInstance(elementInstance); + } + 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() { + var currentEventPriority = fabricGetCurrentEventPriority + ? fabricGetCurrentEventPriority() + : null; + + if (currentEventPriority != null) { + switch (currentEventPriority) { + case FabricDiscretePriority: + return DiscreteEventPriority; + + case FabricDefaultPriority: + default: + return DefaultEventPriority; } - provider = provider.return; } + + return DefaultEventPriority; } - function dispatchReducerAction( - fiber, - queue, - action, - JSCompiler_OptimizeArgumentsArray_p0 - ) { - "function" === typeof JSCompiler_OptimizeArgumentsArray_p0 && - error$jscomp$0( - "State updates from the useState() and useReducer() Hooks don't support the second callback argument. To execute a side effect after rendering, declare it in the component body with useEffect()." - ); - JSCompiler_OptimizeArgumentsArray_p0 = requestUpdateLane(fiber); - action = { - lane: JSCompiler_OptimizeArgumentsArray_p0, - revertLane: 0, - action: action, - hasEagerState: !1, - eagerState: null, - next: null - }; - isRenderPhaseUpdate(fiber) - ? enqueueRenderPhaseUpdate(queue, action) - : ((action = enqueueConcurrentHookUpdate( - fiber, - queue, - action, - JSCompiler_OptimizeArgumentsArray_p0 - )), - null !== action && - (scheduleUpdateOnFiber( - action, - fiber, - JSCompiler_OptimizeArgumentsArray_p0 - ), - entangleTransitionUpdate( - action, - queue, - JSCompiler_OptimizeArgumentsArray_p0 - ))); - markStateUpdateScheduled(fiber, JSCompiler_OptimizeArgumentsArray_p0); - } - function dispatchSetState( - fiber, - queue, - action, - JSCompiler_OptimizeArgumentsArray_p1 + function shouldAttemptEagerTransition() { + return false; + } // The Fabric renderer is secondary to the existing React Native renderer. + + var warnsIfNotActing = false; + var scheduleTimeout = setTimeout; + var cancelTimeout = clearTimeout; + var noTimeout = -1; // ------------------- + function cloneInstance( + instance, + type, + oldProps, + newProps, + keepChildren, + newChildSet ) { - "function" === typeof JSCompiler_OptimizeArgumentsArray_p1 && - error$jscomp$0( - "State updates from the useState() and useReducer() Hooks don't support the second callback argument. To execute a side effect after rendering, declare it in the component body with useEffect()." - ); - JSCompiler_OptimizeArgumentsArray_p1 = requestUpdateLane(fiber); - var update = { - lane: JSCompiler_OptimizeArgumentsArray_p1, - revertLane: 0, - action: action, - hasEagerState: !1, - eagerState: null, - next: null - }; - if (isRenderPhaseUpdate(fiber)) enqueueRenderPhaseUpdate(queue, update); - else { - var alternate = fiber.alternate; - if ( - 0 === fiber.lanes && - (null === alternate || 0 === alternate.lanes) && - ((alternate = queue.lastRenderedReducer), null !== alternate) - ) { - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = InvalidNestedHooksDispatcherOnUpdateInDEV; - try { - var currentState = queue.lastRenderedState, - eagerState = alternate(currentState, action); - update.hasEagerState = !0; - update.eagerState = eagerState; - if (objectIs(eagerState, currentState)) { - enqueueUpdate$1(fiber, queue, update, 0); - null === workInProgressRoot && finishQueueingConcurrentUpdates(); - return; - } - } catch (error$8) { - } finally { - ReactSharedInternals.H = prevDispatcher; + 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; + var node = instance.node; + var clone; + + if (keepChildren) { + if (updatePayload !== null) { + clone = cloneNodeWithNewProps(node, updatePayload); + } else { + // No changes + return instance; + } + } else { + // If passChildrenWhenCloningPersistedNodes is enabled, children will be non-null + if (newChildSet != null) { + if (updatePayload !== null) { + clone = cloneNodeWithNewChildrenAndProps( + node, + newChildSet, + updatePayload + ); + } else { + clone = cloneNodeWithNewChildren(node, newChildSet); + } + } else { + if (updatePayload !== null) { + clone = cloneNodeWithNewChildrenAndProps(node, updatePayload); + } else { + clone = cloneNodeWithNewChildren(node); } } - action = enqueueConcurrentHookUpdate( - fiber, - queue, - update, - JSCompiler_OptimizeArgumentsArray_p1 - ); - null !== action && - (scheduleUpdateOnFiber( - action, - fiber, - JSCompiler_OptimizeArgumentsArray_p1 - ), - entangleTransitionUpdate( - action, - queue, - JSCompiler_OptimizeArgumentsArray_p1 - )); } - markStateUpdateScheduled(fiber, JSCompiler_OptimizeArgumentsArray_p1); - } - function dispatchOptimisticSetState( - fiber, - throwIfDuringRender, - queue, - action - ) { - null === ReactSharedInternals.T && - 0 === currentEntangledLane && - error$jscomp$0( - "An optimistic state update occurred outside a transition or action. To fix, move the update to an action, or wrap with startTransition." - ); - action = { - lane: SyncLane, - revertLane: requestTransitionLane(), - action: action, - hasEagerState: !1, - eagerState: null, - next: null + + return { + node: clone, + canonical: instance.canonical }; - if (isRenderPhaseUpdate(fiber)) { - if (throwIfDuringRender) - throw Error("Cannot update optimistic state while rendering."); - error$jscomp$0("Cannot call startTransition while rendering."); - } else - (throwIfDuringRender = enqueueConcurrentHookUpdate( - fiber, - queue, - action, - SyncLane - )), - null !== throwIfDuringRender && - scheduleUpdateOnFiber(throwIfDuringRender, fiber, SyncLane); - markStateUpdateScheduled(fiber, SyncLane); } - function isRenderPhaseUpdate(fiber) { - var alternate = fiber.alternate; - return ( - fiber === currentlyRenderingFiber$1 || - (null !== alternate && alternate === currentlyRenderingFiber$1) + function cloneHiddenInstance(instance, type, props) { + 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 enqueueRenderPhaseUpdate(queue, update) { - didScheduleRenderPhaseUpdateDuringThisPass = - didScheduleRenderPhaseUpdate = !0; - var pending = queue.pending; - null === pending - ? (update.next = update) - : ((update.next = pending.next), (pending.next = update)); - queue.pending = update; - } - function entangleTransitionUpdate(root, queue, lane) { - if (0 !== (lane & TransitionLanes)) { - var queueLanes = queue.lanes; - queueLanes &= root.pendingLanes; - lane |= queueLanes; - queue.lanes = lane; - markRootEntangled(root, lane); - } - } - function startProfilerTimer(fiber) { - profilerStartTime = now(); - 0 > fiber.actualStartTime && (fiber.actualStartTime = now()); + function cloneHiddenTextInstance(instance, text) { + throw new Error("Not yet implemented."); } - function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) { - if (0 <= profilerStartTime) { - var elapsedTime = now() - profilerStartTime; - fiber.actualDuration += elapsedTime; - overrideBaseTime && (fiber.selfBaseDuration = elapsedTime); - profilerStartTime = -1; + function createContainerChildSet() { + { + return createChildNodeSet(); } } - function recordLayoutEffectDuration(fiber) { - if (0 <= layoutEffectStartTime) { - var elapsedTime = now() - layoutEffectStartTime; - layoutEffectStartTime = -1; - for (fiber = fiber.return; null !== fiber; ) { - switch (fiber.tag) { - case 3: - fiber.stateNode.effectDuration += elapsedTime; - return; - case 12: - fiber.stateNode.effectDuration += elapsedTime; - return; - } - fiber = fiber.return; - } + function appendChildToContainerChildSet(childSet, child) { + { + appendChildNodeToSet(childSet, child.node); } } - function recordPassiveEffectDuration(fiber) { - if (0 <= passiveEffectStartTime) { - var elapsedTime = now() - passiveEffectStartTime; - passiveEffectStartTime = -1; - for (fiber = fiber.return; null !== fiber; ) { - switch (fiber.tag) { - case 3: - fiber = fiber.stateNode; - null !== fiber && (fiber.passiveEffectDuration += elapsedTime); - return; - case 12: - fiber = fiber.stateNode; - null !== fiber && (fiber.passiveEffectDuration += elapsedTime); - return; - } - fiber = fiber.return; - } - } + function finalizeContainerChildren(container, newChildren) { + completeRoot(container, newChildren); } - function startLayoutEffectTimer() { - layoutEffectStartTime = now(); + function replaceContainerChildren(container, newChildren) { + // Noop - children will be replaced in finalizeContainerChildren } - function transferActualDuration(fiber) { - for (var child = fiber.child; child; ) - (fiber.actualDuration += child.actualDuration), (child = child.sibling); + function preloadInstance(type, props) { + return true; } - function warnOnInvalidCallback(callback) { - if (null !== callback && "function" !== typeof callback) { - var key = String(callback); - didWarnOnInvalidCallback.has(key) || - (didWarnOnInvalidCallback.add(key), - error$jscomp$0( - "Expected the last optional `callback` argument to be a function. Instead received: %s.", - callback - )); - } + function waitForCommitToBeReady() { + return null; } - function applyDerivedStateFromProps( - workInProgress, - ctor, - getDerivedStateFromProps, - nextProps - ) { - var prevState = workInProgress.memoizedState, - partialState = getDerivedStateFromProps(nextProps, prevState); - if (workInProgress.mode & 8) { - setIsStrictModeForDevtools(!0); - try { - partialState = getDerivedStateFromProps(nextProps, prevState); - } finally { - setIsStrictModeForDevtools(!1); - } - } - void 0 === partialState && - ((ctor = getComponentNameFromType(ctor) || "Component"), - didWarnAboutUndefinedDerivedState.has(ctor) || - (didWarnAboutUndefinedDerivedState.add(ctor), - error$jscomp$0( - "%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. You have returned undefined.", - ctor - ))); - prevState = - null === partialState || void 0 === partialState - ? prevState - : assign({}, prevState, partialState); - workInProgress.memoizedState = prevState; - 0 === workInProgress.lanes && - (workInProgress.updateQueue.baseState = prevState); + // Microtasks + // ------------------- + + var supportsMicrotasks = + typeof RN$enableMicrotasksInReact !== "undefined" && + !!RN$enableMicrotasksInReact; + var scheduleMicrotask = + typeof queueMicrotask === "function" ? queueMicrotask : scheduleTimeout; + + // This is ok in DOM because they types are interchangeable, but in React Native + // they aren't. + + function getInstanceFromNode(node) { + var instance = node; // In React Native, node is never a text instance + + if ( + instance.canonical != null && + instance.canonical.internalInstanceHandle != null + ) { + return instance.canonical.internalInstanceHandle; + } // $FlowFixMe[incompatible-return] DevTools incorrectly passes a fiber in React Native. + + return node; } - function checkShouldComponentUpdate( - workInProgress, - ctor, - oldProps, - newProps, - oldState, - newState, - nextContext - ) { - var instance = workInProgress.stateNode; - if ("function" === typeof instance.shouldComponentUpdate) { - oldProps = instance.shouldComponentUpdate( - newProps, - newState, - nextContext - ); - if (workInProgress.mode & 8) { - setIsStrictModeForDevtools(!0); - try { - oldProps = instance.shouldComponentUpdate( - newProps, - newState, - nextContext - ); - } finally { - setIsStrictModeForDevtools(!1); - } - } - void 0 === oldProps && - error$jscomp$0( - "%s.shouldComponentUpdate(): Returned undefined instead of a boolean value. Make sure to return true or false.", - getComponentNameFromType(ctor) || "Component" - ); - return oldProps; + + function getNodeFromInstance(fiber) { + var publicInstance = getPublicInstance(fiber.stateNode); + + if (publicInstance == null) { + throw new Error("Could not find host instance from fiber"); } - return ctor.prototype && ctor.prototype.isPureReactComponent - ? !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState) - : !0; + + return publicInstance; } - function constructClassInstance(workInProgress, ctor, props) { - var context = emptyContextObject, - contextType = ctor.contextType; - if ( - "contextType" in ctor && - null !== contextType && - (void 0 === contextType || - contextType.$$typeof !== REACT_CONTEXT_TYPE) && - !didWarnAboutInvalidateContextType.has(ctor) - ) { - didWarnAboutInvalidateContextType.add(ctor); - var addendum = - void 0 === contextType - ? " However, it is set to undefined. This can be caused by a typo or by mixing up named and default imports. This can also happen due to a circular dependency, so try moving the createContext() call to a separate file." - : "object" !== typeof contextType - ? " However, it is set to a " + typeof contextType + "." - : contextType.$$typeof === REACT_CONSUMER_TYPE - ? " Did you accidentally pass the Context.Consumer instead?" - : " However, it is set to an object with keys {" + - Object.keys(contextType).join(", ") + - "}."; - error$jscomp$0( - "%s defines an invalid contextType. contextType should point to the Context object returned by React.createContext().%s", - getComponentNameFromType(ctor) || "Component", - addendum - ); - } - "object" === typeof contextType && - null !== contextType && - (context = readContext(contextType)); - contextType = new ctor(props, context); - if (workInProgress.mode & 8) { - setIsStrictModeForDevtools(!0); - try { - contextType = new ctor(props, context); - } finally { - setIsStrictModeForDevtools(!1); - } - } - props = workInProgress.memoizedState = - null !== contextType.state && void 0 !== contextType.state - ? contextType.state - : null; - contextType.updater = classComponentUpdater; - workInProgress.stateNode = contextType; - contextType._reactInternals = workInProgress; - contextType._reactInternalInstance = fakeInternalInstance; - "function" === typeof ctor.getDerivedStateFromProps && - null === props && - ((workInProgress = getComponentNameFromType(ctor) || "Component"), - didWarnAboutUninitializedState.has(workInProgress) || - (didWarnAboutUninitializedState.add(workInProgress), - error$jscomp$0( - "`%s` uses `getDerivedStateFromProps` but its initial state is %s. This is not recommended. Instead, define the initial state by assigning an object to `this.state` in the constructor of `%s`. This ensures that `getDerivedStateFromProps` arguments have a consistent shape.", - workInProgress, - null === contextType.state ? "null" : "undefined", - workInProgress - ))); - if ( - "function" === typeof ctor.getDerivedStateFromProps || - "function" === typeof contextType.getSnapshotBeforeUpdate - ) - if ( - ((context = props = workInProgress = null), - "function" === typeof contextType.componentWillMount && - !0 !== contextType.componentWillMount.__suppressDeprecationWarning - ? (workInProgress = "componentWillMount") - : "function" === typeof contextType.UNSAFE_componentWillMount && - (workInProgress = "UNSAFE_componentWillMount"), - "function" === typeof contextType.componentWillReceiveProps && - !0 !== - contextType.componentWillReceiveProps.__suppressDeprecationWarning - ? (props = "componentWillReceiveProps") - : "function" === - typeof contextType.UNSAFE_componentWillReceiveProps && - (props = "UNSAFE_componentWillReceiveProps"), - "function" === typeof contextType.componentWillUpdate && - !0 !== contextType.componentWillUpdate.__suppressDeprecationWarning - ? (context = "componentWillUpdate") - : "function" === typeof contextType.UNSAFE_componentWillUpdate && - (context = "UNSAFE_componentWillUpdate"), - null !== workInProgress || null !== props || null !== context) - ) - (addendum = getComponentNameFromType(ctor) || "Component"), - (ctor = - "function" === typeof ctor.getDerivedStateFromProps - ? "getDerivedStateFromProps()" - : "getSnapshotBeforeUpdate()"), - didWarnAboutLegacyLifecyclesAndDerivedState.has(addendum) || - (didWarnAboutLegacyLifecyclesAndDerivedState.add(addendum), - error$jscomp$0( - "Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n%s uses %s but also contains the following legacy lifecycles:%s%s%s\n\nThe above lifecycles should be removed. Learn more about this warning here:\nhttps://react.dev/link/unsafe-component-lifecycles", - addendum, - ctor, - null !== workInProgress ? "\n " + workInProgress : "", - null !== props ? "\n " + props : "", - null !== context ? "\n " + context : "" - )); - return contextType; - } - function callComponentWillReceiveProps( - workInProgress, - instance, - newProps, - nextContext - ) { - var oldState = instance.state; - "function" === typeof instance.componentWillReceiveProps && - instance.componentWillReceiveProps(newProps, nextContext); - "function" === typeof instance.UNSAFE_componentWillReceiveProps && - instance.UNSAFE_componentWillReceiveProps(newProps, nextContext); - instance.state !== oldState && - ((workInProgress = - getComponentNameFromFiber(workInProgress) || "Component"), - didWarnAboutStateAssignmentForComponent.has(workInProgress) || - (didWarnAboutStateAssignmentForComponent.add(workInProgress), - error$jscomp$0( - "%s.componentWillReceiveProps(): Assigning directly to this.state is deprecated (except inside a component's constructor). Use setState instead.", - workInProgress - )), - classComponentUpdater.enqueueReplaceState( - instance, - instance.state, - null - )); + + function getFiberCurrentPropsFromNode(instance) { + return instance.canonical.currentProps; } - function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { - var instance = workInProgress.stateNode, - name = getComponentNameFromType(ctor) || "Component"; - instance.render || - (ctor.prototype && "function" === typeof ctor.prototype.render - ? error$jscomp$0( - "No `render` method found on the %s instance: did you accidentally return an object from the constructor?", - name - ) - : error$jscomp$0( - "No `render` method found on the %s instance: you may have forgotten to define `render`.", - name - )); - !instance.getInitialState || - instance.getInitialState.isReactClassApproved || - instance.state || - error$jscomp$0( - "getInitialState was defined on %s, a plain JavaScript class. This is only supported for classes created using React.createClass. Did you mean to define a state property instead?", - name - ); - instance.getDefaultProps && - !instance.getDefaultProps.isReactClassApproved && - error$jscomp$0( - "getDefaultProps was defined on %s, a plain JavaScript class. This is only supported for classes created using React.createClass. Use a static property to define defaultProps instead.", - name - ); - instance.propTypes && - error$jscomp$0( - "propTypes was defined as an instance property on %s. Use a static property to define propTypes instead.", - name - ); - instance.contextType && - error$jscomp$0( - "contextType was defined as an instance property on %s. Use a static property to define contextType instead.", - name - ); - ctor.childContextTypes && - error$jscomp$0( - "%s uses the legacy childContextTypes API which was removed in React 19. Use React.createContext() instead.", - name - ); - ctor.contextTypes && - error$jscomp$0( - "%s uses the legacy contextTypes API which was removed in React 19. Use React.createContext() with static contextType instead.", - name - ); - "function" === typeof instance.componentShouldUpdate && - error$jscomp$0( - "%s has a method called componentShouldUpdate(). Did you mean shouldComponentUpdate()? The name is phrased as a question because the function is expected to return a value.", - name - ); - ctor.prototype && - ctor.prototype.isPureReactComponent && - "undefined" !== typeof instance.shouldComponentUpdate && - error$jscomp$0( - "%s has a method called shouldComponentUpdate(). shouldComponentUpdate should not be used when extending React.PureComponent. Please extend React.Component if shouldComponentUpdate is used.", - getComponentNameFromType(ctor) || "A pure component" - ); - "function" === typeof instance.componentDidUnmount && - error$jscomp$0( - "%s has a method called componentDidUnmount(). But there is no such lifecycle method. Did you mean componentWillUnmount()?", - name - ); - "function" === typeof instance.componentDidReceiveProps && - error$jscomp$0( - "%s has a method called componentDidReceiveProps(). But there is no such lifecycle method. If you meant to update the state in response to changing props, use componentWillReceiveProps(). If you meant to fetch data or run side-effects or mutations after React has updated the UI, use componentDidUpdate().", - name - ); - "function" === typeof instance.componentWillRecieveProps && - error$jscomp$0( - "%s has a method called componentWillRecieveProps(). Did you mean componentWillReceiveProps()?", - name - ); - "function" === typeof instance.UNSAFE_componentWillRecieveProps && - error$jscomp$0( - "%s has a method called UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?", - name - ); - var hasMutatedProps = instance.props !== newProps; - void 0 !== instance.props && - hasMutatedProps && - error$jscomp$0( - "When calling super() in `%s`, make sure to pass up the same props that your component's constructor was passed.", - name - ); - instance.defaultProps && - error$jscomp$0( - "Setting defaultProps as an instance property on %s is not supported and will be ignored. Instead, define defaultProps as a static property on %s.", - name, - name - ); - "function" !== typeof instance.getSnapshotBeforeUpdate || - "function" === typeof instance.componentDidUpdate || - didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor) || - (didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor), - error$jscomp$0( - "%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). This component defines getSnapshotBeforeUpdate() only.", - getComponentNameFromType(ctor) - )); - "function" === typeof instance.getDerivedStateFromProps && - error$jscomp$0( - "%s: getDerivedStateFromProps() is defined as an instance method and will be ignored. Instead, declare it as a static method.", - name - ); - "function" === typeof instance.getDerivedStateFromError && - error$jscomp$0( - "%s: getDerivedStateFromError() is defined as an instance method and will be ignored. Instead, declare it as a static method.", - name - ); - "function" === typeof ctor.getSnapshotBeforeUpdate && - error$jscomp$0( - "%s: getSnapshotBeforeUpdate() is defined as a static method and will be ignored. Instead, declare it as an instance method.", - name - ); - (hasMutatedProps = instance.state) && - ("object" !== typeof hasMutatedProps || isArrayImpl(hasMutatedProps)) && - error$jscomp$0("%s.state: must be set to an object or null", name); - "function" === typeof instance.getChildContext && - "object" !== typeof ctor.childContextTypes && - error$jscomp$0( - "%s.getChildContext(): childContextTypes must be defined in order to use getChildContext().", - name - ); - instance = workInProgress.stateNode; - instance.props = newProps; - instance.state = workInProgress.memoizedState; - instance.refs = {}; - initializeUpdateQueue(workInProgress); - name = ctor.contextType; - instance.context = - "object" === typeof name && null !== name - ? readContext(name) - : emptyContextObject; - instance.state === newProps && - ((name = getComponentNameFromType(ctor) || "Component"), - didWarnAboutDirectlyAssigningPropsToState.has(name) || - (didWarnAboutDirectlyAssigningPropsToState.add(name), - error$jscomp$0( - "%s: It is not recommended to assign props directly to state because updates to props won't be reflected in state. In most cases, it is better to use props directly.", - name - ))); - workInProgress.mode & 8 && - ReactStrictModeWarnings.recordLegacyContextWarning( - workInProgress, - instance - ); - ReactStrictModeWarnings.recordUnsafeLifecycleWarnings( - workInProgress, - instance - ); - instance.state = workInProgress.memoizedState; - name = ctor.getDerivedStateFromProps; - "function" === typeof name && - (applyDerivedStateFromProps(workInProgress, ctor, name, newProps), - (instance.state = workInProgress.memoizedState)); - "function" === typeof ctor.getDerivedStateFromProps || - "function" === typeof instance.getSnapshotBeforeUpdate || - ("function" !== typeof instance.UNSAFE_componentWillMount && - "function" !== typeof instance.componentWillMount) || - ((ctor = instance.state), - "function" === typeof instance.componentWillMount && - instance.componentWillMount(), - "function" === typeof instance.UNSAFE_componentWillMount && - instance.UNSAFE_componentWillMount(), - ctor !== instance.state && - (error$jscomp$0( - "%s.componentWillMount(): Assigning directly to this.state is deprecated (except inside a component's constructor). Use setState instead.", - getComponentNameFromFiber(workInProgress) || "Component" - ), - classComponentUpdater.enqueueReplaceState( - instance, - instance.state, - null - )), - processUpdateQueue(workInProgress, newProps, instance, renderLanes), - suspendIfUpdateReadFromEntangledAsyncAction(), - (instance.state = workInProgress.memoizedState)); - "function" === typeof instance.componentDidMount && - (workInProgress.flags |= 4194308); - 0 !== (workInProgress.mode & 16) && (workInProgress.flags |= 67108864); - } - function resolveClassComponentProps(Component, baseProps) { - var newProps = baseProps; - if ("ref" in baseProps) { - newProps = {}; - for (var propName in baseProps) - "ref" !== propName && (newProps[propName] = baseProps[propName]); - } - if ((Component = Component.defaultProps)) { - newProps === baseProps && (newProps = assign({}, newProps)); - for (var _propName in Component) - void 0 === newProps[_propName] && - (newProps[_propName] = Component[_propName]); - } - return newProps; - } - function defaultOnRecoverableError(error) { - reportGlobalError(error); - } - function logUncaughtError(root, errorInfo) { - try { - componentName = errorInfo.source - ? getComponentNameFromFiber(errorInfo.source) - : null; - errorBoundaryName = null; - var error = errorInfo.value; - if (null !== ReactSharedInternals.actQueue) - ReactSharedInternals.thrownErrors.push(error); - else { - var onUncaughtError = root.onUncaughtError; - onUncaughtError(error, { componentStack: errorInfo.stack }); + + var ReactFabricGlobalResponderHandler = { + onChange: function (from, to, blockNativeResponder) { + if (from && from.stateNode) { + // equivalent to clearJSResponder + nativeFabricUIManager.setIsJSResponder( + from.stateNode.node, + false, + blockNativeResponder || false + ); + } + + if (to && to.stateNode) { + // equivalent to setJSResponder + nativeFabricUIManager.setIsJSResponder( + to.stateNode.node, + true, + blockNativeResponder || false + ); } - } catch (e) { - setTimeout(function () { - throw e; - }); } + }; + + setComponentTree( + getFiberCurrentPropsFromNode, + getInstanceFromNode, + getNodeFromInstance + ); + ResponderEventPlugin.injection.injectGlobalResponderHandler( + ReactFabricGlobalResponderHandler + ); + + /** + * `ReactInstanceMap` maintains a mapping from a public facing stateful + * instance (key) and the internal representation (value). This allows public + * methods to accept the user facing instance as an argument and map them back + * to internal methods. + * + * Note that this module is currently shared and assumed to be stateless. + * If this becomes an actual Map, that will break. + */ + function get(key) { + return key._reactInternals; + } + function set(key, value) { + key._reactInternals = value; } - function logCaughtError(root, boundary, errorInfo) { - try { - componentName = errorInfo.source - ? getComponentNameFromFiber(errorInfo.source) - : null; - errorBoundaryName = getComponentNameFromFiber(boundary); - var onCaughtError = root.onCaughtError; - onCaughtError(errorInfo.value, { - componentStack: errorInfo.stack, - errorBoundary: 1 === boundary.tag ? boundary.stateNode : null - }); - } catch (e) { - setTimeout(function () { - throw e; - }); + + // ATTENTION + // When adding new symbols to this file, + // Please consider also adding to 'react-devtools-shared/src/backend/ReactSymbols' + // The Symbol used to tag the ReactElement-like types. + var REACT_ELEMENT_TYPE = Symbol.for("react.element"); + var REACT_PORTAL_TYPE = Symbol.for("react.portal"); + var REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"); + var REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"); + var REACT_PROFILER_TYPE = Symbol.for("react.profiler"); + var REACT_PROVIDER_TYPE = Symbol.for("react.provider"); // TODO: Delete with enableRenderableContext + + var REACT_CONSUMER_TYPE = Symbol.for("react.consumer"); + var REACT_CONTEXT_TYPE = Symbol.for("react.context"); + var REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"); + var REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"); + var REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"); + var REACT_MEMO_TYPE = Symbol.for("react.memo"); + var REACT_LAZY_TYPE = Symbol.for("react.lazy"); + var REACT_SCOPE_TYPE = Symbol.for("react.scope"); + var REACT_DEBUG_TRACING_MODE_TYPE = Symbol.for("react.debug_trace_mode"); + var REACT_OFFSCREEN_TYPE = Symbol.for("react.offscreen"); + var REACT_LEGACY_HIDDEN_TYPE = Symbol.for("react.legacy_hidden"); + var REACT_CACHE_TYPE = Symbol.for("react.cache"); + var REACT_TRACING_MARKER_TYPE = Symbol.for("react.tracing_marker"); + var MAYBE_ITERATOR_SYMBOL = Symbol.iterator; + var FAUX_ITERATOR_SYMBOL = "@@iterator"; + function getIteratorFn(maybeIterable) { + if (maybeIterable === null || typeof maybeIterable !== "object") { + return null; } + + var maybeIterator = + (MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL]) || + maybeIterable[FAUX_ITERATOR_SYMBOL]; + + if (typeof maybeIterator === "function") { + return maybeIterator; + } + + return null; } - function createRootErrorUpdate(root, errorInfo, lane) { - lane = createUpdate(lane); - lane.tag = CaptureUpdate; - lane.payload = { element: null }; - lane.callback = function () { - runWithFiberInDEV(errorInfo.source, logUncaughtError, root, errorInfo); - }; - return lane; - } - function createClassErrorUpdate(lane) { - lane = createUpdate(lane); - lane.tag = CaptureUpdate; - return lane; - } - function initializeClassErrorUpdate(update, root, fiber, errorInfo) { - var getDerivedStateFromError = fiber.type.getDerivedStateFromError; - if ("function" === typeof getDerivedStateFromError) { - var error$1 = errorInfo.value; - update.payload = function () { - return getDerivedStateFromError(error$1); - }; - update.callback = function () { - markFailedErrorBoundaryForHotReloading(fiber); - runWithFiberInDEV( - errorInfo.source, - logCaughtError, - root, - fiber, - errorInfo - ); - }; + + function getWrappedName$1(outerType, innerType, wrapperName) { + var displayName = outerType.displayName; + + if (displayName) { + return displayName; } - var inst = fiber.stateNode; - null !== inst && - "function" === typeof inst.componentDidCatch && - (update.callback = function () { - markFailedErrorBoundaryForHotReloading(fiber); - runWithFiberInDEV( - errorInfo.source, - logCaughtError, - root, - fiber, - errorInfo - ); - "function" !== typeof getDerivedStateFromError && - (null === legacyErrorBoundariesThatAlreadyFailed - ? (legacyErrorBoundariesThatAlreadyFailed = new Set([this])) - : legacyErrorBoundariesThatAlreadyFailed.add(this)); - var stack = errorInfo.stack; - this.componentDidCatch(errorInfo.value, { - componentStack: null !== stack ? stack : "" - }); - "function" === typeof getDerivedStateFromError || - (0 === (fiber.lanes & SyncLane) && - error$jscomp$0( - "%s: Error boundaries should implement getDerivedStateFromError(). In that method, return a state update to display an error message or fallback UI.", - getComponentNameFromFiber(fiber) || "Unknown" - )); - }); + + var functionName = innerType.displayName || innerType.name || ""; + return functionName !== "" + ? wrapperName + "(" + functionName + ")" + : wrapperName; + } // Keep in sync with react-reconciler/getComponentNameFromFiber + + function getContextName$1(type) { + return type.displayName || "Context"; } - function throwException( - root, - returnFiber, - sourceFiber, - value, - rootRenderLanes - ) { - sourceFiber.flags |= 32768; - isDevToolsPresent && restorePendingUpdaters(root, rootRenderLanes); - if ( - null !== value && - "object" === typeof value && - "function" === typeof value.then - ) { - var tag = sourceFiber.tag; - 0 !== (sourceFiber.mode & 1) || - (0 !== tag && 11 !== tag && 15 !== tag) || - ((tag = sourceFiber.alternate) - ? ((sourceFiber.updateQueue = tag.updateQueue), - (sourceFiber.memoizedState = tag.memoizedState), - (sourceFiber.lanes = tag.lanes)) - : ((sourceFiber.updateQueue = null), - (sourceFiber.memoizedState = null))); - tag = suspenseHandlerStackCursor.current; - if (null !== tag) { - switch (tag.tag) { - case 13: - return ( - sourceFiber.mode & 1 && - (null === shellBoundary - ? renderDidSuspendDelayIfPossible() - : null === tag.alternate && - workInProgressRootExitStatus === RootInProgress && - (workInProgressRootExitStatus = RootSuspended)), - (tag.flags &= -257), - 0 === (tag.mode & 1) - ? tag === returnFiber - ? (tag.flags |= 65536) - : ((tag.flags |= 128), - (sourceFiber.flags |= 131072), - (sourceFiber.flags &= -52805), - 1 === sourceFiber.tag - ? null === sourceFiber.alternate - ? (sourceFiber.tag = 17) - : ((returnFiber = createUpdate(SyncLane)), - (returnFiber.tag = ForceUpdate), - enqueueUpdate(sourceFiber, returnFiber, SyncLane)) - : 0 === sourceFiber.tag && - null === sourceFiber.alternate && - (sourceFiber.tag = 28), - (sourceFiber.lanes |= SyncLane)) - : ((tag.flags |= 65536), (tag.lanes = rootRenderLanes)), - value === noopSuspenseyCommitThenable - ? (tag.flags |= 16384) - : ((returnFiber = tag.updateQueue), - null === returnFiber - ? (tag.updateQueue = new Set([value])) - : returnFiber.add(value), - tag.mode & 1 && - attachPingListener(root, value, rootRenderLanes)), - !1 - ); - case 22: - if (tag.mode & 1) - return ( - (tag.flags |= 65536), - value === noopSuspenseyCommitThenable - ? (tag.flags |= 16384) - : ((returnFiber = tag.updateQueue), - null === returnFiber - ? ((returnFiber = { - transitions: null, - markerInstances: null, - retryQueue: new Set([value]) - }), - (tag.updateQueue = returnFiber)) - : ((sourceFiber = returnFiber.retryQueue), - null === sourceFiber - ? (returnFiber.retryQueue = new Set([value])) - : sourceFiber.add(value)), - attachPingListener(root, value, rootRenderLanes)), - !1 - ); - } - throw Error( - "Unexpected Suspense handler tag (" + - tag.tag + - "). This is a bug in React." - ); + + var REACT_CLIENT_REFERENCE = Symbol.for("react.client.reference"); // Note that the reconciler package should generally prefer to use getComponentNameFromFiber() instead. + + function getComponentNameFromType(type) { + if (type == null) { + // Host root, text node or just invalid type. + return null; + } + + if (typeof type === "function") { + if (type.$$typeof === REACT_CLIENT_REFERENCE) { + // TODO: Create a convention for naming client references with debug info. + return null; } - if (1 === root.tag) - return ( - attachPingListener(root, value, rootRenderLanes), - renderDidSuspendDelayIfPossible(), - !1 - ); - value = Error( - "A component suspended while responding to synchronous input. This will cause the UI to be replaced with a loading indicator. To fix, updates that suspend should be wrapped with startTransition." - ); + + return type.displayName || type.name || null; } - tag = createCapturedValueAtFiber( - Error( - "There was an error during concurrent rendering but React was able to recover by instead synchronously rendering the entire root.", - { cause: value } - ), - sourceFiber - ); - null === workInProgressRootConcurrentErrors - ? (workInProgressRootConcurrentErrors = [tag]) - : workInProgressRootConcurrentErrors.push(tag); - workInProgressRootExitStatus !== RootSuspendedWithDelay && - (workInProgressRootExitStatus = RootErrored); - if (null === returnFiber) return !0; - value = createCapturedValueAtFiber(value, sourceFiber); - do { - switch (returnFiber.tag) { - case 3: - return ( - (returnFiber.flags |= 65536), - (root = rootRenderLanes & -rootRenderLanes), - (returnFiber.lanes |= root), - (root = createRootErrorUpdate( - returnFiber.stateNode, - value, - root - )), - enqueueCapturedUpdate(returnFiber, root), - !1 + + if (typeof type === "string") { + return type; + } + + switch (type) { + case REACT_FRAGMENT_TYPE: + return "Fragment"; + + case REACT_PORTAL_TYPE: + return "Portal"; + + case REACT_PROFILER_TYPE: + return "Profiler"; + + case REACT_STRICT_MODE_TYPE: + return "StrictMode"; + + case REACT_SUSPENSE_TYPE: + return "Suspense"; + + case REACT_SUSPENSE_LIST_TYPE: + return "SuspenseList"; + } + + if (typeof type === "object") { + { + if (typeof type.tag === "number") { + error( + "Received an unexpected object in getComponentNameFromType(). " + + "This is likely a bug in React. Please file an issue." ); - case 1: - if ( - ((sourceFiber = returnFiber.type), - (tag = returnFiber.stateNode), - 0 === (returnFiber.flags & 128) && - ("function" === typeof sourceFiber.getDerivedStateFromError || - (null !== tag && - "function" === typeof tag.componentDidCatch && - (null === legacyErrorBoundariesThatAlreadyFailed || - !legacyErrorBoundariesThatAlreadyFailed.has(tag))))) - ) - return ( - (returnFiber.flags |= 65536), - (rootRenderLanes &= -rootRenderLanes), - (returnFiber.lanes |= rootRenderLanes), - (rootRenderLanes = createClassErrorUpdate(rootRenderLanes)), - initializeClassErrorUpdate( - rootRenderLanes, - root, - returnFiber, - value - ), - enqueueCapturedUpdate(returnFiber, rootRenderLanes), - !1 - ); + } } - returnFiber = returnFiber.return; - } while (null !== returnFiber); - return !1; - } - function reconcileChildren( - current, - workInProgress, - nextChildren, - renderLanes - ) { - workInProgress.child = - null === current - ? mountChildFibers(workInProgress, null, nextChildren, renderLanes) - : reconcileChildFibers( - workInProgress, - current.child, - nextChildren, - renderLanes - ); + + switch (type.$$typeof) { + case REACT_PROVIDER_TYPE: { + var provider = type; + return getContextName$1(provider._context) + ".Provider"; + } + + case REACT_CONTEXT_TYPE: + var context = type; + + { + return getContextName$1(context) + ".Consumer"; + } + + case REACT_CONSUMER_TYPE: { + return null; + } + + case REACT_FORWARD_REF_TYPE: + return getWrappedName$1(type, type.render, "ForwardRef"); + + case REACT_MEMO_TYPE: + var outerName = type.displayName || null; + + if (outerName !== null) { + return outerName; + } + + return getComponentNameFromType(type.type) || "Memo"; + + case REACT_LAZY_TYPE: { + var lazyComponent = type; + var payload = lazyComponent._payload; + var init = lazyComponent._init; + + try { + return getComponentNameFromType(init(payload)); + } catch (x) { + return null; + } + } + } + } + + return null; } - function updateForwardRef( - current, - workInProgress, - Component, - nextProps, - renderLanes - ) { - Component = Component.render; - var ref = workInProgress.ref; - if ("ref" in nextProps) { - var propsWithoutRef = {}; - for (var key in nextProps) - "ref" !== key && (propsWithoutRef[key] = nextProps[key]); - } else propsWithoutRef = nextProps; - prepareToReadContext(workInProgress, renderLanes); - markComponentRenderStarted(workInProgress); - nextProps = renderWithHooks( - current, - workInProgress, - Component, - propsWithoutRef, - ref, - renderLanes + + function getWrappedName(outerType, innerType, wrapperName) { + var functionName = innerType.displayName || innerType.name || ""; + return ( + outerType.displayName || + (functionName !== "" + ? wrapperName + "(" + functionName + ")" + : wrapperName) ); - markComponentRenderStopped(); - if (null !== current && !didReceiveUpdate) - return ( - bailoutHooks(current, workInProgress, renderLanes), - bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) - ); - workInProgress.flags |= 1; - reconcileChildren(current, workInProgress, nextProps, renderLanes); - return workInProgress.child; + } // Keep in sync with shared/getComponentNameFromType + + function getContextName(type) { + return type.displayName || "Context"; } - function updateMemoComponent( - current, - workInProgress, - Component, - nextProps, - renderLanes - ) { - if (null === current) { - var type = Component.type; - if ( - "function" === typeof type && - !shouldConstruct(type) && - void 0 === type.defaultProps && - null === Component.compare - ) - return ( - (Component = resolveFunctionForHotReloading(type)), - (workInProgress.tag = 15), - (workInProgress.type = Component), - validateFunctionComponentInDev(workInProgress, type), - updateSimpleMemoComponent( - current, - workInProgress, - Component, - nextProps, - renderLanes - ) - ); - current = createFiberFromTypeAndProps( - Component.type, - null, - nextProps, - workInProgress, - workInProgress.mode, - renderLanes - ); - current.ref = workInProgress.ref; - current.return = workInProgress; - return (workInProgress.child = current); - } - type = current.child; - if (0 === (current.lanes & renderLanes)) { - var prevProps = type.memoizedProps; - Component = Component.compare; - Component = null !== Component ? Component : shallowEqual; - if ( - Component(prevProps, nextProps) && - current.ref === workInProgress.ref - ) - return bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderLanes - ); + + function getComponentNameFromFiber(fiber) { + var tag = fiber.tag, + type = fiber.type; + + switch (tag) { + case CacheComponent: + return "Cache"; + + case ContextConsumer: { + var context = type; + return getContextName(context) + ".Consumer"; + } + + case ContextProvider: { + var provider = type; + return getContextName(provider._context) + ".Provider"; + } + + case DehydratedFragment: + return "DehydratedFragment"; + + case ForwardRef: + return getWrappedName(type, type.render, "ForwardRef"); + + case Fragment: + return "Fragment"; + + case HostHoistable: + case HostSingleton: + 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 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"; + + case TracingMarkerComponent: + return "TracingMarker"; + // 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; } - workInProgress.flags |= 1; - current = createWorkInProgress(type, nextProps); - current.ref = workInProgress.ref; - current.return = workInProgress; - return (workInProgress.child = current); + + return null; } - function updateSimpleMemoComponent( - current, - workInProgress, - Component, - nextProps, - renderLanes - ) { - if (null !== current) { - var prevProps = current.memoizedProps; - if ( - shallowEqual(prevProps, nextProps) && - current.ref === workInProgress.ref && - workInProgress.type === current.type - ) - if ( - ((didReceiveUpdate = !1), - (workInProgress.pendingProps = nextProps = prevProps), - 0 !== (current.lanes & renderLanes)) - ) - 0 !== (current.flags & 131072) && (didReceiveUpdate = !0); - else - return ( - (workInProgress.lanes = current.lanes), - bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) - ); + + var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner; + function getNearestMountedFiber(fiber) { + var node = fiber; + var nearestMounted = fiber; + + if (!fiber.alternate) { + // If there is no alternate, this might be a new tree that isn't inserted + // yet. If it is, then it will have a pending insertion effect on it. + var nextNode = node; + + do { + node = nextNode; + + if ((node.flags & (Placement | Hydrating)) !== NoFlags$1) { + // This is an insertion or in-progress hydration. The nearest possible + // mounted fiber is the parent but we need to continue to figure out + // if that one is still mounted. + nearestMounted = node.return; + } // $FlowFixMe[incompatible-type] we bail out when we get a null + + nextNode = node.return; + } while (nextNode); + } else { + while (node.return) { + node = node.return; + } } - return updateFunctionComponent( - current, - workInProgress, - Component, - nextProps, - renderLanes - ); + + if (node.tag === HostRoot) { + // TODO: Check if this was a nested HostRoot when used with + // renderContainerIntoSubtree. + return nearestMounted; + } // If we didn't hit the root, that means that we're in an disconnected tree + // that has been unmounted. + + return null; } - function updateOffscreenComponent(current, workInProgress, renderLanes) { - var nextProps = workInProgress.pendingProps, - nextChildren = nextProps.children, - nextIsDetached = - 0 !== (workInProgress.stateNode._pendingVisibility & 2), - prevState = null !== current ? current.memoizedState : null; - markRef(current, workInProgress); - if ("hidden" === nextProps.mode || nextIsDetached) { - if (0 !== (workInProgress.flags & 128)) { - renderLanes = - null !== prevState - ? prevState.baseLanes | renderLanes - : renderLanes; - if (null !== current) { - nextProps = workInProgress.child = current.child; - for (nextChildren = 0; null !== nextProps; ) - (nextChildren = - nextChildren | nextProps.lanes | nextProps.childLanes), - (nextProps = nextProps.sibling); - workInProgress.childLanes = nextChildren & ~renderLanes; - } else (workInProgress.childLanes = 0), (workInProgress.child = null); - return deferHiddenOffscreenComponent( - current, - workInProgress, - renderLanes - ); + function isMounted(component) { + { + var owner = ReactCurrentOwner$3.current; + + if (owner !== null && owner.tag === ClassComponent) { + var ownerFiber = owner; + var instance = ownerFiber.stateNode; + + if (!instance._warnedAboutRefsInRender) { + error( + "%s is accessing isMounted inside its render() function. " + + "render() should be a pure function of props and state. It should " + + "never access something that requires stale data from the previous " + + "render, such as refs. Move this logic to componentDidMount and " + + "componentDidUpdate instead.", + getComponentNameFromFiber(ownerFiber) || "A component" + ); + } + + instance._warnedAboutRefsInRender = true; } - if (0 === (workInProgress.mode & 1)) - (workInProgress.memoizedState = { baseLanes: 0, cachePool: null }), - null !== current && pushTransition(workInProgress, null), - reuseHiddenContextOnStack(workInProgress), - pushOffscreenSuspenseHandler(workInProgress); - else if (0 !== (renderLanes & OffscreenLane)) - (workInProgress.memoizedState = { baseLanes: 0, cachePool: null }), - null !== current && - pushTransition( - workInProgress, - null !== prevState ? prevState.cachePool : null - ), - null !== prevState - ? pushHiddenContext(workInProgress, prevState) - : reuseHiddenContextOnStack(workInProgress), - pushOffscreenSuspenseHandler(workInProgress); - else - return ( - (workInProgress.lanes = workInProgress.childLanes = OffscreenLane), - deferHiddenOffscreenComponent( - current, - workInProgress, - null !== prevState - ? prevState.baseLanes | renderLanes - : renderLanes - ) - ); - } else - null !== prevState - ? (pushTransition(workInProgress, prevState.cachePool), - pushHiddenContext(workInProgress, prevState), - reuseSuspenseHandlerOnStack(workInProgress), - (workInProgress.memoizedState = null)) - : (null !== current && pushTransition(workInProgress, null), - reuseHiddenContextOnStack(workInProgress), - reuseSuspenseHandlerOnStack(workInProgress)); - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - return workInProgress.child; + } + + var fiber = get(component); + + if (!fiber) { + return false; + } + + return getNearestMountedFiber(fiber) === fiber; } - function deferHiddenOffscreenComponent( - current, - workInProgress, - nextBaseLanes - ) { - var JSCompiler_inline_result = peekCacheFromPool(); - JSCompiler_inline_result = - null === JSCompiler_inline_result - ? null - : { - parent: CacheContext._currentValue2, - pool: JSCompiler_inline_result - }; - workInProgress.memoizedState = { - baseLanes: nextBaseLanes, - cachePool: JSCompiler_inline_result - }; - null !== current && pushTransition(workInProgress, null); - reuseHiddenContextOnStack(workInProgress); - pushOffscreenSuspenseHandler(workInProgress); - return null; + + function assertIsMounted(fiber) { + if (getNearestMountedFiber(fiber) !== fiber) { + throw new Error("Unable to find node on an unmounted component."); + } } - function markRef(current, workInProgress) { - var ref = workInProgress.ref; - if (null === ref) - null !== current && - null !== current.ref && - (workInProgress.flags |= 2097664); - else { - if ("function" !== typeof ref && "object" !== typeof ref) - throw Error( - "Expected ref to be a function, an object returned by React.createRef(), or undefined/null." + + function findCurrentFiberUsingSlowPath(fiber) { + var alternate = fiber.alternate; + + if (!alternate) { + // If there is no alternate, then we only need to check if it is mounted. + var nearestMounted = getNearestMountedFiber(fiber); + + if (nearestMounted === null) { + throw new Error("Unable to find node on an unmounted component."); + } + + if (nearestMounted !== fiber) { + return null; + } + + return fiber; + } // If we have two possible branches, we'll walk backwards up to the root + // to see what path the root points to. On the way we may hit one of the + // special cases and we'll deal with them. + + var a = fiber; + var b = alternate; + + while (true) { + var parentA = a.return; + + if (parentA === null) { + // We're at the root. + break; + } + + var parentB = parentA.alternate; + + if (parentB === null) { + // There is no alternate. This is an unusual case. Currently, it only + // happens when a Suspense component is hidden. An extra fragment fiber + // is inserted in between the Suspense fiber and its children. Skip + // over this extra fragment fiber and proceed to the next parent. + var nextParent = parentA.return; + + if (nextParent !== null) { + a = b = nextParent; + continue; + } // If there's no parent, we're at the root. + + break; + } // If both copies of the parent fiber point to the same child, we can + // assume that the child is current. This happens when we bailout on low + // priority: the bailed out fiber's child reuses the current child. + + if (parentA.child === parentB.child) { + var child = parentA.child; + + while (child) { + if (child === a) { + // We've determined that A is the current branch. + assertIsMounted(parentA); + return fiber; + } + + if (child === b) { + // We've determined that B is the current branch. + assertIsMounted(parentA); + return alternate; + } + + child = child.sibling; + } // We should never have an alternate for any mounting node. So the only + // way this could possibly happen is if this was unmounted, if at all. + + throw new Error("Unable to find node on an unmounted component."); + } + + if (a.return !== b.return) { + // The return pointer of A and the return pointer of B point to different + // fibers. We assume that return pointers never criss-cross, so A must + // belong to the child set of A.return, and B must belong to the child + // set of B.return. + a = parentA; + b = parentB; + } else { + // The return pointers point to the same fiber. We'll have to use the + // default, slow path: scan the child sets of each parent alternate to see + // which child belongs to which set. + // + // Search parent A's child set + var didFindChild = false; + var _child = parentA.child; + + while (_child) { + if (_child === a) { + didFindChild = true; + a = parentA; + b = parentB; + break; + } + + if (_child === b) { + didFindChild = true; + b = parentA; + a = parentB; + break; + } + + _child = _child.sibling; + } + + if (!didFindChild) { + // Search parent B's child set + _child = parentB.child; + + while (_child) { + if (_child === a) { + didFindChild = true; + a = parentB; + b = parentA; + break; + } + + if (_child === b) { + didFindChild = true; + b = parentB; + a = parentA; + break; + } + + _child = _child.sibling; + } + + if (!didFindChild) { + throw new Error( + "Child was not found in either parent set. This indicates a bug " + + "in React related to the return pointer. Please file an issue." + ); + } + } + } + + if (a.alternate !== b) { + throw new Error( + "Return fibers should always be each others' alternates. " + + "This error is likely caused by a bug in React. Please file an issue." ); - if (null === current || current.ref !== ref) - workInProgress.flags |= 2097664; + } + } // If the root is not a host container, we're in a disconnected tree. I.e. + // unmounted. + + if (a.tag !== HostRoot) { + throw new Error("Unable to find node on an unmounted component."); } + + if (a.stateNode.current === a) { + // We've determined that A is the current branch. + return fiber; + } // Otherwise B has to be current branch. + + return alternate; } - function updateFunctionComponent( - current, - workInProgress, - Component, - nextProps, - renderLanes - ) { + function findCurrentHostFiber(parent) { + var currentParent = findCurrentFiberUsingSlowPath(parent); + return currentParent !== null + ? findCurrentHostFiberImpl(currentParent) + : null; + } + + function findCurrentHostFiberImpl(node) { + // Next we'll drill down this component to find the first HostComponent/Text. + var tag = node.tag; + if ( - Component.prototype && - "function" === typeof Component.prototype.render + tag === HostComponent || + tag === HostHoistable || + tag === HostSingleton || + tag === HostText ) { - var componentName = getComponentNameFromType(Component) || "Unknown"; - didWarnAboutBadClass[componentName] || - (error$jscomp$0( - "The <%s /> component appears to have a render method, but doesn't extend React.Component. This is likely to cause errors. Change %s to extend React.Component instead.", - componentName, - componentName - ), - (didWarnAboutBadClass[componentName] = !0)); + return node; } - workInProgress.mode & 8 && - ReactStrictModeWarnings.recordLegacyContextWarning( - workInProgress, - null - ); - null === current && - (validateFunctionComponentInDev(workInProgress, workInProgress.type), - Component.contextTypes && - error$jscomp$0( - "%s uses the legacy contextTypes API which was removed in React 19. Use React.createContext() with React.useContext() instead.", - getComponentNameFromType(Component) || "Unknown" - )); - prepareToReadContext(workInProgress, renderLanes); - markComponentRenderStarted(workInProgress); - Component = renderWithHooks( - current, - workInProgress, - Component, - nextProps, - void 0, - renderLanes - ); - markComponentRenderStopped(); - if (null !== current && !didReceiveUpdate) - return ( - bailoutHooks(current, workInProgress, renderLanes), - bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) - ); - workInProgress.flags |= 1; - reconcileChildren(current, workInProgress, Component, renderLanes); - return workInProgress.child; - } - function replayFunctionComponent( - current, - workInProgress, - nextProps, - Component, - secondArg, - renderLanes - ) { - prepareToReadContext(workInProgress, renderLanes); - markComponentRenderStarted(workInProgress); - hookTypesUpdateIndexDev = -1; - ignorePreviousDependencies = - null !== current && current.type !== workInProgress.type; - nextProps = renderWithHooksAgain( - workInProgress, - Component, - nextProps, - secondArg - ); - finishRenderingHooks(current, workInProgress); - markComponentRenderStopped(); - if (null !== current && !didReceiveUpdate) - return ( - bailoutHooks(current, workInProgress, renderLanes), - bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) - ); - workInProgress.flags |= 1; - reconcileChildren(current, workInProgress, nextProps, renderLanes); - return workInProgress.child; + + var child = node.child; + + while (child !== null) { + var match = findCurrentHostFiberImpl(child); + + if (match !== null) { + return match; + } + + child = child.sibling; + } + + return null; } - function updateClassComponent( - current, - workInProgress, - Component, - nextProps, - renderLanes - ) { - switch (shouldErrorImpl(workInProgress)) { - case !1: - var _instance = workInProgress.stateNode, - state = new workInProgress.type( - workInProgress.memoizedProps, - _instance.context - ).state; - _instance.updater.enqueueSetState(_instance, state, null); - break; - case !0: - workInProgress.flags |= 128; - workInProgress.flags |= 65536; - _instance = Error("Simulated error coming from DevTools"); - var lane = renderLanes & -renderLanes; - workInProgress.lanes |= lane; - state = workInProgressRoot; - if (null === state) - throw Error( - "Expected a work-in-progress root. This is a bug in React. Please file an issue." - ); - lane = createClassErrorUpdate(lane); - initializeClassErrorUpdate( - lane, - state, - workInProgress, - createCapturedValueAtFiber(_instance, workInProgress) - ); - enqueueCapturedUpdate(workInProgress, lane); + function doesFiberContain(parentFiber, childFiber) { + var node = childFiber; + var parentFiberAlternate = parentFiber.alternate; + + while (node !== null) { + if (node === parentFiber || node === parentFiberAlternate) { + return true; + } + + node = node.return; } - prepareToReadContext(workInProgress, renderLanes); - if (null === workInProgress.stateNode) - resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress), - constructClassInstance(workInProgress, Component, nextProps), - mountClassInstance(workInProgress, Component, nextProps, renderLanes), - (_instance = !0); - else if (null === current) { - _instance = workInProgress.stateNode; - var unresolvedOldProps = workInProgress.memoizedProps; - lane = resolveClassComponentProps(Component, unresolvedOldProps); - _instance.props = lane; - var oldContext = _instance.context, - contextType = Component.contextType; - state = emptyContextObject; - "object" === typeof contextType && - null !== contextType && - (state = readContext(contextType)); - var getDerivedStateFromProps = Component.getDerivedStateFromProps; - contextType = - "function" === typeof getDerivedStateFromProps || - "function" === typeof _instance.getSnapshotBeforeUpdate; - unresolvedOldProps = workInProgress.pendingProps !== unresolvedOldProps; - contextType || - ("function" !== typeof _instance.UNSAFE_componentWillReceiveProps && - "function" !== typeof _instance.componentWillReceiveProps) || - ((unresolvedOldProps || oldContext !== state) && - callComponentWillReceiveProps( - workInProgress, - _instance, - nextProps, - state - )); - hasForceUpdate = !1; - var oldState = workInProgress.memoizedState; - _instance.state = oldState; - processUpdateQueue(workInProgress, nextProps, _instance, renderLanes); - suspendIfUpdateReadFromEntangledAsyncAction(); - oldContext = workInProgress.memoizedState; - unresolvedOldProps || oldState !== oldContext || hasForceUpdate - ? ("function" === typeof getDerivedStateFromProps && - (applyDerivedStateFromProps( - workInProgress, - Component, - getDerivedStateFromProps, - nextProps - ), - (oldContext = workInProgress.memoizedState)), - (lane = - hasForceUpdate || - checkShouldComponentUpdate( - workInProgress, - Component, - lane, - nextProps, - oldState, - oldContext, - state - )) - ? (contextType || - ("function" !== typeof _instance.UNSAFE_componentWillMount && - "function" !== typeof _instance.componentWillMount) || - ("function" === typeof _instance.componentWillMount && - _instance.componentWillMount(), - "function" === typeof _instance.UNSAFE_componentWillMount && - _instance.UNSAFE_componentWillMount()), - "function" === typeof _instance.componentDidMount && - (workInProgress.flags |= 4194308), - 0 !== (workInProgress.mode & 16) && - (workInProgress.flags |= 67108864)) - : ("function" === typeof _instance.componentDidMount && - (workInProgress.flags |= 4194308), - 0 !== (workInProgress.mode & 16) && - (workInProgress.flags |= 67108864), - (workInProgress.memoizedProps = nextProps), - (workInProgress.memoizedState = oldContext)), - (_instance.props = nextProps), - (_instance.state = oldContext), - (_instance.context = state), - (_instance = lane)) - : ("function" === typeof _instance.componentDidMount && - (workInProgress.flags |= 4194308), - 0 !== (workInProgress.mode & 16) && - (workInProgress.flags |= 67108864), - (_instance = !1)); - } else { - _instance = workInProgress.stateNode; - cloneUpdateQueue(current, workInProgress); - state = workInProgress.memoizedProps; - contextType = resolveClassComponentProps(Component, state); - _instance.props = contextType; - getDerivedStateFromProps = workInProgress.pendingProps; - oldState = _instance.context; - oldContext = Component.contextType; - lane = emptyContextObject; - "object" === typeof oldContext && - null !== oldContext && - (lane = readContext(oldContext)); - unresolvedOldProps = Component.getDerivedStateFromProps; - (oldContext = - "function" === typeof unresolvedOldProps || - "function" === typeof _instance.getSnapshotBeforeUpdate) || - ("function" !== typeof _instance.UNSAFE_componentWillReceiveProps && - "function" !== typeof _instance.componentWillReceiveProps) || - ((state !== getDerivedStateFromProps || oldState !== lane) && - callComponentWillReceiveProps( - workInProgress, - _instance, - nextProps, - lane - )); - hasForceUpdate = !1; - oldState = workInProgress.memoizedState; - _instance.state = oldState; - processUpdateQueue(workInProgress, nextProps, _instance, renderLanes); - suspendIfUpdateReadFromEntangledAsyncAction(); - var newState = workInProgress.memoizedState; - state !== getDerivedStateFromProps || - oldState !== newState || - hasForceUpdate - ? ("function" === typeof unresolvedOldProps && - (applyDerivedStateFromProps( - workInProgress, - Component, - unresolvedOldProps, - nextProps - ), - (newState = workInProgress.memoizedState)), - (contextType = - hasForceUpdate || - checkShouldComponentUpdate( - workInProgress, - Component, - contextType, - nextProps, - oldState, - newState, - lane - ) || - !1) - ? (oldContext || - ("function" !== typeof _instance.UNSAFE_componentWillUpdate && - "function" !== typeof _instance.componentWillUpdate) || - ("function" === typeof _instance.componentWillUpdate && - _instance.componentWillUpdate(nextProps, newState, lane), - "function" === typeof _instance.UNSAFE_componentWillUpdate && - _instance.UNSAFE_componentWillUpdate( - nextProps, - newState, - lane - )), - "function" === typeof _instance.componentDidUpdate && - (workInProgress.flags |= 4), - "function" === typeof _instance.getSnapshotBeforeUpdate && - (workInProgress.flags |= 1024)) - : ("function" !== typeof _instance.componentDidUpdate || - (state === current.memoizedProps && - oldState === current.memoizedState) || - (workInProgress.flags |= 4), - "function" !== typeof _instance.getSnapshotBeforeUpdate || - (state === current.memoizedProps && - oldState === current.memoizedState) || - (workInProgress.flags |= 1024), - (workInProgress.memoizedProps = nextProps), - (workInProgress.memoizedState = newState)), - (_instance.props = nextProps), - (_instance.state = newState), - (_instance.context = lane), - (_instance = contextType)) - : ("function" !== typeof _instance.componentDidUpdate || - (state === current.memoizedProps && - oldState === current.memoizedState) || - (workInProgress.flags |= 4), - "function" !== typeof _instance.getSnapshotBeforeUpdate || - (state === current.memoizedProps && - oldState === current.memoizedState) || - (workInProgress.flags |= 1024), - (_instance = !1)); - } - current = finishClassComponent( - current, - workInProgress, - Component, - _instance, - !1, - renderLanes - ); - Component = workInProgress.stateNode; - _instance && - Component.props !== nextProps && - (didWarnAboutReassigningProps || - error$jscomp$0( - "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" - ), - (didWarnAboutReassigningProps = !0)); - return current; + + return false; } - function finishClassComponent( - current$jscomp$0, - workInProgress, - Component, - shouldUpdate, - hasContext, - renderLanes - ) { - markRef(current$jscomp$0, workInProgress); - hasContext = 0 !== (workInProgress.flags & 128); - if (!shouldUpdate && !hasContext) - return bailoutOnAlreadyFinishedWork( - current$jscomp$0, - workInProgress, - renderLanes - ); - shouldUpdate = workInProgress.stateNode; - ReactSharedInternals.getCurrentStack = - null === workInProgress ? null : getCurrentFiberStackInDev; - isRendering = !1; - current = workInProgress; - if ( - hasContext && - "function" !== typeof Component.getDerivedStateFromError - ) - (Component = null), (profilerStartTime = -1); - else { - markComponentRenderStarted(workInProgress); - Component = callRenderInDEV(shouldUpdate); - if (workInProgress.mode & 8) { - setIsStrictModeForDevtools(!0); - try { - callRenderInDEV(shouldUpdate); - } finally { - setIsStrictModeForDevtools(!1); - } + + var valueStack = []; + var fiberStack; + + { + fiberStack = []; + } + + var index = -1; + + function createCursor(defaultValue) { + return { + current: defaultValue + }; + } + + function pop(cursor, fiber) { + if (index < 0) { + { + error("Unexpected pop."); } - markComponentRenderStopped(); + + return; } - workInProgress.flags |= 1; - null !== current$jscomp$0 && hasContext - ? ((workInProgress.child = reconcileChildFibers( - workInProgress, - current$jscomp$0.child, - null, - renderLanes - )), - (workInProgress.child = reconcileChildFibers( - workInProgress, - null, - Component, - renderLanes - ))) - : reconcileChildren( - current$jscomp$0, - workInProgress, - Component, - renderLanes - ); - workInProgress.memoizedState = shouldUpdate.state; - return workInProgress.child; + + { + if (fiber !== fiberStack[index]) { + error("Unexpected Fiber popped."); + } + } + + cursor.current = valueStack[index]; + valueStack[index] = null; + + { + fiberStack[index] = null; + } + + index--; } - function validateFunctionComponentInDev(workInProgress, Component) { - Component && - Component.childContextTypes && - error$jscomp$0( - "childContextTypes cannot be defined on a function component.\n %s.childContextTypes = ...", - Component.displayName || Component.name || "Component" - ); - "function" === typeof Component.getDerivedStateFromProps && - ((workInProgress = getComponentNameFromType(Component) || "Unknown"), - didWarnAboutGetDerivedStateOnFunctionComponent[workInProgress] || - (error$jscomp$0( - "%s: Function components do not support getDerivedStateFromProps.", - workInProgress - ), - (didWarnAboutGetDerivedStateOnFunctionComponent[workInProgress] = - !0))); - "object" === typeof Component.contextType && - null !== Component.contextType && - ((Component = getComponentNameFromType(Component) || "Unknown"), - didWarnAboutContextTypeOnFunctionComponent[Component] || - (error$jscomp$0( - "%s: Function components do not support contextType.", - Component - ), - (didWarnAboutContextTypeOnFunctionComponent[Component] = !0))); + + function push(cursor, value, fiber) { + index++; + valueStack[index] = cursor.current; + + { + fiberStack[index] = fiber; + } + + cursor.current = value; } - function mountSuspenseOffscreenState(renderLanes) { - return { baseLanes: renderLanes, cachePool: getSuspendedCache() }; + + var emptyContextObject = {}; + + { + Object.freeze(emptyContextObject); + } // A cursor to the current merged context object on the stack. + + function hasContextChanged() { + { + return false; + } } - function getRemainingWorkInPrimaryTree( - current, - primaryTreeDidDefer, - renderLanes - ) { - current = null !== current ? current.childLanes & ~renderLanes : 0; - primaryTreeDidDefer && (current |= workInProgressDeferredLane); - return current; + + function isContextProvider(type) { + { + return false; + } } - function updateSuspenseComponent(current, workInProgress, renderLanes) { - var nextProps = workInProgress.pendingProps; - shouldSuspendImpl(workInProgress) && (workInProgress.flags |= 128); - var showFallback = !1, - didSuspend = 0 !== (workInProgress.flags & 128), - JSCompiler_temp; - (JSCompiler_temp = didSuspend) || - (JSCompiler_temp = - null !== current && null === current.memoizedState - ? !1 - : 0 !== (suspenseStackCursor.current & ForceSuspenseFallback)); - JSCompiler_temp && ((showFallback = !0), (workInProgress.flags &= -129)); - JSCompiler_temp = 0 !== (workInProgress.flags & 32); - workInProgress.flags &= -33; - if (null === current) { - var nextPrimaryChildren = nextProps.children; - nextProps = nextProps.fallback; - if (showFallback) - return ( - reuseSuspenseHandlerOnStack(workInProgress), - (showFallback = workInProgress.mode), - (didSuspend = workInProgress.child), - (nextPrimaryChildren = { - mode: "hidden", - children: nextPrimaryChildren - }), - 0 === (showFallback & 1) && null !== didSuspend - ? ((didSuspend.childLanes = 0), - (didSuspend.pendingProps = nextPrimaryChildren), - workInProgress.mode & 2 && - ((didSuspend.actualDuration = 0), - (didSuspend.actualStartTime = -1), - (didSuspend.selfBaseDuration = 0), - (didSuspend.treeBaseDuration = 0))) - : (didSuspend = createFiberFromOffscreen( - nextPrimaryChildren, - showFallback, - 0, - null - )), - (nextProps = createFiberFromFragment( - nextProps, - showFallback, - renderLanes, - null - )), - (didSuspend.return = workInProgress), - (nextProps.return = workInProgress), - (didSuspend.sibling = nextProps), - (workInProgress.child = didSuspend), - (nextPrimaryChildren = workInProgress.child), - (nextPrimaryChildren.memoizedState = - mountSuspenseOffscreenState(renderLanes)), - (nextPrimaryChildren.childLanes = getRemainingWorkInPrimaryTree( - current, - JSCompiler_temp, - renderLanes - )), - (workInProgress.memoizedState = SUSPENDED_MARKER), - nextProps - ); - pushPrimaryTreeSuspenseHandler(workInProgress); - return mountSuspensePrimaryChildren( - workInProgress, - nextPrimaryChildren - ); + + function processChildContext(fiber, type, parentContext) { + { + return parentContext; } - nextPrimaryChildren = current.memoizedState; - if ( - null !== nextPrimaryChildren && - null !== nextPrimaryChildren.dehydrated - ) { - if (didSuspend) - workInProgress.flags & 256 - ? (pushPrimaryTreeSuspenseHandler(workInProgress), - (workInProgress.flags &= -257), - (workInProgress = retrySuspenseComponentWithoutHydrating( - current, - workInProgress, - renderLanes - ))) - : null !== workInProgress.memoizedState - ? (reuseSuspenseHandlerOnStack(workInProgress), - (workInProgress.child = current.child), - (workInProgress.flags |= 128), - (workInProgress = null)) - : (reuseSuspenseHandlerOnStack(workInProgress), - (nextPrimaryChildren = nextProps.fallback), - (showFallback = workInProgress.mode), - (nextProps = createFiberFromOffscreen( - { mode: "visible", children: nextProps.children }, - showFallback, - 0, - null - )), - (nextPrimaryChildren = createFiberFromFragment( - nextPrimaryChildren, - showFallback, - renderLanes, - null - )), - (nextPrimaryChildren.flags |= 2), - (nextProps.return = workInProgress), - (nextPrimaryChildren.return = workInProgress), - (nextProps.sibling = nextPrimaryChildren), - (workInProgress.child = nextProps), - 0 !== (workInProgress.mode & 1) && - reconcileChildFibers( - workInProgress, - current.child, - null, - renderLanes - ), - (nextProps = workInProgress.child), - (nextProps.memoizedState = - mountSuspenseOffscreenState(renderLanes)), - (nextProps.childLanes = getRemainingWorkInPrimaryTree( - current, - JSCompiler_temp, - renderLanes - )), - (workInProgress.memoizedState = SUSPENDED_MARKER), - (workInProgress = nextPrimaryChildren)); - else if ( - (pushPrimaryTreeSuspenseHandler(workInProgress), - isSuspenseInstanceFallback()) - ) - (showFallback = getSuspenseInstanceFallbackErrorDetails()), - (JSCompiler_temp = showFallback.digest), - (nextPrimaryChildren = showFallback.message), - (nextProps = showFallback.stack), - (showFallback = showFallback.componentStack), - (nextPrimaryChildren = nextPrimaryChildren - ? Error(nextPrimaryChildren) - : Error( - "The server could not finish this Suspense boundary, likely due to an error during server rendering. Switched to client rendering." - )), - (nextPrimaryChildren.stack = nextProps || ""), - (nextPrimaryChildren.digest = JSCompiler_temp), - (JSCompiler_temp = void 0 === showFallback ? null : showFallback), - "string" === typeof JSCompiler_temp && - CapturedStacks.set(nextPrimaryChildren, JSCompiler_temp), - (JSCompiler_temp = { - value: nextPrimaryChildren, - source: null, - stack: JSCompiler_temp - }), - null === hydrationErrors - ? (hydrationErrors = [JSCompiler_temp]) - : hydrationErrors.push(JSCompiler_temp), - (workInProgress = retrySuspenseComponentWithoutHydrating( - current, - workInProgress, - renderLanes - )); - else if ( - ((JSCompiler_temp = 0 !== (renderLanes & current.childLanes)), - didReceiveUpdate || JSCompiler_temp) - ) { - JSCompiler_temp = workInProgressRoot; - if (null !== JSCompiler_temp) { - nextProps = renderLanes & -renderLanes; - if (0 !== (nextProps & SyncUpdateLanes)) - nextProps = SyncHydrationLane; - else - switch (nextProps) { - case SyncLane: - nextProps = SyncHydrationLane; - break; - case InputContinuousLane: - nextProps = InputContinuousHydrationLane; - break; - case DefaultLane: - nextProps = DefaultHydrationLane; - break; - case 128: - case 256: - case 512: - case 1024: - case 2048: - case 4096: - case 8192: - case 16384: - case 32768: - case 65536: - case 131072: - case 262144: - case 524288: - case 1048576: - case 2097152: - case 4194304: - case 8388608: - case 16777216: - case 33554432: - nextProps = TransitionHydrationLane; - break; - case IdleLane: - nextProps = IdleHydrationLane; - break; - default: - nextProps = 0; - } - nextProps = - 0 !== (nextProps & (JSCompiler_temp.suspendedLanes | renderLanes)) - ? 0 - : nextProps; - if (0 !== nextProps && nextProps !== nextPrimaryChildren.retryLane) - throw ( - ((nextPrimaryChildren.retryLane = nextProps), - enqueueConcurrentRenderForLane(current, nextProps), - scheduleUpdateOnFiber(JSCompiler_temp, current, nextProps), - SelectiveHydrationException) - ); - } - isSuspenseInstancePending() || renderDidSuspendDelayIfPossible(); - workInProgress = retrySuspenseComponentWithoutHydrating( - current, - workInProgress, - renderLanes - ); - } else - isSuspenseInstancePending() - ? ((workInProgress.flags |= 128), - (workInProgress.child = current.child), - retryDehydratedSuspenseBoundary.bind(null, current), - registerSuspenseInstanceRetry(), - (workInProgress = null)) - : ((workInProgress = mountSuspensePrimaryChildren( - workInProgress, - nextProps.children - )), - (workInProgress.flags |= 4096)); - return workInProgress; - } - if (showFallback) { - reuseSuspenseHandlerOnStack(workInProgress); - nextPrimaryChildren = nextProps.fallback; - showFallback = workInProgress.mode; - didSuspend = current.child; - var currentFallbackChildFragment = didSuspend.sibling, - primaryChildProps = { mode: "hidden", children: nextProps.children }; - 0 === (showFallback & 1) && workInProgress.child !== didSuspend - ? ((nextProps = workInProgress.child), - (nextProps.childLanes = 0), - (nextProps.pendingProps = primaryChildProps), - workInProgress.mode & 2 && - ((nextProps.actualDuration = 0), - (nextProps.actualStartTime = -1), - (nextProps.selfBaseDuration = didSuspend.selfBaseDuration), - (nextProps.treeBaseDuration = didSuspend.treeBaseDuration)), - (workInProgress.deletions = null)) - : ((nextProps = createWorkInProgress(didSuspend, primaryChildProps)), - (nextProps.subtreeFlags = didSuspend.subtreeFlags & 31457280)); - null !== currentFallbackChildFragment - ? (nextPrimaryChildren = createWorkInProgress( - currentFallbackChildFragment, - nextPrimaryChildren - )) - : ((nextPrimaryChildren = createFiberFromFragment( - nextPrimaryChildren, - showFallback, - renderLanes, - null - )), - (nextPrimaryChildren.flags |= 2)); - nextPrimaryChildren.return = workInProgress; - nextProps.return = workInProgress; - nextProps.sibling = nextPrimaryChildren; - workInProgress.child = nextProps; - nextProps = nextPrimaryChildren; - nextPrimaryChildren = workInProgress.child; - showFallback = current.child.memoizedState; - null === showFallback - ? (showFallback = mountSuspenseOffscreenState(renderLanes)) - : ((didSuspend = showFallback.cachePool), - null !== didSuspend - ? ((currentFallbackChildFragment = CacheContext._currentValue2), - (didSuspend = - didSuspend.parent !== currentFallbackChildFragment - ? { - parent: currentFallbackChildFragment, - pool: currentFallbackChildFragment - } - : didSuspend)) - : (didSuspend = getSuspendedCache()), - (showFallback = { - baseLanes: showFallback.baseLanes | renderLanes, - cachePool: didSuspend - })); - nextPrimaryChildren.memoizedState = showFallback; - nextPrimaryChildren.childLanes = getRemainingWorkInPrimaryTree( - current, - JSCompiler_temp, - renderLanes - ); - workInProgress.memoizedState = SUSPENDED_MARKER; - return nextProps; + } + + function findCurrentUnmaskedContext(fiber) { + { + return emptyContextObject; } - pushPrimaryTreeSuspenseHandler(workInProgress); - JSCompiler_temp = current.child; - current = JSCompiler_temp.sibling; - JSCompiler_temp = createWorkInProgress(JSCompiler_temp, { - mode: "visible", - children: nextProps.children - }); - 0 === (workInProgress.mode & 1) && (JSCompiler_temp.lanes = renderLanes); - JSCompiler_temp.return = workInProgress; - JSCompiler_temp.sibling = null; - null !== current && - ((renderLanes = workInProgress.deletions), - null === renderLanes - ? ((workInProgress.deletions = [current]), - (workInProgress.flags |= 16)) - : renderLanes.push(current)); - workInProgress.child = JSCompiler_temp; - workInProgress.memoizedState = null; - return JSCompiler_temp; } - function mountSuspensePrimaryChildren(workInProgress, primaryChildren) { - primaryChildren = createFiberFromOffscreen( - { mode: "visible", children: primaryChildren }, - workInProgress.mode, - 0, - null + + var LegacyRoot = 0; + var ConcurrentRoot = 1; + + // We use the existence of the state object as an indicator that the component + // is hidden. + var OffscreenVisible = + /* */ + 1; + var OffscreenDetached = + /* */ + 2; + var OffscreenPassiveEffectsConnected = + /* */ + 4; + function isOffscreenManual(offscreenFiber) { + return ( + offscreenFiber.memoizedProps !== null && + offscreenFiber.memoizedProps.mode === "manual" ); - primaryChildren.return = workInProgress; - return (workInProgress.child = primaryChildren); } - function retrySuspenseComponentWithoutHydrating( - current, - workInProgress, - renderLanes - ) { - reconcileChildFibers(workInProgress, current.child, null, renderLanes); - current = mountSuspensePrimaryChildren( - workInProgress, - workInProgress.pendingProps.children + + /** + * inlined Object.is polyfill to avoid requiring consumers ship their own + * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is + */ + function is(x, y) { + return ( + (x === y && (x !== 0 || 1 / x === 1 / y)) || (x !== x && y !== y) // eslint-disable-line no-self-compare ); - current.flags |= 2; - workInProgress.memoizedState = null; - return current; } - function scheduleSuspenseWorkOnFiber(fiber, renderLanes, propagationRoot) { - fiber.lanes |= renderLanes; - var alternate = fiber.alternate; - null !== alternate && (alternate.lanes |= renderLanes); - scheduleContextWorkOnParentPath( - fiber.return, - renderLanes, - propagationRoot - ); + + var objectIs = typeof Object.is === "function" ? Object.is : is; // $FlowFixMe[method-unbinding] + + // This is imported by the event replaying implementation in React DOM. It's + // in a separate file to break a circular dependency between the renderer and + // the reconciler. + function isRootDehydrated(root) { + var currentState = root.current.memoizedState; + return currentState.isDehydrated; } - function validateSuspenseListNestedChild(childSlot, index) { - var isAnArray = isArrayImpl(childSlot); - childSlot = !isAnArray && "function" === typeof getIteratorFn(childSlot); - return isAnArray || childSlot - ? ((isAnArray = isAnArray ? "array" : "iterable"), - error$jscomp$0( - "A nested %s was passed to row #%s in . Wrap it in an additional SuspenseList to configure its revealOrder: ... {%s} ... ", - isAnArray, - index, - isAnArray - ), - !1) - : !0; + + var contextStackCursor = createCursor(null); + var contextFiberStackCursor = createCursor(null); + var rootInstanceStackCursor = createCursor(null); // Represents the nearest host transition provider (in React DOM, a
) + + function requiredContext(c) { + { + if (c === null) { + error( + "Expected host context to exist. This error is likely caused by a bug " + + "in React. Please file an issue." + ); + } + } + + return c; } - function initSuspenseListRenderState( - workInProgress, - isBackwards, - tail, - lastContentRow, - tailMode - ) { - var renderState = workInProgress.memoizedState; - null === renderState - ? (workInProgress.memoizedState = { - isBackwards: isBackwards, - rendering: null, - renderingStartTime: 0, - last: lastContentRow, - tail: tail, - tailMode: tailMode - }) - : ((renderState.isBackwards = isBackwards), - (renderState.rendering = null), - (renderState.renderingStartTime = 0), - (renderState.last = lastContentRow), - (renderState.tail = tail), - (renderState.tailMode = tailMode)); + + function getRootHostContainer() { + var rootInstance = requiredContext(rootInstanceStackCursor.current); + return rootInstance; } - function updateSuspenseListComponent(current, workInProgress, renderLanes) { - var nextProps = workInProgress.pendingProps, - revealOrder = nextProps.revealOrder, - tailMode = nextProps.tail; - nextProps = nextProps.children; - if ( - void 0 !== revealOrder && - "forwards" !== revealOrder && - "backwards" !== revealOrder && - "together" !== revealOrder && - !didWarnAboutRevealOrder[revealOrder] - ) - if ( - ((didWarnAboutRevealOrder[revealOrder] = !0), - "string" === typeof revealOrder) - ) - switch (revealOrder.toLowerCase()) { - case "together": - case "forwards": - case "backwards": - error$jscomp$0( - '"%s" is not a valid value for revealOrder on . Use lowercase "%s" instead.', - revealOrder, - revealOrder.toLowerCase() - ); - break; - case "forward": - case "backward": - error$jscomp$0( - '"%s" is not a valid value for revealOrder on . React uses the -s suffix in the spelling. Use "%ss" instead.', - revealOrder, - revealOrder.toLowerCase() - ); - break; - default: - error$jscomp$0( - '"%s" is not a supported revealOrder on . Did you mean "together", "forwards" or "backwards"?', - revealOrder - ); - } - else - error$jscomp$0( - '%s is not a supported value for revealOrder on . Did you mean "together", "forwards" or "backwards"?', - revealOrder - ); - void 0 === tailMode || - didWarnAboutTailOptions[tailMode] || - ("collapsed" !== tailMode && "hidden" !== tailMode - ? ((didWarnAboutTailOptions[tailMode] = !0), - error$jscomp$0( - '"%s" is not a supported value for tail on . Did you mean "collapsed" or "hidden"?', - tailMode - )) - : "forwards" !== revealOrder && - "backwards" !== revealOrder && - ((didWarnAboutTailOptions[tailMode] = !0), - error$jscomp$0( - ' is only valid if revealOrder is "forwards" or "backwards". Did you mean to specify revealOrder="forwards"?', - tailMode - ))); - a: if ( - ("forwards" === revealOrder || "backwards" === revealOrder) && - void 0 !== nextProps && - null !== nextProps && - !1 !== nextProps - ) - if (isArrayImpl(nextProps)) - for (var i = 0; i < nextProps.length; i++) { - if (!validateSuspenseListNestedChild(nextProps[i], i)) break a; - } - else if (((i = getIteratorFn(nextProps)), "function" === typeof i)) { - if ((i = i.call(nextProps))) - for (var step = i.next(), _i = 0; !step.done; step = i.next()) { - if (!validateSuspenseListNestedChild(step.value, _i)) break a; - _i++; - } - } else - error$jscomp$0( - '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 - ); - reconcileChildren(current, workInProgress, nextProps, renderLanes); - nextProps = suspenseStackCursor.current; - if (0 !== (nextProps & ForceSuspenseFallback)) - (nextProps = - (nextProps & SubtreeSuspenseContextMask) | ForceSuspenseFallback), - (workInProgress.flags |= 128); - else { - if (null !== current && 0 !== (current.flags & 128)) - a: for (current = workInProgress.child; null !== current; ) { - if (13 === current.tag) - null !== current.memoizedState && - scheduleSuspenseWorkOnFiber( - current, - renderLanes, - workInProgress - ); - else if (19 === current.tag) - scheduleSuspenseWorkOnFiber(current, renderLanes, workInProgress); - else if (null !== current.child) { - current.child.return = current; - current = current.child; - continue; - } - if (current === workInProgress) break a; - for (; null === current.sibling; ) { - if (null === current.return || current.return === workInProgress) - break a; - current = current.return; - } - current.sibling.return = current.return; - current = current.sibling; - } - nextProps &= SubtreeSuspenseContextMask; + + function pushHostContainer(fiber, nextRootInstance) { + // Push current root instance onto the stack; + // This allows us to reset root when portals are popped. + push(rootInstanceStackCursor, nextRootInstance, fiber); // Track the context and the Fiber that provided it. + // This enables us to pop only Fibers that provide unique contexts. + + push(contextFiberStackCursor, fiber, fiber); // Finally, we need to push the host context to the stack. + // However, we can't just call getRootHostContext() and push it because + // we'd have a different number of entries on the stack depending on + // whether getRootHostContext() throws somewhere in renderer code or not. + // So we push an empty value first. This lets us safely unwind on errors. + + push(contextStackCursor, null, fiber); + var nextRootContext = getRootHostContext(); // Now that we know this function doesn't throw, replace it. + + pop(contextStackCursor, fiber); + push(contextStackCursor, nextRootContext, fiber); + } + + function popHostContainer(fiber) { + pop(contextStackCursor, fiber); + pop(contextFiberStackCursor, fiber); + pop(rootInstanceStackCursor, fiber); + } + + function getHostContext() { + var context = requiredContext(contextStackCursor.current); + return context; + } + + function pushHostContext(fiber) { + var context = requiredContext(contextStackCursor.current); + var nextContext = getChildHostContext(context, fiber.type); // Don't push this Fiber's context unless it's unique. + + if (context !== nextContext) { + // Track the context and the Fiber that provided it. + // This enables us to pop only Fibers that provide unique contexts. + push(contextFiberStackCursor, fiber, fiber); + push(contextStackCursor, nextContext, fiber); } - push(suspenseStackCursor, nextProps, workInProgress); - if (0 === (workInProgress.mode & 1)) workInProgress.memoizedState = null; - else - switch (revealOrder) { - case "forwards": - renderLanes = workInProgress.child; - for (revealOrder = null; null !== renderLanes; ) - (current = renderLanes.alternate), - null !== current && - null === findFirstSuspended(current) && - (revealOrder = renderLanes), - (renderLanes = renderLanes.sibling); - renderLanes = revealOrder; - null === renderLanes - ? ((revealOrder = workInProgress.child), - (workInProgress.child = null)) - : ((revealOrder = renderLanes.sibling), - (renderLanes.sibling = null)); - initSuspenseListRenderState( - workInProgress, - !1, - revealOrder, - renderLanes, - tailMode - ); - break; - case "backwards": - renderLanes = null; - revealOrder = workInProgress.child; - for (workInProgress.child = null; null !== revealOrder; ) { - current = revealOrder.alternate; - if (null !== current && null === findFirstSuspended(current)) { - workInProgress.child = revealOrder; - break; - } - current = revealOrder.sibling; - revealOrder.sibling = renderLanes; - renderLanes = revealOrder; - revealOrder = current; - } - initSuspenseListRenderState( - workInProgress, - !0, - renderLanes, - null, - tailMode - ); - break; - case "together": - initSuspenseListRenderState(workInProgress, !1, null, null, void 0); - break; - default: - workInProgress.memoizedState = null; + } + + function popHostContext(fiber) { + if (contextFiberStackCursor.current === fiber) { + // Do not pop unless this Fiber provided the current context. + // pushHostContext() only pushes Fibers that provide unique contexts. + pop(contextStackCursor, fiber); + pop(contextFiberStackCursor, fiber); + } + } + + var isHydrating = false; // This flag allows for warning supression when we expect there to be mismatches + + var hydrationErrors = null; + + function prepareToHydrateHostInstance(fiber, hostContext) { + { + throw new Error( + "Expected prepareToHydrateHostInstance() to never be called. " + + "This error is likely caused by a bug in React. Please file an issue." + ); + } + } + + function prepareToHydrateHostTextInstance(fiber) { + { + throw new Error( + "Expected prepareToHydrateHostTextInstance() to never be called. " + + "This error is likely caused by a bug in React. Please file an issue." + ); + } + } + + function prepareToHydrateHostSuspenseInstance(fiber) { + { + throw new Error( + "Expected prepareToHydrateHostSuspenseInstance() to never be called. " + + "This error is likely caused by a bug in React. Please file an issue." + ); + } + } + + function popHydrationState(fiber) { + { + return false; + } + } + + function upgradeHydrationErrorsToRecoverable() { + if (hydrationErrors !== null) { + // Successfully completed a forced client render. The errors that occurred + // during the hydration attempt are now recovered. We will log them in + // commit phase, once the entire tree has finished. + queueRecoverableErrors(hydrationErrors); + hydrationErrors = null; + } + } + + function getIsHydrating() { + return isHydrating; + } + + function queueHydrationError(error) { + if (hydrationErrors === null) { + hydrationErrors = [error]; + } else { + hydrationErrors.push(error); + } + } + + // we wait until the current render is over (either finished or interrupted) + // before adding it to the fiber/hook queue. Push to this array so we can + // access the queue, fiber, update, et al later. + + var concurrentQueues = []; + var concurrentQueuesIndex = 0; + var concurrentlyUpdatedLanes = NoLanes; + function finishQueueingConcurrentUpdates() { + var endIndex = concurrentQueuesIndex; + concurrentQueuesIndex = 0; + concurrentlyUpdatedLanes = NoLanes; + var i = 0; + + while (i < endIndex) { + var fiber = concurrentQueues[i]; + concurrentQueues[i++] = null; + var queue = concurrentQueues[i]; + concurrentQueues[i++] = null; + var update = concurrentQueues[i]; + concurrentQueues[i++] = null; + var lane = concurrentQueues[i]; + concurrentQueues[i++] = null; + + if (queue !== null && update !== null) { + 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; } - return workInProgress.child; + + if (lane !== NoLane) { + markUpdateLaneFromFiberToRoot(fiber, update, lane); + } + } } - function resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress) { - 0 === (workInProgress.mode & 1) && - null !== current && - ((current.alternate = null), - (workInProgress.alternate = null), - (workInProgress.flags |= 2)); + function getConcurrentlyUpdatedLanes() { + return concurrentlyUpdatedLanes; } - function bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderLanes - ) { - null !== current && (workInProgress.dependencies = current.dependencies); - profilerStartTime = -1; - workInProgressRootSkippedLanes |= workInProgress.lanes; - 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; + + function enqueueUpdate$1(fiber, queue, update, lane) { + // Don't update the `childLanes` on the return path yet. If we already in + // the middle of rendering, wait until after it has completed. + concurrentQueues[concurrentQueuesIndex++] = fiber; + concurrentQueues[concurrentQueuesIndex++] = queue; + concurrentQueues[concurrentQueuesIndex++] = update; + concurrentQueues[concurrentQueuesIndex++] = lane; + concurrentlyUpdatedLanes = mergeLanes(concurrentlyUpdatedLanes, lane); // The fiber's `lane` field is used in some places to check if any work is + // scheduled, to perform an eager bailout, so we need to update it immediately. + // TODO: We should probably move this to the "shared" queue instead. + + fiber.lanes = mergeLanes(fiber.lanes, lane); + var alternate = fiber.alternate; + + if (alternate !== null) { + alternate.lanes = mergeLanes(alternate.lanes, lane); } - return workInProgress.child; } - function attemptEarlyBailoutIfNoScheduledUpdate( - current, - workInProgress, - renderLanes + + function enqueueConcurrentHookUpdate(fiber, queue, update, lane) { + var concurrentQueue = queue; + var concurrentUpdate = update; + enqueueUpdate$1(fiber, concurrentQueue, concurrentUpdate, lane); + return getRootForUpdatedFiber(fiber); + } + function enqueueConcurrentHookUpdateAndEagerlyBailout( + fiber, + queue, + update ) { - switch (workInProgress.tag) { - case 3: - pushHostContainer( - workInProgress, - workInProgress.stateNode.containerInfo - ); - pushProvider( - workInProgress, - CacheContext, - current.memoizedState.cache - ); - break; - case 27: - case 5: - pushHostContext(workInProgress); - break; - case 4: - pushHostContainer( - workInProgress, - workInProgress.stateNode.containerInfo - ); - break; - case 10: - pushProvider( - workInProgress, - workInProgress.type, - workInProgress.memoizedProps.value - ); - break; - case 12: - 0 !== (renderLanes & workInProgress.childLanes) && - (workInProgress.flags |= 4); - var stateNode = workInProgress.stateNode; - stateNode.effectDuration = 0; - stateNode.passiveEffectDuration = 0; - break; - case 13: - stateNode = workInProgress.memoizedState; - if (null !== stateNode) { - if (null !== stateNode.dehydrated) - return ( - pushPrimaryTreeSuspenseHandler(workInProgress), - (workInProgress.flags |= 128), - null - ); - if (0 !== (renderLanes & workInProgress.child.childLanes)) - return updateSuspenseComponent( - current, - workInProgress, - renderLanes - ); - pushPrimaryTreeSuspenseHandler(workInProgress); - current = bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderLanes - ); - return null !== current ? current.sibling : null; - } - pushPrimaryTreeSuspenseHandler(workInProgress); - break; - case 19: - stateNode = 0 !== (renderLanes & workInProgress.childLanes); - if (0 !== (current.flags & 128)) { - if (stateNode) - return updateSuspenseListComponent( - current, - workInProgress, - renderLanes - ); - workInProgress.flags |= 128; + // This function is used to queue an update that doesn't need a rerender. The + // only reason we queue it is in case there's a subsequent higher priority + // update that causes it to be rebased. + var lane = NoLane; + var concurrentQueue = queue; + var concurrentUpdate = update; + enqueueUpdate$1(fiber, concurrentQueue, concurrentUpdate, lane); // Usually we can rely on the upcoming render phase to process the concurrent + // queue. However, since this is a bail out, we're not scheduling any work + // here. So the update we just queued will leak until something else happens + // to schedule work (if ever). + // + // Check if we're currently in the middle of rendering a tree, and if not, + // process the queue immediately to prevent a leak. + + var isConcurrentlyRendering = getWorkInProgressRoot() !== null; + + if (!isConcurrentlyRendering) { + finishQueueingConcurrentUpdates(); + } + } + function enqueueConcurrentClassUpdate(fiber, queue, update, lane) { + var concurrentQueue = queue; + var concurrentUpdate = update; + enqueueUpdate$1(fiber, concurrentQueue, concurrentUpdate, lane); + return getRootForUpdatedFiber(fiber); + } + function enqueueConcurrentRenderForLane(fiber, lane) { + enqueueUpdate$1(fiber, null, null, lane); + return getRootForUpdatedFiber(fiber); + } // Calling this function outside this module should only be done for backwards + // compatibility and should always be accompanied by a warning. + + function unsafe_markUpdateLaneFromFiberToRoot(sourceFiber, lane) { + // NOTE: For Hyrum's Law reasons, if an infinite update loop is detected, it + // should throw before `markUpdateLaneFromFiberToRoot` is called. But this is + // undefined behavior and we can change it if we need to; it just so happens + // that, at the time of this writing, there's an internal product test that + // happens to rely on this. + var root = getRootForUpdatedFiber(sourceFiber); + markUpdateLaneFromFiberToRoot(sourceFiber, null, lane); + return root; + } + + function markUpdateLaneFromFiberToRoot(sourceFiber, update, lane) { + // Update the source fiber's lanes + sourceFiber.lanes = mergeLanes(sourceFiber.lanes, lane); + var alternate = sourceFiber.alternate; + + if (alternate !== null) { + alternate.lanes = mergeLanes(alternate.lanes, lane); + } // Walk the parent path to the root and update the child lanes. + + var isHidden = false; + var parent = sourceFiber.return; + var node = sourceFiber; + + while (parent !== null) { + parent.childLanes = mergeLanes(parent.childLanes, lane); + alternate = parent.alternate; + + if (alternate !== null) { + alternate.childLanes = mergeLanes(alternate.childLanes, lane); + } + + if (parent.tag === OffscreenComponent) { + // Check if this offscreen boundary is currently hidden. + // + // The instance may be null if the Offscreen parent was unmounted. Usually + // the parent wouldn't be reachable in that case because we disconnect + // fibers from the tree when they are deleted. However, there's a weird + // edge case where setState is called on a fiber that was interrupted + // before it ever mounted. Because it never mounts, it also never gets + // deleted. Because it never gets deleted, its return pointer never gets + // disconnected. Which means it may be attached to a deleted Offscreen + // parent node. (This discovery suggests it may be better for memory usage + // if we don't attach the `return` pointer until the commit phase, though + // in order to do that we'd need some other way to track the return + // pointer during the initial render, like on the stack.) + // + // This case is always accompanied by a warning, but we still need to + // account for it. (There may be other cases that we haven't discovered, + // too.) + var offscreenInstance = parent.stateNode; + + if ( + offscreenInstance !== null && + !(offscreenInstance._visibility & OffscreenVisible) + ) { + isHidden = true; } - var renderState = workInProgress.memoizedState; - null !== renderState && - ((renderState.rendering = null), - (renderState.tail = null), - (renderState.lastEffect = null)); - push( - suspenseStackCursor, - suspenseStackCursor.current, - workInProgress - ); - if (stateNode) break; - else return null; - case 22: - case 23: - return ( - (workInProgress.lanes = 0), - updateOffscreenComponent(current, workInProgress, renderLanes) - ); - case 24: - pushProvider( - workInProgress, - CacheContext, - current.memoizedState.cache - ); + } + + node = parent; + parent = parent.return; + } + + if (isHidden && update !== null && node.tag === HostRoot) { + var root = node.stateNode; + markHiddenUpdate(root, update, lane); } - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); } - function beginWork(current, workInProgress, renderLanes) { - if (workInProgress._debugNeedsRemount && null !== current) { - renderLanes = createFiberFromTypeAndProps( - workInProgress.type, - workInProgress.key, - workInProgress.pendingProps, - workInProgress._debugOwner || null, - workInProgress.mode, - workInProgress.lanes - ); - renderLanes._debugStack = workInProgress._debugStack; - renderLanes._debugTask = workInProgress._debugTask; - var returnFiber = workInProgress.return; - if (null === returnFiber) throw Error("Cannot swap the root fiber."); - current.alternate = null; - workInProgress.alternate = null; - renderLanes.index = workInProgress.index; - renderLanes.sibling = workInProgress.sibling; - renderLanes.return = workInProgress.return; - renderLanes.ref = workInProgress.ref; - renderLanes._debugInfo = workInProgress._debugInfo; - if (workInProgress === returnFiber.child) - returnFiber.child = renderLanes; - else { - var prevSibling = returnFiber.child; - if (null === prevSibling) - throw Error("Expected parent to have a child."); - for (; prevSibling.sibling !== workInProgress; ) - if (((prevSibling = prevSibling.sibling), null === prevSibling)) - throw Error("Expected to find the previous sibling."); - prevSibling.sibling = renderLanes; - } - workInProgress = returnFiber.deletions; - null === workInProgress - ? ((returnFiber.deletions = [current]), (returnFiber.flags |= 16)) - : workInProgress.push(current); - renderLanes.flags |= 2; - return renderLanes; - } - if (null !== current) + + function getRootForUpdatedFiber(sourceFiber) { + // TODO: We will detect and infinite update loop and throw even if this fiber + // has already unmounted. This isn't really necessary but it happens to be the + // current behavior we've used for several release cycles. Consider not + // performing this check if the updated fiber already unmounted, since it's + // not possible for that to cause an infinite update loop. + throwIfInfiniteUpdateLoopDetected(); // When a setState happens, we must ensure the root is scheduled. Because + // update queues do not have a backpointer to the root, the only way to do + // this currently is to walk up the return path. This used to not be a big + // deal because we would have to walk up the return path to set + // the `childLanes`, anyway, but now those two traversals happen at + // different times. + // TODO: Consider adding a `root` backpointer on the update queue. + + detectUpdateOnUnmountedFiber(sourceFiber, sourceFiber); + var node = sourceFiber; + var parent = node.return; + + while (parent !== null) { + detectUpdateOnUnmountedFiber(sourceFiber, node); + node = parent; + parent = node.return; + } + + return node.tag === HostRoot ? node.stateNode : null; + } + + function detectUpdateOnUnmountedFiber(sourceFiber, parent) { + { + var alternate = parent.alternate; + if ( - current.memoizedProps !== workInProgress.pendingProps || - workInProgress.type !== current.type - ) - didReceiveUpdate = !0; - else { - if ( - 0 === (current.lanes & renderLanes) && - 0 === (workInProgress.flags & 128) - ) - return ( - (didReceiveUpdate = !1), - attemptEarlyBailoutIfNoScheduledUpdate( - current, - workInProgress, - renderLanes - ) - ); - didReceiveUpdate = 0 !== (current.flags & 131072) ? !0 : !1; + alternate === null && + (parent.flags & (Placement | Hydrating)) !== NoFlags$1 + ) { + warnAboutUpdateOnNotYetMountedFiberInDEV(sourceFiber); } - else didReceiveUpdate = !1; - workInProgress.lanes = 0; - switch (workInProgress.tag) { - case 16: - a: if ( - ((prevSibling = workInProgress.elementType), - resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress), - (returnFiber = workInProgress.pendingProps), - (current = callLazyInitInDEV(prevSibling)), - (workInProgress.type = current), - "function" === typeof current) - ) - shouldConstruct(current) - ? ((returnFiber = resolveClassComponentProps( - current, - returnFiber - )), - (workInProgress.tag = 1), - (workInProgress.type = current = - resolveFunctionForHotReloading(current)), - (workInProgress = updateClassComponent( - null, - workInProgress, - current, - returnFiber, - renderLanes - ))) - : ((workInProgress.tag = 0), - validateFunctionComponentInDev(workInProgress, current), - (workInProgress.type = current = - resolveFunctionForHotReloading(current)), - (workInProgress = updateFunctionComponent( - null, - workInProgress, - current, - returnFiber, - renderLanes - ))); - else { - if (void 0 !== current && null !== current) - if ( - ((prevSibling = current.$$typeof), - prevSibling === REACT_FORWARD_REF_TYPE) - ) { - workInProgress.tag = 11; - workInProgress.type = current = - resolveForwardRefForHotReloading(current); - workInProgress = updateForwardRef( - null, - workInProgress, - current, - returnFiber, - renderLanes - ); - break a; - } else if (prevSibling === REACT_MEMO_TYPE) { - workInProgress.tag = 14; - workInProgress = updateMemoComponent( - null, - workInProgress, - current, - returnFiber, - renderLanes - ); - break a; - } - workInProgress = ""; - null !== current && - "object" === typeof current && - current.$$typeof === REACT_LAZY_TYPE && - (workInProgress = - " Did you wrap a component in React.lazy() more than once?"); - throw Error( - "Element type is invalid. Received a promise that resolves to: " + - current + - ". Lazy element type must resolve to a class or function." + - workInProgress - ); - } - return workInProgress; - case 0: - return updateFunctionComponent( - current, - workInProgress, - workInProgress.type, - workInProgress.pendingProps, - renderLanes - ); - case 1: - return ( - (returnFiber = workInProgress.type), - (prevSibling = resolveClassComponentProps( - returnFiber, - workInProgress.pendingProps - )), - updateClassComponent( - current, - workInProgress, - returnFiber, - prevSibling, - renderLanes - ) - ); - case 3: - pushHostContainer( - workInProgress, - workInProgress.stateNode.containerInfo - ); - if (null === current) - throw Error("Should have a current fiber. This is a bug in React."); - var nextProps = workInProgress.pendingProps; - prevSibling = workInProgress.memoizedState; - returnFiber = prevSibling.element; - cloneUpdateQueue(current, workInProgress); - processUpdateQueue(workInProgress, nextProps, null, renderLanes); - nextProps = workInProgress.memoizedState; - var nextCache = nextProps.cache; - pushProvider(workInProgress, CacheContext, nextCache); - nextCache !== prevSibling.cache && - propagateContextChange(workInProgress, CacheContext, renderLanes); - suspendIfUpdateReadFromEntangledAsyncAction(); - prevSibling = nextProps.element; - prevSibling === returnFiber - ? (workInProgress = bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderLanes - )) - : (reconcileChildren( - current, - workInProgress, - prevSibling, - renderLanes - ), - (workInProgress = workInProgress.child)); - return workInProgress; - case 26: - case 27: - case 5: - return ( - pushHostContext(workInProgress), - (returnFiber = workInProgress.pendingProps.children), - null !== workInProgress.memoizedState && - ((prevSibling = renderWithHooks( - current, - workInProgress, - TransitionAwareHostComponent, - null, - null, - renderLanes - )), - (HostTransitionContext._currentValue2 = prevSibling), - didReceiveUpdate && - null !== current && - current.memoizedState.memoizedState !== prevSibling && - propagateContextChange( - workInProgress, - HostTransitionContext, - renderLanes - )), - markRef(current, workInProgress), - reconcileChildren( - current, - workInProgress, - returnFiber, - renderLanes - ), - workInProgress.child - ); - case 6: - return null; - case 13: - return updateSuspenseComponent(current, workInProgress, renderLanes); - case 4: - return ( - pushHostContainer( - workInProgress, - workInProgress.stateNode.containerInfo - ), - (returnFiber = workInProgress.pendingProps), - null === current - ? (workInProgress.child = reconcileChildFibers( - workInProgress, - null, - returnFiber, - renderLanes - )) - : reconcileChildren( - current, - workInProgress, - returnFiber, - renderLanes - ), - workInProgress.child - ); - case 11: - return updateForwardRef( - current, - workInProgress, - workInProgress.type, - workInProgress.pendingProps, - renderLanes - ); - case 7: - return ( - reconcileChildren( - current, - workInProgress, - workInProgress.pendingProps, - renderLanes - ), - workInProgress.child - ); - case 8: - return ( - reconcileChildren( - current, - workInProgress, - workInProgress.pendingProps.children, - renderLanes - ), - workInProgress.child - ); - case 12: - return ( - (workInProgress.flags |= 4), - (returnFiber = workInProgress.stateNode), - (returnFiber.effectDuration = 0), - (returnFiber.passiveEffectDuration = 0), - reconcileChildren( - current, - workInProgress, - workInProgress.pendingProps.children, - renderLanes - ), - workInProgress.child - ); - case 10: - a: { - returnFiber = workInProgress.type; - prevSibling = workInProgress.pendingProps; - nextProps = workInProgress.memoizedProps; - nextCache = prevSibling.value; - "value" in prevSibling || - hasWarnedAboutUsingNoValuePropOnContextProvider || - ((hasWarnedAboutUsingNoValuePropOnContextProvider = !0), - error$jscomp$0( - "The `value` prop is required for the ``. Did you misspell it or forget to pass it?" - )); - pushProvider(workInProgress, returnFiber, nextCache); - if (null !== nextProps) - if (objectIs(nextProps.value, nextCache)) { - if (nextProps.children === prevSibling.children) { - workInProgress = bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderLanes - ); - break a; - } - } else - propagateContextChange( - workInProgress, - returnFiber, - renderLanes - ); - reconcileChildren( - current, - workInProgress, - prevSibling.children, - renderLanes - ); - workInProgress = workInProgress.child; - } - return workInProgress; - case 9: - return ( - (prevSibling = workInProgress.type._context), - (returnFiber = workInProgress.pendingProps.children), - "function" !== typeof returnFiber && - error$jscomp$0( - "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." - ), - prepareToReadContext(workInProgress, renderLanes), - (prevSibling = readContext(prevSibling)), - markComponentRenderStarted(workInProgress), - (returnFiber = callComponentInDEV( - returnFiber, - prevSibling, - void 0 - )), - markComponentRenderStopped(), - (workInProgress.flags |= 1), - reconcileChildren( - current, - workInProgress, - returnFiber, - renderLanes - ), - workInProgress.child - ); - case 14: - return updateMemoComponent( - current, - workInProgress, - workInProgress.type, - workInProgress.pendingProps, - renderLanes - ); - case 15: - return updateSimpleMemoComponent( - current, - workInProgress, - workInProgress.type, - workInProgress.pendingProps, - renderLanes - ); - case 17: - return ( - (returnFiber = workInProgress.type), - (prevSibling = resolveClassComponentProps( - returnFiber, - workInProgress.pendingProps - )), - resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress), - (workInProgress.tag = 1), - prepareToReadContext(workInProgress, renderLanes), - constructClassInstance(workInProgress, returnFiber, prevSibling), - mountClassInstance( - workInProgress, - returnFiber, - prevSibling, - renderLanes - ), - finishClassComponent( - null, - workInProgress, - returnFiber, - !0, - !1, - renderLanes - ) - ); - case 28: - return ( - (returnFiber = workInProgress.type), - (prevSibling = resolveClassComponentProps( - returnFiber, - workInProgress.pendingProps - )), - resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress), - (workInProgress.tag = 0), - updateFunctionComponent( - null, - workInProgress, - returnFiber, - prevSibling, - renderLanes - ) - ); - case 19: - return updateSuspenseListComponent( - current, - workInProgress, - renderLanes - ); - case 22: - return updateOffscreenComponent(current, workInProgress, renderLanes); - case 24: - return ( - prepareToReadContext(workInProgress, renderLanes), - (returnFiber = readContext(CacheContext)), - null === current - ? ((prevSibling = peekCacheFromPool()), - null === prevSibling && - ((prevSibling = workInProgressRoot), - (nextProps = createCache()), - (prevSibling.pooledCache = nextProps), - retainCache(nextProps), - null !== nextProps && - (prevSibling.pooledCacheLanes |= renderLanes), - (prevSibling = nextProps)), - (workInProgress.memoizedState = { - parent: returnFiber, - cache: prevSibling - }), - initializeUpdateQueue(workInProgress), - pushProvider(workInProgress, CacheContext, prevSibling)) - : (0 !== (current.lanes & renderLanes) && - (cloneUpdateQueue(current, workInProgress), - processUpdateQueue(workInProgress, null, null, renderLanes), - suspendIfUpdateReadFromEntangledAsyncAction()), - (prevSibling = current.memoizedState), - (nextProps = workInProgress.memoizedState), - prevSibling.parent !== returnFiber - ? ((prevSibling = { - parent: returnFiber, - cache: returnFiber - }), - (workInProgress.memoizedState = prevSibling), - 0 === workInProgress.lanes && - (workInProgress.memoizedState = - workInProgress.updateQueue.baseState = - prevSibling), - pushProvider(workInProgress, CacheContext, returnFiber)) - : ((returnFiber = nextProps.cache), - pushProvider(workInProgress, CacheContext, returnFiber), - returnFiber !== prevSibling.cache && - propagateContextChange( - workInProgress, - CacheContext, - renderLanes - ))), - reconcileChildren( - current, - workInProgress, - workInProgress.pendingProps.children, - renderLanes - ), - workInProgress.child - ); - case 29: - throw workInProgress.pendingProps; } - throw Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in React. Please file an issue." - ); } - function resetContextDependencies() { - lastFullyObservedContext = - lastContextDependency = - currentlyRenderingFiber = - null; - isDisallowedContextReadInDEV = !1; + + var ReactCurrentActQueue$3 = ReactSharedInternals.ReactCurrentActQueue; // A linked list of all the roots with pending work. In an idiomatic app, + // there's only a single root, but we do support multi root apps, hence this + // extra complexity. But this module is optimized for the single root case. + + var firstScheduledRoot = null; + var lastScheduledRoot = null; // Used to prevent redundant mircotasks from being scheduled. + + var didScheduleMicrotask = false; // `act` "microtasks" are scheduled on the `act` queue instead of an actual + // microtask, so we have to dedupe those separately. This wouldn't be an issue + // if we required all `act` calls to be awaited, which we might in the future. + + var didScheduleMicrotask_act = false; // Used to quickly bail out of flushSync if there's no sync work to do. + + var mightHavePendingSyncWork = false; + var isFlushingWork = false; + var currentEventTransitionLane = NoLane; + function ensureRootIsScheduled(root) { + // This function is called whenever a root receives an update. It does two + // things 1) it ensures the root is in the root schedule, and 2) it ensures + // there's a pending microtask to process the root schedule. + // + // Most of the actual scheduling logic does not happen until + // `scheduleTaskForRootDuringMicrotask` runs. + // Add the root to the schedule + if (root === lastScheduledRoot || root.next !== null); + else { + if (lastScheduledRoot === null) { + firstScheduledRoot = lastScheduledRoot = root; + } else { + lastScheduledRoot.next = root; + lastScheduledRoot = root; + } + } // Any time a root received an update, we set this to true until the next time + // we process the schedule. If it's false, then we can quickly exit flushSync + // without consulting the schedule. + + mightHavePendingSyncWork = true; // At the end of the current event, go through each of the roots and ensure + // there's a task scheduled for each one at the correct priority. + + if (ReactCurrentActQueue$3.current !== null) { + // We're inside an `act` scope. + if (!didScheduleMicrotask_act) { + didScheduleMicrotask_act = true; + scheduleImmediateTask(processRootScheduleInMicrotask); + } + } else { + if (!didScheduleMicrotask) { + didScheduleMicrotask = true; + scheduleImmediateTask(processRootScheduleInMicrotask); + } + } + + { + // While this flag is disabled, we schedule the render task immediately + // instead of waiting a microtask. + // TODO: We need to land enableDeferRootSchedulingToMicrotask ASAP to + // unblock additional features we have planned. + scheduleTaskForRootDuringMicrotask(root, now$1()); + } + + if (ReactCurrentActQueue$3.isBatchingLegacy && root.tag === LegacyRoot) { + // Special `act` case: Record whenever a legacy update is scheduled. + ReactCurrentActQueue$3.didScheduleLegacyUpdate = true; + } } - function pushProvider(providerFiber, context, nextValue) { - push(valueCursor, context._currentValue2, providerFiber); - context._currentValue2 = nextValue; - push(renderer2CursorDEV, context._currentRenderer2, providerFiber); - void 0 !== context._currentRenderer2 && - null !== context._currentRenderer2 && - context._currentRenderer2 !== rendererSigil && - error$jscomp$0( - "Detected multiple renderers concurrently rendering the same context provider. This is currently unsupported." - ); - context._currentRenderer2 = rendererSigil; + function flushSyncWorkOnAllRoots() { + // This is allowed to be called synchronously, but the caller should check + // the execution context first. + flushSyncWorkAcrossRoots_impl(false); } - function popProvider(context, providerFiber) { - context._currentValue2 = valueCursor.current; - var currentRenderer2 = renderer2CursorDEV.current; - pop(renderer2CursorDEV, providerFiber); - context._currentRenderer2 = currentRenderer2; - pop(valueCursor, providerFiber); + function flushSyncWorkOnLegacyRootsOnly() { + // This is allowed to be called synchronously, but the caller should check + // the execution context first. + flushSyncWorkAcrossRoots_impl(true); } - function scheduleContextWorkOnParentPath( - parent, - renderLanes, - propagationRoot - ) { - for (; null !== parent; ) { - var alternate = parent.alternate; - (parent.childLanes & renderLanes) !== renderLanes - ? ((parent.childLanes |= renderLanes), - null !== alternate && (alternate.childLanes |= renderLanes)) - : null !== alternate && - (alternate.childLanes & renderLanes) !== renderLanes && - (alternate.childLanes |= renderLanes); - if (parent === propagationRoot) break; - parent = parent.return; + + function flushSyncWorkAcrossRoots_impl(onlyLegacy) { + if (isFlushingWork) { + // Prevent reentrancy. + // TODO: Is this overly defensive? The callers must check the execution + // context first regardless. + return; } - parent !== propagationRoot && - error$jscomp$0( - "Expected to find the propagation root when scheduling context work. This error is likely caused by a bug in React. Please file an issue." - ); - } - function propagateContextChange(workInProgress, context, renderLanes) { - var fiber = workInProgress.child; - null !== fiber && (fiber.return = workInProgress); - for (; null !== fiber; ) { - var list = fiber.dependencies; - if (null !== list) { - var nextFiber = fiber.child; - for (var dependency = list.firstContext; null !== dependency; ) { - if (dependency.context === context) { - if (1 === fiber.tag) { - dependency = createUpdate(renderLanes & -renderLanes); - dependency.tag = ForceUpdate; - var updateQueue = fiber.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; + + if (!mightHavePendingSyncWork) { + // Fast path. There's no sync work to do. + return; + } // There may or may not be synchronous work scheduled. Let's check. + + var didPerformSomeWork; + var errors = null; + isFlushingWork = true; + + do { + didPerformSomeWork = false; + var root = firstScheduledRoot; + + while (root !== null) { + if (onlyLegacy && root.tag !== LegacyRoot); + else { + var workInProgressRoot = getWorkInProgressRoot(); + var workInProgressRootRenderLanes = + getWorkInProgressRootRenderLanes(); + var nextLanes = getNextLanes( + root, + root === workInProgressRoot + ? workInProgressRootRenderLanes + : NoLanes + ); + + if (includesSyncLane(nextLanes)) { + // This root has pending sync work. Flush it now. + try { + didPerformSomeWork = true; + performSyncWorkOnRoot(root, nextLanes); + } catch (error) { + // Collect errors so we can rethrow them at the end + if (errors === null) { + errors = [error]; + } else { + errors.push(error); } } - fiber.lanes |= renderLanes; - dependency = fiber.alternate; - null !== dependency && (dependency.lanes |= renderLanes); - scheduleContextWorkOnParentPath( - fiber.return, - renderLanes, - workInProgress - ); - list.lanes |= renderLanes; - break; } - dependency = dependency.next; } - } else if (10 === fiber.tag) - nextFiber = fiber.type === workInProgress.type ? null : fiber.child; - else if (18 === fiber.tag) { - nextFiber = fiber.return; - if (null === nextFiber) - throw Error( - "We just came from a parent so we must have had a parent. This is a bug in React." - ); - nextFiber.lanes |= renderLanes; - list = nextFiber.alternate; - null !== list && (list.lanes |= renderLanes); - scheduleContextWorkOnParentPath( - nextFiber, - renderLanes, - workInProgress - ); - nextFiber = fiber.sibling; - } else nextFiber = fiber.child; - if (null !== nextFiber) nextFiber.return = fiber; - else - for (nextFiber = fiber; null !== nextFiber; ) { - if (nextFiber === workInProgress) { - nextFiber = null; - break; - } - fiber = nextFiber.sibling; - if (null !== fiber) { - fiber.return = nextFiber.return; - nextFiber = fiber; - break; + + root = root.next; + } + } while (didPerformSomeWork); + + isFlushingWork = false; // If any errors were thrown, rethrow them right before exiting. + // TODO: Consider returning these to the caller, to allow them to decide + // how/when to rethrow. + + if (errors !== null) { + if (errors.length > 1) { + if (typeof AggregateError === "function") { + // eslint-disable-next-line no-undef + throw new AggregateError(errors); + } else { + for (var i = 1; i < errors.length; i++) { + scheduleImmediateTask(throwError.bind(null, errors[i])); } - nextFiber = nextFiber.return; + + var firstError = errors[0]; + throw firstError; } - fiber = nextFiber; + } else { + var error = errors[0]; + throw error; + } } } - function prepareToReadContext(workInProgress, renderLanes) { - currentlyRenderingFiber = workInProgress; - lastFullyObservedContext = lastContextDependency = null; - workInProgress = workInProgress.dependencies; - null !== workInProgress && - null !== workInProgress.firstContext && - (0 !== (workInProgress.lanes & renderLanes) && (didReceiveUpdate = !0), - (workInProgress.firstContext = null)); - } - function readContext(context) { - isDisallowedContextReadInDEV && - error$jscomp$0( - "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()." - ); - return readContextForConsumer(currentlyRenderingFiber, context); - } - function readContextDuringReconciliation(consumer, context, renderLanes) { - null === currentlyRenderingFiber && - prepareToReadContext(consumer, renderLanes); - return readContextForConsumer(consumer, context); + + function throwError(error) { + throw error; } - function readContextForConsumer(consumer, context) { - var value = context._currentValue2; - if (lastFullyObservedContext !== context) + + function processRootScheduleInMicrotask() { + // This function is always called inside a microtask. It should never be + // called synchronously. + didScheduleMicrotask = false; + + { + didScheduleMicrotask_act = false; + } // We'll recompute this as we iterate through all the roots and schedule them. + + mightHavePendingSyncWork = false; + var currentTime = now$1(); + var prev = null; + var root = firstScheduledRoot; + + while (root !== null) { + var next = root.next; + if ( - ((context = { context: context, memoizedValue: value, next: null }), - null === lastContextDependency) + currentEventTransitionLane !== NoLane && + shouldAttemptEagerTransition() ) { - if (null === consumer) - 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 = context; - consumer.dependencies = { lanes: 0, firstContext: context }; - } else lastContextDependency = lastContextDependency.next = context; - return value; - } - function createCache() { - return { - controller: new AbortControllerLocal(), - data: new Map(), - refCount: 0 - }; - } - function retainCache(cache) { - cache.controller.signal.aborted && - warn( - "A cache instance was retained after it was already freed. This likely indicates a bug in React." - ); - cache.refCount++; - } - function releaseCache(cache) { - cache.refCount--; - 0 > cache.refCount && - warn( - "A cache instance was released after it was already freed. This likely indicates a bug in React." - ); - 0 === cache.refCount && - scheduleCallback$1(NormalPriority, function () { - cache.controller.abort(); - }); - } - function peekCacheFromPool() { - var cacheResumedFromPreviousRender = resumedCache.current; - return null !== cacheResumedFromPreviousRender - ? cacheResumedFromPreviousRender - : workInProgressRoot.pooledCache; - } - function pushTransition(offscreenWorkInProgress, prevCachePool) { - null === prevCachePool - ? push(resumedCache, resumedCache.current, offscreenWorkInProgress) - : push(resumedCache, prevCachePool.pool, offscreenWorkInProgress); - } - function getSuspendedCache() { - var cacheFromPool = peekCacheFromPool(); - return null === cacheFromPool - ? null - : { parent: CacheContext._currentValue2, pool: cacheFromPool }; - } - function doesRequireClone(current, completedWork) { - if (null !== current && current.child === completedWork.child) return !1; - if (0 !== (completedWork.flags & 16)) return !0; - for (current = completedWork.child; null !== current; ) { - if ( - 0 !== (current.flags & 13878) || - 0 !== (current.subtreeFlags & 13878) - ) - return !0; - current = current.sibling; - } - return !1; - } - function appendAllChildren( - parent, - workInProgress, - needsVisibilityToggle, - isHidden - ) { - for (var _node = workInProgress.child; null !== _node; ) { - if (5 === _node.tag) { - var instance = _node.stateNode; - needsVisibilityToggle && - isHidden && - (instance = cloneHiddenInstance(instance)); - appendChildNode(parent.node, instance.node); - } else if (6 === _node.tag) { - instance = _node.stateNode; - if (needsVisibilityToggle && isHidden) - throw Error("Not yet implemented."); - appendChildNode(parent.node, instance.node); - } else if (4 !== _node.tag) - if (22 === _node.tag && null !== _node.memoizedState) - (instance = _node.child), - null !== instance && (instance.return = _node), - appendAllChildren(parent, _node, !0, !0); - else if (null !== _node.child) { - _node.child.return = _node; - _node = _node.child; - continue; + // A transition was scheduled during an event, but we're going to try to + // render it synchronously anyway. We do this during a popstate event to + // preserve the scroll position of the previous page. + upgradePendingLaneToSync(root, currentEventTransitionLane); + } + + var nextLanes = scheduleTaskForRootDuringMicrotask(root, currentTime); + + if (nextLanes === NoLane) { + // This root has no more pending work. Remove it from the schedule. To + // guard against subtle reentrancy bugs, this microtask is the only place + // we do this — you can add roots to the schedule whenever, but you can + // only remove them here. + // Null this out so we know it's been removed from the schedule. + root.next = null; + + if (prev === null) { + // This is the new head of the list + firstScheduledRoot = next; + } else { + prev.next = next; + } + + if (next === null) { + // This is the new tail of the list + lastScheduledRoot = prev; + } + } else { + // This root still has work. Keep it in the list. + prev = root; + + if (includesSyncLane(nextLanes)) { + mightHavePendingSyncWork = true; } - if (_node === workInProgress) break; - for (; null === _node.sibling; ) { - if (null === _node.return || _node.return === workInProgress) return; - _node = _node.return; } - _node.sibling.return = _node.return; - _node = _node.sibling; + + root = next; } + + currentEventTransitionLane = NoLane; // At the end of the microtask, flush any pending synchronous work. This has + // to come at the end, because it does actual rendering work that might throw. + + flushSyncWorkOnAllRoots(); } - function appendAllChildrenToContainer( - containerChildSet, - workInProgress, - needsVisibilityToggle, - isHidden - ) { - for (var node = workInProgress.child; null !== node; ) { - if (5 === node.tag) { - var instance = node.stateNode; - needsVisibilityToggle && - isHidden && - (instance = cloneHiddenInstance(instance)); - appendChildNodeToSet(containerChildSet, instance.node); - } else if (6 === node.tag) { - instance = node.stateNode; - if (needsVisibilityToggle && isHidden) - throw Error("Not yet implemented."); - appendChildNodeToSet(containerChildSet, instance.node); - } else if (4 !== node.tag) - if (22 === node.tag && null !== node.memoizedState) - (instance = node.child), - null !== instance && (instance.return = node), - appendAllChildrenToContainer( - containerChildSet, - node, - !( - null !== node.memoizedProps && - "manual" === node.memoizedProps.mode - ), - !0 - ); - else if (null !== node.child) { - node.child.return = node; - node = node.child; - continue; - } - if (node === workInProgress) break; - for (; null === node.sibling; ) { - if (null === node.return || node.return === workInProgress) return; - node = node.return; + + function scheduleTaskForRootDuringMicrotask(root, currentTime) { + // This function is always called inside a microtask, or at the very end of a + // rendering task right before we yield to the main thread. It should never be + // called synchronously. + // + // TODO: Unless enableDeferRootSchedulingToMicrotask is off. We need to land + // that ASAP to unblock additional features we have planned. + // + // This function also never performs React work synchronously; it should + // only schedule work to be performed later, in a separate task or microtask. + // Check if any lanes are being starved by other work. If so, mark them as + // expired so we know to work on those next. + markStarvedLanesAsExpired(root, currentTime); // Determine the next lanes to work on, and their priority. + + var workInProgressRoot = getWorkInProgressRoot(); + var workInProgressRootRenderLanes = getWorkInProgressRootRenderLanes(); + var nextLanes = getNextLanes( + root, + root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes + ); + var existingCallbackNode = root.callbackNode; + + if ( + // Check if there's nothing to work on + nextLanes === NoLanes || // If this root is currently suspended and waiting for data to resolve, don't + // schedule a task to render it. We'll either wait for a ping, or wait to + // receive an update. + // + // Suspended render phase + (root === workInProgressRoot && isWorkLoopSuspendedOnData()) || // Suspended commit phase + root.cancelPendingCommit !== null + ) { + // Fast path: There's nothing to work on. + if (existingCallbackNode !== null) { + cancelCallback(existingCallbackNode); } - node.sibling.return = node.return; - node = node.sibling; + + root.callbackNode = null; + root.callbackPriority = NoLane; + return NoLane; + } // Schedule a new callback in the host environment. + + if (includesSyncLane(nextLanes)) { + // Synchronous work is always flushed at the end of the microtask, so we + // don't need to schedule an additional task. + if (existingCallbackNode !== null) { + cancelCallback(existingCallbackNode); + } + + root.callbackPriority = SyncLane; + root.callbackNode = null; + return SyncLane; + } else { + // We use the highest priority lane to represent the priority of the callback. + var existingCallbackPriority = root.callbackPriority; + var newCallbackPriority = getHighestPriorityLane(nextLanes); + + if ( + newCallbackPriority === existingCallbackPriority && // Special case related to `act`. If the currently scheduled task is a + // Scheduler task, rather than an `act` task, cancel it and re-schedule + // on the `act` queue. + !( + ReactCurrentActQueue$3.current !== null && + existingCallbackNode !== fakeActCallbackNode$1 + ) + ) { + // The priority hasn't changed. We can reuse the existing task. + return newCallbackPriority; + } else { + // Cancel the existing callback. We'll schedule a new one below. + cancelCallback(existingCallbackNode); + } + + 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; + } + + var newCallbackNode = scheduleCallback$1( + schedulerPriorityLevel, + performConcurrentWorkOnRoot.bind(null, root) + ); + root.callbackPriority = newCallbackPriority; + root.callbackNode = newCallbackNode; + return newCallbackPriority; } } - function updateHostContainer(current, workInProgress) { - if (doesRequireClone(current, workInProgress)) { - current = workInProgress.stateNode; - var container = current.containerInfo, - newChildSet = createChildNodeSet(); - appendAllChildrenToContainer(newChildSet, workInProgress, !1, !1); - current.pendingChildren = newChildSet; - workInProgress.flags |= 4; - completeRoot(container, newChildSet); + + function getContinuationForRoot(root, originalCallbackNode) { + // This is called at the end of `performConcurrentWorkOnRoot` to determine + // if we need to schedule a continuation task. + // + // Usually `scheduleTaskForRootDuringMicrotask` only runs inside a microtask; + // however, since most of the logic for determining if we need a continuation + // versus a new task is the same, we cheat a bit and call it here. This is + // only safe to do because we know we're at the end of the browser task. + // So although it's not an actual microtask, it might as well be. + scheduleTaskForRootDuringMicrotask(root, now$1()); + + if (root.callbackNode === originalCallbackNode) { + // The task node scheduled for this root is the same one that's + // currently executed. Need to return a continuation. + return performConcurrentWorkOnRoot.bind(null, root); } + + return null; } - function scheduleRetryEffect(workInProgress, retryQueue) { - null !== retryQueue - ? (workInProgress.flags |= 4) - : workInProgress.flags & 16384 && - ((retryQueue = - 22 !== workInProgress.tag ? claimNextRetryLane() : OffscreenLane), - (workInProgress.lanes |= retryQueue)); + var fakeActCallbackNode$1 = {}; + + function scheduleCallback$1(priorityLevel, callback) { + if (ReactCurrentActQueue$3.current !== null) { + // Special case: We're inside an `act` scope (a testing utility). + // Instead of scheduling work in the host environment, add it to a + // fake internal queue that's managed by the `act` implementation. + ReactCurrentActQueue$3.current.push(callback); + return fakeActCallbackNode$1; + } else { + return scheduleCallback$2(priorityLevel, callback); + } } - function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { - switch (renderState.tailMode) { - case "hidden": - hasRenderedATailFallback = renderState.tail; - for (var lastTailNode = null; null !== hasRenderedATailFallback; ) - null !== hasRenderedATailFallback.alternate && - (lastTailNode = hasRenderedATailFallback), - (hasRenderedATailFallback = hasRenderedATailFallback.sibling); - null === lastTailNode - ? (renderState.tail = null) - : (lastTailNode.sibling = null); - break; - case "collapsed": - lastTailNode = renderState.tail; - for (var _lastTailNode = null; null !== lastTailNode; ) - null !== lastTailNode.alternate && (_lastTailNode = lastTailNode), - (lastTailNode = lastTailNode.sibling); - null === _lastTailNode - ? hasRenderedATailFallback || null === renderState.tail - ? (renderState.tail = null) - : (renderState.tail.sibling = null) - : (_lastTailNode.sibling = null); + + function cancelCallback(callbackNode) { + if (callbackNode === fakeActCallbackNode$1); + else if (callbackNode !== null) { + cancelCallback$1(callbackNode); } } - 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 = completedWork.selfBaseDuration, - _child2 = completedWork.child; - null !== _child2; - ) - (newChildLanes |= _child2.lanes | _child2.childLanes), - (subtreeFlags |= _child2.subtreeFlags & 31457280), - (subtreeFlags |= _child2.flags & 31457280), - (_treeBaseDuration += _child2.treeBaseDuration), - (_child2 = _child2.sibling); - completedWork.treeBaseDuration = _treeBaseDuration; - } else - for ( - _treeBaseDuration = completedWork.child; - null !== _treeBaseDuration; + function scheduleImmediateTask(cb) { + if (ReactCurrentActQueue$3.current !== null) { + // Special case: Inside an `act` scope, we push microtasks to the fake `act` + // callback queue. This is because we currently support calling `act` + // without awaiting the result. The plan is to deprecate that, and require + // that you always await the result so that the microtasks have a chance to + // run. But it hasn't happened yet. + ReactCurrentActQueue$3.current.push(function () { + cb(); + return null; + }); + } // TODO: Can we land supportsMicrotasks? Which environments don't support it? + // Alternatively, can we move this check to the host config? - ) - (newChildLanes |= - _treeBaseDuration.lanes | _treeBaseDuration.childLanes), - (subtreeFlags |= _treeBaseDuration.subtreeFlags & 31457280), - (subtreeFlags |= _treeBaseDuration.flags & 31457280), - (_treeBaseDuration.return = completedWork), - (_treeBaseDuration = _treeBaseDuration.sibling); - else if (0 !== (completedWork.mode & 2)) { - _treeBaseDuration = completedWork.actualDuration; - _child2 = completedWork.selfBaseDuration; - for (var child = completedWork.child; null !== child; ) - (newChildLanes |= child.lanes | child.childLanes), - (subtreeFlags |= child.subtreeFlags), - (subtreeFlags |= child.flags), - (_treeBaseDuration += child.actualDuration), - (_child2 += child.treeBaseDuration), - (child = child.sibling); - completedWork.actualDuration = _treeBaseDuration; - completedWork.treeBaseDuration = _child2; - } else - for ( - _treeBaseDuration = completedWork.child; - null !== _treeBaseDuration; + if (supportsMicrotasks) { + scheduleMicrotask(function () { + // In Safari, appending an iframe forces microtasks to run. + // https://github.com/facebook/react/issues/22459 + // We don't support running callbacks in the middle of render + // or commit so we need to check against that. + var executionContext = getExecutionContext(); - ) - (newChildLanes |= - _treeBaseDuration.lanes | _treeBaseDuration.childLanes), - (subtreeFlags |= _treeBaseDuration.subtreeFlags), - (subtreeFlags |= _treeBaseDuration.flags), - (_treeBaseDuration.return = completedWork), - (_treeBaseDuration = _treeBaseDuration.sibling); - completedWork.subtreeFlags |= subtreeFlags; - completedWork.childLanes = newChildLanes; - return didBailout; - } - function completeWork(current, workInProgress, renderLanes) { - var newProps = workInProgress.pendingProps; - switch (workInProgress.tag) { - case 28: - case 16: - case 15: - case 0: - case 11: - case 7: - case 8: - case 12: - case 9: - case 14: - return bubbleProperties(workInProgress), null; - case 1: - return bubbleProperties(workInProgress), null; - case 3: - return ( - (newProps = workInProgress.stateNode), - (renderLanes = null), - null !== current && (renderLanes = current.memoizedState.cache), - workInProgress.memoizedState.cache !== renderLanes && - (workInProgress.flags |= 2048), - popProvider(CacheContext, workInProgress), - popHostContainer(workInProgress), - newProps.pendingContext && - ((newProps.context = newProps.pendingContext), - (newProps.pendingContext = null)), - (null !== current && null !== current.child) || - null === current || - (current.memoizedState.isDehydrated && - 0 === (workInProgress.flags & 256)) || - ((workInProgress.flags |= 1024), - null !== hydrationErrors && - (queueRecoverableErrors(hydrationErrors), - (hydrationErrors = null))), - updateHostContainer(current, workInProgress), - bubbleProperties(workInProgress), - null - ); - case 26: - case 27: - case 5: - popHostContext(workInProgress); - renderLanes = workInProgress.type; - if (null !== current && null != workInProgress.stateNode) { - renderLanes = current.stateNode; - var _oldProps = current.memoizedProps; - if ( - (current = doesRequireClone(current, workInProgress)) || - _oldProps !== newProps - ) { - requiredContext(contextStackCursor.current); - b: { - var keepChildren = !current; - _oldProps = diffProperties( - null, - _oldProps, - newProps, - renderLanes.canonical.viewConfig.validAttributes - ); - renderLanes.canonical.currentProps = newProps; - newProps = renderLanes.node; - if (keepChildren) - if (null !== _oldProps) - newProps = cloneNodeWithNewProps(newProps, _oldProps); - else { - newProps = renderLanes; - break b; - } - else - newProps = - null !== _oldProps - ? cloneNodeWithNewChildrenAndProps(newProps, _oldProps) - : cloneNodeWithNewChildren(newProps); - newProps = { node: newProps, canonical: renderLanes.canonical }; - } - newProps === renderLanes - ? (workInProgress.stateNode = renderLanes) - : ((workInProgress.stateNode = newProps), - current - ? appendAllChildren(newProps, workInProgress, !1, !1) - : (workInProgress.flags |= 4)); - } else workInProgress.stateNode = renderLanes; - } 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.current); - _oldProps = requiredContext(rootInstanceStackCursor.current); - current = nextReactTag; - nextReactTag += 2; - renderLanes = getViewConfigForType(renderLanes); - for (keepChildren in renderLanes.validAttributes) - newProps.hasOwnProperty(keepChildren) && - ReactNativePrivateInterface.deepFreezeAndThrowOnMutationInDev( - newProps[keepChildren] - ); - keepChildren = diffProperties( - null, - emptyObject$1, - newProps, - renderLanes.validAttributes - ); - keepChildren = createNode( - current, - renderLanes.uiViewClassName, - _oldProps, - keepChildren, - workInProgress - ); - _oldProps = ReactNativePrivateInterface.createPublicInstance( - current, - renderLanes, - workInProgress - ); - current = { - node: keepChildren, - canonical: { - nativeTag: current, - viewConfig: renderLanes, - currentProps: newProps, - internalInstanceHandle: workInProgress, - publicInstance: _oldProps - } - }; - appendAllChildren(current, workInProgress, !1, !1); - workInProgress.stateNode = current; - } - bubbleProperties(workInProgress); - workInProgress.flags &= -16777217; - return null; - case 6: - if (current && null != workInProgress.stateNode) - current.memoizedProps !== newProps - ? ((current = requiredContext(rootInstanceStackCursor.current)), - (renderLanes = requiredContext(contextStackCursor.current)), - (workInProgress.stateNode = createTextInstance( - newProps, - current, - renderLanes, - workInProgress - )), - (workInProgress.flags |= 4)) - : (workInProgress.stateNode = current.stateNode); - else { - if ( - "string" !== typeof newProps && - null === workInProgress.stateNode - ) - throw Error( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." - ); - current = requiredContext(rootInstanceStackCursor.current); - renderLanes = requiredContext(contextStackCursor.current); - workInProgress.stateNode = createTextInstance( - newProps, - current, - renderLanes, - workInProgress - ); - } - bubbleProperties(workInProgress); - return null; - case 13: - newProps = workInProgress.memoizedState; if ( - null === current || - (null !== current.memoizedState && - null !== current.memoizedState.dehydrated) + (executionContext & (RenderContext | CommitContext)) !== + NoContext ) { - if (null !== newProps && null !== newProps.dehydrated) { - if (null === current) { - throw Error( - "A dehydrated suspense component was completed without a hydrated node. This is probably a bug in React." - ); - throw Error( - "Expected prepareToHydrateHostSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." - ); - } - keepChildren = hydrationDiffRootDEV; - if (null !== keepChildren) { - hydrationDiffRootDEV = null; - try { - _oldProps = "\n\n" + describeNode(keepChildren, 0); - } catch (x) { - _oldProps = ""; - } - error$jscomp$0( - "A tree hydrated but some attributes of the server rendered HTML didn't match the client properties. This won't be patched up. This can happen if a SSR-ed Client Component used:\n\n- A server/client branch `if (typeof window !== 'undefined')`.\n- Variable input such as `Date.now()` or `Math.random()` which changes each time it's called.\n- Date formatting in a user's locale which doesn't match the server.\n- External changing data without sending a snapshot of it along with the HTML.\n- Invalid HTML tag nesting.\n\nIt can also happen if the client has a browser extension installed which messes with the HTML before React loaded.\n\n%s%s", - "https://react.dev/link/hydration-mismatch", - _oldProps - ); - } - 0 === (workInProgress.flags & 128) && - (workInProgress.memoizedState = null); - workInProgress.flags |= 4; - bubbleProperties(workInProgress); - 0 !== (workInProgress.mode & 2) && - null !== newProps && - ((keepChildren = workInProgress.child), - null !== keepChildren && - (workInProgress.treeBaseDuration -= - keepChildren.treeBaseDuration)); - keepChildren = !1; - } else - null !== hydrationErrors && - (queueRecoverableErrors(hydrationErrors), - (hydrationErrors = null)), - (keepChildren = !0); - if (!keepChildren) { - if (workInProgress.flags & 256) - return popSuspenseHandler(workInProgress), workInProgress; - popSuspenseHandler(workInProgress); - return null; - } + // Note that this would still prematurely flush the callbacks + // if this happens outside render or commit phase (e.g. in an event). + // Intentionally using a macrotask instead of a microtask here. This is + // wrong semantically but it prevents an infinite loop. The bug is + // Safari's, not ours, so we just do our best to not crash even though + // the behavior isn't completely correct. + scheduleCallback$2(ImmediatePriority, cb); + return; } - popSuspenseHandler(workInProgress); - if (0 !== (workInProgress.flags & 128)) - return ( - (workInProgress.lanes = renderLanes), - 0 !== (workInProgress.mode & 2) && - transferActualDuration(workInProgress), - workInProgress - ); - newProps = null !== newProps; - current = null !== current && null !== current.memoizedState; - newProps && - ((renderLanes = workInProgress.child), - (keepChildren = null), - null !== renderLanes.alternate && - null !== renderLanes.alternate.memoizedState && - null !== renderLanes.alternate.memoizedState.cachePool && - (keepChildren = - renderLanes.alternate.memoizedState.cachePool.pool), - (_oldProps = null), - null !== renderLanes.memoizedState && - null !== renderLanes.memoizedState.cachePool && - (_oldProps = renderLanes.memoizedState.cachePool.pool), - _oldProps !== keepChildren && (renderLanes.flags |= 2048)); - newProps !== current && - newProps && - (workInProgress.child.flags |= 8192); - scheduleRetryEffect(workInProgress, workInProgress.updateQueue); - bubbleProperties(workInProgress); - 0 !== (workInProgress.mode & 2) && - newProps && - ((current = workInProgress.child), - null !== current && - (workInProgress.treeBaseDuration -= current.treeBaseDuration)); - return null; - case 4: - return ( - popHostContainer(workInProgress), - updateHostContainer(current, workInProgress), - bubbleProperties(workInProgress), - null - ); - case 10: - return ( - popProvider(workInProgress.type, workInProgress), - bubbleProperties(workInProgress), - null - ); - case 17: - return bubbleProperties(workInProgress), null; - case 19: - pop(suspenseStackCursor, workInProgress); - keepChildren = workInProgress.memoizedState; - if (null === keepChildren) - return bubbleProperties(workInProgress), null; - newProps = 0 !== (workInProgress.flags & 128); - _oldProps = keepChildren.rendering; - if (null === _oldProps) - if (newProps) cutOffTailIfNeeded(keepChildren, !1); - else { - if ( - workInProgressRootExitStatus !== RootInProgress || - (null !== current && 0 !== (current.flags & 128)) - ) - for (current = workInProgress.child; null !== current; ) { - _oldProps = findFirstSuspended(current); - if (null !== _oldProps) { - workInProgress.flags |= 128; - cutOffTailIfNeeded(keepChildren, !1); - current = _oldProps.updateQueue; - workInProgress.updateQueue = current; - scheduleRetryEffect(workInProgress, current); - workInProgress.subtreeFlags = 0; - current = renderLanes; - for (newProps = workInProgress.child; null !== newProps; ) - resetWorkInProgress(newProps, current), - (newProps = newProps.sibling); - push( - suspenseStackCursor, - (suspenseStackCursor.current & - SubtreeSuspenseContextMask) | - ForceSuspenseFallback, - workInProgress - ); - return workInProgress.child; - } - current = current.sibling; - } - null !== keepChildren.tail && - now$1() > workInProgressRootRenderTargetTime && - ((workInProgress.flags |= 128), - (newProps = !0), - cutOffTailIfNeeded(keepChildren, !1), - (workInProgress.lanes = 4194304)); - } - else { - if (!newProps) - if ( - ((current = findFirstSuspended(_oldProps)), null !== current) - ) { - if ( - ((workInProgress.flags |= 128), - (newProps = !0), - (current = current.updateQueue), - (workInProgress.updateQueue = current), - scheduleRetryEffect(workInProgress, current), - cutOffTailIfNeeded(keepChildren, !0), - null === keepChildren.tail && - "hidden" === keepChildren.tailMode && - !_oldProps.alternate) - ) - return bubbleProperties(workInProgress), null; - } else - 2 * now$1() - keepChildren.renderingStartTime > - workInProgressRootRenderTargetTime && - renderLanes !== OffscreenLane && - ((workInProgress.flags |= 128), - (newProps = !0), - cutOffTailIfNeeded(keepChildren, !1), - (workInProgress.lanes = 4194304)); - keepChildren.isBackwards - ? ((_oldProps.sibling = workInProgress.child), - (workInProgress.child = _oldProps)) - : ((current = keepChildren.last), - null !== current - ? (current.sibling = _oldProps) - : (workInProgress.child = _oldProps), - (keepChildren.last = _oldProps)); - } - if (null !== keepChildren.tail) - return ( - (current = keepChildren.tail), - (keepChildren.rendering = current), - (keepChildren.tail = current.sibling), - (keepChildren.renderingStartTime = now$1()), - (current.sibling = null), - (renderLanes = suspenseStackCursor.current), - (renderLanes = newProps - ? (renderLanes & SubtreeSuspenseContextMask) | - ForceSuspenseFallback - : renderLanes & SubtreeSuspenseContextMask), - push(suspenseStackCursor, renderLanes, workInProgress), - current - ); - bubbleProperties(workInProgress); - return null; - case 22: - case 23: - return ( - popSuspenseHandler(workInProgress), - popHiddenContext(workInProgress), - (newProps = null !== workInProgress.memoizedState), - null !== current - ? (null !== current.memoizedState) !== newProps && - (workInProgress.flags |= 8192) - : newProps && (workInProgress.flags |= 8192), - newProps && 0 !== (workInProgress.mode & 1) - ? 0 !== (renderLanes & OffscreenLane) && - 0 === (workInProgress.flags & 128) && - (bubbleProperties(workInProgress), - workInProgress.subtreeFlags & 6 && - (workInProgress.flags |= 8192)) - : bubbleProperties(workInProgress), - (newProps = workInProgress.updateQueue), - null !== newProps && - scheduleRetryEffect(workInProgress, newProps.retryQueue), - (newProps = null), - null !== current && - null !== current.memoizedState && - null !== current.memoizedState.cachePool && - (newProps = current.memoizedState.cachePool.pool), - (renderLanes = null), - null !== workInProgress.memoizedState && - null !== workInProgress.memoizedState.cachePool && - (renderLanes = workInProgress.memoizedState.cachePool.pool), - renderLanes !== newProps && (workInProgress.flags |= 2048), - null !== current && pop(resumedCache, workInProgress), - null - ); - case 24: - return ( - (newProps = null), - null !== current && (newProps = current.memoizedState.cache), - workInProgress.memoizedState.cache !== newProps && - (workInProgress.flags |= 2048), - popProvider(CacheContext, workInProgress), - bubbleProperties(workInProgress), - null - ); - case 25: - return null; - case 29: - return null; - } - throw Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in React. Please file an issue." - ); - } - function unwindWork(current, workInProgress) { - switch (workInProgress.tag) { - case 1: - return ( - (current = workInProgress.flags), - current & 65536 - ? ((workInProgress.flags = (current & -65537) | 128), - 0 !== (workInProgress.mode & 2) && - transferActualDuration(workInProgress), - workInProgress) - : null - ); - case 3: - return ( - popProvider(CacheContext, workInProgress), - popHostContainer(workInProgress), - (current = workInProgress.flags), - 0 !== (current & 65536) && 0 === (current & 128) - ? ((workInProgress.flags = (current & -65537) | 128), - workInProgress) - : null - ); - case 26: - case 27: - case 5: - return popHostContext(workInProgress), null; - case 13: - popSuspenseHandler(workInProgress); - current = workInProgress.memoizedState; - if ( - null !== current && - null !== current.dehydrated && - null === workInProgress.alternate - ) - throw Error( - "Threw in newly mounted dehydrated component. This is likely a bug in React. Please file an issue." - ); - current = workInProgress.flags; - return current & 65536 - ? ((workInProgress.flags = (current & -65537) | 128), - 0 !== (workInProgress.mode & 2) && - transferActualDuration(workInProgress), - workInProgress) - : null; - case 19: - return pop(suspenseStackCursor, workInProgress), null; - case 4: - return popHostContainer(workInProgress), null; - case 10: - return popProvider(workInProgress.type, workInProgress), null; - case 22: - case 23: - return ( - popSuspenseHandler(workInProgress), - popHiddenContext(workInProgress), - null !== current && pop(resumedCache, workInProgress), - (current = workInProgress.flags), - current & 65536 - ? ((workInProgress.flags = (current & -65537) | 128), - 0 !== (workInProgress.mode & 2) && - transferActualDuration(workInProgress), - workInProgress) - : null - ); - case 24: - return popProvider(CacheContext, workInProgress), null; - case 25: - return null; - default: - return null; - } - } - function unwindInterruptedWork(current, interruptedWork) { - switch (interruptedWork.tag) { - case 3: - popProvider(CacheContext, interruptedWork); - popHostContainer(interruptedWork); - break; - case 26: - case 27: - case 5: - popHostContext(interruptedWork); - break; - case 4: - popHostContainer(interruptedWork); - break; - case 13: - popSuspenseHandler(interruptedWork); - break; - case 19: - pop(suspenseStackCursor, interruptedWork); - break; - case 10: - popProvider(interruptedWork.type, interruptedWork); - break; - case 22: - case 23: - popSuspenseHandler(interruptedWork); - popHiddenContext(interruptedWork); - null !== current && pop(resumedCache, interruptedWork); - break; - case 24: - popProvider(CacheContext, interruptedWork); + + cb(); + }); + } else { + // If microtasks are not supported, use Scheduler. + scheduleCallback$2(ImmediatePriority, cb); } } - function shouldProfile(current) { - return ( - 0 !== (current.mode & 2) && - (executionContext & CommitContext) !== NoContext - ); - } - function safelyCallComponentWillUnmount( - current, - nearestMountedAncestor, - instance + + function requestTransitionLane( // This argument isn't used, it's only here to encourage the caller to + // check that it's inside a transition before calling this function. + // TODO: Make this non-nullable. Requires a tweak to useOptimistic. + transition ) { - try { - if ( - ((instance.props = resolveClassComponentProps( - current.type, - current.memoizedProps - )), - (instance.state = current.memoizedState), - shouldProfile(current)) - ) - try { - startLayoutEffectTimer(), instance.componentWillUnmount(); - } finally { - recordLayoutEffectDuration(current); - } - else instance.componentWillUnmount(); - } catch (error$9) { - captureCommitPhaseError(current, nearestMountedAncestor, error$9); + // 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 currentEventTransitionLane; } - function safelyAttachRef(current, nearestMountedAncestor) { - try { - var ref = current.ref; - if (null !== ref) { - var instance = current.stateNode; - switch (current.tag) { - case 26: - case 27: - case 5: - var instanceToUse = getPublicInstance(instance); - break; - default: - instanceToUse = instance; - } - if ("function" === typeof ref) - if (shouldProfile(current)) - try { - startLayoutEffectTimer(), - (current.refCleanup = ref(instanceToUse)); - } finally { - recordLayoutEffectDuration(current); - } - else current.refCleanup = ref(instanceToUse); - else - "string" === typeof ref - ? error$jscomp$0("String refs are no longer supported.") - : ref.hasOwnProperty("current") || - error$jscomp$0( - "Unexpected ref object provided for %s. Use either a ref-setter function or React.createRef().", - getComponentNameFromFiber(current) - ), - (ref.current = instanceToUse); + + var currentEntangledLane = NoLane; // A thenable that resolves when the entangled scope completes. It does not + // resolve to a particular value because it's only used for suspending the UI + // until the async action scope has completed. + + var currentEntangledActionThenable = null; + + function chainThenableValue(thenable, result) { + // Equivalent to: Promise.resolve(thenable).then(() => result), except we can + // cheat a bit since we know that that this thenable is only ever consumed + // by React. + // + // We don't technically require promise support on the client yet, hence this + // extra code. + var listeners = []; + var thenableWithOverride = { + status: "pending", + value: null, + reason: null, + then: function (resolve) { + listeners.push(resolve); } - } catch (error$10) { - captureCommitPhaseError(current, nearestMountedAncestor, error$10); - } - } - function safelyDetachRef(current, nearestMountedAncestor) { - var ref = current.ref, - refCleanup = current.refCleanup; - if (null !== ref) - if ("function" === typeof refCleanup) - try { - if (shouldProfile(current)) - try { - startLayoutEffectTimer(), refCleanup(); - } finally { - recordLayoutEffectDuration(current); - } - else refCleanup(); - } catch (error$11) { - captureCommitPhaseError(current, nearestMountedAncestor, error$11); - } finally { - (current.refCleanup = null), - (current = current.alternate), - null != current && (current.refCleanup = null); + }; + thenable.then( + function (value) { + var fulfilledThenable = thenableWithOverride; + fulfilledThenable.status = "fulfilled"; + fulfilledThenable.value = result; + + for (var i = 0; i < listeners.length; i++) { + var listener = listeners[i]; + listener(result); } - else if ("function" === typeof ref) - try { - if (shouldProfile(current)) - try { - startLayoutEffectTimer(), ref(null); - } finally { - recordLayoutEffectDuration(current); - } - else ref(null); - } catch (error$12) { - captureCommitPhaseError(current, nearestMountedAncestor, error$12); + }, + function (error) { + var rejectedThenable = thenableWithOverride; + rejectedThenable.status = "rejected"; + rejectedThenable.reason = error; + + for (var i = 0; i < listeners.length; i++) { + var listener = listeners[i]; // This is a perf hack where we call the `onFulfill` ping function + // instead of `onReject`, because we know that React is the only + // consumer of these promises, and it passes the same listener to both. + // We also know that it will read the error directly off the + // `.reason` field. + + listener(undefined); } - else ref.current = null; + } + ); + return thenableWithOverride; } - function safelyCallDestroy(current, nearestMountedAncestor, destroy) { - try { - destroy(); - } catch (error$13) { - captureCommitPhaseError(current, nearestMountedAncestor, error$13); - } + function peekEntangledActionLane() { + return currentEntangledLane; } - function commitBeforeMutationEffects(root, firstChild) { - for (nextEffect = firstChild; null !== nextEffect; ) - if ( - ((root = nextEffect), - (firstChild = root.child), - 0 !== (root.subtreeFlags & 1028) && null !== firstChild) - ) - (firstChild.return = root), (nextEffect = firstChild); - else - for (; null !== nextEffect; ) { - root = nextEffect; - try { - runWithFiberInDEV(root, commitBeforeMutationEffectsOnFiber, root); - } catch (error$14) { - captureCommitPhaseError(root, root.return, error$14); - } - firstChild = root.sibling; - if (null !== firstChild) { - firstChild.return = root.return; - nextEffect = firstChild; - break; - } - nextEffect = root.return; - } - root = shouldFireAfterActiveInstanceBlur; - shouldFireAfterActiveInstanceBlur = !1; - return root; + function peekEntangledActionThenable() { + return currentEntangledActionThenable; } - function commitBeforeMutationEffectsOnFiber(finishedWork) { - var current = finishedWork.alternate, - flags = finishedWork.flags; - switch (finishedWork.tag) { - case 0: - break; - case 11: - case 15: - break; - case 1: - if (0 !== (flags & 1024) && null !== current) { - flags = current.memoizedProps; - var prevState = current.memoizedState; - current = finishedWork.stateNode; - finishedWork.type.defaultProps || - "ref" in finishedWork.memoizedProps || - didWarnAboutReassigningProps || - (current.props !== finishedWork.memoizedProps && - error$jscomp$0( - "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" - ), - current.state !== finishedWork.memoizedState && - error$jscomp$0( - "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" - )); - flags = current.getSnapshotBeforeUpdate( - resolveClassComponentProps(finishedWork.type, flags), - prevState - ); - prevState = didWarnAboutUndefinedSnapshotBeforeUpdate; - void 0 !== flags || - prevState.has(finishedWork.type) || - (prevState.add(finishedWork.type), - error$jscomp$0( - "%s.getSnapshotBeforeUpdate(): A snapshot value (or null) must be returned. You have returned undefined.", - getComponentNameFromFiber(finishedWork) - )); - current.__reactInternalSnapshotBeforeUpdate = flags; - } - break; - case 3: - break; - case 5: - case 26: - case 27: - case 6: - case 4: - case 17: - break; - default: - if (0 !== (flags & 1024)) - 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." - ); - } + + var UpdateState = 0; + var ReplaceState = 1; + var ForceUpdate = 2; + var CaptureUpdate = 3; // Global state that is reset at the beginning of calling `processUpdateQueue`. + // It should only be read right after calling `processUpdateQueue`, via + // `checkHasForceUpdateAfterProcessing`. + + var hasForceUpdate = false; + var didWarnUpdateInsideUpdate; + var currentlyProcessingQueue; + + { + didWarnUpdateInsideUpdate = false; + currentlyProcessingQueue = null; } - function commitHookEffectListUnmount( - flags, - finishedWork, - nearestMountedAncestor - ) { - 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 inst = effect.inst, - destroy = inst.destroy; - void 0 !== destroy && - ((inst.destroy = void 0), - (flags & Passive) !== NoFlags - ? null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markComponentPassiveEffectUnmountStarted && - injectedProfilingHooks.markComponentPassiveEffectUnmountStarted( - finishedWork - ) - : (flags & Layout) !== NoFlags && - markComponentLayoutEffectUnmountStarted(finishedWork), - (flags & Insertion) !== NoFlags && - (isRunningInsertionEffect = !0), - safelyCallDestroy(finishedWork, nearestMountedAncestor, destroy), - (flags & Insertion) !== NoFlags && - (isRunningInsertionEffect = !1), - (flags & Passive) !== NoFlags - ? null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markComponentPassiveEffectUnmountStopped && - injectedProfilingHooks.markComponentPassiveEffectUnmountStopped() - : (flags & Layout) !== NoFlags && - markComponentLayoutEffectUnmountStopped()); - } - effect = effect.next; - } while (effect !== updateQueue); - } + + function initializeUpdateQueue(fiber) { + var queue = { + baseState: fiber.memoizedState, + firstBaseUpdate: null, + lastBaseUpdate: null, + shared: { + pending: null, + lanes: NoLanes, + hiddenCallbacks: null + }, + callbacks: null + }; + fiber.updateQueue = queue; } - function commitHookEffectListMount(flags, finishedWork) { - var updateQueue = finishedWork.updateQueue; - updateQueue = null !== updateQueue ? updateQueue.lastEffect : null; - if (null !== updateQueue) { - var effect = (updateQueue = updateQueue.next); - do { - if ((effect.tag & flags) === flags) { - (flags & Passive) !== NoFlags - ? null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markComponentPassiveEffectMountStarted && - injectedProfilingHooks.markComponentPassiveEffectMountStarted( - finishedWork - ) - : (flags & Layout) !== NoFlags && - null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markComponentLayoutEffectMountStarted && - injectedProfilingHooks.markComponentLayoutEffectMountStarted( - finishedWork - ); - var create = effect.create; - (flags & Insertion) !== NoFlags && (isRunningInsertionEffect = !0); - var inst = effect.inst; - create = create(); - inst.destroy = create; - (flags & Insertion) !== NoFlags && (isRunningInsertionEffect = !1); - (flags & Passive) !== NoFlags - ? null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markComponentPassiveEffectMountStopped && - injectedProfilingHooks.markComponentPassiveEffectMountStopped() - : (flags & Layout) !== NoFlags && - null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markComponentLayoutEffectMountStopped && - injectedProfilingHooks.markComponentLayoutEffectMountStopped(); - void 0 !== create && - "function" !== typeof create && - ((inst = - 0 !== (effect.tag & Layout) - ? "useLayoutEffect" - : 0 !== (effect.tag & Insertion) - ? "useInsertionEffect" - : "useEffect"), - error$jscomp$0( - "%s must not return anything besides a function, which is used for clean-up.%s", - inst, - null === create - ? " You returned null. If your effect does not require clean up, return undefined (or nothing)." - : "function" === typeof create.then - ? "\n\nIt looks like you wrote " + - inst + - "(async () => ...) or returned a Promise. Instead, write the async function inside your effect and call it immediately:\n\n" + - inst + - "(() => {\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\nLearn more about data fetching with Hooks: https://react.dev/link/hooks-data-fetching" - : " You returned: " + create - )); - } - effect = effect.next; - } while (effect !== updateQueue); + function cloneUpdateQueue(current, workInProgress) { + // Clone the update queue from current. Unless it's already a clone. + var queue = workInProgress.updateQueue; + var currentQueue = current.updateQueue; + + if (queue === currentQueue) { + var clone = { + baseState: currentQueue.baseState, + firstBaseUpdate: currentQueue.firstBaseUpdate, + lastBaseUpdate: currentQueue.lastBaseUpdate, + shared: currentQueue.shared, + callbacks: null + }; + workInProgress.updateQueue = clone; } } - function commitHookLayoutEffects(finishedWork, hookFlags) { - if (shouldProfile(finishedWork)) { - try { - startLayoutEffectTimer(), - commitHookEffectListMount(hookFlags, finishedWork); - } catch (error$15) { - captureCommitPhaseError(finishedWork, finishedWork.return, error$15); - } - recordLayoutEffectDuration(finishedWork); - } else - try { - commitHookEffectListMount(hookFlags, finishedWork); - } catch (error$16) { - captureCommitPhaseError(finishedWork, finishedWork.return, error$16); - } + function createUpdate(lane) { + var update = { + lane: lane, + tag: UpdateState, + payload: null, + callback: null, + next: null + }; + return update; } - function commitClassCallbacks(finishedWork) { - var updateQueue = finishedWork.updateQueue; - if (null !== updateQueue) { - var instance = finishedWork.stateNode; - finishedWork.type.defaultProps || - "ref" in finishedWork.memoizedProps || - didWarnAboutReassigningProps || - (instance.props !== finishedWork.memoizedProps && - error$jscomp$0( - "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" - ), - instance.state !== finishedWork.memoizedState && - error$jscomp$0( - "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" - )); - try { - commitCallbacks(updateQueue, instance); - } catch (error$21) { - captureCommitPhaseError(finishedWork, finishedWork.return, error$21); + function enqueueUpdate(fiber, update, lane) { + var updateQueue = fiber.updateQueue; + + if (updateQueue === null) { + // Only occurs if the fiber has been unmounted. + return null; + } + + var sharedQueue = updateQueue.shared; + + { + if ( + currentlyProcessingQueue === sharedQueue && + !didWarnUpdateInsideUpdate + ) { + var componentName = getComponentNameFromFiber(fiber); + + error( + "An update (setState, replaceState, or forceUpdate) was scheduled " + + "from inside an update function. Update functions should be pure, " + + "with zero side-effects. Consider using componentDidUpdate or a " + + "callback.\n\nPlease update the following component: %s", + componentName + ); + + didWarnUpdateInsideUpdate = true; + } + } + + if (isUnsafeClassRenderPhaseUpdate()) { + // This is an unsafe render phase update. Add directly to the update + // queue so we can process it immediately during the current render. + 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; // Update the childLanes even though we're most likely already rendering + // this fiber. This is for backwards compatibility in the case where you + // update a different component during render phase than the one that is + // currently renderings (a pattern that is accompanied by a warning). + + return unsafe_markUpdateLaneFromFiberToRoot(fiber, lane); + } else { + return enqueueConcurrentClassUpdate(fiber, sharedQueue, update, lane); } } - function commitHostComponentMount(finishedWork) { - try { - throw Error( - "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." - ); - } catch (error$22) { - captureCommitPhaseError(finishedWork, finishedWork.return, error$22); + 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 commitProfilerUpdate(finishedWork, current) { - if (executionContext & CommitContext) - try { - var _finishedWork$memoize2 = finishedWork.memoizedProps, - onCommit = _finishedWork$memoize2.onCommit, - onRender = _finishedWork$memoize2.onRender, - effectDuration = finishedWork.stateNode.effectDuration; - _finishedWork$memoize2 = commitTime; - current = null === current ? "mount" : "update"; - currentUpdateIsNested && (current = "nested-update"); - "function" === typeof onRender && - onRender( - finishedWork.memoizedProps.id, - current, - finishedWork.actualDuration, - finishedWork.treeBaseDuration, - finishedWork.actualStartTime, - _finishedWork$memoize2 - ); - "function" === typeof onCommit && - onCommit( - finishedWork.memoizedProps.id, - current, - effectDuration, - _finishedWork$memoize2 - ); - enqueuePendingPassiveProfilerEffect(finishedWork); - var parentFiber = finishedWork.return; - a: for (; null !== parentFiber; ) { - switch (parentFiber.tag) { - case 3: - parentFiber.stateNode.effectDuration += effectDuration; - break a; - case 12: - parentFiber.stateNode.effectDuration += effectDuration; - break a; + 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, + // we should only put them on the work-in-progress queue, not the current one. + var queue = workInProgress.updateQueue; // Check if the work-in-progress queue is a clone. + + var current = workInProgress.alternate; + + if (current !== null) { + var currentQueue = current.updateQueue; + + if (queue === currentQueue) { + // The work-in-progress queue is the same as current. This happens when + // we bail out on a parent fiber that then captures an error thrown by + // a child. Since we want to append the update only to the work-in + // -progress queue, we need to clone the updates. We usually clone during + // processUpdateQueue, but that didn't happen in this case because we + // skipped over the parent when we bailed out. + var newFirst = null; + var newLast = null; + var firstBaseUpdate = queue.firstBaseUpdate; + + if (firstBaseUpdate !== null) { + // Loop through the updates and clone them. + var update = firstBaseUpdate; + + do { + var clone = { + lane: update.lane, + tag: update.tag, + payload: update.payload, + // When this update is rebased, we should not fire its + // callback again. + callback: null, + next: null + }; + + if (newLast === null) { + newFirst = newLast = clone; + } else { + newLast.next = clone; + newLast = clone; + } // $FlowFixMe[incompatible-type] we bail out when we get a null + + update = update.next; + } while (update !== null); // Append the captured update the end of the cloned list. + + if (newLast === null) { + newFirst = newLast = capturedUpdate; + } else { + newLast.next = capturedUpdate; + newLast = capturedUpdate; } - parentFiber = parentFiber.return; + } else { + // There are no base updates. + newFirst = newLast = capturedUpdate; } - } catch (error$23) { - captureCommitPhaseError(finishedWork, finishedWork.return, error$23); + + queue = { + baseState: currentQueue.baseState, + firstBaseUpdate: newFirst, + lastBaseUpdate: newLast, + shared: currentQueue.shared, + callbacks: currentQueue.callbacks + }; + workInProgress.updateQueue = queue; + return; } + } // Append the update to the end of the list. + + var lastBaseUpdate = queue.lastBaseUpdate; + + if (lastBaseUpdate === null) { + queue.firstBaseUpdate = capturedUpdate; + } else { + lastBaseUpdate.next = capturedUpdate; + } + + queue.lastBaseUpdate = capturedUpdate; } - function commitLayoutEffectOnFiber( - finishedRoot, - current, - finishedWork, - committedLanes + + function getStateFromUpdate( + workInProgress, + queue, + update, + prevState, + nextProps, + instance ) { - var flags = finishedWork.flags; - switch (finishedWork.tag) { - case 0: - case 11: - case 15: - recursivelyTraverseLayoutEffects( - finishedRoot, - finishedWork, - committedLanes - ); - flags & 4 && - commitHookLayoutEffects(finishedWork, Layout | HasEffect); - break; - case 1: - recursivelyTraverseLayoutEffects( - finishedRoot, - finishedWork, - committedLanes - ); - if (flags & 4) - if (((finishedRoot = finishedWork.stateNode), null === current)) - if ( - (finishedWork.type.defaultProps || - "ref" in finishedWork.memoizedProps || - didWarnAboutReassigningProps || - (finishedRoot.props !== finishedWork.memoizedProps && - error$jscomp$0( - "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" - ), - finishedRoot.state !== finishedWork.memoizedState && - error$jscomp$0( - "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" - )), - shouldProfile(finishedWork)) - ) { - try { - startLayoutEffectTimer(), finishedRoot.componentDidMount(); - } catch (error$17) { - captureCommitPhaseError( - finishedWork, - finishedWork.return, - error$17 - ); - } - recordLayoutEffectDuration(finishedWork); - } else - try { - finishedRoot.componentDidMount(); - } catch (error$18) { - captureCommitPhaseError( - finishedWork, - finishedWork.return, - error$18 - ); - } - else { - committedLanes = resolveClassComponentProps( - finishedWork.type, - current.memoizedProps - ); - var prevState = current.memoizedState; - finishedWork.type.defaultProps || - "ref" in finishedWork.memoizedProps || - didWarnAboutReassigningProps || - (finishedRoot.props !== finishedWork.memoizedProps && - error$jscomp$0( - "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" - ), - finishedRoot.state !== finishedWork.memoizedState && - error$jscomp$0( - "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 (shouldProfile(finishedWork)) { + switch (update.tag) { + case ReplaceState: { + var payload = update.payload; + + if (typeof payload === "function") { + // Updater function + { + enterDisallowedContextReadInDEV(); + } + + var nextState = payload.call(instance, prevState, nextProps); + + { + if (workInProgress.mode & StrictLegacyMode) { + setIsStrictModeForDevtools(true); + try { - startLayoutEffectTimer(), - finishedRoot.componentDidUpdate( - committedLanes, - prevState, - finishedRoot.__reactInternalSnapshotBeforeUpdate - ); - } catch (error$19) { - captureCommitPhaseError( - finishedWork, - finishedWork.return, - error$19 - ); + payload.call(instance, prevState, nextProps); + } finally { + setIsStrictModeForDevtools(false); } - recordLayoutEffectDuration(finishedWork); - } else + } + + exitDisallowedContextReadInDEV(); + } + + return nextState; + } // State object + + return payload; + } + + case CaptureUpdate: { + workInProgress.flags = + (workInProgress.flags & ~ShouldCapture) | DidCapture; + } + // Intentional fallthrough + + case UpdateState: { + var _payload = update.payload; + var partialState; + + if (typeof _payload === "function") { + // Updater function + { + enterDisallowedContextReadInDEV(); + } + + partialState = _payload.call(instance, prevState, nextProps); + + { + if (workInProgress.mode & StrictLegacyMode) { + setIsStrictModeForDevtools(true); + try { - finishedRoot.componentDidUpdate( - committedLanes, - prevState, - finishedRoot.__reactInternalSnapshotBeforeUpdate - ); - } catch (error$20) { - captureCommitPhaseError( - finishedWork, - finishedWork.return, - error$20 - ); + _payload.call(instance, prevState, nextProps); + } finally { + setIsStrictModeForDevtools(false); } - } - flags & 64 && commitClassCallbacks(finishedWork); - flags & 512 && safelyAttachRef(finishedWork, finishedWork.return); - break; - case 3: - recursivelyTraverseLayoutEffects( - finishedRoot, - finishedWork, - committedLanes - ); - if ( - flags & 64 && - ((flags = finishedWork.updateQueue), null !== flags) - ) { - finishedRoot = null; - if (null !== finishedWork.child) - switch (finishedWork.child.tag) { - case 27: - case 5: - finishedRoot = getPublicInstance( - finishedWork.child.stateNode - ); - break; - case 1: - finishedRoot = finishedWork.child.stateNode; } - try { - commitCallbacks(flags, finishedRoot); - } catch (error$24) { - captureCommitPhaseError( - finishedWork, - finishedWork.return, - error$24 - ); + + exitDisallowedContextReadInDEV(); } + } else { + // Partial state object + partialState = _payload; } - break; - case 26: - case 27: - case 5: - recursivelyTraverseLayoutEffects( - finishedRoot, - finishedWork, - committedLanes - ); - null === current && - flags & 4 && - commitHostComponentMount(finishedWork); - flags & 512 && safelyAttachRef(finishedWork, finishedWork.return); - break; - case 12: - recursivelyTraverseLayoutEffects( - finishedRoot, - finishedWork, - committedLanes - ); - flags & 4 && commitProfilerUpdate(finishedWork, current); - break; - case 13: - recursivelyTraverseLayoutEffects( - finishedRoot, - finishedWork, - committedLanes - ); - break; - case 22: - if (0 !== (finishedWork.mode & 1)) { - if ( - ((prevState = - null !== finishedWork.memoizedState || - offscreenSubtreeIsHidden), - !prevState) - ) { - current = - (null !== current && null !== current.memoizedState) || - offscreenSubtreeWasHidden; - var prevOffscreenSubtreeIsHidden = offscreenSubtreeIsHidden, - prevOffscreenSubtreeWasHidden = offscreenSubtreeWasHidden; - offscreenSubtreeIsHidden = prevState; - (offscreenSubtreeWasHidden = current) && - !prevOffscreenSubtreeWasHidden - ? recursivelyTraverseReappearLayoutEffects( - finishedRoot, - finishedWork, - 0 !== (finishedWork.subtreeFlags & 8772) - ) - : recursivelyTraverseLayoutEffects( - finishedRoot, - finishedWork, - committedLanes - ); - offscreenSubtreeIsHidden = prevOffscreenSubtreeIsHidden; - offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden; - } - } else - recursivelyTraverseLayoutEffects( - finishedRoot, - finishedWork, - committedLanes - ); - flags & 512 && - ("manual" === finishedWork.memoizedProps.mode - ? safelyAttachRef(finishedWork, finishedWork.return) - : safelyDetachRef(finishedWork, finishedWork.return)); - break; - default: - recursivelyTraverseLayoutEffects( - finishedRoot, - finishedWork, - committedLanes - ); + + if (partialState === null || partialState === undefined) { + // Null and undefined are treated as no-ops. + return prevState; + } // Merge the partial state and the previous state. + + return assign({}, prevState, partialState); + } + + case ForceUpdate: { + hasForceUpdate = true; + return prevState; + } } + + return prevState; } - function detachFiberAfterEffects(fiber) { - var alternate = fiber.alternate; - null !== alternate && - ((fiber.alternate = null), detachFiberAfterEffects(alternate)); - fiber.child = null; - fiber.deletions = null; - fiber.sibling = null; - fiber.stateNode = null; - fiber._debugOwner = null; - fiber.return = null; - fiber.dependencies = null; - fiber.memoizedProps = null; - fiber.memoizedState = null; - fiber.pendingProps = null; - fiber.stateNode = null; - fiber.updateQueue = null; - } - function recursivelyTraverseDeletionEffects( - finishedRoot, - nearestMountedAncestor, - parent - ) { - for (parent = parent.child; null !== parent; ) - commitDeletionEffectsOnFiber( - finishedRoot, - nearestMountedAncestor, - parent - ), - (parent = parent.sibling); + + var didReadFromEntangledAsyncAction = false; // Each call to processUpdateQueue should be accompanied by a call to this. It's + // only in a separate function because in updateHostRoot, it must happen after + // all the context stacks have been pushed to, to prevent a stack mismatch. A + // bit unfortunate. + + function suspendIfUpdateReadFromEntangledAsyncAction() { + // Check if this update is part of a pending async action. If so, we'll + // need to suspend until the action has finished, so that it's batched + // together with future updates in the same action. + // TODO: Once we support hooks inside useMemo (or an equivalent + // memoization boundary like Forget), hoist this logic so that it only + // suspends if the memo boundary produces a new value. + if (didReadFromEntangledAsyncAction) { + var entangledActionThenable = peekEntangledActionThenable(); + + if (entangledActionThenable !== null) { + // TODO: Instead of the throwing the thenable directly, throw a + // special object like `use` does so we can detect if it's captured + // by userspace. + throw entangledActionThenable; + } + } } - function commitDeletionEffectsOnFiber( - finishedRoot, - nearestMountedAncestor, - deletedFiber - ) { - if ( - injectedHook && - "function" === typeof injectedHook.onCommitFiberUnmount - ) - try { - injectedHook.onCommitFiberUnmount(rendererID, deletedFiber); - } catch (err) { - hasLoggedError || - ((hasLoggedError = !0), - error$jscomp$0( - "React instrumentation encountered an error: %s", - err - )); + function processUpdateQueue(workInProgress, props, instance, renderLanes) { + didReadFromEntangledAsyncAction = false; // This is always non-null on a ClassComponent or HostRoot + + var queue = workInProgress.updateQueue; + hasForceUpdate = false; + + { + currentlyProcessingQueue = queue.shared; + } + + var firstBaseUpdate = queue.firstBaseUpdate; + var lastBaseUpdate = queue.lastBaseUpdate; // Check if there are pending updates. If so, transfer them to the base queue. + + var pendingQueue = queue.shared.pending; + + if (pendingQueue !== null) { + queue.shared.pending = null; // The pending queue is circular. Disconnect the pointer between first + // and last so that it's non-circular. + + var lastPendingUpdate = pendingQueue; + var firstPendingUpdate = lastPendingUpdate.next; + lastPendingUpdate.next = null; // Append pending updates to base queue + + if (lastBaseUpdate === null) { + firstBaseUpdate = firstPendingUpdate; + } else { + lastBaseUpdate.next = firstPendingUpdate; } - switch (deletedFiber.tag) { - case 26: - case 27: - case 5: - offscreenSubtreeWasHidden || - safelyDetachRef(deletedFiber, nearestMountedAncestor); - case 6: - recursivelyTraverseDeletionEffects( - finishedRoot, - nearestMountedAncestor, - deletedFiber - ); - break; - case 18: - break; - case 4: - createChildNodeSet(); - recursivelyTraverseDeletionEffects( - finishedRoot, - nearestMountedAncestor, - deletedFiber - ); - break; - case 0: - case 11: - case 14: - case 15: - if (!offscreenSubtreeWasHidden) { - var updateQueue = deletedFiber.updateQueue; + + lastBaseUpdate = lastPendingUpdate; // If there's a current queue, and it's different from the base queue, then + // we need to transfer the updates to that queue, too. Because the base + // queue is a singly-linked list with no cycles, we can append to both + // lists and take advantage of structural sharing. + // TODO: Pass `current` as argument + + var current = workInProgress.alternate; + + if (current !== null) { + // This is always non-null on a ClassComponent or HostRoot + var currentQueue = current.updateQueue; + var currentLastBaseUpdate = currentQueue.lastBaseUpdate; + + if (currentLastBaseUpdate !== lastBaseUpdate) { + if (currentLastBaseUpdate === null) { + currentQueue.firstBaseUpdate = firstPendingUpdate; + } else { + currentLastBaseUpdate.next = firstPendingUpdate; + } + + currentQueue.lastBaseUpdate = lastPendingUpdate; + } + } + } // These values may change as we process the queue. + + if (firstBaseUpdate !== null) { + // Iterate through the list of updates to compute the result. + var newState = queue.baseState; // TODO: Don't need to accumulate this. Instead, we can remove renderLanes + // from the original lanes. + + var newLanes = NoLanes; + var newBaseState = null; + var newFirstBaseUpdate = null; + var newLastBaseUpdate = null; + var update = firstBaseUpdate; + + do { + // An extra OffscreenLane bit is added to updates that were made to + // a hidden tree, so that we can distinguish them from updates that were + // already there when the tree was hidden. + var updateLane = removeLanes(update.lane, OffscreenLane); + var isHiddenUpdate = updateLane !== update.lane; // Check if this update was made while the tree was hidden. If so, then + // it's not a "base" update and we should disregard the extra base lanes + // that were added to renderLanes when we entered the Offscreen tree. + + var shouldSkipUpdate = isHiddenUpdate + ? !isSubsetOfLanes(getWorkInProgressRootRenderLanes(), updateLane) + : !isSubsetOfLanes(renderLanes, updateLane); + + if (shouldSkipUpdate) { + // Priority is insufficient. Skip this update. If this is the first + // skipped update, the previous update/state is the new base + // update/state. + var clone = { + lane: updateLane, + tag: update.tag, + payload: update.payload, + callback: update.callback, + next: null + }; + + if (newLastBaseUpdate === null) { + newFirstBaseUpdate = newLastBaseUpdate = clone; + newBaseState = newState; + } else { + newLastBaseUpdate = newLastBaseUpdate.next = clone; + } // Update the remaining priority in the queue. + + newLanes = mergeLanes(newLanes, updateLane); + } else { + // This update does have sufficient priority. + // Check if this update is part of a pending async action. If so, + // we'll need to suspend until the action has finished, so that it's + // batched together with future updates in the same action. if ( - null !== updateQueue && - ((updateQueue = updateQueue.lastEffect), null !== updateQueue) + updateLane !== NoLane && + updateLane === peekEntangledActionLane() ) { - var effect = (updateQueue = updateQueue.next); - do { - var tag = effect.tag, - inst = effect.inst, - destroy = inst.destroy; - void 0 !== destroy && - ((tag & Insertion) !== NoFlags - ? ((inst.destroy = void 0), - safelyCallDestroy( - deletedFiber, - nearestMountedAncestor, - destroy - )) - : (tag & Layout) !== NoFlags && - (markComponentLayoutEffectUnmountStarted(deletedFiber), - shouldProfile(deletedFiber) - ? (startLayoutEffectTimer(), - (inst.destroy = void 0), - safelyCallDestroy( - deletedFiber, - nearestMountedAncestor, - destroy - ), - recordLayoutEffectDuration(deletedFiber)) - : ((inst.destroy = void 0), - safelyCallDestroy( - deletedFiber, - nearestMountedAncestor, - destroy - )), - markComponentLayoutEffectUnmountStopped())); - effect = effect.next; - } while (effect !== updateQueue); + didReadFromEntangledAsyncAction = true; + } + + if (newLastBaseUpdate !== null) { + var _clone = { + // This update is going to be committed so we never want uncommit + // it. Using NoLane works because 0 is a subset of all bitmasks, so + // this will never be skipped by the check above. + lane: NoLane, + tag: update.tag, + payload: update.payload, + // When this update is rebased, we should not fire its + // callback again. + callback: null, + next: null + }; + newLastBaseUpdate = newLastBaseUpdate.next = _clone; + } // Process this update. + + newState = getStateFromUpdate( + workInProgress, + queue, + update, + newState, + props, + instance + ); + var callback = update.callback; + + if (callback !== null) { + workInProgress.flags |= Callback; + + if (isHiddenUpdate) { + workInProgress.flags |= Visibility; + } + + var callbacks = queue.callbacks; + + if (callbacks === null) { + queue.callbacks = [callback]; + } else { + callbacks.push(callback); + } + } + } // $FlowFixMe[incompatible-type] we bail out when we get a null + + update = update.next; + + if (update === null) { + pendingQueue = queue.shared.pending; + + if (pendingQueue === null) { + break; + } else { + // An update was scheduled from inside a reducer. Add the new + // pending updates to the end of the list and keep processing. + var _lastPendingUpdate = pendingQueue; // Intentionally unsound. Pending updates form a circular list, but we + // unravel them when transferring them to the base queue. + + var _firstPendingUpdate = _lastPendingUpdate.next; + _lastPendingUpdate.next = null; + update = _firstPendingUpdate; + queue.lastBaseUpdate = _lastPendingUpdate; + queue.shared.pending = null; } } - recursivelyTraverseDeletionEffects( - finishedRoot, - nearestMountedAncestor, - deletedFiber - ); - break; - case 1: - offscreenSubtreeWasHidden || - (safelyDetachRef(deletedFiber, nearestMountedAncestor), - (updateQueue = deletedFiber.stateNode), - "function" === typeof updateQueue.componentWillUnmount && - safelyCallComponentWillUnmount( - deletedFiber, - nearestMountedAncestor, - updateQueue - )); - recursivelyTraverseDeletionEffects( - finishedRoot, - nearestMountedAncestor, - deletedFiber - ); - break; - case 21: - recursivelyTraverseDeletionEffects( - finishedRoot, - nearestMountedAncestor, - deletedFiber - ); - break; - case 22: - safelyDetachRef(deletedFiber, nearestMountedAncestor); - deletedFiber.mode & 1 - ? ((offscreenSubtreeWasHidden = - (updateQueue = offscreenSubtreeWasHidden) || - null !== deletedFiber.memoizedState), - recursivelyTraverseDeletionEffects( - finishedRoot, - nearestMountedAncestor, - deletedFiber - ), - (offscreenSubtreeWasHidden = updateQueue)) - : recursivelyTraverseDeletionEffects( - finishedRoot, - nearestMountedAncestor, - deletedFiber - ); - break; - default: - recursivelyTraverseDeletionEffects( - finishedRoot, - nearestMountedAncestor, - deletedFiber - ); + } while (true); + + if (newLastBaseUpdate === null) { + newBaseState = newState; + } + + queue.baseState = newBaseState; + queue.firstBaseUpdate = newFirstBaseUpdate; + queue.lastBaseUpdate = newLastBaseUpdate; + + 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 + // dealt with the props. Context in components that specify + // shouldComponentUpdate is tricky; but we'll have to account for + // that regardless. + + markSkippedUpdateLanes(newLanes); + workInProgress.lanes = newLanes; + workInProgress.memoizedState = newState; + } + + { + currentlyProcessingQueue = null; } } - function getRetryCache(finishedWork) { - switch (finishedWork.tag) { - case 13: - case 19: - var retryCache = finishedWork.stateNode; - null === retryCache && - (retryCache = finishedWork.stateNode = new PossiblyWeakSet()); - return retryCache; - case 22: - return ( - (finishedWork = finishedWork.stateNode), - (retryCache = finishedWork._retryCache), - null === retryCache && - (retryCache = finishedWork._retryCache = new PossiblyWeakSet()), - retryCache - ); - default: - throw Error( - "Unexpected Suspense handler tag (" + - finishedWork.tag + - "). This is a bug in React." - ); + + function callCallback(callback, context) { + if (typeof callback !== "function") { + throw new Error( + "Invalid argument passed as callback. Expected a function. Instead " + + ("received: " + callback) + ); } + + callback.call(context); } - function attachSuspenseRetryListeners(finishedWork, wakeables) { - var retryCache = getRetryCache(finishedWork); - wakeables.forEach(function (wakeable) { - var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable); - if (!retryCache.has(wakeable)) { - retryCache.add(wakeable); - if (isDevToolsPresent) - if (null !== inProgressLanes && null !== inProgressRoot) - restorePendingUpdaters(inProgressRoot, inProgressLanes); - else - throw Error( - "Expected finished root and lanes to be set. This is a bug in React." - ); - wakeable.then(retry, retry); + + function resetHasForceUpdateBeforeProcessing() { + hasForceUpdate = false; + } + function checkHasForceUpdateAfterProcessing() { + return hasForceUpdate; + } + function deferHiddenCallbacks(updateQueue) { + // When an update finishes on a hidden component, its callback should not + // be fired until/unless the component is made visible again. Stash the + // callback on the shared queue object so it can be fired later. + var newHiddenCallbacks = updateQueue.callbacks; + + if (newHiddenCallbacks !== null) { + var existingHiddenCallbacks = updateQueue.shared.hiddenCallbacks; + + if (existingHiddenCallbacks === null) { + updateQueue.shared.hiddenCallbacks = newHiddenCallbacks; + } else { + updateQueue.shared.hiddenCallbacks = + existingHiddenCallbacks.concat(newHiddenCallbacks); } - }); + } } - function commitMutationEffects(root, finishedWork, committedLanes) { - inProgressLanes = committedLanes; - inProgressRoot = root; - runWithFiberInDEV( - finishedWork, - commitMutationEffectsOnFiber, - finishedWork, - root, - committedLanes + function commitHiddenCallbacks(updateQueue, context) { + // This component is switching from hidden -> visible. Commit any callbacks + // that were previously deferred. + var hiddenCallbacks = updateQueue.shared.hiddenCallbacks; + + if (hiddenCallbacks !== null) { + updateQueue.shared.hiddenCallbacks = null; + + for (var i = 0; i < hiddenCallbacks.length; i++) { + var callback = hiddenCallbacks[i]; + callCallback(callback, context); + } + } + } + function commitCallbacks(updateQueue, context) { + var callbacks = updateQueue.callbacks; + + if (callbacks !== null) { + updateQueue.callbacks = null; + + for (var i = 0; i < callbacks.length; i++) { + var callback = callbacks[i]; + callCallback(callback, context); + } + } + } + + // $FlowFixMe[method-unbinding] + 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. + * Returns true when the values of all keys are strictly equal. + */ + + function shallowEqual(objA, objB) { + if (objectIs(objA, objB)) { + return true; + } + + if ( + typeof objA !== "object" || + objA === null || + typeof objB !== "object" || + objB === null + ) { + return false; + } + + var keysA = Object.keys(objA); + var keysB = Object.keys(objB); + + if (keysA.length !== keysB.length) { + return false; + } // Test for A's keys different from B. + + for (var i = 0; i < keysA.length; i++) { + var currentKey = keysA[i]; + + if ( + !hasOwnProperty.call(objB, currentKey) || // $FlowFixMe[incompatible-use] lost refinement of `objB` + !objectIs(objA[currentKey], objB[currentKey]) + ) { + return false; + } + } + + return true; + } + + function describeBuiltInComponentFrame(name, ownerFn) { + { + var ownerName = null; + + if (ownerFn) { + ownerName = ownerFn.displayName || ownerFn.name || null; + } + + return describeComponentFrame(name, ownerName); + } + } + function describeDebugInfoFrame(name, env) { + return describeBuiltInComponentFrame( + name + (env ? " (" + env + ")" : ""), + null ); - inProgressRoot = inProgressLanes = null; } - function recursivelyTraverseMutationEffects(root, parentFiber, lanes) { - var deletions = parentFiber.deletions; - if (null !== deletions) - for (var i = 0; i < deletions.length; i++) { - var childToDelete = deletions[i]; - try { - var deletedFiber = childToDelete; - commitDeletionEffectsOnFiber(root, parentFiber, deletedFiber); - var alternate = deletedFiber.alternate; - null !== alternate && (alternate.return = null); - deletedFiber.return = null; - } catch (error$25) { - captureCommitPhaseError(childToDelete, parentFiber, error$25); - } - } - if (parentFiber.subtreeFlags & 13878) - for (parentFiber = parentFiber.child; null !== parentFiber; ) - runWithFiberInDEV( - parentFiber, - commitMutationEffectsOnFiber, - parentFiber, - root, - lanes - ), - (parentFiber = parentFiber.sibling); + + { + var PossiblyWeakMap$1 = typeof WeakMap === "function" ? WeakMap : Map; + new PossiblyWeakMap$1(); } - function commitMutationEffectsOnFiber(finishedWork, root, lanes) { - var current = finishedWork.alternate, - flags = finishedWork.flags; - switch (finishedWork.tag) { - case 0: - case 11: - case 14: - case 15: - recursivelyTraverseMutationEffects(root, finishedWork, lanes); - commitReconciliationEffects(finishedWork); - if (flags & 4) { - try { - commitHookEffectListUnmount( - Insertion | HasEffect, - finishedWork, - finishedWork.return - ), - commitHookEffectListMount(Insertion | HasEffect, finishedWork); - } catch (error$26) { - captureCommitPhaseError( - finishedWork, - finishedWork.return, - error$26 - ); - } - if (shouldProfile(finishedWork)) { - try { - startLayoutEffectTimer(), - commitHookEffectListUnmount( - Layout | HasEffect, - finishedWork, - finishedWork.return - ); - } catch (error$27) { - captureCommitPhaseError( - finishedWork, - finishedWork.return, - error$27 - ); - } - recordLayoutEffectDuration(finishedWork); - } else - try { - commitHookEffectListUnmount( - Layout | HasEffect, - finishedWork, - finishedWork.return - ); - } catch (error$28) { - captureCommitPhaseError( - finishedWork, - finishedWork.return, - error$28 - ); - } - } - break; - case 1: - recursivelyTraverseMutationEffects(root, finishedWork, lanes); - commitReconciliationEffects(finishedWork); - flags & 512 && - null !== current && - safelyDetachRef(current, current.return); - flags & 64 && - offscreenSubtreeIsHidden && - ((finishedWork = finishedWork.updateQueue), - null !== finishedWork && - ((flags = finishedWork.callbacks), - null !== flags && - ((current = finishedWork.shared.hiddenCallbacks), - (finishedWork.shared.hiddenCallbacks = - null === current ? flags : current.concat(flags))))); - break; - case 26: - case 27: - case 5: - recursivelyTraverseMutationEffects(root, finishedWork, lanes); - commitReconciliationEffects(finishedWork); - flags & 512 && - null !== current && - safelyDetachRef(current, current.return); - break; - case 6: - recursivelyTraverseMutationEffects(root, finishedWork, lanes); - commitReconciliationEffects(finishedWork); - break; - case 3: - recursivelyTraverseMutationEffects(root, finishedWork, lanes); - commitReconciliationEffects(finishedWork); - break; - case 4: - recursivelyTraverseMutationEffects(root, finishedWork, lanes); - commitReconciliationEffects(finishedWork); - break; - case 13: - recursivelyTraverseMutationEffects(root, finishedWork, lanes); - commitReconciliationEffects(finishedWork); - finishedWork.child.flags & 8192 && - ((current = null !== current && null !== current.memoizedState), - null === finishedWork.memoizedState || - current || - (globalMostRecentFallbackTime = now$1())); - flags & 4 && - ((flags = finishedWork.updateQueue), - null !== flags && - ((finishedWork.updateQueue = null), - attachSuspenseRetryListeners(finishedWork, flags))); - break; - case 22: - flags & 512 && - null !== current && - safelyDetachRef(current, current.return); - var isHidden = null !== finishedWork.memoizedState, - wasHidden = null !== current && null !== current.memoizedState; - if (finishedWork.mode & 1) { - var prevOffscreenSubtreeIsHidden = offscreenSubtreeIsHidden, - prevOffscreenSubtreeWasHidden = offscreenSubtreeWasHidden; - offscreenSubtreeIsHidden = prevOffscreenSubtreeIsHidden || isHidden; - offscreenSubtreeWasHidden = - prevOffscreenSubtreeWasHidden || wasHidden; - recursivelyTraverseMutationEffects(root, finishedWork, lanes); - offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden; - offscreenSubtreeIsHidden = prevOffscreenSubtreeIsHidden; - } else recursivelyTraverseMutationEffects(root, finishedWork, lanes); - commitReconciliationEffects(finishedWork); - root = finishedWork.stateNode; - root._current = finishedWork; - root._visibility &= -3; - root._visibility |= root._pendingVisibility & 2; - flags & 8192 && - ((root._visibility = isHidden - ? root._visibility & -2 - : root._visibility | 1), - isHidden && - ((isHidden = - offscreenSubtreeIsHidden || offscreenSubtreeWasHidden), - null === current || - wasHidden || - isHidden || - (0 !== (finishedWork.mode & 1) && - recursivelyTraverseDisappearLayoutEffects(finishedWork)))); - flags & 4 && - ((flags = finishedWork.updateQueue), - null !== flags && - ((current = flags.retryQueue), - null !== current && - ((flags.retryQueue = null), - attachSuspenseRetryListeners(finishedWork, current)))); - break; - case 19: - recursivelyTraverseMutationEffects(root, finishedWork, lanes); - commitReconciliationEffects(finishedWork); - flags & 4 && - ((flags = finishedWork.updateQueue), - null !== flags && - ((finishedWork.updateQueue = null), - attachSuspenseRetryListeners(finishedWork, flags))); - break; - case 21: - break; - default: - recursivelyTraverseMutationEffects(root, finishedWork, lanes), - commitReconciliationEffects(finishedWork); + + function describeComponentFrame(name, ownerName) { + var sourceInfo = ""; + + if (ownerName) { + sourceInfo = " (created by " + ownerName + ")"; } + + return "\n in " + (name || "Unknown") + sourceInfo; } - function commitReconciliationEffects(finishedWork) { - var flags = finishedWork.flags; - flags & 2 && (finishedWork.flags &= -3); - flags & 4096 && (finishedWork.flags &= -4097); + + function describeClassComponentFrame(ctor, ownerFn) { + { + return describeFunctionComponentFrame(ctor, ownerFn); + } } - function commitLayoutEffects(finishedWork, root, committedLanes) { - inProgressLanes = committedLanes; - inProgressRoot = root; - runWithFiberInDEV( - finishedWork, - commitLayoutEffectOnFiber, - root, - finishedWork.alternate, - finishedWork, - committedLanes - ); - inProgressRoot = inProgressLanes = null; + function describeFunctionComponentFrame(fn, ownerFn) { + { + if (!fn) { + return ""; + } + + var name = fn.displayName || fn.name || null; + var ownerName = null; + + if (ownerFn) { + ownerName = ownerFn.displayName || ownerFn.name || null; + } + + return describeComponentFrame(name, ownerName); + } } - function recursivelyTraverseLayoutEffects(root, parentFiber, lanes) { - if (parentFiber.subtreeFlags & 8772) - for (parentFiber = parentFiber.child; null !== parentFiber; ) - runWithFiberInDEV( - parentFiber, - commitLayoutEffectOnFiber, - root, - parentFiber.alternate, - parentFiber, - lanes - ), - (parentFiber = parentFiber.sibling); + + function describeFiber(fiber) { + var owner = fiber._debugOwner ? fiber._debugOwner.type : null; + + switch (fiber.tag) { + case HostHoistable: + case HostSingleton: + case HostComponent: + return describeBuiltInComponentFrame(fiber.type, owner); + + case LazyComponent: + return describeBuiltInComponentFrame("Lazy", owner); + + case SuspenseComponent: + return describeBuiltInComponentFrame("Suspense", owner); + + case SuspenseListComponent: + return describeBuiltInComponentFrame("SuspenseList", owner); + + case FunctionComponent: + case IndeterminateComponent: + case SimpleMemoComponent: + return describeFunctionComponentFrame(fiber.type, owner); + + case ForwardRef: + return describeFunctionComponentFrame(fiber.type.render, owner); + + case ClassComponent: + return describeClassComponentFrame(fiber.type, owner); + + default: + return ""; + } } - function disappearLayoutEffects(finishedWork) { - switch (finishedWork.tag) { - case 0: - case 11: - case 14: - case 15: - if (shouldProfile(finishedWork)) - try { - startLayoutEffectTimer(), - commitHookEffectListUnmount( - Layout, - finishedWork, - finishedWork.return - ); - } finally { - recordLayoutEffectDuration(finishedWork); + + function getStackByFiberInDevAndProd(workInProgress) { + try { + var info = ""; + var node = workInProgress; + + do { + info += describeFiber(node); + + if (true) { + // Add any Server Component stack frames in reverse order. + var debugInfo = node._debugInfo; + + if (debugInfo) { + for (var i = debugInfo.length - 1; i >= 0; i--) { + var entry = debugInfo[i]; + + if (typeof entry.name === "string") { + info += describeDebugInfoFrame(entry.name, entry.env); + } + } } - else - commitHookEffectListUnmount( - Layout, - finishedWork, - finishedWork.return - ); - recursivelyTraverseDisappearLayoutEffects(finishedWork); - break; - case 1: - safelyDetachRef(finishedWork, finishedWork.return); - var instance = finishedWork.stateNode; - "function" === typeof instance.componentWillUnmount && - safelyCallComponentWillUnmount( - finishedWork, - finishedWork.return, - instance - ); - recursivelyTraverseDisappearLayoutEffects(finishedWork); - break; - case 26: - case 27: - case 5: - safelyDetachRef(finishedWork, finishedWork.return); - recursivelyTraverseDisappearLayoutEffects(finishedWork); - break; - case 22: - safelyDetachRef(finishedWork, finishedWork.return); - null === finishedWork.memoizedState && - recursivelyTraverseDisappearLayoutEffects(finishedWork); - break; - default: - recursivelyTraverseDisappearLayoutEffects(finishedWork); + } // $FlowFixMe[incompatible-type] we bail out when we get a null + + node = node.return; + } while (node); + + return info; + } catch (x) { + return "\nError generating stack: " + x.message + "\n" + x.stack; } } - function recursivelyTraverseDisappearLayoutEffects(parentFiber) { - for (parentFiber = parentFiber.child; null !== parentFiber; ) - disappearLayoutEffects(parentFiber), - (parentFiber = parentFiber.sibling); + + var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; + var current = null; + var isRendering = false; + function getCurrentFiberOwnerNameInDevOrNull() { + { + if (current === null) { + return null; + } + + var owner = current._debugOwner; + + if (owner !== null && typeof owner !== "undefined") { + return getComponentNameFromFiber(owner); + } + } + + return null; } - function reappearLayoutEffects( - finishedRoot, - current, - finishedWork, - includeWorkInProgressEffects - ) { - var flags = finishedWork.flags; - switch (finishedWork.tag) { - case 0: - case 11: - case 15: - recursivelyTraverseReappearLayoutEffects( - finishedRoot, - finishedWork, - includeWorkInProgressEffects - ); - commitHookLayoutEffects(finishedWork, Layout); - break; - case 1: - recursivelyTraverseReappearLayoutEffects( - finishedRoot, - finishedWork, - includeWorkInProgressEffects - ); - finishedRoot = finishedWork.stateNode; - if ("function" === typeof finishedRoot.componentDidMount) - try { - finishedRoot.componentDidMount(); - } catch (error$33) { - captureCommitPhaseError( - finishedWork, - finishedWork.return, - error$33 - ); - } - var updateQueue = finishedWork.updateQueue; - if ( - null !== updateQueue && - ((current = updateQueue.shared.hiddenCallbacks), null !== current) - ) - for ( - updateQueue.shared.hiddenCallbacks = null, updateQueue = 0; - updateQueue < current.length; - updateQueue++ - ) - callCallback(current[updateQueue], finishedRoot); - includeWorkInProgressEffects && - flags & 64 && - commitClassCallbacks(finishedWork); - safelyAttachRef(finishedWork, finishedWork.return); - break; - case 26: - case 27: - case 5: - recursivelyTraverseReappearLayoutEffects( - finishedRoot, - finishedWork, - includeWorkInProgressEffects - ); - includeWorkInProgressEffects && - null === current && - flags & 4 && - commitHostComponentMount(finishedWork); - safelyAttachRef(finishedWork, finishedWork.return); - break; - case 12: - recursivelyTraverseReappearLayoutEffects( - finishedRoot, - finishedWork, - includeWorkInProgressEffects - ); - includeWorkInProgressEffects && - flags & 4 && - commitProfilerUpdate(finishedWork, current); - break; - case 13: - recursivelyTraverseReappearLayoutEffects( - finishedRoot, - finishedWork, - includeWorkInProgressEffects - ); - break; - case 22: - null === finishedWork.memoizedState && - recursivelyTraverseReappearLayoutEffects( - finishedRoot, - finishedWork, - includeWorkInProgressEffects - ); - safelyAttachRef(finishedWork, finishedWork.return); - break; - default: - recursivelyTraverseReappearLayoutEffects( - finishedRoot, - finishedWork, - includeWorkInProgressEffects - ); + + function getCurrentFiberStackInDev() { + { + if (current === null) { + return ""; + } // Safe because if current fiber exists, we are reconciling, + // and it is guaranteed to be the work-in-progress version. + + return getStackByFiberInDevAndProd(current); } } - function recursivelyTraverseReappearLayoutEffects( - finishedRoot, - parentFiber, - includeWorkInProgressEffects - ) { - includeWorkInProgressEffects = - includeWorkInProgressEffects && 0 !== (parentFiber.subtreeFlags & 8772); - for (parentFiber = parentFiber.child; null !== parentFiber; ) - runWithFiberInDEV( - parentFiber, - reappearLayoutEffects, - finishedRoot, - parentFiber.alternate, - parentFiber, - includeWorkInProgressEffects - ), - (parentFiber = parentFiber.sibling); + + function resetCurrentFiber() { + { + ReactDebugCurrentFrame.getCurrentStack = null; + current = null; + isRendering = false; + } } - function commitHookPassiveMountEffects(finishedWork, hookFlags) { - if (shouldProfile(finishedWork)) { - passiveEffectStartTime = now(); - try { - commitHookEffectListMount(hookFlags, finishedWork); - } catch (error$34) { - captureCommitPhaseError(finishedWork, finishedWork.return, error$34); - } - recordPassiveEffectDuration(finishedWork); - } else - try { - commitHookEffectListMount(hookFlags, finishedWork); - } catch (error$35) { - captureCommitPhaseError(finishedWork, finishedWork.return, error$35); - } - } - function commitOffscreenPassiveMountEffects(current, finishedWork) { - var previousCache = null; - null !== current && - null !== current.memoizedState && - null !== current.memoizedState.cachePool && - (previousCache = current.memoizedState.cachePool.pool); - current = null; - null !== finishedWork.memoizedState && - null !== finishedWork.memoizedState.cachePool && - (current = finishedWork.memoizedState.cachePool.pool); - current !== previousCache && - (null != current && retainCache(current), - null != previousCache && releaseCache(previousCache)); - } - function commitCachePassiveMountEffect(current, finishedWork) { - current = null; - null !== finishedWork.alternate && - (current = finishedWork.alternate.memoizedState.cache); - finishedWork = finishedWork.memoizedState.cache; - finishedWork !== current && - (retainCache(finishedWork), null != current && releaseCache(current)); + function setCurrentFiber(fiber) { + { + ReactDebugCurrentFrame.getCurrentStack = + fiber === null ? null : getCurrentFiberStackInDev; + current = fiber; + isRendering = false; + } } - function recursivelyTraversePassiveMountEffects( - root, - parentFiber, - committedLanes, - committedTransitions - ) { - if (parentFiber.subtreeFlags & 10256) - for (parentFiber = parentFiber.child; null !== parentFiber; ) - runWithFiberInDEV( - parentFiber, - commitPassiveMountOnFiber, - root, - parentFiber, - committedLanes, - committedTransitions - ), - (parentFiber = parentFiber.sibling); + function getCurrentFiber() { + { + return current; + } } - function commitPassiveMountOnFiber( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - ) { - var flags = finishedWork.flags; - switch (finishedWork.tag) { - case 0: - case 11: - case 15: - recursivelyTraversePassiveMountEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions + function setIsRendering(rendering) { + { + isRendering = rendering; + } + } + + var ReactStrictModeWarnings = { + recordUnsafeLifecycleWarnings: function (fiber, instance) {}, + flushPendingUnsafeLifecycleWarnings: function () {}, + recordLegacyContextWarning: function (fiber, instance) {}, + flushLegacyContextWarning: function () {}, + discardPendingWarnings: function () {} + }; + + { + var findStrictRoot = function (fiber) { + var maybeStrictRoot = null; + var node = fiber; + + while (node !== null) { + if (node.mode & StrictLegacyMode) { + maybeStrictRoot = node; + } + + node = node.return; + } + + return maybeStrictRoot; + }; + + var setToSortedString = function (set) { + var array = []; + set.forEach(function (value) { + array.push(value); + }); + return array.sort().join(", "); + }; + + var pendingComponentWillMountWarnings = []; + var pendingUNSAFE_ComponentWillMountWarnings = []; + var pendingComponentWillReceivePropsWarnings = []; + var pendingUNSAFE_ComponentWillReceivePropsWarnings = []; + var pendingComponentWillUpdateWarnings = []; + var pendingUNSAFE_ComponentWillUpdateWarnings = []; // Tracks components we have already warned about. + + var didWarnAboutUnsafeLifecycles = new Set(); + + ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function ( + fiber, + instance + ) { + // Dedupe strategy: Warn once per component. + if (didWarnAboutUnsafeLifecycles.has(fiber.type)) { + return; + } + + if ( + typeof instance.componentWillMount === "function" && // Don't warn about react-lifecycles-compat polyfilled components. + instance.componentWillMount.__suppressDeprecationWarning !== true + ) { + pendingComponentWillMountWarnings.push(fiber); + } + + if ( + fiber.mode & StrictLegacyMode && + typeof instance.UNSAFE_componentWillMount === "function" + ) { + pendingUNSAFE_ComponentWillMountWarnings.push(fiber); + } + + if ( + typeof instance.componentWillReceiveProps === "function" && + instance.componentWillReceiveProps.__suppressDeprecationWarning !== + true + ) { + pendingComponentWillReceivePropsWarnings.push(fiber); + } + + if ( + fiber.mode & StrictLegacyMode && + typeof instance.UNSAFE_componentWillReceiveProps === "function" + ) { + pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber); + } + + if ( + typeof instance.componentWillUpdate === "function" && + instance.componentWillUpdate.__suppressDeprecationWarning !== true + ) { + pendingComponentWillUpdateWarnings.push(fiber); + } + + if ( + fiber.mode & StrictLegacyMode && + typeof instance.UNSAFE_componentWillUpdate === "function" + ) { + pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber); + } + }; + + ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = + function () { + // We do an initial pass to gather component names + var componentWillMountUniqueNames = new Set(); + + if (pendingComponentWillMountWarnings.length > 0) { + pendingComponentWillMountWarnings.forEach(function (fiber) { + componentWillMountUniqueNames.add( + getComponentNameFromFiber(fiber) || "Component" + ); + didWarnAboutUnsafeLifecycles.add(fiber.type); + }); + pendingComponentWillMountWarnings = []; + } + + var UNSAFE_componentWillMountUniqueNames = new Set(); + + if (pendingUNSAFE_ComponentWillMountWarnings.length > 0) { + pendingUNSAFE_ComponentWillMountWarnings.forEach(function (fiber) { + UNSAFE_componentWillMountUniqueNames.add( + getComponentNameFromFiber(fiber) || "Component" + ); + didWarnAboutUnsafeLifecycles.add(fiber.type); + }); + pendingUNSAFE_ComponentWillMountWarnings = []; + } + + var componentWillReceivePropsUniqueNames = new Set(); + + if (pendingComponentWillReceivePropsWarnings.length > 0) { + pendingComponentWillReceivePropsWarnings.forEach(function (fiber) { + componentWillReceivePropsUniqueNames.add( + getComponentNameFromFiber(fiber) || "Component" + ); + didWarnAboutUnsafeLifecycles.add(fiber.type); + }); + pendingComponentWillReceivePropsWarnings = []; + } + + var UNSAFE_componentWillReceivePropsUniqueNames = new Set(); + + if (pendingUNSAFE_ComponentWillReceivePropsWarnings.length > 0) { + pendingUNSAFE_ComponentWillReceivePropsWarnings.forEach( + function (fiber) { + UNSAFE_componentWillReceivePropsUniqueNames.add( + getComponentNameFromFiber(fiber) || "Component" + ); + didWarnAboutUnsafeLifecycles.add(fiber.type); + } + ); + pendingUNSAFE_ComponentWillReceivePropsWarnings = []; + } + + var componentWillUpdateUniqueNames = new Set(); + + if (pendingComponentWillUpdateWarnings.length > 0) { + pendingComponentWillUpdateWarnings.forEach(function (fiber) { + componentWillUpdateUniqueNames.add( + getComponentNameFromFiber(fiber) || "Component" + ); + didWarnAboutUnsafeLifecycles.add(fiber.type); + }); + pendingComponentWillUpdateWarnings = []; + } + + var UNSAFE_componentWillUpdateUniqueNames = new Set(); + + if (pendingUNSAFE_ComponentWillUpdateWarnings.length > 0) { + pendingUNSAFE_ComponentWillUpdateWarnings.forEach(function (fiber) { + UNSAFE_componentWillUpdateUniqueNames.add( + getComponentNameFromFiber(fiber) || "Component" + ); + didWarnAboutUnsafeLifecycles.add(fiber.type); + }); + pendingUNSAFE_ComponentWillUpdateWarnings = []; + } // Finally, we flush all the warnings + // UNSAFE_ ones before the deprecated ones, since they'll be 'louder' + + if (UNSAFE_componentWillMountUniqueNames.size > 0) { + var sortedNames = setToSortedString( + UNSAFE_componentWillMountUniqueNames + ); + + error( + "Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. " + + "See https://react.dev/link/unsafe-component-lifecycles for details.\n\n" + + "* Move code with side effects to componentDidMount, and set initial state in the constructor.\n" + + "\nPlease update the following components: %s", + sortedNames + ); + } + + if (UNSAFE_componentWillReceivePropsUniqueNames.size > 0) { + var _sortedNames = setToSortedString( + UNSAFE_componentWillReceivePropsUniqueNames + ); + + error( + "Using UNSAFE_componentWillReceiveProps in strict mode is not recommended " + + "and may indicate bugs in your code. " + + "See https://react.dev/link/unsafe-component-lifecycles for details.\n\n" + + "* Move data fetching code or side effects to componentDidUpdate.\n" + + "* If you're updating state whenever props change, " + + "refactor your code to use memoization techniques or move it to " + + "static getDerivedStateFromProps. Learn more at: https://react.dev/link/derived-state\n" + + "\nPlease update the following components: %s", + _sortedNames + ); + } + + if (UNSAFE_componentWillUpdateUniqueNames.size > 0) { + var _sortedNames2 = setToSortedString( + UNSAFE_componentWillUpdateUniqueNames + ); + + error( + "Using UNSAFE_componentWillUpdate in strict mode is not recommended " + + "and may indicate bugs in your code. " + + "See https://react.dev/link/unsafe-component-lifecycles for details.\n\n" + + "* Move data fetching code or side effects to componentDidUpdate.\n" + + "\nPlease update the following components: %s", + _sortedNames2 + ); + } + + if (componentWillMountUniqueNames.size > 0) { + var _sortedNames3 = setToSortedString( + componentWillMountUniqueNames + ); + + warn( + "componentWillMount has been renamed, and is not recommended for use. " + + "See https://react.dev/link/unsafe-component-lifecycles for details.\n\n" + + "* Move code with side effects to componentDidMount, and set initial state in the constructor.\n" + + "* Rename componentWillMount to UNSAFE_componentWillMount to suppress " + + "this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. " + + "To rename all deprecated lifecycles to their new names, you can run " + + "`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n" + + "\nPlease update the following components: %s", + _sortedNames3 + ); + } + + if (componentWillReceivePropsUniqueNames.size > 0) { + var _sortedNames4 = setToSortedString( + componentWillReceivePropsUniqueNames + ); + + warn( + "componentWillReceiveProps has been renamed, and is not recommended for use. " + + "See https://react.dev/link/unsafe-component-lifecycles for details.\n\n" + + "* Move data fetching code or side effects to componentDidUpdate.\n" + + "* If you're updating state whenever props change, refactor your " + + "code to use memoization techniques or move it to " + + "static getDerivedStateFromProps. Learn more at: https://react.dev/link/derived-state\n" + + "* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress " + + "this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. " + + "To rename all deprecated lifecycles to their new names, you can run " + + "`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n" + + "\nPlease update the following components: %s", + _sortedNames4 + ); + } + + if (componentWillUpdateUniqueNames.size > 0) { + var _sortedNames5 = setToSortedString( + componentWillUpdateUniqueNames + ); + + warn( + "componentWillUpdate has been renamed, and is not recommended for use. " + + "See https://react.dev/link/unsafe-component-lifecycles for details.\n\n" + + "* Move data fetching code or side effects to componentDidUpdate.\n" + + "* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress " + + "this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. " + + "To rename all deprecated lifecycles to their new names, you can run " + + "`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n" + + "\nPlease update the following components: %s", + _sortedNames5 + ); + } + }; + + var pendingLegacyContextWarning = new Map(); // Tracks components we have already warned about. + + var didWarnAboutLegacyContext = new Set(); + + ReactStrictModeWarnings.recordLegacyContextWarning = function ( + fiber, + instance + ) { + var strictRoot = findStrictRoot(fiber); + + if (strictRoot === null) { + error( + "Expected to find a StrictMode component in a strict mode tree. " + + "This error is likely caused by a bug in React. Please file an issue." + ); + + return; + } // Dedup strategy: Warn once per component. + + if (didWarnAboutLegacyContext.has(fiber.type)) { + return; + } + + var warningsForRoot = pendingLegacyContextWarning.get(strictRoot); + + if ( + fiber.type.contextTypes != null || + fiber.type.childContextTypes != null || + (instance !== null && typeof instance.getChildContext === "function") + ) { + if (warningsForRoot === undefined) { + warningsForRoot = []; + pendingLegacyContextWarning.set(strictRoot, warningsForRoot); + } + + warningsForRoot.push(fiber); + } + }; + + ReactStrictModeWarnings.flushLegacyContextWarning = function () { + pendingLegacyContextWarning.forEach(function (fiberArray, strictRoot) { + if (fiberArray.length === 0) { + return; + } + + var firstFiber = fiberArray[0]; + var uniqueNames = new Set(); + fiberArray.forEach(function (fiber) { + uniqueNames.add(getComponentNameFromFiber(fiber) || "Component"); + didWarnAboutLegacyContext.add(fiber.type); + }); + var sortedNames = setToSortedString(uniqueNames); + + try { + setCurrentFiber(firstFiber); + + error( + "Legacy context API has been detected within a strict-mode tree." + + "\n\nThe old API will be supported in all 16.x releases, but applications " + + "using it should migrate to the new version." + + "\n\nPlease update the following components: %s" + + "\n\nLearn more about this warning here: https://react.dev/link/legacy-context", + sortedNames + ); + } finally { + resetCurrentFiber(); + } + }); + }; + + ReactStrictModeWarnings.discardPendingWarnings = function () { + pendingComponentWillMountWarnings = []; + pendingUNSAFE_ComponentWillMountWarnings = []; + pendingComponentWillReceivePropsWarnings = []; + pendingUNSAFE_ComponentWillReceivePropsWarnings = []; + pendingComponentWillUpdateWarnings = []; + pendingUNSAFE_ComponentWillUpdateWarnings = []; + pendingLegacyContextWarning = new Map(); + }; + } + + /* + * The `'' + value` pattern (used in perf-sensitive code) throws for Symbol + * and Temporal.* types. See https://github.com/facebook/react/pull/22064. + * + * The functions in this module will throw an easier-to-understand, + * easier-to-debug exception with a clear errors message message explaining the + * problem. (Instead of a confusing exception thrown inside the implementation + * of the `value` object). + */ + // $FlowFixMe[incompatible-return] only called in DEV, so void return is not possible. + function typeName(value) { + { + // toStringTag is needed for namespaced types like Temporal.Instant + var hasToStringTag = typeof Symbol === "function" && Symbol.toStringTag; + var type = + (hasToStringTag && value[Symbol.toStringTag]) || + value.constructor.name || + "Object"; // $FlowFixMe[incompatible-return] + + return type; + } + } // $FlowFixMe[incompatible-return] only called in DEV, so void return is not possible. + + function willCoercionThrow(value) { + { + try { + testStringCoercion(value); + return false; + } catch (e) { + return true; + } + } + } + + function testStringCoercion(value) { + // If you ended up here by following an exception call stack, here's what's + // happened: you supplied an object or symbol value to React (as a prop, key, + // DOM attribute, CSS property, string ref, etc.) and when React tried to + // coerce it to a string using `'' + value`, an exception was thrown. + // + // The most common types that will cause this exception are `Symbol` instances + // and Temporal objects like `Temporal.Instant`. But any object that has a + // `valueOf` or `[Symbol.toPrimitive]` method that throws will also cause this + // exception. (Library authors do this to prevent users from using built-in + // numeric operators like `+` or comparison operators like `>=` because custom + // methods are needed to perform accurate arithmetic or comparison.) + // + // To fix the problem, coerce this object or symbol value to a string before + // passing it to React. The most reliable way is usually `String(value)`. + // + // To find which value is throwing, check the browser or debugger console. + // Before this exception was thrown, there should be `console.error` output + // that shows the type (Symbol, Temporal.PlainDate, etc.) that caused the + // problem and how that type was used: key, atrribute, input value prop, etc. + // In most cases, this console output also shows the component and its + // ancestor components where the exception happened. + // + // eslint-disable-next-line react-internal/safe-string-coercion + return "" + value; + } + function checkKeyStringCoercion(value) { + { + if (willCoercionThrow(value)) { + error( + "The provided key is an unsupported type %s." + + " This value must be coerced to a string before using it here.", + typeName(value) + ); + + return testStringCoercion(value); // throw (to help callers find troubleshooting comments) + } + } + } + function checkPropStringCoercion(value, propName) { + { + if (willCoercionThrow(value)) { + error( + "The provided `%s` prop is an unsupported type %s." + + " This value must be coerced to a string before using it here.", + propName, + typeName(value) + ); + + return testStringCoercion(value); // throw (to help callers find troubleshooting comments) + } + } + } + + var ReactCurrentActQueue$2 = ReactSharedInternals.ReactCurrentActQueue; + + function getThenablesFromState(state) { + { + var devState = state; + return devState.thenables; + } + } // An error that is thrown (e.g. by `use`) to trigger Suspense. If we + // detect this is caught by userspace, we'll log a warning in development. + + var SuspenseException = new Error( + "Suspense Exception: This is not a real error! It's an implementation " + + "detail of `use` to interrupt the current render. You must either " + + "rethrow it immediately, or move the `use` call outside of the " + + "`try/catch` block. Capturing without rethrowing will lead to " + + "unexpected behavior.\n\n" + + "To handle async errors, wrap your component in an error boundary, or " + + "call the promise's `.catch` method and pass the result to `use`" + ); + var SuspenseyCommitException = new Error( + "Suspense Exception: This is not a real error, and should not leak into " + + "userspace. If you're seeing this, it's likely a bug in React." + ); // This is a noop thenable that we use to trigger a fallback in throwException. + // TODO: It would be better to refactor throwException into multiple functions + // so we can trigger a fallback directly without having to check the type. But + // for now this will do. + + var noopSuspenseyCommitThenable = { + then: function () { + { + error( + "Internal React error: A listener was unexpectedly attached to a " + + '"noop" thenable. This is a bug in React. Please file an issue.' + ); + } + } + }; + function createThenableState() { + // The ThenableState is created the first time a component suspends. If it + // suspends again, we'll reuse the same state. + { + return { + didWarnAboutUncachedPromise: false, + thenables: [] + }; + } + } + function isThenableResolved(thenable) { + var status = thenable.status; + return status === "fulfilled" || status === "rejected"; + } + + function noop() {} + + function trackUsedThenable(thenableState, thenable, index) { + if (ReactCurrentActQueue$2.current !== null) { + ReactCurrentActQueue$2.didUsePromise = true; + } + + var trackedThenables = getThenablesFromState(thenableState); + var previous = trackedThenables[index]; + + if (previous === undefined) { + trackedThenables.push(thenable); + } else { + if (previous !== thenable) { + // Reuse the previous thenable, and drop the new one. We can assume + // they represent the same value, because components are idempotent. + { + var thenableStateDev = thenableState; + + if (!thenableStateDev.didWarnAboutUncachedPromise) { + // We should only warn the first time an uncached thenable is + // discovered per component, because if there are multiple, the + // subsequent ones are likely derived from the first. + // + // We track this on the thenableState instead of deduping using the + // component name like we usually do, because in the case of a + // promise-as-React-node, the owner component is likely different from + // the parent that's currently being reconciled. We'd have to track + // the owner using state, which we're trying to move away from. Though + // since this is dev-only, maybe that'd be OK. + // + // However, another benefit of doing it this way is we might + // eventually have a thenableState per memo/Forget boundary instead + // of per component, so this would allow us to have more + // granular warnings. + thenableStateDev.didWarnAboutUncachedPromise = true; // TODO: This warning should link to a corresponding docs page. + + error( + "A component was suspended by an uncached promise. Creating " + + "promises inside a Client Component or hook is not yet " + + "supported, except via a Suspense-compatible library or framework." + ); + } + } // Avoid an unhandled rejection errors for the Promises that we'll + // intentionally ignore. + + thenable.then(noop, noop); + thenable = previous; + } + } // We use an expando to track the status and result of a thenable so that we + // can synchronously unwrap the value. Think of this as an extension of the + // Promise API, or a custom interface that is a superset of Thenable. + // + // If the thenable doesn't have a status, set it to "pending" and attach + // a listener that will update its status and result when it resolves. + + switch (thenable.status) { + case "fulfilled": { + var fulfilledValue = thenable.value; + return fulfilledValue; + } + + case "rejected": { + var rejectedError = thenable.reason; + checkIfUseWrappedInAsyncCatch(rejectedError); + throw rejectedError; + } + + default: { + if (typeof thenable.status === "string") { + // Only instrument the thenable if the status if not defined. If + // it's defined, but an unknown value, assume it's been instrumented by + // some custom userspace implementation. We treat it as "pending". + // Attach a dummy listener, to ensure that any lazy initialization can + // happen. Flight lazily parses JSON when the value is actually awaited. + thenable.then(noop, noop); + } else { + // This is an uncached thenable that we haven't seen before. + // Detect infinite ping loops caused by uncached promises. + var root = getWorkInProgressRoot(); + + if (root !== null && root.shellSuspendCounter > 100) { + // This root has suspended repeatedly in the shell without making any + // progress (i.e. committing something). This is highly suggestive of + // an infinite ping loop, often caused by an accidental Async Client + // Component. + // + // During a transition, we can suspend the work loop until the promise + // to resolve, but this is a sync render, so that's not an option. We + // also can't show a fallback, because none was provided. So our last + // resort is to throw an error. + // + // TODO: Remove this error in a future release. Other ways of handling + // this case include forcing a concurrent render, or putting the whole + // root into offscreen mode. + throw new Error( + "async/await is not yet supported in Client Components, only " + + "Server Components. This error is often caused by accidentally " + + "adding `'use client'` to a module that was originally written " + + "for the server." + ); + } + + var pendingThenable = thenable; + pendingThenable.status = "pending"; + pendingThenable.then( + function (fulfilledValue) { + if (thenable.status === "pending") { + var fulfilledThenable = thenable; + fulfilledThenable.status = "fulfilled"; + fulfilledThenable.value = fulfilledValue; + } + }, + function (error) { + if (thenable.status === "pending") { + var rejectedThenable = thenable; + rejectedThenable.status = "rejected"; + rejectedThenable.reason = error; + } + } + ); + } // Check one more time in case the thenable resolved synchronously. + + switch (thenable.status) { + case "fulfilled": { + var fulfilledThenable = thenable; + return fulfilledThenable.value; + } + + case "rejected": { + var rejectedThenable = thenable; + var _rejectedError = rejectedThenable.reason; + checkIfUseWrappedInAsyncCatch(_rejectedError); + throw _rejectedError; + } + } // Suspend. + // + // Throwing here is an implementation detail that allows us to unwind the + // call stack. But we shouldn't allow it to leak into userspace. Throw an + // opaque placeholder value instead of the actual thenable. If it doesn't + // get captured by the work loop, log a warning, because that means + // something in userspace must have caught it. + + suspendedThenable = thenable; + + { + needsToResetSuspendedThenableDEV = true; + } + + throw SuspenseException; + } + } + } + // passed to the rest of the Suspense implementation — which, for historical + // reasons, expects to receive a thenable. + + var suspendedThenable = null; + var needsToResetSuspendedThenableDEV = false; + function getSuspendedThenable() { + // This is called right after `use` suspends by throwing an exception. `use` + // throws an opaque value instead of the thenable itself so that it can't be + // caught in userspace. Then the work loop accesses the actual thenable using + // this function. + if (suspendedThenable === null) { + throw new Error( + "Expected a suspended thenable. This is a bug in React. Please file " + + "an issue." + ); + } + + var thenable = suspendedThenable; + suspendedThenable = null; + + { + needsToResetSuspendedThenableDEV = false; + } + + return thenable; + } + function checkIfUseWrappedInTryCatch() { + { + // This was set right before SuspenseException was thrown, and it should + // have been cleared when the exception was handled. If it wasn't, + // it must have been caught by userspace. + if (needsToResetSuspendedThenableDEV) { + needsToResetSuspendedThenableDEV = false; + return true; + } + } + + return false; + } + function checkIfUseWrappedInAsyncCatch(rejectedReason) { + // This check runs in prod, too, because it prevents a more confusing + // downstream error, where SuspenseException is caught by a promise and + // thrown asynchronously. + // TODO: Another way to prevent SuspenseException from leaking into an async + // execution context is to check the dispatcher every time `use` is called, + // or some equivalent. That might be preferable for other reasons, too, since + // it matches how we prevent similar mistakes for other hooks. + if (rejectedReason === SuspenseException) { + throw new Error( + "Hooks are not supported inside an async component. This " + + "error is often caused by accidentally adding `'use client'` " + + "to a module that was originally written for the server." + ); + } + } + + var thenableState$1 = null; + var thenableIndexCounter$1 = 0; + + function mergeDebugInfo(outer, inner) { + if (inner == null) { + return outer; + } else if (outer === null) { + return inner; + } else { + // If we have two debugInfo, we need to create a new one. This makes the array no longer + // live so we'll miss any future updates if we received more so ideally we should always + // do this after both have fully resolved/unsuspended. + return outer.concat(inner); + } + } + + var didWarnAboutMaps; + var didWarnAboutGenerators; + var didWarnAboutStringRefs; + var ownerHasKeyUseWarning; + var ownerHasFunctionTypeWarning; + var ownerHasSymbolTypeWarning; + + var warnForMissingKey = function (child, returnFiber) {}; + + { + didWarnAboutMaps = false; + didWarnAboutGenerators = false; + didWarnAboutStringRefs = {}; + /** + * Warn if there's no key explicitly set on dynamic arrays of children or + * object keys are not valid. This allows us to keep track of children between + * updates. + */ + + ownerHasKeyUseWarning = {}; + ownerHasFunctionTypeWarning = {}; + ownerHasSymbolTypeWarning = {}; + + warnForMissingKey = function (child, returnFiber) { + if (child === null || typeof child !== "object") { + return; + } + + if (!child._store || child._store.validated || child.key != null) { + return; + } + + if (typeof child._store !== "object") { + throw new Error( + "React Component in warnForMissingKey should have a _store. " + + "This error is likely caused by a bug in React. Please file an issue." + ); + } // $FlowFixMe[cannot-write] unable to narrow type from mixed to writable object + + child._store.validated = true; + var componentName = + getComponentNameFromFiber(returnFiber) || "Component"; + + if (ownerHasKeyUseWarning[componentName]) { + return; + } + + ownerHasKeyUseWarning[componentName] = true; + + error( + "Each child in a list should have a unique " + + '"key" prop. See https://react.dev/link/warning-keys for ' + + "more information." + ); + }; + } + + function isReactClass(type) { + return type.prototype && type.prototype.isReactComponent; + } + + function unwrapThenable(thenable) { + var index = thenableIndexCounter$1; + thenableIndexCounter$1 += 1; + + if (thenableState$1 === null) { + thenableState$1 = createThenableState(); + } + + return trackUsedThenable(thenableState$1, thenable, index); + } + + function convertStringRefToCallbackRef( + returnFiber, + current, + element, + mixedRef + ) { + { + checkPropStringCoercion(mixedRef, "ref"); + } + + var stringRef = "" + mixedRef; + var owner = element._owner; + + if (!owner) { + throw new Error( + "Element ref was specified as a string (" + + stringRef + + ") but no owner was set. This could happen for one of" + + " the following reasons:\n" + + "1. You may be adding a ref to a function component\n" + + "2. You may be adding a ref to a component that was not created inside a component's render method\n" + + "3. You have multiple copies of React loaded\n" + + "See https://react.dev/link/refs-must-have-owner for more information." + ); + } + + if (owner.tag !== ClassComponent) { + throw new Error( + "Function components cannot have string refs. " + + "We recommend using useRef() instead. " + + "Learn more about using refs safely here: " + + "https://react.dev/link/strict-mode-string-ref" + ); + } + + { + if ( + // Will already warn with "Function components cannot be given refs" + !(typeof element.type === "function" && !isReactClass(element.type)) + ) { + var componentName = + getComponentNameFromFiber(returnFiber) || "Component"; + + if (!didWarnAboutStringRefs[componentName]) { + error( + 'Component "%s" contains the string ref "%s". Support for string refs ' + + "will be removed in a future major release. We recommend using " + + "useRef() or createRef() instead. " + + "Learn more about using refs safely here: " + + "https://react.dev/link/strict-mode-string-ref", + componentName, + stringRef + ); + + didWarnAboutStringRefs[componentName] = true; + } + } + } + + var inst = owner.stateNode; + + if (!inst) { + throw new Error( + "Missing owner for string ref " + + stringRef + + ". This error is likely caused by a " + + "bug in React. Please file an issue." + ); + } // Check if previous string ref matches new string ref + + if ( + current !== null && + current.ref !== null && + typeof current.ref === "function" && + current.ref._stringRef === stringRef + ) { + // Reuse the existing string ref + var currentRef = current.ref; + return currentRef; + } // Create a new string ref + + var ref = function (value) { + var refs = inst.refs; + + if (value === null) { + delete refs[stringRef]; + } else { + refs[stringRef] = value; + } + }; + + ref._stringRef = stringRef; + return ref; + } + + function coerceRef(returnFiber, current, workInProgress, element) { + var mixedRef; + + { + // Old behavior. + mixedRef = element.ref; + } + + var coercedRef; + + if ( + typeof mixedRef === "string" || + typeof mixedRef === "number" || + typeof mixedRef === "boolean" + ) { + coercedRef = convertStringRefToCallbackRef( + returnFiber, + current, + element, + mixedRef + ); + } else { + coercedRef = mixedRef; + } // TODO: If enableRefAsProp is on, we shouldn't use the `ref` field. We + // should always read the ref from the prop. + + workInProgress.ref = coercedRef; + } + + function throwOnInvalidObjectType(returnFiber, newChild) { + // $FlowFixMe[method-unbinding] + var childString = Object.prototype.toString.call(newChild); + throw new 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, invalidChild) { + { + var parentName = getComponentNameFromFiber(returnFiber) || "Component"; + + if (ownerHasFunctionTypeWarning[parentName]) { + return; + } + + ownerHasFunctionTypeWarning[parentName] = true; + var name = invalidChild.displayName || invalidChild.name || "Component"; + + if (returnFiber.tag === HostRoot) { + error( + "Functions are not valid as a React child. This may happen if " + + "you return %s instead of <%s /> from render. " + + "Or maybe you meant to call this function rather than return it.\n" + + " root.render(%s)", + name, + name, + name + ); + } else { + error( + "Functions are not valid as a React child. This may happen if " + + "you return %s instead of <%s /> from render. " + + "Or maybe you meant to call this function rather than return it.\n" + + " <%s>{%s}", + name, + name, + parentName, + name, + parentName + ); + } + } + } + + function warnOnSymbolType(returnFiber, invalidChild) { + { + var parentName = getComponentNameFromFiber(returnFiber) || "Component"; + + if (ownerHasSymbolTypeWarning[parentName]) { + return; + } + + ownerHasSymbolTypeWarning[parentName] = true; // eslint-disable-next-line react-internal/safe-string-coercion + + var name = String(invalidChild); + + if (returnFiber.tag === HostRoot) { + error( + "Symbols are not valid as a React child.\n" + " root.render(%s)", + name + ); + } else { + error( + "Symbols are not valid as a React child.\n" + " <%s>%s", + parentName, + name, + parentName + ); + } + } + } + + function resolveLazy(lazyType) { + var payload = lazyType._payload; + var init = lazyType._init; + return init(payload); + } // This wrapper function exists because I expect to clone the code in each path + // to be able to optimize each path individually by branching early. This needs + // a compiler or we can do it manually. Helpers that don't need this branching + // live outside of this function. + + function createChildReconciler(shouldTrackSideEffects) { + function deleteChild(returnFiber, childToDelete) { + if (!shouldTrackSideEffects) { + // Noop. + return; + } + + var deletions = returnFiber.deletions; + + if (deletions === null) { + returnFiber.deletions = [childToDelete]; + returnFiber.flags |= ChildDeletion; + } else { + deletions.push(childToDelete); + } + } + + function deleteRemainingChildren(returnFiber, currentFirstChild) { + if (!shouldTrackSideEffects) { + // Noop. + return null; + } // TODO: For the shouldClone case, this could be micro-optimized a bit by + // assuming that after the first child we've already added everything. + + var childToDelete = currentFirstChild; + + while (childToDelete !== null) { + deleteChild(returnFiber, childToDelete); + childToDelete = childToDelete.sibling; + } + + return null; + } + + function mapRemainingChildren(currentFirstChild) { + // Add the remaining children to a temporary map so that we can find them by + // keys quickly. Implicit (null) keys get added to this set with their index + // instead. + var existingChildren = new Map(); + var existingChild = currentFirstChild; + + while (existingChild !== null) { + if (existingChild.key !== null) { + existingChildren.set(existingChild.key, existingChild); + } else { + existingChildren.set(existingChild.index, existingChild); + } + + existingChild = existingChild.sibling; + } + + return existingChildren; + } + + function useFiber(fiber, pendingProps) { + // We currently set sibling to null and index to 0 here because it is easy + // to forget to do before returning it. E.g. for the single child case. + var clone = createWorkInProgress(fiber, pendingProps); + clone.index = 0; + clone.sibling = null; + return clone; + } + + function placeChild(newFiber, lastPlacedIndex, newIndex) { + newFiber.index = newIndex; + + if (!shouldTrackSideEffects) { + // During hydration, the useId algorithm needs to know which fibers are + // part of a list of children (arrays, iterators). + newFiber.flags |= Forked; + return lastPlacedIndex; + } + + var current = newFiber.alternate; + + if (current !== null) { + var oldIndex = current.index; + + if (oldIndex < lastPlacedIndex) { + // This is a move. + newFiber.flags |= Placement | PlacementDEV; + return lastPlacedIndex; + } else { + // This item can stay in place. + return oldIndex; + } + } else { + // This is an insertion. + newFiber.flags |= Placement | PlacementDEV; + return lastPlacedIndex; + } + } + + function placeSingleChild(newFiber) { + // 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 | PlacementDEV; + } + + return newFiber; + } + + function updateTextNode( + returnFiber, + current, + textContent, + lanes, + debugInfo + ) { + if (current === null || current.tag !== HostText) { + // Insert + var created = createFiberFromText( + textContent, + returnFiber.mode, + lanes + ); + created.return = returnFiber; + + { + created._debugInfo = debugInfo; + } + + return created; + } else { + // Update + var existing = useFiber(current, textContent); + existing.return = returnFiber; + + { + existing._debugInfo = debugInfo; + } + + return existing; + } + } + + function updateElement(returnFiber, current, element, lanes, debugInfo) { + var elementType = element.type; + + if (elementType === REACT_FRAGMENT_TYPE) { + return updateFragment( + returnFiber, + current, + element.props.children, + lanes, + element.key, + debugInfo + ); + } + + if (current !== null) { + if ( + 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. + (typeof elementType === "object" && + elementType !== null && + elementType.$$typeof === REACT_LAZY_TYPE && + resolveLazy(elementType) === current.type) + ) { + // Move based on index + var existing = useFiber(current, element.props); + coerceRef(returnFiber, current, existing, element); + existing.return = returnFiber; + + { + existing._debugOwner = element._owner; + existing._debugInfo = debugInfo; + } + + return existing; + } + } // Insert + + var created = createFiberFromElement(element, returnFiber.mode, lanes); + coerceRef(returnFiber, current, created, element); + created.return = returnFiber; + + { + created._debugInfo = debugInfo; + } + + return created; + } + + function updatePortal(returnFiber, current, portal, lanes, debugInfo) { + if ( + current === null || + current.tag !== HostPortal || + current.stateNode.containerInfo !== portal.containerInfo || + current.stateNode.implementation !== portal.implementation + ) { + // Insert + var created = createFiberFromPortal(portal, returnFiber.mode, lanes); + created.return = returnFiber; + + { + created._debugInfo = debugInfo; + } + + return created; + } else { + // Update + var existing = useFiber(current, portal.children || []); + existing.return = returnFiber; + + { + existing._debugInfo = debugInfo; + } + + return existing; + } + } + + function updateFragment( + returnFiber, + current, + fragment, + lanes, + key, + debugInfo + ) { + if (current === null || current.tag !== Fragment) { + // Insert + var created = createFiberFromFragment( + fragment, + returnFiber.mode, + lanes, + key + ); + created.return = returnFiber; + + { + created._debugInfo = debugInfo; + } + + return created; + } else { + // Update + var existing = useFiber(current, fragment); + existing.return = returnFiber; + + { + existing._debugInfo = debugInfo; + } + + return existing; + } + } + + function createChild(returnFiber, newChild, lanes, debugInfo) { + if ( + (typeof newChild === "string" && newChild !== "") || + typeof newChild === "number" || + enableBigIntSupport + ) { + // Text nodes don't have keys. If the previous node is implicitly keyed + // we can continue to replace it without aborting even if it is not a text + // node. + var created = createFiberFromText( + // $FlowFixMe[unsafe-addition] Flow doesn't want us to use `+` operator with string and bigint + "" + newChild, + returnFiber.mode, + lanes + ); + created.return = returnFiber; + + { + created._debugInfo = debugInfo; + } + + return created; + } + + if (typeof newChild === "object" && newChild !== null) { + switch (newChild.$$typeof) { + case REACT_ELEMENT_TYPE: { + var _created = createFiberFromElement( + newChild, + returnFiber.mode, + lanes + ); + + coerceRef(returnFiber, null, _created, newChild); + _created.return = returnFiber; + + { + _created._debugInfo = mergeDebugInfo( + debugInfo, + newChild._debugInfo + ); + } + + return _created; + } + + case REACT_PORTAL_TYPE: { + var _created2 = createFiberFromPortal( + newChild, + returnFiber.mode, + lanes + ); + + _created2.return = returnFiber; + + { + _created2._debugInfo = debugInfo; + } + + return _created2; + } + + case REACT_LAZY_TYPE: { + var payload = newChild._payload; + var init = newChild._init; + return createChild( + returnFiber, + init(payload), + lanes, + mergeDebugInfo(debugInfo, newChild._debugInfo) // call merge after init + ); + } + } + + if (isArray(newChild) || getIteratorFn(newChild)) { + var _created3 = createFiberFromFragment( + newChild, + returnFiber.mode, + lanes, + null + ); + + _created3.return = returnFiber; + + { + _created3._debugInfo = mergeDebugInfo( + debugInfo, + newChild._debugInfo + ); + } + + return _created3; + } // Usable node types + // + // Unwrap the inner value and recursively call this function again. + + if (typeof newChild.then === "function") { + var thenable = newChild; + return createChild( + returnFiber, + unwrapThenable(thenable), + lanes, + mergeDebugInfo(debugInfo, newChild._debugInfo) + ); + } + + if (newChild.$$typeof === REACT_CONTEXT_TYPE) { + var context = newChild; + return createChild( + returnFiber, + readContextDuringReconciliation(returnFiber, context, lanes), + lanes, + debugInfo + ); + } + + throwOnInvalidObjectType(returnFiber, newChild); + } + + { + if (typeof newChild === "function") { + warnOnFunctionType(returnFiber, newChild); + } + + if (typeof newChild === "symbol") { + warnOnSymbolType(returnFiber, newChild); + } + } + + return null; + } + + function updateSlot(returnFiber, oldFiber, newChild, lanes, debugInfo) { + // Update the fiber if the keys match, otherwise return null. + var key = oldFiber !== null ? oldFiber.key : null; + + if ( + (typeof newChild === "string" && newChild !== "") || + typeof newChild === "number" || + enableBigIntSupport + ) { + // Text nodes don't have keys. If the previous node is implicitly keyed + // we can continue to replace it without aborting even if it is not a text + // node. + if (key !== null) { + return null; + } + + return updateTextNode( + returnFiber, + oldFiber, // $FlowFixMe[unsafe-addition] Flow doesn't want us to use `+` operator with string and bigint + "" + newChild, + lanes, + debugInfo + ); + } + + if (typeof newChild === "object" && newChild !== null) { + switch (newChild.$$typeof) { + case REACT_ELEMENT_TYPE: { + if (newChild.key === key) { + return updateElement( + returnFiber, + oldFiber, + newChild, + lanes, + mergeDebugInfo(debugInfo, newChild._debugInfo) + ); + } else { + return null; + } + } + + case REACT_PORTAL_TYPE: { + if (newChild.key === key) { + return updatePortal( + returnFiber, + oldFiber, + newChild, + lanes, + debugInfo + ); + } else { + return null; + } + } + + case REACT_LAZY_TYPE: { + var payload = newChild._payload; + var init = newChild._init; + return updateSlot( + returnFiber, + oldFiber, + init(payload), + lanes, + mergeDebugInfo(debugInfo, newChild._debugInfo) + ); + } + } + + if (isArray(newChild) || getIteratorFn(newChild)) { + if (key !== null) { + return null; + } + + return updateFragment( + returnFiber, + oldFiber, + newChild, + lanes, + null, + mergeDebugInfo(debugInfo, newChild._debugInfo) + ); + } // Usable node types + // + // Unwrap the inner value and recursively call this function again. + + if (typeof newChild.then === "function") { + var thenable = newChild; + return updateSlot( + returnFiber, + oldFiber, + unwrapThenable(thenable), + lanes, + debugInfo + ); + } + + if (newChild.$$typeof === REACT_CONTEXT_TYPE) { + var context = newChild; + return updateSlot( + returnFiber, + oldFiber, + readContextDuringReconciliation(returnFiber, context, lanes), + lanes, + debugInfo + ); + } + + throwOnInvalidObjectType(returnFiber, newChild); + } + + { + if (typeof newChild === "function") { + warnOnFunctionType(returnFiber, newChild); + } + + if (typeof newChild === "symbol") { + warnOnSymbolType(returnFiber, newChild); + } + } + + return null; + } + + function updateFromMap( + existingChildren, + returnFiber, + newIdx, + newChild, + lanes, + debugInfo + ) { + if ( + (typeof newChild === "string" && newChild !== "") || + typeof newChild === "number" || + enableBigIntSupport + ) { + // Text nodes don't have keys, so we neither have to check the old nor + // new node for the key. If both are text nodes, they match. + var matchedFiber = existingChildren.get(newIdx) || null; + return updateTextNode( + returnFiber, + matchedFiber, // $FlowFixMe[unsafe-addition] Flow doesn't want us to use `+` operator with string and bigint + "" + newChild, + lanes, + debugInfo + ); + } + + if (typeof newChild === "object" && newChild !== null) { + switch (newChild.$$typeof) { + case REACT_ELEMENT_TYPE: { + var _matchedFiber = + existingChildren.get( + newChild.key === null ? newIdx : newChild.key + ) || null; + + return updateElement( + returnFiber, + _matchedFiber, + newChild, + lanes, + mergeDebugInfo(debugInfo, newChild._debugInfo) + ); + } + + case REACT_PORTAL_TYPE: { + var _matchedFiber2 = + existingChildren.get( + newChild.key === null ? newIdx : newChild.key + ) || null; + + return updatePortal( + returnFiber, + _matchedFiber2, + newChild, + lanes, + debugInfo + ); + } + + case REACT_LAZY_TYPE: + var payload = newChild._payload; + var init = newChild._init; + return updateFromMap( + existingChildren, + returnFiber, + newIdx, + init(payload), + lanes, + mergeDebugInfo(debugInfo, newChild._debugInfo) + ); + } + + if (isArray(newChild) || getIteratorFn(newChild)) { + var _matchedFiber3 = existingChildren.get(newIdx) || null; + + return updateFragment( + returnFiber, + _matchedFiber3, + newChild, + lanes, + null, + mergeDebugInfo(debugInfo, newChild._debugInfo) + ); + } // Usable node types + // + // Unwrap the inner value and recursively call this function again. + + if (typeof newChild.then === "function") { + var thenable = newChild; + return updateFromMap( + existingChildren, + returnFiber, + newIdx, + unwrapThenable(thenable), + lanes, + debugInfo + ); + } + + if (newChild.$$typeof === REACT_CONTEXT_TYPE) { + var context = newChild; + return updateFromMap( + existingChildren, + returnFiber, + newIdx, + readContextDuringReconciliation(returnFiber, context, lanes), + lanes, + debugInfo + ); + } + + throwOnInvalidObjectType(returnFiber, newChild); + } + + { + if (typeof newChild === "function") { + warnOnFunctionType(returnFiber, newChild); + } + + if (typeof newChild === "symbol") { + warnOnSymbolType(returnFiber, newChild); + } + } + + return null; + } + /** + * Warns if there is a duplicate or missing key + */ + + function warnOnInvalidKey(child, knownKeys, returnFiber) { + { + if (typeof child !== "object" || child === null) { + return knownKeys; + } + + switch (child.$$typeof) { + case REACT_ELEMENT_TYPE: + case REACT_PORTAL_TYPE: + warnForMissingKey(child, returnFiber); + var key = child.key; + + if (typeof key !== "string") { + break; + } + + if (knownKeys === null) { + knownKeys = new Set(); + knownKeys.add(key); + break; + } + + if (!knownKeys.has(key)) { + knownKeys.add(key); + break; + } + + error( + "Encountered two children with the same key, `%s`. " + + "Keys should be unique so that components maintain their identity " + + "across updates. Non-unique keys may cause children to be " + + "duplicated and/or omitted — the behavior is unsupported and " + + "could change in a future version.", + key + ); + + break; + + case REACT_LAZY_TYPE: + var payload = child._payload; + var init = child._init; + warnOnInvalidKey(init(payload), knownKeys, returnFiber); + break; + } + } + + return knownKeys; + } + + function reconcileChildrenArray( + returnFiber, + currentFirstChild, + newChildren, + lanes, + debugInfo + ) { + // This algorithm can't optimize by searching from both ends since we + // don't have backpointers on fibers. I'm trying to see how far we can get + // with that model. If it ends up not being worth the tradeoffs, we can + // add it later. + // Even with a two ended optimization, we'd want to optimize for the case + // where there are few changes and brute force the comparison instead of + // going for the Map. It'd like to explore hitting that path first in + // forward-only mode and only go for the Map once we notice that we need + // lots of look ahead. This doesn't handle reversal as well as two ended + // search but that's unusual. Besides, for the two ended optimization to + // work on Iterables, we'd need to copy the whole set. + // In this first iteration, we'll just live with hitting the bad case + // (adding everything to a Map) in for every insert/move. + // If you change this code, also update reconcileChildrenIterator() which + // uses the same algorithm. + { + // First, validate keys. + var knownKeys = null; + + for (var i = 0; i < newChildren.length; i++) { + var child = newChildren[i]; + knownKeys = warnOnInvalidKey(child, knownKeys, returnFiber); + } + } + + var resultingFirstChild = null; + var previousNewFiber = null; + var oldFiber = currentFirstChild; + var lastPlacedIndex = 0; + var newIdx = 0; + var nextOldFiber = null; + + for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) { + if (oldFiber.index > newIdx) { + nextOldFiber = oldFiber; + oldFiber = null; + } else { + nextOldFiber = oldFiber.sibling; + } + + var newFiber = updateSlot( + returnFiber, + oldFiber, + newChildren[newIdx], + lanes, + debugInfo + ); + + if (newFiber === null) { + // TODO: This breaks on empty slots like null children. That's + // unfortunate because it triggers the slow path all the time. We need + // a better way to communicate whether this was a miss or null, + // boolean, undefined, etc. + if (oldFiber === null) { + oldFiber = nextOldFiber; + } + + break; + } + + if (shouldTrackSideEffects) { + if (oldFiber && newFiber.alternate === null) { + // We matched the slot, but we didn't reuse the existing fiber, so we + // need to delete the existing child. + deleteChild(returnFiber, oldFiber); + } + } + + lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx); + + if (previousNewFiber === null) { + // TODO: Move out of the loop. This only happens for the first run. + resultingFirstChild = newFiber; + } else { + // TODO: Defer siblings if we're not at the right index for this slot. + // I.e. if we had null values before, then we want to defer this + // for each null value. However, we also don't want to call updateSlot + // with the previous one. + previousNewFiber.sibling = newFiber; + } + + previousNewFiber = newFiber; + oldFiber = nextOldFiber; + } + + if (newIdx === newChildren.length) { + // We've reached the end of the new children. We can delete the rest. + deleteRemainingChildren(returnFiber, oldFiber); + + return resultingFirstChild; + } + + if (oldFiber === null) { + // If we don't have any more existing children we can choose a fast path + // since the rest will all be insertions. + for (; newIdx < newChildren.length; newIdx++) { + var _newFiber = createChild( + returnFiber, + newChildren[newIdx], + lanes, + debugInfo + ); + + if (_newFiber === null) { + continue; + } + + lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx); + + if (previousNewFiber === null) { + // TODO: Move out of the loop. This only happens for the first run. + resultingFirstChild = _newFiber; + } else { + previousNewFiber.sibling = _newFiber; + } + + previousNewFiber = _newFiber; + } + + return resultingFirstChild; + } // Add all children to a key map for quick lookups. + + var existingChildren = mapRemainingChildren(oldFiber); // Keep scanning and use the map to restore deleted items as moves. + + for (; newIdx < newChildren.length; newIdx++) { + var _newFiber2 = updateFromMap( + existingChildren, + returnFiber, + newIdx, + newChildren[newIdx], + lanes, + debugInfo + ); + + if (_newFiber2 !== null) { + if (shouldTrackSideEffects) { + if (_newFiber2.alternate !== null) { + // The new fiber is a work in progress, but if there exists a + // current, that means that we reused the fiber. We need to delete + // it from the child list so that we don't add it to the deletion + // list. + existingChildren.delete( + _newFiber2.key === null ? newIdx : _newFiber2.key + ); + } + } + + lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx); + + if (previousNewFiber === null) { + resultingFirstChild = _newFiber2; + } else { + previousNewFiber.sibling = _newFiber2; + } + + previousNewFiber = _newFiber2; + } + } + + if (shouldTrackSideEffects) { + // Any existing children that weren't consumed above were deleted. We need + // to add them to the deletion list. + existingChildren.forEach(function (child) { + return deleteChild(returnFiber, child); + }); + } + + return resultingFirstChild; + } + + function reconcileChildrenIterator( + returnFiber, + currentFirstChild, + newChildrenIterable, + lanes, + debugInfo + ) { + // This is the same implementation as reconcileChildrenArray(), + // but using the iterator instead. + var iteratorFn = getIteratorFn(newChildrenIterable); + + if (typeof iteratorFn !== "function") { + throw new Error( + "An object is not an iterable. This error is likely caused by a bug in " + + "React. Please file an issue." + ); + } + + { + // We don't support rendering Generators because it's a mutation. + // See https://github.com/facebook/react/issues/12995 + if ( + typeof Symbol === "function" && // $FlowFixMe[prop-missing] Flow doesn't know about toStringTag + newChildrenIterable[Symbol.toStringTag] === "Generator" + ) { + if (!didWarnAboutGenerators) { + error( + "Using Generators as children is unsupported and will likely yield " + + "unexpected results because enumerating a generator mutates it. " + + "You may convert it to an array with `Array.from()` or the " + + "`[...spread]` operator before rendering. Keep in mind " + + "you might need to polyfill these features for older browsers." + ); + } + + didWarnAboutGenerators = true; + } // Warn about using Maps as children + + if (newChildrenIterable.entries === iteratorFn) { + if (!didWarnAboutMaps) { + error( + "Using Maps as children is not supported. " + + "Use an array of keyed ReactElements instead." + ); + } + + didWarnAboutMaps = true; + } // First, validate keys. + // We'll get a different iterator later for the main pass. + + var _newChildren = iteratorFn.call(newChildrenIterable); + + if (_newChildren) { + var knownKeys = null; + + var _step = _newChildren.next(); + + for (; !_step.done; _step = _newChildren.next()) { + var child = _step.value; + knownKeys = warnOnInvalidKey(child, knownKeys, returnFiber); + } + } + } + + var newChildren = iteratorFn.call(newChildrenIterable); + + if (newChildren == null) { + throw new Error("An iterable object provided no iterator."); + } + + var resultingFirstChild = null; + var previousNewFiber = null; + var oldFiber = currentFirstChild; + var lastPlacedIndex = 0; + var newIdx = 0; + var nextOldFiber = null; + var step = newChildren.next(); + + for ( + ; + oldFiber !== null && !step.done; + newIdx++, step = newChildren.next() + ) { + if (oldFiber.index > newIdx) { + nextOldFiber = oldFiber; + oldFiber = null; + } else { + nextOldFiber = oldFiber.sibling; + } + + var newFiber = updateSlot( + returnFiber, + oldFiber, + step.value, + lanes, + debugInfo + ); + + if (newFiber === null) { + // TODO: This breaks on empty slots like null children. That's + // unfortunate because it triggers the slow path all the time. We need + // a better way to communicate whether this was a miss or null, + // boolean, undefined, etc. + if (oldFiber === null) { + oldFiber = nextOldFiber; + } + + break; + } + + if (shouldTrackSideEffects) { + if (oldFiber && newFiber.alternate === null) { + // We matched the slot, but we didn't reuse the existing fiber, so we + // need to delete the existing child. + deleteChild(returnFiber, oldFiber); + } + } + + lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx); + + if (previousNewFiber === null) { + // TODO: Move out of the loop. This only happens for the first run. + resultingFirstChild = newFiber; + } else { + // TODO: Defer siblings if we're not at the right index for this slot. + // I.e. if we had null values before, then we want to defer this + // for each null value. However, we also don't want to call updateSlot + // with the previous one. + previousNewFiber.sibling = newFiber; + } + + previousNewFiber = newFiber; + oldFiber = nextOldFiber; + } + + if (step.done) { + // We've reached the end of the new children. We can delete the rest. + deleteRemainingChildren(returnFiber, oldFiber); + + return resultingFirstChild; + } + + if (oldFiber === null) { + // If we don't have any more existing children we can choose a fast path + // since the rest will all be insertions. + for (; !step.done; newIdx++, step = newChildren.next()) { + var _newFiber3 = createChild( + returnFiber, + step.value, + lanes, + debugInfo + ); + + if (_newFiber3 === null) { + continue; + } + + lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx); + + if (previousNewFiber === null) { + // TODO: Move out of the loop. This only happens for the first run. + resultingFirstChild = _newFiber3; + } else { + previousNewFiber.sibling = _newFiber3; + } + + previousNewFiber = _newFiber3; + } + + return resultingFirstChild; + } // Add all children to a key map for quick lookups. + + var existingChildren = mapRemainingChildren(oldFiber); // Keep scanning and use the map to restore deleted items as moves. + + for (; !step.done; newIdx++, step = newChildren.next()) { + var _newFiber4 = updateFromMap( + existingChildren, + returnFiber, + newIdx, + step.value, + lanes, + debugInfo + ); + + if (_newFiber4 !== null) { + if (shouldTrackSideEffects) { + if (_newFiber4.alternate !== null) { + // The new fiber is a work in progress, but if there exists a + // current, that means that we reused the fiber. We need to delete + // it from the child list so that we don't add it to the deletion + // list. + existingChildren.delete( + _newFiber4.key === null ? newIdx : _newFiber4.key + ); + } + } + + lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx); + + if (previousNewFiber === null) { + resultingFirstChild = _newFiber4; + } else { + previousNewFiber.sibling = _newFiber4; + } + + previousNewFiber = _newFiber4; + } + } + + if (shouldTrackSideEffects) { + // Any existing children that weren't consumed above were deleted. We need + // to add them to the deletion list. + existingChildren.forEach(function (child) { + return deleteChild(returnFiber, child); + }); + } + + return resultingFirstChild; + } + + function reconcileSingleTextNode( + returnFiber, + currentFirstChild, + textContent, + lanes + ) { + // There's no need to check for keys on text nodes since we don't have a + // way to define them. + if (currentFirstChild !== null && currentFirstChild.tag === HostText) { + // We already have an existing node so let's just update it and delete + // the rest. + deleteRemainingChildren(returnFiber, currentFirstChild.sibling); + var existing = useFiber(currentFirstChild, textContent); + existing.return = returnFiber; + return existing; + } // The existing first child is not a text node so we need to create one + // and delete the existing ones. + + deleteRemainingChildren(returnFiber, currentFirstChild); + var created = createFiberFromText(textContent, returnFiber.mode, lanes); + created.return = returnFiber; + return created; + } + + function reconcileSingleElement( + returnFiber, + currentFirstChild, + element, + lanes, + debugInfo + ) { + var key = element.key; + var child = currentFirstChild; + + while (child !== null) { + // TODO: If key === null and child.key === null, then this only applies to + // the first item in the list. + if (child.key === key) { + var elementType = element.type; + + if (elementType === REACT_FRAGMENT_TYPE) { + if (child.tag === Fragment) { + deleteRemainingChildren(returnFiber, child.sibling); + var existing = useFiber(child, element.props.children); + existing.return = returnFiber; + + { + existing._debugOwner = element._owner; + existing._debugInfo = debugInfo; + } + + 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. + (typeof elementType === "object" && + elementType !== null && + elementType.$$typeof === REACT_LAZY_TYPE && + resolveLazy(elementType) === child.type) + ) { + deleteRemainingChildren(returnFiber, child.sibling); + + var _existing = useFiber(child, element.props); + + coerceRef(returnFiber, child, _existing, element); + _existing.return = returnFiber; + + { + _existing._debugOwner = element._owner; + _existing._debugInfo = debugInfo; + } + + return _existing; + } + } // Didn't match. + + deleteRemainingChildren(returnFiber, child); + break; + } else { + deleteChild(returnFiber, child); + } + + child = child.sibling; + } + + if (element.type === REACT_FRAGMENT_TYPE) { + var created = createFiberFromFragment( + element.props.children, + returnFiber.mode, + lanes, + element.key + ); + created.return = returnFiber; + + { + created._debugInfo = debugInfo; + } + + return created; + } else { + var _created4 = createFiberFromElement( + element, + returnFiber.mode, + lanes + ); + + coerceRef(returnFiber, currentFirstChild, _created4, element); + _created4.return = returnFiber; + + { + _created4._debugInfo = debugInfo; + } + + return _created4; + } + } + + function reconcileSinglePortal( + returnFiber, + currentFirstChild, + portal, + lanes, + debugInfo + ) { + var key = portal.key; + var child = currentFirstChild; + + while (child !== null) { + // TODO: If key === null and child.key === null, then this only applies to + // the first item in the list. + if (child.key === key) { + if ( + child.tag === HostPortal && + child.stateNode.containerInfo === portal.containerInfo && + child.stateNode.implementation === portal.implementation + ) { + deleteRemainingChildren(returnFiber, child.sibling); + var existing = useFiber(child, portal.children || []); + existing.return = returnFiber; + return existing; + } else { + deleteRemainingChildren(returnFiber, child); + break; + } + } else { + deleteChild(returnFiber, child); + } + + child = child.sibling; + } + + var created = createFiberFromPortal(portal, returnFiber.mode, lanes); + created.return = returnFiber; + return created; + } // This API will tag the children with the side-effect of the reconciliation + // itself. They will be added to the side-effect list as we pass through the + // children and the parent. + + function reconcileChildFibersImpl( + returnFiber, + currentFirstChild, + newChild, + lanes, + debugInfo + ) { + // This function is not recursive. + // If the top level item is an array, we treat it as a set of children, + // not as a fragment. Nested arrays on the other hand will be treated as + // fragment nodes. Recursion happens at the normal flow. + // Handle top level unkeyed fragments as if they were arrays. + // This leads to an ambiguity between <>{[...]} and <>.... + // We treat the ambiguous cases above the same. + // TODO: Let's use recursion like we do for Usable nodes? + var isUnkeyedTopLevelFragment = + typeof newChild === "object" && + newChild !== null && + newChild.type === REACT_FRAGMENT_TYPE && + newChild.key === null; + + if (isUnkeyedTopLevelFragment) { + newChild = newChild.props.children; + } // Handle object types + + if (typeof newChild === "object" && newChild !== null) { + switch (newChild.$$typeof) { + case REACT_ELEMENT_TYPE: + return placeSingleChild( + reconcileSingleElement( + returnFiber, + currentFirstChild, + newChild, + lanes, + mergeDebugInfo(debugInfo, newChild._debugInfo) + ) + ); + + case REACT_PORTAL_TYPE: + return placeSingleChild( + reconcileSinglePortal( + returnFiber, + currentFirstChild, + newChild, + lanes + ) + ); + + case REACT_LAZY_TYPE: + var payload = newChild._payload; + var init = newChild._init; + return reconcileChildFibersImpl( + returnFiber, + currentFirstChild, + init(payload), + lanes, + mergeDebugInfo(debugInfo, newChild._debugInfo) + ); + } + + if (isArray(newChild)) { + return reconcileChildrenArray( + returnFiber, + currentFirstChild, + newChild, + lanes, + mergeDebugInfo(debugInfo, newChild._debugInfo) + ); + } + + if (getIteratorFn(newChild)) { + return reconcileChildrenIterator( + returnFiber, + currentFirstChild, + newChild, + lanes, + mergeDebugInfo(debugInfo, newChild._debugInfo) + ); + } // Usables are a valid React node type. When React encounters a Usable in + // a child position, it unwraps it using the same algorithm as `use`. For + // example, for promises, React will throw an exception to unwind the + // stack, then replay the component once the promise resolves. + // + // A difference from `use` is that React will keep unwrapping the value + // until it reaches a non-Usable type. + // + // e.g. Usable>> should resolve to T + // + // The structure is a bit unfortunate. Ideally, we shouldn't need to + // replay the entire begin phase of the parent fiber in order to reconcile + // the children again. This would require a somewhat significant refactor, + // because reconcilation happens deep within the begin phase, and + // depending on the type of work, not always at the end. We should + // consider as an future improvement. + + if (typeof newChild.then === "function") { + var thenable = newChild; + return reconcileChildFibersImpl( + returnFiber, + currentFirstChild, + unwrapThenable(thenable), + lanes, + mergeDebugInfo(debugInfo, thenable._debugInfo) + ); + } + + if (newChild.$$typeof === REACT_CONTEXT_TYPE) { + var context = newChild; + return reconcileChildFibersImpl( + returnFiber, + currentFirstChild, + readContextDuringReconciliation(returnFiber, context, lanes), + lanes, + debugInfo + ); + } + + throwOnInvalidObjectType(returnFiber, newChild); + } + + if ( + (typeof newChild === "string" && newChild !== "") || + typeof newChild === "number" || + enableBigIntSupport + ) { + return placeSingleChild( + reconcileSingleTextNode( + returnFiber, + currentFirstChild, // $FlowFixMe[unsafe-addition] Flow doesn't want us to use `+` operator with string and bigint + "" + newChild, + lanes + ) + ); + } + + { + if (typeof newChild === "function") { + warnOnFunctionType(returnFiber, newChild); + } + + if (typeof newChild === "symbol") { + warnOnSymbolType(returnFiber, newChild); + } + } // Remaining cases are all treated as empty. + + return deleteRemainingChildren(returnFiber, currentFirstChild); + } + + function reconcileChildFibers( + returnFiber, + currentFirstChild, + newChild, + lanes + ) { + // This indirection only exists so we can reset `thenableState` at the end. + // It should get inlined by Closure. + thenableIndexCounter$1 = 0; + var firstChildFiber = reconcileChildFibersImpl( + returnFiber, + currentFirstChild, + newChild, + lanes, + null // debugInfo + ); + thenableState$1 = null; // Don't bother to reset `thenableIndexCounter` to 0 because it always gets + // set at the beginning. + + return firstChildFiber; + } + + return reconcileChildFibers; + } + + var reconcileChildFibers = createChildReconciler(true); + var mountChildFibers = createChildReconciler(false); + function resetChildReconcilerOnUnwind() { + // On unwind, clear any pending thenables that were used. + thenableState$1 = null; + thenableIndexCounter$1 = 0; + } + function cloneChildFibers(current, workInProgress) { + if (current !== null && workInProgress.child !== current.child) { + throw new Error("Resuming work not yet implemented."); + } + + if (workInProgress.child === null) { + return; + } + + var currentChild = workInProgress.child; + var newChild = createWorkInProgress( + currentChild, + currentChild.pendingProps + ); + workInProgress.child = newChild; + newChild.return = workInProgress; + + while (currentChild.sibling !== null) { + currentChild = currentChild.sibling; + newChild = newChild.sibling = createWorkInProgress( + currentChild, + currentChild.pendingProps + ); + newChild.return = workInProgress; + } + + newChild.sibling = null; + } // Reset a workInProgress child set to prepare it for a second pass. + + function resetChildFibers(workInProgress, lanes) { + var child = workInProgress.child; + + while (child !== null) { + resetWorkInProgress(child, lanes); + child = child.sibling; + } + } + + // TODO: This isn't being used yet, but it's intended to replace the + // InvisibleParentContext that is currently managed by SuspenseContext. + + var currentTreeHiddenStackCursor = createCursor(null); + var prevEntangledRenderLanesCursor = createCursor(NoLanes); + function pushHiddenContext(fiber, context) { + var prevEntangledRenderLanes = getEntangledRenderLanes(); + push(prevEntangledRenderLanesCursor, prevEntangledRenderLanes, fiber); + push(currentTreeHiddenStackCursor, context, fiber); // When rendering a subtree that's currently hidden, we must include all + // lanes that would have rendered if the hidden subtree hadn't been deferred. + // That is, in order to reveal content from hidden -> visible, we must commit + // all the updates that we skipped when we originally hid the tree. + + setEntangledRenderLanes( + mergeLanes(prevEntangledRenderLanes, context.baseLanes) + ); + } + function reuseHiddenContextOnStack(fiber) { + // This subtree is not currently hidden, so we don't need to add any lanes + // to the render lanes. But we still need to push something to avoid a + // context mismatch. Reuse the existing context on the stack. + push(prevEntangledRenderLanesCursor, getEntangledRenderLanes(), fiber); + push( + currentTreeHiddenStackCursor, + currentTreeHiddenStackCursor.current, + fiber + ); + } + function popHiddenContext(fiber) { + // Restore the previous render lanes from the stack + setEntangledRenderLanes(prevEntangledRenderLanesCursor.current); + pop(currentTreeHiddenStackCursor, fiber); + pop(prevEntangledRenderLanesCursor, fiber); + } + function isCurrentTreeHidden() { + return currentTreeHiddenStackCursor.current !== null; + } + + // suspends, i.e. it's the nearest `catch` block on the stack. + + var suspenseHandlerStackCursor = createCursor(null); // Represents the outermost boundary that is not visible in the current tree. + // Everything above this is the "shell". When this is null, it means we're + // rendering in the shell of the app. If it's non-null, it means we're rendering + // deeper than the shell, inside a new tree that wasn't already visible. + // + // The main way we use this concept is to determine whether showing a fallback + // would result in a desirable or undesirable loading state. Activing a fallback + // in the shell is considered an undersirable loading state, because it would + // mean hiding visible (albeit stale) content in the current tree — we prefer to + // show the stale content, rather than switch to a fallback. But showing a + // fallback in a new tree is fine, because there's no stale content to + // prefer instead. + + var shellBoundary = null; + function getShellBoundary() { + return shellBoundary; + } + function pushPrimaryTreeSuspenseHandler(handler) { + // TODO: Pass as argument + var current = handler.alternate; + // propagated a single level. For example, when ForceSuspenseFallback is set, + // it should only force the nearest Suspense boundary into fallback mode. + + pushSuspenseListContext( + handler, + setDefaultShallowSuspenseListContext(suspenseStackCursor.current) + ); // Experimental feature: Some Suspense boundaries are marked as having an + // to push a nested Suspense handler, because it will get replaced by the + // outer fallback, anyway. Consider this as a future optimization. + + push(suspenseHandlerStackCursor, handler, handler); + + if (shellBoundary === null) { + if (current === null || isCurrentTreeHidden()) { + // This boundary is not visible in the current UI. + shellBoundary = handler; + } else { + var prevState = current.memoizedState; + + if (prevState !== null) { + // This boundary is showing a fallback in the current UI. + shellBoundary = handler; + } + } + } + } + function pushFallbackTreeSuspenseHandler(fiber) { + // We're about to render the fallback. If something in the fallback suspends, + // it's akin to throwing inside of a `catch` block. This boundary should not + // capture. Reuse the existing handler on the stack. + reuseSuspenseHandlerOnStack(fiber); + } + function pushOffscreenSuspenseHandler(fiber) { + if (fiber.tag === OffscreenComponent) { + // A SuspenseList context is only pushed here to avoid a push/pop mismatch. + // Reuse the current value on the stack. + // TODO: We can avoid needing to push here by by forking popSuspenseHandler + // into separate functions for Suspense and Offscreen. + pushSuspenseListContext(fiber, suspenseStackCursor.current); + push(suspenseHandlerStackCursor, fiber, fiber); + + if (shellBoundary !== null); + else { + var current = fiber.alternate; + + if (current !== null) { + var prevState = current.memoizedState; + + if (prevState !== null) { + // This is the first boundary in the stack that's already showing + // a fallback. So everything outside is considered the shell. + shellBoundary = fiber; + } + } + } + } else { + // This is a LegacyHidden component. + reuseSuspenseHandlerOnStack(fiber); + } + } + function reuseSuspenseHandlerOnStack(fiber) { + pushSuspenseListContext(fiber, suspenseStackCursor.current); + push(suspenseHandlerStackCursor, getSuspenseHandler(), fiber); + } + function getSuspenseHandler() { + return suspenseHandlerStackCursor.current; + } + function popSuspenseHandler(fiber) { + pop(suspenseHandlerStackCursor, fiber); + + if (shellBoundary === fiber) { + // Popping back into the shell. + shellBoundary = null; + } + + popSuspenseListContext(fiber); + } // SuspenseList context + // TODO: Move to a separate module? We may change the SuspenseList + // implementation to hide/show in the commit phase, anyway. + + var DefaultSuspenseContext = 0; + var SubtreeSuspenseContextMask = 1; // ForceSuspenseFallback can be used by SuspenseList to force newly added + // items into their fallback state during one of the render passes. + + var ForceSuspenseFallback = 2; + var suspenseStackCursor = createCursor(DefaultSuspenseContext); + function hasSuspenseListContext(parentContext, flag) { + return (parentContext & flag) !== 0; + } + function setDefaultShallowSuspenseListContext(parentContext) { + return parentContext & SubtreeSuspenseContextMask; + } + function setShallowSuspenseListContext(parentContext, shallowContext) { + return (parentContext & SubtreeSuspenseContextMask) | shallowContext; + } + function pushSuspenseListContext(fiber, newContext) { + push(suspenseStackCursor, newContext, fiber); + } + function popSuspenseListContext(fiber) { + pop(suspenseStackCursor, fiber); + } + + // A non-null SuspenseState means that it is blocked for one reason or another. + // - A non-null dehydrated field means it's blocked pending hydration. + // - A non-null dehydrated field can use isSuspenseInstancePending or + // isSuspenseInstanceFallback to query the reason for being dehydrated. + // - A null dehydrated field means it's blocked by something suspending and + // we're currently showing a fallback instead. + + function findFirstSuspended(row) { + var node = row; + + while (node !== null) { + if (node.tag === SuspenseComponent) { + var state = node.memoizedState; + + if (state !== null) { + var dehydrated = state.dehydrated; + + if ( + dehydrated === null || + isSuspenseInstancePending() || + isSuspenseInstanceFallback() + ) { + return node; + } + } + } else if ( + node.tag === SuspenseListComponent && // revealOrder undefined can't be trusted because it don't + // keep track of whether it suspended or not. + node.memoizedProps.revealOrder !== undefined + ) { + var didSuspend = (node.flags & DidCapture) !== NoFlags$1; + + if (didSuspend) { + return node; + } + } else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; + } + + if (node === row) { + return null; + } + + while (node.sibling === null) { + if (node.return === null || node.return === row) { + return null; + } + + node = node.return; + } + + node.sibling.return = node.return; + node = node.sibling; + } + + return null; + } + + var NoFlags = + /* */ + 0; // Represents whether effect should fire. + + var HasEffect = + /* */ + 1; // Represents the phase in which the effect (not the clean-up) fires. + + var Insertion = + /* */ + 2; + var Layout = + /* */ + 4; + var Passive = + /* */ + 8; + + var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, + ReactCurrentBatchConfig$2 = ReactSharedInternals.ReactCurrentBatchConfig; + var didWarnAboutMismatchedHooksForComponent; + var didWarnUncachedGetSnapshot; + var didWarnAboutUseWrappedInTryCatch; + var didWarnAboutAsyncClientComponent; + + { + didWarnAboutMismatchedHooksForComponent = new Set(); + didWarnAboutUseWrappedInTryCatch = new Set(); + didWarnAboutAsyncClientComponent = new Set(); + } // The effect "instance" is a shared object that remains the same for the entire + // lifetime of an effect. In Rust terms, a RefCell. We use it to store the + // "destroy" function that is returned from an effect, because that is stateful. + // The field is `undefined` if the effect is unmounted, or if the effect ran + // but is not stateful. We don't explicitly track whether the effect is mounted + // or unmounted because that can be inferred by the hiddenness of the fiber in + // the tree, i.e. whether there is a hidden Offscreen fiber above it. + // + // It's unfortunate that this is stored on a separate object, because it adds + // more memory per effect instance, but it's conceptually sound. I think there's + // likely a better data structure we could use for effects; perhaps just one + // array of effect instances per fiber. But I think this is OK for now despite + // the additional memory and we can follow up with performance + // optimizations later. + // These are set right before calling the component. + + var renderLanes = NoLanes; // The work-in-progress fiber. I've named it differently to distinguish it from + // the work-in-progress hook. + + var currentlyRenderingFiber$1 = null; // Hooks are stored as a linked list on the fiber's memoizedState field. The + // current hook list is the list that belongs to the current fiber. The + // work-in-progress hook list is a new list that will be added to the + // work-in-progress fiber. + + var currentHook = null; + var workInProgressHook = null; // Whether an update was scheduled at any point during the render phase. This + // does not get reset if we do another render pass; only when we're completely + // finished evaluating this component. This is an optimization so we know + // whether we need to clear render phase updates after a throw. + + var didScheduleRenderPhaseUpdate = false; // Where an update was scheduled only during the current render pass. This + // gets reset after each attempt. + // TODO: Maybe there's some way to consolidate this with + // `didScheduleRenderPhaseUpdate`. Or with `numberOfReRenders`. + + var didScheduleRenderPhaseUpdateDuringThisPass = false; + var shouldDoubleInvokeUserFnsInHooksDEV = false; // Counts the number of useId hooks in this component. + + var thenableIndexCounter = 0; + var thenableState = null; // Used for ids that are generated completely client-side (i.e. not during + // hydration). This counter is global, so client ids are not stable across + // render attempts. + + var globalClientIdCounter = 0; + var RE_RENDER_LIMIT = 25; // In DEV, this is the name of the currently executing primitive hook + + var currentHookNameInDev = null; // In DEV, this list ensures that hooks are called in the same order between renders. + // The list stores the order of hooks used during the initial render (mount). + // Subsequent renders (updates) reference this list. + + var hookTypesDev = null; + var hookTypesUpdateIndexDev = -1; // In DEV, this tracks whether currently rendering component needs to ignore + // the dependencies for Hooks that need them (e.g. useEffect or useMemo). + // When true, such Hooks will always be "remounted". Only used during hot reload. + + var ignorePreviousDependencies = false; + + function mountHookTypesDev() { + { + var hookName = currentHookNameInDev; + + if (hookTypesDev === null) { + hookTypesDev = [hookName]; + } else { + hookTypesDev.push(hookName); + } + } + } + + function updateHookTypesDev() { + { + var hookName = currentHookNameInDev; + + if (hookTypesDev !== null) { + hookTypesUpdateIndexDev++; + + if (hookTypesDev[hookTypesUpdateIndexDev] !== hookName) { + warnOnHookMismatchInDev(hookName); + } + } + } + } + + function checkDepsAreArrayDev(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( + "%s received a final argument that is not an array (instead, received `%s`). When " + + "specified, the final argument must be an array.", + currentHookNameInDev, + typeof deps + ); + } + } + } + + function warnOnHookMismatchInDev(currentHookName) { + { + var componentName = getComponentNameFromFiber( + currentlyRenderingFiber$1 + ); + + if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) { + didWarnAboutMismatchedHooksForComponent.add(componentName); + + if (hookTypesDev !== null) { + var table = ""; + var secondColumnStart = 30; + + for (var i = 0; i <= hookTypesUpdateIndexDev; i++) { + var oldHookName = hookTypesDev[i]; + var newHookName = + i === hookTypesUpdateIndexDev ? currentHookName : oldHookName; + var row = i + 1 + ". " + oldHookName; // Extra space so second column lines up + // lol @ IE not supporting String#repeat + + while (row.length < secondColumnStart) { + row += " "; + } + + row += newHookName + "\n"; + table += row; + } + + error( + "React has detected a change in the order of Hooks called by %s. " + + "This will lead to bugs and errors if not fixed. " + + "For more information, read the Rules of Hooks: https://react.dev/link/rules-of-hooks\n\n" + + " Previous render Next render\n" + + " ------------------------------------------------------\n" + + "%s" + + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + componentName, + table + ); + } + } + } + } + + function warnIfAsyncClientComponent(Component) { + { + // This dev-only check only works for detecting native async functions, + // not transpiled ones. There's also a prod check that we use to prevent + // async client components from crashing the app; the prod one works even + // for transpiled async functions. Neither mechanism is completely + // bulletproof but together they cover the most common cases. + var isAsyncFunction = // $FlowIgnore[method-unbinding] + Object.prototype.toString.call(Component) === + "[object AsyncFunction]"; + + if (isAsyncFunction) { + // Encountered an async Client Component. This is not yet supported. + var componentName = getComponentNameFromFiber( + currentlyRenderingFiber$1 + ); + + if (!didWarnAboutAsyncClientComponent.has(componentName)) { + didWarnAboutAsyncClientComponent.add(componentName); + + error( + "async/await is not yet supported in Client Components, only " + + "Server Components. This error is often caused by accidentally " + + "adding `'use client'` to a module that was originally written " + + "for the server." + ); + } + } + } + } + + function throwInvalidHookError() { + throw new Error( + "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for" + + " one of the following reasons:\n" + + "1. You might have mismatching versions of React and the renderer (such as React DOM)\n" + + "2. You might be breaking the Rules of Hooks\n" + + "3. You might have more than one copy of React in the same app\n" + + "See https://react.dev/link/invalid-hook-call for tips about how to debug and fix this problem." + ); + } + + function areHookInputsEqual(nextDeps, prevDeps) { + { + if (ignorePreviousDependencies) { + // Only true when this component is being hot reloaded. + return false; + } + } + + if (prevDeps === null) { + { + error( + "%s received a final argument during this render, but not during " + + "the previous render. Even though the final argument is optional, " + + "its type cannot change between renders.", + currentHookNameInDev + ); + } + + return false; + } + + { + // Don't bother comparing lengths in prod because these arrays should be + // passed inline. + if (nextDeps.length !== prevDeps.length) { + error( + "The final argument passed to %s changed size between renders. The " + + "order and size of this array must remain constant.\n\n" + + "Previous: %s\n" + + "Incoming: %s", + currentHookNameInDev, + "[" + prevDeps.join(", ") + "]", + "[" + nextDeps.join(", ") + "]" + ); + } + } // $FlowFixMe[incompatible-use] found when upgrading Flow + + for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) { + // $FlowFixMe[incompatible-use] found when upgrading Flow + if (objectIs(nextDeps[i], prevDeps[i])) { + continue; + } + + return false; + } + + return true; + } + + function renderWithHooks( + current, + workInProgress, + Component, + props, + secondArg, + nextRenderLanes + ) { + renderLanes = nextRenderLanes; + currentlyRenderingFiber$1 = workInProgress; + + { + hookTypesDev = current !== null ? current._debugHookTypes : null; + hookTypesUpdateIndexDev = -1; // Used for hot reloading: + + ignorePreviousDependencies = + current !== null && current.type !== workInProgress.type; + warnIfAsyncClientComponent(Component); + } + + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; + workInProgress.lanes = NoLanes; // The following should have already been reset + // currentHook = null; + // workInProgressHook = null; + // didScheduleRenderPhaseUpdate = false; + // localIdCounter = 0; + // thenableIndexCounter = 0; + // thenableState = null; + // TODO Warn if no hooks are used at all during mount, then some are used during update. + // Currently we will identify the update render as a mount because memoizedState === null. + // This is tricky because it's valid for certain types of components (e.g. React.lazy) + // Using memoizedState to differentiate between mount/update only works if at least one stateful hook is used. + // Non-stateful hooks (e.g. context) don't get added to memoizedState, + // so memoizedState would be null during updates and mounts. + + { + if (current !== null && current.memoizedState !== null) { + ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV; + } else if (hookTypesDev !== null) { + // This dispatcher handles an edge case where a component is updating, + // but no stateful hooks have been used. + // We want to match the production code behavior (which will use HooksDispatcherOnMount), + // but with the extra DEV validation to ensure hooks ordering hasn't changed. + // This dispatcher does that. + ReactCurrentDispatcher$1.current = + HooksDispatcherOnMountWithHookTypesInDEV; + } else { + ReactCurrentDispatcher$1.current = HooksDispatcherOnMountInDEV; + } + } // In Strict Mode, during development, user functions are double invoked to + // help detect side effects. The logic for how this is implemented for in + // hook components is a bit complex so let's break it down. + // + // We will invoke the entire component function twice. However, during the + // second invocation of the component, the hook state from the first + // invocation will be reused. That means things like `useMemo` functions won't + // run again, because the deps will match and the memoized result will + // be reused. + // + // We want memoized functions to run twice, too, so account for this, user + // functions are double invoked during the *first* invocation of the component + // function, and are *not* double invoked during the second incovation: + // + // - First execution of component function: user functions are double invoked + // - Second execution of component function (in Strict Mode, during + // development): user functions are not double invoked. + // + // This is intentional for a few reasons; most importantly, it's because of + // how `use` works when something suspends: it reuses the promise that was + // passed during the first attempt. This is itself a form of memoization. + // We need to be able to memoize the reactive inputs to the `use` call using + // a hook (i.e. `useMemo`), which means, the reactive inputs to `use` must + // come from the same component invocation as the output. + // + // There are plenty of tests to ensure this behavior is correct. + + var shouldDoubleRenderDEV = + (workInProgress.mode & StrictLegacyMode) !== NoMode; + shouldDoubleInvokeUserFnsInHooksDEV = shouldDoubleRenderDEV; + var children = Component(props, secondArg); + shouldDoubleInvokeUserFnsInHooksDEV = false; // Check if there was a render phase update + + if (didScheduleRenderPhaseUpdateDuringThisPass) { + // Keep rendering until the component stabilizes (there are no more render + // phase updates). + children = renderWithHooksAgain( + workInProgress, + Component, + props, + secondArg + ); + } + + if (shouldDoubleRenderDEV) { + // In development, components are invoked twice to help detect side effects. + setIsStrictModeForDevtools(true); + + try { + children = renderWithHooksAgain( + workInProgress, + Component, + props, + secondArg + ); + } finally { + setIsStrictModeForDevtools(false); + } + } + + finishRenderingHooks(current, workInProgress); + return children; + } + + function finishRenderingHooks(current, workInProgress, Component) { + { + workInProgress._debugHookTypes = hookTypesDev; + } // We can assume the previous dispatcher is always this one, since we set it + // at the beginning of the render phase and there's no re-entrance. + + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; // This check uses currentHook so that it works the same in DEV and prod bundles. + // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles. + + var didRenderTooFewHooks = + currentHook !== null && currentHook.next !== null; + renderLanes = NoLanes; + currentlyRenderingFiber$1 = null; + currentHook = null; + workInProgressHook = null; + + { + currentHookNameInDev = null; + hookTypesDev = null; + 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; // This is reset by checkDidRenderIdHook + // localIdCounter = 0; + + thenableIndexCounter = 0; + thenableState = null; + + if (didRenderTooFewHooks) { + throw new Error( + "Rendered fewer hooks than expected. This may be caused by an accidental " + + "early return statement." + ); + } + + { + if (checkIfUseWrappedInTryCatch()) { + var componentName = + getComponentNameFromFiber(workInProgress) || "Unknown"; + + if ( + !didWarnAboutUseWrappedInTryCatch.has(componentName) && // This warning also fires if you suspend with `use` inside an + // async component. Since we warn for that above, we'll silence this + // second warning by checking here. + !didWarnAboutAsyncClientComponent.has(componentName) + ) { + didWarnAboutUseWrappedInTryCatch.add(componentName); + + error( + "`use` was called from inside a try/catch block. This is not allowed " + + "and can lead to unexpected behavior. To handle errors triggered " + + "by `use`, wrap your component in a error boundary." + ); + } + } + } + } + + function replaySuspendedComponentWithHooks( + current, + workInProgress, + Component, + props, + secondArg + ) { + // This function is used to replay a component that previously suspended, + // after its data resolves. + // + // It's a simplified version of renderWithHooks, but it doesn't need to do + // most of the set up work because they weren't reset when we suspended; they + // only get reset when the component either completes (finishRenderingHooks) + // or unwinds (resetHooksOnUnwind). + { + hookTypesUpdateIndexDev = -1; // Used for hot reloading: + + ignorePreviousDependencies = + current !== null && current.type !== workInProgress.type; + } + + var children = renderWithHooksAgain( + workInProgress, + Component, + props, + secondArg + ); + finishRenderingHooks(current, workInProgress); + return children; + } + + function renderWithHooksAgain(workInProgress, Component, props, secondArg) { + // This is used to perform another render pass. It's used when setState is + // called during render, and for double invoking components in Strict Mode + // during development. + // + // The state from the previous pass is reused whenever possible. So, state + // updates that were already processed are not processed again, and memoized + // functions (`useMemo`) are not invoked again. + // + // Keep rendering in a loop for as long as render phase updates continue to + // be scheduled. Use a counter to prevent infinite loops. + currentlyRenderingFiber$1 = workInProgress; + var numberOfReRenders = 0; + var children; + + do { + if (didScheduleRenderPhaseUpdateDuringThisPass) { + // It's possible that a use() value depended on a state that was updated in + // this rerender, so we need to watch for different thenables this time. + thenableState = null; + } + + thenableIndexCounter = 0; + didScheduleRenderPhaseUpdateDuringThisPass = false; + + if (numberOfReRenders >= RE_RENDER_LIMIT) { + throw new Error( + "Too many re-renders. React limits the number of renders to prevent " + + "an infinite loop." + ); + } + + numberOfReRenders += 1; + + { + // Even when hot reloading, allow dependencies to stabilize + // after first render to prevent infinite render phase updates. + ignorePreviousDependencies = false; + } // Start over from the beginning of the list + + currentHook = null; + workInProgressHook = null; + workInProgress.updateQueue = null; + + { + // Also validate hook order for cascading updates. + hookTypesUpdateIndexDev = -1; + } + + ReactCurrentDispatcher$1.current = HooksDispatcherOnRerenderInDEV; + children = Component(props, secondArg); + } while (didScheduleRenderPhaseUpdateDuringThisPass); + + return children; + } + 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$1 | + Update + ); + } else { + workInProgress.flags &= ~(Passive$1 | Update); + } + + current.lanes = removeLanes(current.lanes, lanes); + } + function resetHooksAfterThrow() { + // This is called immediaetly after a throw. It shouldn't reset the entire + // module state, because the work loop might decide to replay the component + // again without rewinding. + // + // It should only reset things like the current dispatcher, to prevent hooks + // from being called outside of a component. + currentlyRenderingFiber$1 = null; // We can assume the previous dispatcher is always this one, since we set it + // at the beginning of the render phase and there's no re-entrance. + + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + } + function resetHooksOnUnwind(workInProgress) { + if (didScheduleRenderPhaseUpdate) { + // There were render phase updates. These are only valid for this render + // phase, which we are now aborting. Remove the updates from the queues so + // they do not persist to the next render. Do not remove updates from hooks + // that weren't processed. + // + // Only reset the updates from the queue if it has a clone. If it does + // not have a clone, that means it wasn't processed, and the updates were + // scheduled before we entered the render phase. + var hook = workInProgress.memoizedState; + + while (hook !== null) { + var queue = hook.queue; + + if (queue !== null) { + queue.pending = null; + } + + hook = hook.next; + } + + didScheduleRenderPhaseUpdate = false; + } + + renderLanes = NoLanes; + currentlyRenderingFiber$1 = null; + currentHook = null; + workInProgressHook = null; + + { + hookTypesDev = null; + hookTypesUpdateIndexDev = -1; + currentHookNameInDev = null; + } + + didScheduleRenderPhaseUpdateDuringThisPass = false; + thenableIndexCounter = 0; + thenableState = null; + } + + function mountWorkInProgressHook() { + var hook = { + memoizedState: null, + baseState: null, + baseQueue: null, + queue: null, + next: null + }; + + if (workInProgressHook === null) { + // This is the first hook in the list + currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook; + } else { + // Append to the end of the list + workInProgressHook = workInProgressHook.next = hook; + } + + return workInProgressHook; + } + + function updateWorkInProgressHook() { + // This function is used both for updates and for re-renders triggered by a + // render phase update. It assumes there is either a current hook we can + // clone, or a work-in-progress hook from a previous render pass that we can + // use as a base. + var nextCurrentHook; + + if (currentHook === null) { + var current = currentlyRenderingFiber$1.alternate; + + if (current !== null) { + nextCurrentHook = current.memoizedState; + } else { + nextCurrentHook = null; + } + } else { + nextCurrentHook = currentHook.next; + } + + var nextWorkInProgressHook; + + if (workInProgressHook === null) { + nextWorkInProgressHook = currentlyRenderingFiber$1.memoizedState; + } else { + nextWorkInProgressHook = workInProgressHook.next; + } + + if (nextWorkInProgressHook !== null) { + // There's already a work-in-progress. Reuse it. + workInProgressHook = nextWorkInProgressHook; + nextWorkInProgressHook = workInProgressHook.next; + currentHook = nextCurrentHook; + } else { + // Clone from the current hook. + if (nextCurrentHook === null) { + var currentFiber = currentlyRenderingFiber$1.alternate; + + if (currentFiber === null) { + // This is the initial render. This branch is reached when the component + // suspends, resumes, then renders an additional hook. + // Should never be reached because we should switch to the mount dispatcher first. + throw new Error( + "Update hook called on initial render. This is likely a bug in React. Please file an issue." + ); + } else { + // This is an update. We should always have a current hook. + throw new Error( + "Rendered more hooks than during the previous render." + ); + } + } + + currentHook = nextCurrentHook; + var newHook = { + memoizedState: currentHook.memoizedState, + baseState: currentHook.baseState, + baseQueue: currentHook.baseQueue, + queue: currentHook.queue, + next: null + }; + + if (workInProgressHook === null) { + // This is the first hook in the list. + currentlyRenderingFiber$1.memoizedState = workInProgressHook = + newHook; + } else { + // Append to the end of the list. + workInProgressHook = workInProgressHook.next = newHook; + } + } + + return workInProgressHook; + } // NOTE: defining two versions of this function to avoid size impact when this feature is disabled. + // Previously this function was inlined, the additional `memoCache` property makes it not inlined. + + var createFunctionComponentUpdateQueue; + + { + createFunctionComponentUpdateQueue = function () { + return { + lastEffect: null, + events: null, + stores: null + }; + }; + } + + function useThenable(thenable) { + // Track the position of the thenable within this fiber. + var index = thenableIndexCounter; + thenableIndexCounter += 1; + + if (thenableState === null) { + thenableState = createThenableState(); + } + + var result = trackUsedThenable(thenableState, thenable, index); + + if ( + currentlyRenderingFiber$1.alternate === null && + (workInProgressHook === null + ? currentlyRenderingFiber$1.memoizedState === null + : workInProgressHook.next === null) + ) { + // Initial render, and either this is the first time the component is + // called, or there were no Hooks called after this use() the previous + // time (perhaps because it threw). Subsequent Hook calls should use the + // mount dispatcher. + { + ReactCurrentDispatcher$1.current = HooksDispatcherOnMountInDEV; + } + } + + return result; + } + + function use(usable) { + if (usable !== null && typeof usable === "object") { + // $FlowFixMe[method-unbinding] + if (typeof usable.then === "function") { + // This is a thenable. + var thenable = usable; + return useThenable(thenable); + } else if (usable.$$typeof === REACT_CONTEXT_TYPE) { + var context = usable; + return readContext(context); + } + } // eslint-disable-next-line react-internal/safe-string-coercion + + throw new Error( + "An unsupported type was passed to use(): " + String(usable) + ); + } + + function basicStateReducer(state, action) { + // $FlowFixMe[incompatible-use]: Flow doesn't like mixed types + return typeof action === "function" ? action(state) : action; + } + + function mountReducer(reducer, initialArg, init) { + var hook = mountWorkInProgressHook(); + var initialState; + + if (init !== undefined) { + initialState = init(initialArg); + + if (shouldDoubleInvokeUserFnsInHooksDEV) { + setIsStrictModeForDevtools(true); + init(initialArg); + setIsStrictModeForDevtools(false); + } + } else { + initialState = initialArg; + } + + hook.memoizedState = hook.baseState = initialState; + var queue = { + pending: null, + lanes: NoLanes, + dispatch: null, + lastRenderedReducer: reducer, + lastRenderedState: initialState + }; + hook.queue = queue; + var dispatch = (queue.dispatch = dispatchReducerAction.bind( + null, + currentlyRenderingFiber$1, + queue + )); + return [hook.memoizedState, dispatch]; + } + + function updateReducer(reducer, initialArg, init) { + var hook = updateWorkInProgressHook(); + return updateReducerImpl(hook, currentHook, reducer); + } + + function updateReducerImpl(hook, current, reducer) { + var queue = hook.queue; + + if (queue === null) { + throw new Error( + "Should have a queue. This is likely a bug in React. Please file an issue." + ); + } + + queue.lastRenderedReducer = reducer; // The last rebase update that is NOT part of the base state. + + var baseQueue = hook.baseQueue; // The last pending update that hasn't been processed yet. + + var pendingQueue = queue.pending; + + if (pendingQueue !== null) { + // We have new updates that haven't been processed yet. + // We'll add them to the base queue. + if (baseQueue !== null) { + // Merge the pending queue and the base queue. + var baseFirst = baseQueue.next; + var pendingFirst = pendingQueue.next; + baseQueue.next = pendingFirst; + pendingQueue.next = baseFirst; + } + + { + if (current.baseQueue !== baseQueue) { + // Internal invariant that should never happen, but feasibly could in + // the future if we implement resuming, or some form of that. + error( + "Internal error: Expected work-in-progress queue to be a clone. " + + "This is a bug in React." + ); + } + } + + current.baseQueue = baseQueue = pendingQueue; + queue.pending = null; + } + + var baseState = hook.baseState; + + if (baseQueue === null) { + // If there are no pending updates, then the memoized state should be the + // same as the base state. Currently these only diverge in the case of + // useOptimistic, because useOptimistic accepts a new baseState on + // every render. + hook.memoizedState = baseState; // We don't need to call markWorkInProgressReceivedUpdate because + // baseState is derived from other reactive values. + } else { + // We have a queue to process. + var first = baseQueue.next; + var newState = baseState; + var newBaseState = null; + var newBaseQueueFirst = null; + var newBaseQueueLast = null; + var update = first; + var didReadFromEntangledAsyncAction = false; + + do { + // An extra OffscreenLane bit is added to updates that were made to + // a hidden tree, so that we can distinguish them from updates that were + // already there when the tree was hidden. + var updateLane = removeLanes(update.lane, OffscreenLane); + var isHiddenUpdate = updateLane !== update.lane; // Check if this update was made while the tree was hidden. If so, then + // it's not a "base" update and we should disregard the extra base lanes + // that were added to renderLanes when we entered the Offscreen tree. + + var shouldSkipUpdate = isHiddenUpdate + ? !isSubsetOfLanes(getWorkInProgressRootRenderLanes(), updateLane) + : !isSubsetOfLanes(renderLanes, updateLane); + + if (shouldSkipUpdate) { + // Priority is insufficient. Skip this update. If this is the first + // skipped update, the previous update/state is the new base + // update/state. + var clone = { + lane: updateLane, + revertLane: update.revertLane, + action: update.action, + hasEagerState: update.hasEagerState, + eagerState: update.eagerState, + next: null + }; + + if (newBaseQueueLast === null) { + newBaseQueueFirst = newBaseQueueLast = clone; + newBaseState = newState; + } else { + newBaseQueueLast = newBaseQueueLast.next = clone; + } // Update the remaining priority in the queue. + // TODO: Don't need to accumulate this. Instead, we can remove + // renderLanes from the original lanes. + + currentlyRenderingFiber$1.lanes = mergeLanes( + currentlyRenderingFiber$1.lanes, + updateLane + ); + markSkippedUpdateLanes(updateLane); + } else { + { + // This is not an optimistic update, and we're going to apply it now. + // But, if there were earlier updates that were skipped, we need to + // leave this update in the queue so it can be rebased later. + if (newBaseQueueLast !== null) { + var _clone = { + // This update is going to be committed so we never want uncommit + // it. Using NoLane works because 0 is a subset of all bitmasks, so + // this will never be skipped by the check above. + lane: NoLane, + revertLane: NoLane, + action: update.action, + hasEagerState: update.hasEagerState, + eagerState: update.eagerState, + next: null + }; + newBaseQueueLast = newBaseQueueLast.next = _clone; + } // Check if this update is part of a pending async action. If so, + // we'll need to suspend until the action has finished, so that it's + // batched together with future updates in the same action. + + if (updateLane === peekEntangledActionLane()) { + didReadFromEntangledAsyncAction = true; + } + } // Process this update. + + var action = update.action; + + if (shouldDoubleInvokeUserFnsInHooksDEV) { + reducer(newState, action); + } + + if (update.hasEagerState) { + // If this update is a state update (not a reducer) and was processed eagerly, + // we can use the eagerly computed state + newState = update.eagerState; + } else { + newState = reducer(newState, action); + } + } + + update = update.next; + } while (update !== null && update !== first); + + if (newBaseQueueLast === null) { + newBaseState = newState; + } else { + newBaseQueueLast.next = newBaseQueueFirst; + } // Mark that the fiber performed work, but only if the new state is + // different from the current state. + + if (!objectIs(newState, hook.memoizedState)) { + markWorkInProgressReceivedUpdate(); // Check if this update is part of a pending async action. If so, we'll + // need to suspend until the action has finished, so that it's batched + // together with future updates in the same action. + // TODO: Once we support hooks inside useMemo (or an equivalent + // memoization boundary like Forget), hoist this logic so that it only + // suspends if the memo boundary produces a new value. + + if (didReadFromEntangledAsyncAction) { + var entangledActionThenable = peekEntangledActionThenable(); + + if (entangledActionThenable !== null) { + // TODO: Instead of the throwing the thenable directly, throw a + // special object like `use` does so we can detect if it's captured + // by userspace. + throw entangledActionThenable; + } + } + } + + hook.memoizedState = newState; + hook.baseState = newBaseState; + hook.baseQueue = newBaseQueueLast; + queue.lastRenderedState = newState; + } + + 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; + return [hook.memoizedState, dispatch]; + } + + function rerenderReducer(reducer, initialArg, init) { + var hook = updateWorkInProgressHook(); + var queue = hook.queue; + + if (queue === null) { + throw new Error( + "Should have a queue. This is likely a bug in React. Please file an issue." + ); + } + + queue.lastRenderedReducer = reducer; // This is a re-render. Apply the new render phase updates to the previous + // work-in-progress hook. + + var dispatch = queue.dispatch; + var lastRenderPhaseUpdate = queue.pending; + var newState = hook.memoizedState; + + if (lastRenderPhaseUpdate !== null) { + // The queue doesn't persist past this render pass. + queue.pending = null; + var firstRenderPhaseUpdate = lastRenderPhaseUpdate.next; + var update = firstRenderPhaseUpdate; + + do { + // Process this render phase update. We don't have to check the + // priority because it will always be the same as the current + // render's. + var action = update.action; + newState = reducer(newState, action); + update = update.next; + } while (update !== firstRenderPhaseUpdate); // Mark that the fiber performed work, but only if the new state is + // different from the current state. + + if (!objectIs(newState, hook.memoizedState)) { + markWorkInProgressReceivedUpdate(); + } + + hook.memoizedState = newState; // Don't persist the state accumulated from the render phase updates to + // the base state unless the queue is empty. + // TODO: Not sure if this is the desired semantics, but it's what we + // do for gDSFP. I can't remember why. + + if (hook.baseQueue === null) { + hook.baseState = newState; + } + + queue.lastRenderedState = newState; + } + + return [newState, dispatch]; + } + + function mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) { + var fiber = currentlyRenderingFiber$1; + var hook = mountWorkInProgressHook(); + var nextSnapshot; + + { + nextSnapshot = getSnapshot(); + + { + if (!didWarnUncachedGetSnapshot) { + var cachedSnapshot = getSnapshot(); + + if (!objectIs(nextSnapshot, cachedSnapshot)) { + error( + "The result of getSnapshot should be cached to avoid an infinite loop" + ); + + didWarnUncachedGetSnapshot = true; + } + } + } // Unless we're rendering a blocking lane, schedule a consistency check. + // Right before committing, we will walk the tree and check if any of the + // stores were mutated. + // + // We won't do this if we're hydrating server-rendered content, because if + // the content is stale, it's already visible anyway. Instead we'll patch + // it up in a passive effect. + + var root = getWorkInProgressRoot(); + + if (root === null) { + throw new Error( + "Expected a work-in-progress root. This is a bug in React. Please file an issue." + ); + } + + var rootRenderLanes = getWorkInProgressRootRenderLanes(); + + if (!includesBlockingLane(root, rootRenderLanes)) { + pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot); + } + } // Read the current snapshot from the store on every render. This breaks the + // normal rules of React, and only works because store updates are + // always synchronous. + + hook.memoizedState = nextSnapshot; + var inst = { + value: nextSnapshot, + getSnapshot: getSnapshot + }; + hook.queue = inst; // Schedule an effect to subscribe to the store. + + mountEffect(subscribeToStore.bind(null, fiber, inst, subscribe), [ + subscribe + ]); // Schedule an effect to update the mutable instance fields. We will update + // this whenever subscribe, getSnapshot, or value changes. Because there's no + // clean-up function, and we track the deps correctly, we can call pushEffect + // directly, without storing any additional state. For the same reason, we + // don't need to set a static flag, either. + + fiber.flags |= Passive$1; + pushEffect( + HasEffect | Passive, + updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot), + createEffectInstance(), + null + ); + return nextSnapshot; + } + + function updateSyncExternalStore( + subscribe, + getSnapshot, + getServerSnapshot + ) { + var fiber = currentlyRenderingFiber$1; + var hook = updateWorkInProgressHook(); // Read the current snapshot from the store on every render. This breaks the + // normal rules of React, and only works because store updates are + // always synchronous. + + var nextSnapshot; + + { + nextSnapshot = getSnapshot(); + + { + if (!didWarnUncachedGetSnapshot) { + var cachedSnapshot = getSnapshot(); + + if (!objectIs(nextSnapshot, cachedSnapshot)) { + error( + "The result of getSnapshot should be cached to avoid an infinite loop" + ); + + didWarnUncachedGetSnapshot = true; + } + } + } + } + + var prevSnapshot = (currentHook || hook).memoizedState; + var snapshotChanged = !objectIs(prevSnapshot, nextSnapshot); + + if (snapshotChanged) { + hook.memoizedState = nextSnapshot; + markWorkInProgressReceivedUpdate(); + } + + var inst = hook.queue; + updateEffect(subscribeToStore.bind(null, fiber, inst, subscribe), [ + subscribe + ]); // Whenever getSnapshot or subscribe changes, we need to check in the + // commit phase if there was an interleaved mutation. In concurrent mode + // this can happen all the time, but even in synchronous mode, an earlier + // effect may have mutated the store. + + if ( + inst.getSnapshot !== getSnapshot || + snapshotChanged || // Check if the subscribe function changed. We can save some memory by + // checking whether we scheduled a subscription effect above. + (workInProgressHook !== null && + workInProgressHook.memoizedState.tag & HasEffect) + ) { + fiber.flags |= Passive$1; + pushEffect( + HasEffect | Passive, + updateStoreInstance.bind( + null, + fiber, + inst, + nextSnapshot, + getSnapshot + ), + createEffectInstance(), + null + ); // Unless we're rendering a blocking lane, schedule a consistency check. + // Right before committing, we will walk the tree and check if any of the + // stores were mutated. + + var root = getWorkInProgressRoot(); + + if (root === null) { + throw new Error( + "Expected a work-in-progress root. This is a bug in React. Please file an issue." + ); + } + + if (!includesBlockingLane(root, renderLanes)) { + pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot); + } + } + + return nextSnapshot; + } + + function pushStoreConsistencyCheck(fiber, getSnapshot, renderedSnapshot) { + fiber.flags |= StoreConsistency; + var check = { + getSnapshot: getSnapshot, + value: renderedSnapshot + }; + var componentUpdateQueue = currentlyRenderingFiber$1.updateQueue; + + if (componentUpdateQueue === null) { + componentUpdateQueue = createFunctionComponentUpdateQueue(); + currentlyRenderingFiber$1.updateQueue = componentUpdateQueue; + componentUpdateQueue.stores = [check]; + } else { + var stores = componentUpdateQueue.stores; + + if (stores === null) { + componentUpdateQueue.stores = [check]; + } else { + stores.push(check); + } + } + } + + function updateStoreInstance(fiber, inst, nextSnapshot, getSnapshot) { + // These are updated in the passive phase + inst.value = nextSnapshot; + inst.getSnapshot = getSnapshot; // Something may have been mutated in between render and commit. This could + // have been in an event that fired before the passive effects, or it could + // have been in a layout effect. In that case, we would have used the old + // snapsho and getSnapshot values to bail out. We need to check one more time. + + if (checkIfSnapshotChanged(inst)) { + // Force a re-render. + forceStoreRerender(fiber); + } + } + + function subscribeToStore(fiber, inst, subscribe) { + var handleStoreChange = function () { + // The store changed. Check if the snapshot changed since the last time we + // read from the store. + if (checkIfSnapshotChanged(inst)) { + // Force a re-render. + forceStoreRerender(fiber); + } + }; // Subscribe to the store and return a clean-up function. + + return subscribe(handleStoreChange); + } + + function checkIfSnapshotChanged(inst) { + var latestGetSnapshot = inst.getSnapshot; + var prevValue = inst.value; + + try { + var nextValue = latestGetSnapshot(); + return !objectIs(prevValue, nextValue); + } catch (error) { + return true; + } + } + + function forceStoreRerender(fiber) { + var root = enqueueConcurrentRenderForLane(fiber, SyncLane); + + if (root !== null) { + scheduleUpdateOnFiber(root, fiber, SyncLane); + } + } + + function mountStateImpl(initialState) { + var hook = mountWorkInProgressHook(); + + if (typeof initialState === "function") { + var initialStateInitializer = initialState; // $FlowFixMe[incompatible-use]: Flow doesn't like mixed types + + initialState = initialStateInitializer(); + + if (shouldDoubleInvokeUserFnsInHooksDEV) { + setIsStrictModeForDevtools(true); // $FlowFixMe[incompatible-use]: Flow doesn't like mixed types + + initialStateInitializer(); + setIsStrictModeForDevtools(false); + } + } + + hook.memoizedState = hook.baseState = initialState; + var queue = { + pending: null, + lanes: NoLanes, + dispatch: null, + lastRenderedReducer: basicStateReducer, + lastRenderedState: initialState + }; + hook.queue = queue; + return hook; + } + + function mountState(initialState) { + var hook = mountStateImpl(initialState); + var queue = hook.queue; + var dispatch = dispatchSetState.bind( + null, + currentlyRenderingFiber$1, + queue + ); + queue.dispatch = dispatch; + return [hook.memoizedState, dispatch]; + } + + function updateState(initialState) { + return updateReducer(basicStateReducer); + } + + function rerenderState(initialState) { + return rerenderReducer(basicStateReducer); + } + + function pushEffect(tag, create, inst, deps) { + var effect = { + tag: tag, + create: create, + inst: inst, + deps: deps, + // Circular + next: null + }; + var componentUpdateQueue = currentlyRenderingFiber$1.updateQueue; + + if (componentUpdateQueue === null) { + componentUpdateQueue = createFunctionComponentUpdateQueue(); + currentlyRenderingFiber$1.updateQueue = componentUpdateQueue; + componentUpdateQueue.lastEffect = effect.next = effect; + } else { + var lastEffect = componentUpdateQueue.lastEffect; + + if (lastEffect === null) { + componentUpdateQueue.lastEffect = effect.next = effect; + } else { + var firstEffect = lastEffect.next; + lastEffect.next = effect; + effect.next = firstEffect; + componentUpdateQueue.lastEffect = effect; + } + } + + return effect; + } + + function createEffectInstance() { + return { + destroy: undefined + }; + } + + function mountRef(initialValue) { + var hook = mountWorkInProgressHook(); + + { + var _ref2 = { + current: initialValue + }; + hook.memoizedState = _ref2; + return _ref2; + } + } + + function updateRef(initialValue) { + var hook = updateWorkInProgressHook(); + return hook.memoizedState; + } + + function mountEffectImpl(fiberFlags, hookFlags, create, deps) { + var hook = mountWorkInProgressHook(); + var nextDeps = deps === undefined ? null : deps; + currentlyRenderingFiber$1.flags |= fiberFlags; + hook.memoizedState = pushEffect( + HasEffect | hookFlags, + create, + createEffectInstance(), + nextDeps + ); + } + + function updateEffectImpl(fiberFlags, hookFlags, create, deps) { + var hook = updateWorkInProgressHook(); + var nextDeps = deps === undefined ? null : deps; + var effect = hook.memoizedState; + var inst = effect.inst; // currentHook is null on initial mount when rerendering after a render phase + // state update or for strict mode. + + if (currentHook !== null) { + if (nextDeps !== null) { + var prevEffect = currentHook.memoizedState; + var prevDeps = prevEffect.deps; + + if (areHookInputsEqual(nextDeps, prevDeps)) { + hook.memoizedState = pushEffect(hookFlags, create, inst, nextDeps); + return; + } + } + } + + currentlyRenderingFiber$1.flags |= fiberFlags; + hook.memoizedState = pushEffect( + HasEffect | hookFlags, + create, + inst, + nextDeps + ); + } + + function mountEffect(create, deps) { + if ( + (currentlyRenderingFiber$1.mode & StrictEffectsMode) !== NoMode && + (currentlyRenderingFiber$1.mode & NoStrictPassiveEffectsMode) === NoMode + ) { + mountEffectImpl( + MountPassiveDev | Passive$1 | PassiveStatic, + Passive, + create, + deps + ); + } else { + mountEffectImpl(Passive$1 | PassiveStatic, Passive, create, deps); + } + } + + function updateEffect(create, deps) { + updateEffectImpl(Passive$1, Passive, create, deps); + } + + function mountInsertionEffect(create, deps) { + mountEffectImpl(Update, Insertion, create, deps); + } + + function updateInsertionEffect(create, deps) { + return updateEffectImpl(Update, Insertion, create, deps); + } + + function mountLayoutEffect(create, deps) { + var fiberFlags = Update | LayoutStatic; + + if ((currentlyRenderingFiber$1.mode & StrictEffectsMode) !== NoMode) { + fiberFlags |= MountLayoutDev; + } + + return mountEffectImpl(fiberFlags, Layout, create, deps); + } + + function updateLayoutEffect(create, deps) { + return updateEffectImpl(Update, Layout, create, deps); + } + + function imperativeHandleEffect(create, ref) { + if (typeof ref === "function") { + var refCallback = ref; + var inst = create(); + refCallback(inst); + return function () { + refCallback(null); + }; + } else if (ref !== null && ref !== undefined) { + var refObject = ref; + + { + if (!refObject.hasOwnProperty("current")) { + error( + "Expected useImperativeHandle() first argument to either be a " + + "ref callback or React.createRef() object. Instead received: %s.", + "an object with keys {" + Object.keys(refObject).join(", ") + "}" + ); + } + } + + var _inst = create(); + + refObject.current = _inst; + return function () { + refObject.current = null; + }; + } + } + + function mountImperativeHandle(ref, create, deps) { + { + if (typeof create !== "function") { + error( + "Expected useImperativeHandle() second argument to be a function " + + "that creates a handle. Instead received: %s.", + create !== null ? typeof create : "null" + ); + } + } // TODO: If deps are provided, should we skip comparing the ref itself? + + var effectDeps = + deps !== null && deps !== undefined ? deps.concat([ref]) : null; + var fiberFlags = Update | LayoutStatic; + + if ((currentlyRenderingFiber$1.mode & StrictEffectsMode) !== NoMode) { + fiberFlags |= MountLayoutDev; + } + + mountEffectImpl( + fiberFlags, + Layout, + imperativeHandleEffect.bind(null, create, ref), + effectDeps + ); + } + + function updateImperativeHandle(ref, create, deps) { + { + if (typeof create !== "function") { + error( + "Expected useImperativeHandle() second argument to be a function " + + "that creates a handle. Instead received: %s.", + create !== null ? typeof create : "null" + ); + } + } // TODO: If deps are provided, should we skip comparing the ref itself? + + var effectDeps = + deps !== null && deps !== undefined ? deps.concat([ref]) : null; + updateEffectImpl( + Update, + Layout, + imperativeHandleEffect.bind(null, create, ref), + effectDeps + ); + } + + function mountDebugValue(value, formatterFn) { + // This hook is normally a no-op. + // The react-debug-hooks package injects its own implementation + // so that e.g. DevTools can display custom hook values. + } + + var updateDebugValue = mountDebugValue; + + function mountCallback(callback, deps) { + var hook = mountWorkInProgressHook(); + var nextDeps = deps === undefined ? null : deps; + hook.memoizedState = [callback, nextDeps]; + return callback; + } + + function updateCallback(callback, deps) { + var hook = updateWorkInProgressHook(); + var nextDeps = deps === undefined ? null : deps; + var prevState = hook.memoizedState; + + if (nextDeps !== null) { + var prevDeps = prevState[1]; + + if (areHookInputsEqual(nextDeps, prevDeps)) { + return prevState[0]; + } + } + + hook.memoizedState = [callback, nextDeps]; + return callback; + } + + function mountMemo(nextCreate, deps) { + var hook = mountWorkInProgressHook(); + var nextDeps = deps === undefined ? null : deps; + var nextValue = nextCreate(); + + if (shouldDoubleInvokeUserFnsInHooksDEV) { + setIsStrictModeForDevtools(true); + nextCreate(); + setIsStrictModeForDevtools(false); + } + + hook.memoizedState = [nextValue, nextDeps]; + return nextValue; + } + + function updateMemo(nextCreate, deps) { + var hook = updateWorkInProgressHook(); + var nextDeps = deps === undefined ? null : deps; + var prevState = hook.memoizedState; // Assume these are defined. If they're not, areHookInputsEqual will warn. + + if (nextDeps !== null) { + var prevDeps = prevState[1]; + + if (areHookInputsEqual(nextDeps, prevDeps)) { + return prevState[0]; + } + } + + var nextValue = nextCreate(); + + if (shouldDoubleInvokeUserFnsInHooksDEV) { + setIsStrictModeForDevtools(true); + nextCreate(); + setIsStrictModeForDevtools(false); + } + + hook.memoizedState = [nextValue, nextDeps]; + return nextValue; + } + + function mountDeferredValue(value, initialValue) { + var hook = mountWorkInProgressHook(); + return mountDeferredValueImpl(hook, value, initialValue); + } + + function updateDeferredValue(value, initialValue) { + var hook = updateWorkInProgressHook(); + var resolvedCurrentHook = currentHook; + var prevValue = resolvedCurrentHook.memoizedState; + return updateDeferredValueImpl(hook, prevValue, value, initialValue); + } + + function rerenderDeferredValue(value, initialValue) { + var hook = updateWorkInProgressHook(); + + if (currentHook === null) { + // This is a rerender during a mount. + return mountDeferredValueImpl(hook, value, initialValue); + } else { + // This is a rerender during an update. + var prevValue = currentHook.memoizedState; + return updateDeferredValueImpl(hook, prevValue, value, initialValue); + } + } + + function mountDeferredValueImpl(hook, value, initialValue) { + if ( + // When `initialValue` is provided, we defer the initial render even if the + // current render is not synchronous. + initialValue !== undefined && // However, to avoid waterfalls, we do not defer if this render + // was itself spawned by an earlier useDeferredValue. Check if DeferredLane + // is part of the render lanes. + !includesSomeLane(renderLanes, DeferredLane) + ) { + // Render with the initial value + hook.memoizedState = initialValue; // Schedule a deferred render to switch to the final value. + + var deferredLane = requestDeferredLane(); + currentlyRenderingFiber$1.lanes = mergeLanes( + currentlyRenderingFiber$1.lanes, + deferredLane + ); + markSkippedUpdateLanes(deferredLane); + return initialValue; + } else { + hook.memoizedState = value; + return value; + } + } + + function updateDeferredValueImpl(hook, prevValue, value, initialValue) { + if (objectIs(value, prevValue)) { + // The incoming value is referentially identical to the currently rendered + // value, so we can bail out quickly. + return value; + } else { + // Received a new value that's different from the current value. + // Check if we're inside a hidden tree + if (isCurrentTreeHidden()) { + // Revealing a prerendered tree is considered the same as mounting new + // one, so we reuse the "mount" path in this case. + var resultValue = mountDeferredValueImpl(hook, value, initialValue); // Unlike during an actual mount, we need to mark this as an update if + // the value changed. + + if (!objectIs(resultValue, prevValue)) { + markWorkInProgressReceivedUpdate(); + } + + return resultValue; + } + + var shouldDeferValue = !includesOnlyNonUrgentLanes(renderLanes); + + if (shouldDeferValue) { + // This is an urgent update. Since the value has changed, keep using the + // previous value and spawn a deferred render to update it later. + // Schedule a deferred render + var deferredLane = requestDeferredLane(); + currentlyRenderingFiber$1.lanes = mergeLanes( + currentlyRenderingFiber$1.lanes, + deferredLane + ); + markSkippedUpdateLanes(deferredLane); // Reuse the previous value. We do not need to mark this as an update, + // because we did not render a new value. + + return prevValue; + } else { + // This is not an urgent update, so we can use the latest value regardless + // of what it is. No need to defer it. + // Mark this as an update to prevent the fiber from bailing out. + markWorkInProgressReceivedUpdate(); + hook.memoizedState = value; + return value; + } + } + } + + function startTransition( + fiber, + queue, + pendingState, + finishedState, + callback, + options + ) { + var previousPriority = getCurrentUpdatePriority(); + setCurrentUpdatePriority( + higherEventPriority(previousPriority, ContinuousEventPriority) + ); + var prevTransition = ReactCurrentBatchConfig$2.transition; + var currentTransition = { + _callbacks: new Set() + }; + + { + ReactCurrentBatchConfig$2.transition = null; + dispatchSetState(fiber, queue, pendingState); + ReactCurrentBatchConfig$2.transition = currentTransition; + } + + { + ReactCurrentBatchConfig$2.transition._updatedFibers = new Set(); + } + + try { + var returnValue, thenable, thenableForFinishedState; + if (enableAsyncActions); + else { + // Async actions are not enabled. + dispatchSetState(fiber, queue, finishedState); + callback(); + } + } catch (error) { + { + // The error rethrowing behavior is only enabled when the async actions + // feature is on, even for sync actions. + throw error; + } + } finally { + setCurrentUpdatePriority(previousPriority); + ReactCurrentBatchConfig$2.transition = prevTransition; + + { + if (prevTransition === null && currentTransition._updatedFibers) { + var updatedFibersCount = currentTransition._updatedFibers.size; + + currentTransition._updatedFibers.clear(); + + if (updatedFibersCount > 10) { + warn( + "Detected a large number of updates inside startTransition. " + + "If this is due to a subscription please re-write it to use React provided hooks. " + + "Otherwise concurrent mode guarantees are off the table." + ); + } + } + } + } + } + + function mountTransition() { + var stateHook = mountStateImpl(false); // The `start` method never changes. + + var start = startTransition.bind( + null, + currentlyRenderingFiber$1, + stateHook.queue, + true, + false + ); + var hook = mountWorkInProgressHook(); + hook.memoizedState = start; + return [false, start]; + } + + function updateTransition() { + var _updateState2 = updateState(), + booleanOrThenable = _updateState2[0]; + + var hook = updateWorkInProgressHook(); + var start = hook.memoizedState; + var isPending = + typeof booleanOrThenable === "boolean" + ? booleanOrThenable // This will suspend until the async action scope has finished. + : useThenable(booleanOrThenable); + return [isPending, start]; + } + + function rerenderTransition() { + var _rerenderState = rerenderState(), + booleanOrThenable = _rerenderState[0]; + + var hook = updateWorkInProgressHook(); + var start = hook.memoizedState; + var isPending = + typeof booleanOrThenable === "boolean" + ? booleanOrThenable // This will suspend until the async action scope has finished. + : useThenable(booleanOrThenable); + return [isPending, start]; + } + + function mountId() { + var hook = mountWorkInProgressHook(); + var root = getWorkInProgressRoot(); // TODO: In Fizz, id generation is specific to each server config. Maybe we + // should do this in Fiber, too? Deferring this decision for now because + // there's no other place to store the prefix except for an internal field on + // the public createRoot object, which the fiber tree does not currently have + // a reference to. + + var identifierPrefix = root.identifierPrefix; + var id; + + { + // Use a lowercase r prefix for client-generated ids. + var globalClientId = globalClientIdCounter++; + id = ":" + identifierPrefix + "r" + globalClientId.toString(32) + ":"; + } + + hook.memoizedState = id; + return id; + } + + function updateId() { + var hook = updateWorkInProgressHook(); + var id = hook.memoizedState; + return id; + } + + function dispatchReducerAction(fiber, queue, action) { + { + if (typeof arguments[3] === "function") { + error( + "State updates from the useState() and useReducer() Hooks don't support the " + + "second callback argument. To execute a side effect after " + + "rendering, declare it in the component body with useEffect()." + ); + } + } + + var lane = requestUpdateLane(fiber); + var update = { + lane: lane, + revertLane: NoLane, + action: action, + hasEagerState: false, + eagerState: null, + next: null + }; + + if (isRenderPhaseUpdate(fiber)) { + enqueueRenderPhaseUpdate(queue, update); + } else { + var root = enqueueConcurrentHookUpdate(fiber, queue, update, lane); + + if (root !== null) { + scheduleUpdateOnFiber(root, fiber, lane); + entangleTransitionUpdate(root, queue, lane); + } + } + } + + function dispatchSetState(fiber, queue, action) { + { + if (typeof arguments[3] === "function") { + error( + "State updates from the useState() and useReducer() Hooks don't support the " + + "second callback argument. To execute a side effect after " + + "rendering, declare it in the component body with useEffect()." + ); + } + } + + var lane = requestUpdateLane(fiber); + var update = { + lane: lane, + revertLane: NoLane, + action: action, + hasEagerState: false, + eagerState: null, + next: null + }; + + if (isRenderPhaseUpdate(fiber)) { + enqueueRenderPhaseUpdate(queue, update); + } else { + var alternate = fiber.alternate; + + if ( + fiber.lanes === NoLanes && + (alternate === null || alternate.lanes === NoLanes) + ) { + // The queue is currently empty, which means we can eagerly compute the + // next state before entering the render phase. If the new state is the + // same as the current state, we may be able to bail out entirely. + var lastRenderedReducer = queue.lastRenderedReducer; + + if (lastRenderedReducer !== null) { + var prevDispatcher; + + { + prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = + InvalidNestedHooksDispatcherOnUpdateInDEV; + } + + try { + var currentState = queue.lastRenderedState; + var eagerState = lastRenderedReducer(currentState, action); // Stash the eagerly computed state, and the reducer used to compute + // it, on the update object. If the reducer hasn't changed by the + // time we enter the render phase, then the eager state can be used + // without calling the reducer again. + + update.hasEagerState = true; + update.eagerState = eagerState; + + if (objectIs(eagerState, currentState)) { + // Fast path. We can bail out without scheduling React to re-render. + // It's still possible that we'll need to rebase this update later, + // if the component re-renders for a different reason and by that + // time the reducer has changed. + // TODO: Do we still need to entangle transitions in this case? + enqueueConcurrentHookUpdateAndEagerlyBailout( + fiber, + queue, + update + ); + return; + } + } catch (error) { + // Suppress the error. It will throw again in the render phase. + } finally { + { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + } + } + } + + var root = enqueueConcurrentHookUpdate(fiber, queue, update, lane); + + if (root !== null) { + scheduleUpdateOnFiber(root, fiber, lane); + entangleTransitionUpdate(root, queue, lane); + } + } + } + + function isRenderPhaseUpdate(fiber) { + var alternate = fiber.alternate; + return ( + fiber === currentlyRenderingFiber$1 || + (alternate !== null && alternate === currentlyRenderingFiber$1) + ); + } + + function enqueueRenderPhaseUpdate(queue, update) { + // This is a render phase update. Stash it in a lazily-created map of + // 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; + } // TODO: Move to ReactFiberConcurrentUpdates? + + function entangleTransitionUpdate(root, queue, lane) { + if (isTransitionLane(lane)) { + 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); + } + } + + var ContextOnlyDispatcher = { + readContext: readContext, + use: use, + useCallback: throwInvalidHookError, + useContext: throwInvalidHookError, + useEffect: throwInvalidHookError, + useImperativeHandle: throwInvalidHookError, + useInsertionEffect: throwInvalidHookError, + useLayoutEffect: throwInvalidHookError, + useMemo: throwInvalidHookError, + useReducer: throwInvalidHookError, + useRef: throwInvalidHookError, + useState: throwInvalidHookError, + useDebugValue: throwInvalidHookError, + useDeferredValue: throwInvalidHookError, + useTransition: throwInvalidHookError, + useSyncExternalStore: throwInvalidHookError, + useId: throwInvalidHookError + }; + + var HooksDispatcherOnMountInDEV = null; + var HooksDispatcherOnMountWithHookTypesInDEV = null; + var HooksDispatcherOnUpdateInDEV = null; + var HooksDispatcherOnRerenderInDEV = null; + var InvalidNestedHooksDispatcherOnMountInDEV = null; + var InvalidNestedHooksDispatcherOnUpdateInDEV = null; + var InvalidNestedHooksDispatcherOnRerenderInDEV = null; + + { + var warnInvalidContextAccess = function () { + 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()." + ); + }; + + var warnInvalidHookAccess = function () { + error( + "Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. " + + "You can only call Hooks at the top level of your React function. " + + "For more information, see " + + "https://react.dev/link/rules-of-hooks" + ); + }; + + HooksDispatcherOnMountInDEV = { + readContext: function (context) { + return readContext(context); + }, + use: use, + useCallback: function (callback, deps) { + currentHookNameInDev = "useCallback"; + mountHookTypesDev(); + checkDepsAreArrayDev(deps); + return mountCallback(callback, deps); + }, + useContext: function (context) { + currentHookNameInDev = "useContext"; + mountHookTypesDev(); + return readContext(context); + }, + useEffect: function (create, deps) { + currentHookNameInDev = "useEffect"; + mountHookTypesDev(); + checkDepsAreArrayDev(deps); + return mountEffect(create, deps); + }, + useImperativeHandle: function (ref, create, deps) { + currentHookNameInDev = "useImperativeHandle"; + mountHookTypesDev(); + checkDepsAreArrayDev(deps); + return mountImperativeHandle(ref, create, deps); + }, + useInsertionEffect: function (create, deps) { + currentHookNameInDev = "useInsertionEffect"; + mountHookTypesDev(); + checkDepsAreArrayDev(deps); + return mountInsertionEffect(create, deps); + }, + useLayoutEffect: function (create, deps) { + currentHookNameInDev = "useLayoutEffect"; + mountHookTypesDev(); + checkDepsAreArrayDev(deps); + return mountLayoutEffect(create, deps); + }, + useMemo: function (create, deps) { + currentHookNameInDev = "useMemo"; + mountHookTypesDev(); + checkDepsAreArrayDev(deps); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = + InvalidNestedHooksDispatcherOnMountInDEV; + + try { + return mountMemo(create, deps); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useReducer: function (reducer, initialArg, init) { + currentHookNameInDev = "useReducer"; + mountHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = + InvalidNestedHooksDispatcherOnMountInDEV; + + try { + return mountReducer(reducer, initialArg, init); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useRef: function (initialValue) { + currentHookNameInDev = "useRef"; + mountHookTypesDev(); + return mountRef(initialValue); + }, + useState: function (initialState) { + currentHookNameInDev = "useState"; + mountHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = + InvalidNestedHooksDispatcherOnMountInDEV; + + try { + return mountState(initialState); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useDebugValue: function (value, formatterFn) { + currentHookNameInDev = "useDebugValue"; + mountHookTypesDev(); + return mountDebugValue(); + }, + useDeferredValue: function (value, initialValue) { + currentHookNameInDev = "useDeferredValue"; + mountHookTypesDev(); + return mountDeferredValue(value, initialValue); + }, + useTransition: function () { + currentHookNameInDev = "useTransition"; + mountHookTypesDev(); + return mountTransition(); + }, + useSyncExternalStore: function ( + subscribe, + getSnapshot, + getServerSnapshot + ) { + currentHookNameInDev = "useSyncExternalStore"; + mountHookTypesDev(); + return mountSyncExternalStore(subscribe, getSnapshot); + }, + useId: function () { + currentHookNameInDev = "useId"; + mountHookTypesDev(); + return mountId(); + } + }; + + HooksDispatcherOnMountWithHookTypesInDEV = { + readContext: function (context) { + return readContext(context); + }, + use: use, + useCallback: function (callback, deps) { + currentHookNameInDev = "useCallback"; + updateHookTypesDev(); + return mountCallback(callback, deps); + }, + useContext: function (context) { + currentHookNameInDev = "useContext"; + updateHookTypesDev(); + return readContext(context); + }, + useEffect: function (create, deps) { + currentHookNameInDev = "useEffect"; + updateHookTypesDev(); + return mountEffect(create, deps); + }, + useImperativeHandle: function (ref, create, deps) { + currentHookNameInDev = "useImperativeHandle"; + updateHookTypesDev(); + return mountImperativeHandle(ref, create, deps); + }, + useInsertionEffect: function (create, deps) { + currentHookNameInDev = "useInsertionEffect"; + updateHookTypesDev(); + return mountInsertionEffect(create, deps); + }, + useLayoutEffect: function (create, deps) { + currentHookNameInDev = "useLayoutEffect"; + updateHookTypesDev(); + return mountLayoutEffect(create, deps); + }, + useMemo: function (create, deps) { + currentHookNameInDev = "useMemo"; + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = + InvalidNestedHooksDispatcherOnMountInDEV; + + try { + return mountMemo(create, deps); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useReducer: function (reducer, initialArg, init) { + currentHookNameInDev = "useReducer"; + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = + InvalidNestedHooksDispatcherOnMountInDEV; + + try { + return mountReducer(reducer, initialArg, init); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useRef: function (initialValue) { + currentHookNameInDev = "useRef"; + updateHookTypesDev(); + return mountRef(initialValue); + }, + useState: function (initialState) { + currentHookNameInDev = "useState"; + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = + InvalidNestedHooksDispatcherOnMountInDEV; + + try { + return mountState(initialState); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useDebugValue: function (value, formatterFn) { + currentHookNameInDev = "useDebugValue"; + updateHookTypesDev(); + return mountDebugValue(); + }, + useDeferredValue: function (value, initialValue) { + currentHookNameInDev = "useDeferredValue"; + updateHookTypesDev(); + return mountDeferredValue(value, initialValue); + }, + useTransition: function () { + currentHookNameInDev = "useTransition"; + updateHookTypesDev(); + return mountTransition(); + }, + useSyncExternalStore: function ( + subscribe, + getSnapshot, + getServerSnapshot + ) { + currentHookNameInDev = "useSyncExternalStore"; + updateHookTypesDev(); + return mountSyncExternalStore(subscribe, getSnapshot); + }, + useId: function () { + currentHookNameInDev = "useId"; + updateHookTypesDev(); + return mountId(); + } + }; + + HooksDispatcherOnUpdateInDEV = { + readContext: function (context) { + return readContext(context); + }, + use: use, + useCallback: function (callback, deps) { + currentHookNameInDev = "useCallback"; + updateHookTypesDev(); + return updateCallback(callback, deps); + }, + useContext: function (context) { + currentHookNameInDev = "useContext"; + updateHookTypesDev(); + return readContext(context); + }, + useEffect: function (create, deps) { + currentHookNameInDev = "useEffect"; + updateHookTypesDev(); + return updateEffect(create, deps); + }, + useImperativeHandle: function (ref, create, deps) { + currentHookNameInDev = "useImperativeHandle"; + updateHookTypesDev(); + return updateImperativeHandle(ref, create, deps); + }, + useInsertionEffect: function (create, deps) { + currentHookNameInDev = "useInsertionEffect"; + updateHookTypesDev(); + return updateInsertionEffect(create, deps); + }, + useLayoutEffect: function (create, deps) { + currentHookNameInDev = "useLayoutEffect"; + updateHookTypesDev(); + return updateLayoutEffect(create, deps); + }, + useMemo: function (create, deps) { + currentHookNameInDev = "useMemo"; + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = + InvalidNestedHooksDispatcherOnUpdateInDEV; + + try { + return updateMemo(create, deps); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useReducer: function (reducer, initialArg, init) { + currentHookNameInDev = "useReducer"; + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = + InvalidNestedHooksDispatcherOnUpdateInDEV; + + try { + return updateReducer(reducer, initialArg, init); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useRef: function (initialValue) { + currentHookNameInDev = "useRef"; + updateHookTypesDev(); + return updateRef(); + }, + useState: function (initialState) { + currentHookNameInDev = "useState"; + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = + InvalidNestedHooksDispatcherOnUpdateInDEV; + + try { + return updateState(initialState); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useDebugValue: function (value, formatterFn) { + currentHookNameInDev = "useDebugValue"; + updateHookTypesDev(); + return updateDebugValue(); + }, + useDeferredValue: function (value, initialValue) { + currentHookNameInDev = "useDeferredValue"; + updateHookTypesDev(); + return updateDeferredValue(value, initialValue); + }, + useTransition: function () { + currentHookNameInDev = "useTransition"; + updateHookTypesDev(); + return updateTransition(); + }, + useSyncExternalStore: function ( + subscribe, + getSnapshot, + getServerSnapshot + ) { + currentHookNameInDev = "useSyncExternalStore"; + updateHookTypesDev(); + return updateSyncExternalStore(subscribe, getSnapshot); + }, + useId: function () { + currentHookNameInDev = "useId"; + updateHookTypesDev(); + return updateId(); + } + }; + + HooksDispatcherOnRerenderInDEV = { + readContext: function (context) { + return readContext(context); + }, + use: use, + useCallback: function (callback, deps) { + currentHookNameInDev = "useCallback"; + updateHookTypesDev(); + return updateCallback(callback, deps); + }, + useContext: function (context) { + currentHookNameInDev = "useContext"; + updateHookTypesDev(); + return readContext(context); + }, + useEffect: function (create, deps) { + currentHookNameInDev = "useEffect"; + updateHookTypesDev(); + return updateEffect(create, deps); + }, + useImperativeHandle: function (ref, create, deps) { + currentHookNameInDev = "useImperativeHandle"; + updateHookTypesDev(); + return updateImperativeHandle(ref, create, deps); + }, + useInsertionEffect: function (create, deps) { + currentHookNameInDev = "useInsertionEffect"; + updateHookTypesDev(); + return updateInsertionEffect(create, deps); + }, + useLayoutEffect: function (create, deps) { + currentHookNameInDev = "useLayoutEffect"; + updateHookTypesDev(); + return updateLayoutEffect(create, deps); + }, + useMemo: function (create, deps) { + currentHookNameInDev = "useMemo"; + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = + InvalidNestedHooksDispatcherOnRerenderInDEV; + + try { + return updateMemo(create, deps); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useReducer: function (reducer, initialArg, init) { + currentHookNameInDev = "useReducer"; + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = + InvalidNestedHooksDispatcherOnRerenderInDEV; + + try { + return rerenderReducer(reducer, initialArg, init); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useRef: function (initialValue) { + currentHookNameInDev = "useRef"; + updateHookTypesDev(); + return updateRef(); + }, + useState: function (initialState) { + currentHookNameInDev = "useState"; + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = + InvalidNestedHooksDispatcherOnRerenderInDEV; + + try { + return rerenderState(initialState); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useDebugValue: function (value, formatterFn) { + currentHookNameInDev = "useDebugValue"; + updateHookTypesDev(); + return updateDebugValue(); + }, + useDeferredValue: function (value, initialValue) { + currentHookNameInDev = "useDeferredValue"; + updateHookTypesDev(); + return rerenderDeferredValue(value, initialValue); + }, + useTransition: function () { + currentHookNameInDev = "useTransition"; + updateHookTypesDev(); + return rerenderTransition(); + }, + useSyncExternalStore: function ( + subscribe, + getSnapshot, + getServerSnapshot + ) { + currentHookNameInDev = "useSyncExternalStore"; + updateHookTypesDev(); + return updateSyncExternalStore(subscribe, getSnapshot); + }, + useId: function () { + currentHookNameInDev = "useId"; + updateHookTypesDev(); + return updateId(); + } + }; + + InvalidNestedHooksDispatcherOnMountInDEV = { + readContext: function (context) { + warnInvalidContextAccess(); + return readContext(context); + }, + use: function (usable) { + warnInvalidHookAccess(); + return use(usable); + }, + useCallback: function (callback, deps) { + currentHookNameInDev = "useCallback"; + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountCallback(callback, deps); + }, + useContext: function (context) { + currentHookNameInDev = "useContext"; + warnInvalidHookAccess(); + mountHookTypesDev(); + return readContext(context); + }, + useEffect: function (create, deps) { + currentHookNameInDev = "useEffect"; + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountEffect(create, deps); + }, + useImperativeHandle: function (ref, create, deps) { + currentHookNameInDev = "useImperativeHandle"; + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountImperativeHandle(ref, create, deps); + }, + useInsertionEffect: function (create, deps) { + currentHookNameInDev = "useInsertionEffect"; + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountInsertionEffect(create, deps); + }, + useLayoutEffect: function (create, deps) { + currentHookNameInDev = "useLayoutEffect"; + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountLayoutEffect(create, deps); + }, + useMemo: function (create, deps) { + currentHookNameInDev = "useMemo"; + warnInvalidHookAccess(); + mountHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = + InvalidNestedHooksDispatcherOnMountInDEV; + + try { + return mountMemo(create, deps); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useReducer: function (reducer, initialArg, init) { + currentHookNameInDev = "useReducer"; + warnInvalidHookAccess(); + mountHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = + InvalidNestedHooksDispatcherOnMountInDEV; + + try { + return mountReducer(reducer, initialArg, init); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useRef: function (initialValue) { + currentHookNameInDev = "useRef"; + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountRef(initialValue); + }, + useState: function (initialState) { + currentHookNameInDev = "useState"; + warnInvalidHookAccess(); + mountHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = + InvalidNestedHooksDispatcherOnMountInDEV; + + try { + return mountState(initialState); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useDebugValue: function (value, formatterFn) { + currentHookNameInDev = "useDebugValue"; + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountDebugValue(); + }, + useDeferredValue: function (value, initialValue) { + currentHookNameInDev = "useDeferredValue"; + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountDeferredValue(value, initialValue); + }, + useTransition: function () { + currentHookNameInDev = "useTransition"; + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountTransition(); + }, + useSyncExternalStore: function ( + subscribe, + getSnapshot, + getServerSnapshot + ) { + currentHookNameInDev = "useSyncExternalStore"; + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountSyncExternalStore(subscribe, getSnapshot); + }, + useId: function () { + currentHookNameInDev = "useId"; + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountId(); + } + }; + + InvalidNestedHooksDispatcherOnUpdateInDEV = { + readContext: function (context) { + warnInvalidContextAccess(); + return readContext(context); + }, + use: function (usable) { + warnInvalidHookAccess(); + return use(usable); + }, + useCallback: function (callback, deps) { + currentHookNameInDev = "useCallback"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateCallback(callback, deps); + }, + useContext: function (context) { + currentHookNameInDev = "useContext"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return readContext(context); + }, + useEffect: function (create, deps) { + currentHookNameInDev = "useEffect"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateEffect(create, deps); + }, + useImperativeHandle: function (ref, create, deps) { + currentHookNameInDev = "useImperativeHandle"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateImperativeHandle(ref, create, deps); + }, + useInsertionEffect: function (create, deps) { + currentHookNameInDev = "useInsertionEffect"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateInsertionEffect(create, deps); + }, + useLayoutEffect: function (create, deps) { + currentHookNameInDev = "useLayoutEffect"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateLayoutEffect(create, deps); + }, + useMemo: function (create, deps) { + currentHookNameInDev = "useMemo"; + warnInvalidHookAccess(); + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = + InvalidNestedHooksDispatcherOnUpdateInDEV; + + try { + return updateMemo(create, deps); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useReducer: function (reducer, initialArg, init) { + currentHookNameInDev = "useReducer"; + warnInvalidHookAccess(); + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = + InvalidNestedHooksDispatcherOnUpdateInDEV; + + try { + return updateReducer(reducer, initialArg, init); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useRef: function (initialValue) { + currentHookNameInDev = "useRef"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateRef(); + }, + useState: function (initialState) { + currentHookNameInDev = "useState"; + warnInvalidHookAccess(); + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = + InvalidNestedHooksDispatcherOnUpdateInDEV; + + try { + return updateState(initialState); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useDebugValue: function (value, formatterFn) { + currentHookNameInDev = "useDebugValue"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateDebugValue(); + }, + useDeferredValue: function (value, initialValue) { + currentHookNameInDev = "useDeferredValue"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateDeferredValue(value, initialValue); + }, + useTransition: function () { + currentHookNameInDev = "useTransition"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateTransition(); + }, + useSyncExternalStore: function ( + subscribe, + getSnapshot, + getServerSnapshot + ) { + currentHookNameInDev = "useSyncExternalStore"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateSyncExternalStore(subscribe, getSnapshot); + }, + useId: function () { + currentHookNameInDev = "useId"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateId(); + } + }; + + InvalidNestedHooksDispatcherOnRerenderInDEV = { + readContext: function (context) { + warnInvalidContextAccess(); + return readContext(context); + }, + use: function (usable) { + warnInvalidHookAccess(); + return use(usable); + }, + useCallback: function (callback, deps) { + currentHookNameInDev = "useCallback"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateCallback(callback, deps); + }, + useContext: function (context) { + currentHookNameInDev = "useContext"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return readContext(context); + }, + useEffect: function (create, deps) { + currentHookNameInDev = "useEffect"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateEffect(create, deps); + }, + useImperativeHandle: function (ref, create, deps) { + currentHookNameInDev = "useImperativeHandle"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateImperativeHandle(ref, create, deps); + }, + useInsertionEffect: function (create, deps) { + currentHookNameInDev = "useInsertionEffect"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateInsertionEffect(create, deps); + }, + useLayoutEffect: function (create, deps) { + currentHookNameInDev = "useLayoutEffect"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateLayoutEffect(create, deps); + }, + useMemo: function (create, deps) { + currentHookNameInDev = "useMemo"; + warnInvalidHookAccess(); + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = + InvalidNestedHooksDispatcherOnUpdateInDEV; + + try { + return updateMemo(create, deps); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useReducer: function (reducer, initialArg, init) { + currentHookNameInDev = "useReducer"; + warnInvalidHookAccess(); + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = + InvalidNestedHooksDispatcherOnUpdateInDEV; + + try { + return rerenderReducer(reducer, initialArg, init); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useRef: function (initialValue) { + currentHookNameInDev = "useRef"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateRef(); + }, + useState: function (initialState) { + currentHookNameInDev = "useState"; + warnInvalidHookAccess(); + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = + InvalidNestedHooksDispatcherOnUpdateInDEV; + + try { + return rerenderState(initialState); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useDebugValue: function (value, formatterFn) { + currentHookNameInDev = "useDebugValue"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateDebugValue(); + }, + useDeferredValue: function (value, initialValue) { + currentHookNameInDev = "useDeferredValue"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return rerenderDeferredValue(value, initialValue); + }, + useTransition: function () { + currentHookNameInDev = "useTransition"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return rerenderTransition(); + }, + useSyncExternalStore: function ( + subscribe, + getSnapshot, + getServerSnapshot + ) { + currentHookNameInDev = "useSyncExternalStore"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateSyncExternalStore(subscribe, getSnapshot); + }, + useId: function () { + currentHookNameInDev = "useId"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateId(); + } + }; + } + + var now = Scheduler.unstable_now; + var commitTime = 0; + var layoutEffectStartTime = -1; + var profilerStartTime = -1; + var passiveEffectStartTime = -1; + /** + * Tracks whether the current update was a nested/cascading update (scheduled from a layout effect). + * + * The overall sequence is: + * 1. render + * 2. commit (and call `onRender`, `onCommit`) + * 3. check for nested updates + * 4. flush passive effects (and call `onPostCommit`) + * + * Nested updates are identified in step 3 above, + * but step 4 still applies to the work that was just committed. + * We use two flags to track nested updates then: + * one tracks whether the upcoming update is a nested update, + * and the other tracks whether the current update was a nested update. + * The first value gets synced to the second at the start of the render phase. + */ + + var currentUpdateIsNested = false; + var nestedUpdateScheduled = false; + + function isCurrentUpdateNested() { + return currentUpdateIsNested; + } + + function markNestedUpdateScheduled() { + { + nestedUpdateScheduled = true; + } + } + + function resetNestedUpdateFlag() { + { + currentUpdateIsNested = false; + nestedUpdateScheduled = false; + } + } + + function syncNestedUpdateFlag() { + { + currentUpdateIsNested = nestedUpdateScheduled; + nestedUpdateScheduled = false; + } + } + + function getCommitTime() { + return commitTime; + } + + function recordCommitTime() { + commitTime = now(); + } + + function startProfilerTimer(fiber) { + profilerStartTime = now(); + + if (fiber.actualStartTime < 0) { + fiber.actualStartTime = now(); + } + } + + function stopProfilerTimerIfRunning(fiber) { + profilerStartTime = -1; + } + + function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) { + if (profilerStartTime >= 0) { + var elapsedTime = now() - profilerStartTime; + fiber.actualDuration += elapsedTime; + + if (overrideBaseTime) { + fiber.selfBaseDuration = elapsedTime; + } + + profilerStartTime = -1; + } + } + + function recordLayoutEffectDuration(fiber) { + if (layoutEffectStartTime >= 0) { + var elapsedTime = now() - layoutEffectStartTime; + layoutEffectStartTime = -1; // Store duration on the next nearest Profiler ancestor + // Or the root (for the DevTools Profiler to read) + + var parentFiber = fiber.return; + + while (parentFiber !== null) { + switch (parentFiber.tag) { + case HostRoot: + var root = parentFiber.stateNode; + root.effectDuration += elapsedTime; + return; + + case Profiler: + var parentStateNode = parentFiber.stateNode; + parentStateNode.effectDuration += elapsedTime; + return; + } + + parentFiber = parentFiber.return; + } + } + } + + function recordPassiveEffectDuration(fiber) { + if (passiveEffectStartTime >= 0) { + var elapsedTime = now() - passiveEffectStartTime; + passiveEffectStartTime = -1; // Store duration on the next nearest Profiler ancestor + // Or the root (for the DevTools Profiler to read) + + var parentFiber = fiber.return; + + while (parentFiber !== null) { + switch (parentFiber.tag) { + case HostRoot: + var root = parentFiber.stateNode; + + if (root !== null) { + root.passiveEffectDuration += elapsedTime; + } + + return; + + case Profiler: + var parentStateNode = parentFiber.stateNode; + + if (parentStateNode !== null) { + // Detached fibers have their state node cleared out. + // In this case, the return pointer is also cleared out, + // so we won't be able to report the time spent in this Profiler's subtree. + parentStateNode.passiveEffectDuration += elapsedTime; + } + + return; + } + + parentFiber = parentFiber.return; + } + } + } + + function startLayoutEffectTimer() { + layoutEffectStartTime = now(); + } + + function startPassiveEffectTimer() { + passiveEffectStartTime = now(); + } + + 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) { + // $FlowFixMe[unsafe-addition] addition with possible null/undefined value + fiber.actualDuration += child.actualDuration; + child = child.sibling; + } + } + + function resolveDefaultProps(Component, baseProps) { + if (Component && Component.defaultProps) { + // Resolve default props. Taken from ReactElement + var props = assign({}, baseProps); + var defaultProps = Component.defaultProps; + + for (var propName in defaultProps) { + if (props[propName] === undefined) { + props[propName] = defaultProps[propName]; + } + } + + return props; + } + + return baseProps; + } + + var fakeInternalInstance = {}; + var didWarnAboutStateAssignmentForComponent; + var didWarnAboutUninitializedState; + var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate; + var didWarnAboutLegacyLifecyclesAndDerivedState; + var didWarnAboutUndefinedDerivedState; + var didWarnAboutDirectlyAssigningPropsToState; + var didWarnAboutInvalidateContextType; + var didWarnOnInvalidCallback; + + { + didWarnAboutStateAssignmentForComponent = new Set(); + didWarnAboutUninitializedState = new Set(); + didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set(); + didWarnAboutLegacyLifecyclesAndDerivedState = new Set(); + didWarnAboutDirectlyAssigningPropsToState = new Set(); + didWarnAboutUndefinedDerivedState = new Set(); + didWarnAboutInvalidateContextType = new Set(); + didWarnOnInvalidCallback = new Set(); // This is so gross but it's at least non-critical and can be removed if + // it causes problems. This is meant to give a nicer error message for + // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component, + // ...)) which otherwise throws a "_processChildContext is not a function" + // exception. + + Object.defineProperty(fakeInternalInstance, "_processChildContext", { + enumerable: false, + value: function () { + throw new Error( + "_processChildContext is not available in React 16+. This likely " + + "means you have multiple copies of React and are attempting to nest " + + "a React 15 tree inside a React 16 tree using " + + "unstable_renderSubtreeIntoContainer, which isn't supported. Try " + + "to make sure you have only one copy of React (and ideally, switch " + + "to ReactDOM.createPortal)." + ); + } + }); + Object.freeze(fakeInternalInstance); + } + + function warnOnInvalidCallback(callback) { + { + if (callback === null || typeof callback === "function") { + return; + } // eslint-disable-next-line react-internal/safe-string-coercion + + var key = String(callback); + + if (!didWarnOnInvalidCallback.has(key)) { + didWarnOnInvalidCallback.add(key); + + error( + "Expected the last optional `callback` argument to be a " + + "function. Instead received: %s.", + callback + ); + } + } + } + + function warnOnUndefinedDerivedState(type, partialState) { + { + if (partialState === undefined) { + var componentName = getComponentNameFromType(type) || "Component"; + + if (!didWarnAboutUndefinedDerivedState.has(componentName)) { + didWarnAboutUndefinedDerivedState.add(componentName); + + error( + "%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. " + + "You have returned undefined.", + componentName + ); + } + } + } + } + + function applyDerivedStateFromProps( + workInProgress, + ctor, + getDerivedStateFromProps, + nextProps + ) { + var prevState = workInProgress.memoizedState; + var partialState = getDerivedStateFromProps(nextProps, prevState); + + { + if (workInProgress.mode & StrictLegacyMode) { + setIsStrictModeForDevtools(true); + + try { + // Invoke the function an extra time to help detect side-effects. + partialState = getDerivedStateFromProps(nextProps, prevState); + } finally { + setIsStrictModeForDevtools(false); + } + } + + warnOnUndefinedDerivedState(ctor, partialState); + } // Merge the partial state and the previous state. + + var memoizedState = + partialState === null || partialState === undefined + ? prevState + : assign({}, prevState, partialState); + workInProgress.memoizedState = memoizedState; // Once the update queue is empty, persist the derived state onto the + // base state. + + if (workInProgress.lanes === NoLanes) { + // Queue is always non-null for classes + var updateQueue = workInProgress.updateQueue; + updateQueue.baseState = memoizedState; + } + } + + var classComponentUpdater = { + isMounted: isMounted, + // $FlowFixMe[missing-local-annot] + enqueueSetState: function (inst, payload, callback) { + var fiber = get(inst); + var lane = requestUpdateLane(fiber); + var update = createUpdate(lane); + update.payload = payload; + + if (callback !== undefined && callback !== null) { + { + warnOnInvalidCallback(callback); + } + + update.callback = callback; + } + + var root = enqueueUpdate(fiber, update, lane); + + if (root !== null) { + scheduleUpdateOnFiber(root, fiber, lane); + entangleTransitions(root, fiber, lane); + } + }, + enqueueReplaceState: function (inst, payload, callback) { + var fiber = get(inst); + var lane = requestUpdateLane(fiber); + var update = createUpdate(lane); + update.tag = ReplaceState; + update.payload = payload; + + if (callback !== undefined && callback !== null) { + { + warnOnInvalidCallback(callback); + } + + update.callback = callback; + } + + var root = enqueueUpdate(fiber, update, lane); + + if (root !== null) { + scheduleUpdateOnFiber(root, fiber, lane); + entangleTransitions(root, fiber, lane); + } + }, + // $FlowFixMe[missing-local-annot] + enqueueForceUpdate: function (inst, callback) { + var fiber = get(inst); + var lane = requestUpdateLane(fiber); + var update = createUpdate(lane); + update.tag = ForceUpdate; + + if (callback !== undefined && callback !== null) { + { + warnOnInvalidCallback(callback); + } + + update.callback = callback; + } + + var root = enqueueUpdate(fiber, update, lane); + + if (root !== null) { + scheduleUpdateOnFiber(root, fiber, lane); + entangleTransitions(root, fiber, lane); + } + } + }; + + function checkShouldComponentUpdate( + workInProgress, + ctor, + oldProps, + newProps, + oldState, + newState, + nextContext + ) { + var instance = workInProgress.stateNode; + + if (typeof instance.shouldComponentUpdate === "function") { + var shouldUpdate = instance.shouldComponentUpdate( + newProps, + newState, + nextContext + ); + + { + if (workInProgress.mode & StrictLegacyMode) { + setIsStrictModeForDevtools(true); + + try { + // Invoke the function an extra time to help detect side-effects. + shouldUpdate = instance.shouldComponentUpdate( + newProps, + newState, + nextContext + ); + } finally { + setIsStrictModeForDevtools(false); + } + } + + if (shouldUpdate === undefined) { + error( + "%s.shouldComponentUpdate(): Returned undefined instead of a " + + "boolean value. Make sure to return true or false.", + getComponentNameFromType(ctor) || "Component" + ); + } + } + + return shouldUpdate; + } + + if (ctor.prototype && ctor.prototype.isPureReactComponent) { + return ( + !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState) + ); + } + + return true; + } + + function checkClassInstance(workInProgress, ctor, newProps) { + var instance = workInProgress.stateNode; + + { + var name = getComponentNameFromType(ctor) || "Component"; + var renderPresent = instance.render; + + if (!renderPresent) { + if (ctor.prototype && typeof ctor.prototype.render === "function") { + error( + "No `render` method found on the %s " + + "instance: did you accidentally return an object from the constructor?", + name + ); + } else { + error( + "No `render` method found on the %s " + + "instance: you may have forgotten to define `render`.", + name + ); + } + } + + if ( + instance.getInitialState && + !instance.getInitialState.isReactClassApproved && + !instance.state + ) { + error( + "getInitialState was defined on %s, a plain JavaScript class. " + + "This is only supported for classes created using React.createClass. " + + "Did you mean to define a state property instead?", + name + ); + } + + if ( + instance.getDefaultProps && + !instance.getDefaultProps.isReactClassApproved + ) { + error( + "getDefaultProps was defined on %s, a plain JavaScript class. " + + "This is only supported for classes created using React.createClass. " + + "Use a static property to define defaultProps instead.", + name + ); + } + + if (instance.propTypes) { + error( + "propTypes was defined as an instance property on %s. Use a static " + + "property to define propTypes instead.", + name + ); + } + + if (instance.contextType) { + error( + "contextType was defined as an instance property on %s. Use a static " + + "property to define contextType instead.", + name + ); + } + + { + if (ctor.childContextTypes) { + error( + "%s uses the legacy childContextTypes API which is no longer supported. " + + "Use React.createContext() instead.", + name + ); + } + + if (ctor.contextTypes) { + error( + "%s uses the legacy contextTypes API which is no longer supported. " + + "Use React.createContext() with static contextType instead.", + name + ); + } + } + + if (typeof instance.componentShouldUpdate === "function") { + error( + "%s has a method called " + + "componentShouldUpdate(). Did you mean shouldComponentUpdate()? " + + "The name is phrased as a question because the function is " + + "expected to return a value.", + name + ); + } + + if ( + ctor.prototype && + ctor.prototype.isPureReactComponent && + typeof instance.shouldComponentUpdate !== "undefined" + ) { + error( + "%s has a method called shouldComponentUpdate(). " + + "shouldComponentUpdate should not be used when extending React.PureComponent. " + + "Please extend React.Component if shouldComponentUpdate is used.", + getComponentNameFromType(ctor) || "A pure component" + ); + } + + if (typeof instance.componentDidUnmount === "function") { + error( + "%s has a method called " + + "componentDidUnmount(). But there is no such lifecycle method. " + + "Did you mean componentWillUnmount()?", + name + ); + } + + if (typeof instance.componentDidReceiveProps === "function") { + error( + "%s has a method called " + + "componentDidReceiveProps(). But there is no such lifecycle method. " + + "If you meant to update the state in response to changing props, " + + "use componentWillReceiveProps(). If you meant to fetch data or " + + "run side-effects or mutations after React has updated the UI, use componentDidUpdate().", + name + ); + } + + if (typeof instance.componentWillRecieveProps === "function") { + error( + "%s has a method called " + + "componentWillRecieveProps(). Did you mean componentWillReceiveProps()?", + name + ); + } + + if (typeof instance.UNSAFE_componentWillRecieveProps === "function") { + error( + "%s has a method called " + + "UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?", + name + ); + } + + var hasMutatedProps = instance.props !== newProps; + + if (instance.props !== undefined && hasMutatedProps) { + error( + "When calling super() in `%s`, make sure to pass " + + "up the same props that your component's constructor was passed.", + name + ); + } + + if (instance.defaultProps) { + error( + "Setting defaultProps as an instance property on %s is not supported and will be ignored." + + " Instead, define defaultProps as a static property on %s.", + name, + name + ); + } + + if ( + typeof instance.getSnapshotBeforeUpdate === "function" && + typeof instance.componentDidUpdate !== "function" && + !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor) + ) { + didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor); + + error( + "%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). " + + "This component defines getSnapshotBeforeUpdate() only.", + getComponentNameFromType(ctor) + ); + } + + if (typeof instance.getDerivedStateFromProps === "function") { + error( + "%s: getDerivedStateFromProps() is defined as an instance method " + + "and will be ignored. Instead, declare it as a static method.", + name + ); + } + + if (typeof instance.getDerivedStateFromError === "function") { + error( + "%s: getDerivedStateFromError() is defined as an instance method " + + "and will be ignored. Instead, declare it as a static method.", + name + ); + } + + if (typeof ctor.getSnapshotBeforeUpdate === "function") { + error( + "%s: getSnapshotBeforeUpdate() is defined as a static method " + + "and will be ignored. Instead, declare it as an instance method.", + name + ); + } + + var state = instance.state; + + if (state && (typeof state !== "object" || isArray(state))) { + error("%s.state: must be set to an object or null", name); + } + + if ( + typeof instance.getChildContext === "function" && + typeof ctor.childContextTypes !== "object" + ) { + error( + "%s.getChildContext(): childContextTypes must be defined in order to " + + "use getChildContext().", + name + ); + } + } + } + + function adoptClassInstance(workInProgress, instance) { + instance.updater = classComponentUpdater; + workInProgress.stateNode = instance; // The instance needs access to the fiber so that it can schedule updates + + set(instance, workInProgress); + + { + instance._reactInternalInstance = fakeInternalInstance; + } + } + + function constructClassInstance(workInProgress, ctor, props) { + var context = emptyContextObject; + var contextType = ctor.contextType; + + { + if ("contextType" in ctor) { + var isValid = // Allow null for conditional declaration + contextType === null || + (contextType !== undefined && + contextType.$$typeof === REACT_CONTEXT_TYPE); + + if (!isValid && !didWarnAboutInvalidateContextType.has(ctor)) { + didWarnAboutInvalidateContextType.add(ctor); + var addendum = ""; + + if (contextType === undefined) { + addendum = + " However, it is set to undefined. " + + "This can be caused by a typo or by mixing up named and default imports. " + + "This can also happen due to a circular dependency, so " + + "try moving the createContext() call to a separate file."; + } else if (typeof contextType !== "object") { + addendum = " However, it is set to a " + typeof contextType + "."; + } else if (contextType.$$typeof === REACT_CONSUMER_TYPE) { + addendum = + " Did you accidentally pass the Context.Consumer instead?"; + } else { + addendum = + " However, it is set to an object with keys {" + + Object.keys(contextType).join(", ") + + "}."; + } + + error( + "%s defines an invalid contextType. " + + "contextType should point to the Context object returned by React.createContext().%s", + getComponentNameFromType(ctor) || "Component", + addendum + ); + } + } + } + + if (typeof contextType === "object" && contextType !== null) { + context = readContext(contextType); + } + + var instance = new ctor(props, context); // Instantiate twice to help detect side-effects. + + { + if (workInProgress.mode & StrictLegacyMode) { + setIsStrictModeForDevtools(true); + + try { + instance = new ctor(props, context); // eslint-disable-line no-new + } finally { + setIsStrictModeForDevtools(false); + } + } + } + + var state = (workInProgress.memoizedState = + instance.state !== null && instance.state !== undefined + ? instance.state + : null); + adoptClassInstance(workInProgress, instance); + + { + if ( + typeof ctor.getDerivedStateFromProps === "function" && + state === null + ) { + var componentName = getComponentNameFromType(ctor) || "Component"; + + if (!didWarnAboutUninitializedState.has(componentName)) { + didWarnAboutUninitializedState.add(componentName); + + error( + "`%s` uses `getDerivedStateFromProps` but its initial state is " + + "%s. This is not recommended. Instead, define the initial state by " + + "assigning an object to `this.state` in the constructor of `%s`. " + + "This ensures that `getDerivedStateFromProps` arguments have a consistent shape.", + componentName, + instance.state === null ? "null" : "undefined", + componentName + ); + } + } // If new component APIs are defined, "unsafe" lifecycles won't be called. + // Warn about these lifecycles if they are present. + // Don't warn about react-lifecycles-compat polyfilled methods though. + + if ( + typeof ctor.getDerivedStateFromProps === "function" || + typeof instance.getSnapshotBeforeUpdate === "function" + ) { + var foundWillMountName = null; + var foundWillReceivePropsName = null; + var foundWillUpdateName = null; + + if ( + typeof instance.componentWillMount === "function" && + instance.componentWillMount.__suppressDeprecationWarning !== true + ) { + foundWillMountName = "componentWillMount"; + } else if (typeof instance.UNSAFE_componentWillMount === "function") { + foundWillMountName = "UNSAFE_componentWillMount"; + } + + if ( + typeof instance.componentWillReceiveProps === "function" && + instance.componentWillReceiveProps.__suppressDeprecationWarning !== + true + ) { + foundWillReceivePropsName = "componentWillReceiveProps"; + } else if ( + typeof instance.UNSAFE_componentWillReceiveProps === "function" + ) { + foundWillReceivePropsName = "UNSAFE_componentWillReceiveProps"; + } + + if ( + typeof instance.componentWillUpdate === "function" && + instance.componentWillUpdate.__suppressDeprecationWarning !== true + ) { + foundWillUpdateName = "componentWillUpdate"; + } else if ( + typeof instance.UNSAFE_componentWillUpdate === "function" + ) { + foundWillUpdateName = "UNSAFE_componentWillUpdate"; + } + + if ( + foundWillMountName !== null || + foundWillReceivePropsName !== null || + foundWillUpdateName !== null + ) { + var _componentName = getComponentNameFromType(ctor) || "Component"; + + var newApiName = + typeof ctor.getDerivedStateFromProps === "function" + ? "getDerivedStateFromProps()" + : "getSnapshotBeforeUpdate()"; + + if ( + !didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName) + ) { + didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName); + + error( + "Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n" + + "%s uses %s but also contains the following legacy lifecycles:%s%s%s\n\n" + + "The above lifecycles should be removed. Learn more about this warning here:\n" + + "https://react.dev/link/unsafe-component-lifecycles", + _componentName, + newApiName, + foundWillMountName !== null ? "\n " + foundWillMountName : "", + foundWillReceivePropsName !== null + ? "\n " + foundWillReceivePropsName + : "", + foundWillUpdateName !== null ? "\n " + foundWillUpdateName : "" + ); + } + } + } + } // Cache unmasked context so we can avoid recreating masked context unless necessary. + + return instance; + } + + function callComponentWillMount(workInProgress, instance) { + var oldState = instance.state; + + if (typeof instance.componentWillMount === "function") { + instance.componentWillMount(); + } + + if (typeof instance.UNSAFE_componentWillMount === "function") { + instance.UNSAFE_componentWillMount(); + } + + if (oldState !== instance.state) { + { + error( + "%s.componentWillMount(): Assigning directly to this.state is " + + "deprecated (except inside a component's " + + "constructor). Use setState instead.", + getComponentNameFromFiber(workInProgress) || "Component" + ); + } + + classComponentUpdater.enqueueReplaceState( + instance, + instance.state, + null + ); + } + } + + function callComponentWillReceiveProps( + workInProgress, + instance, + newProps, + nextContext + ) { + var oldState = instance.state; + + if (typeof instance.componentWillReceiveProps === "function") { + instance.componentWillReceiveProps(newProps, nextContext); + } + + if (typeof instance.UNSAFE_componentWillReceiveProps === "function") { + instance.UNSAFE_componentWillReceiveProps(newProps, nextContext); + } + + if (instance.state !== oldState) { + { + var componentName = + getComponentNameFromFiber(workInProgress) || "Component"; + + if (!didWarnAboutStateAssignmentForComponent.has(componentName)) { + didWarnAboutStateAssignmentForComponent.add(componentName); + + error( + "%s.componentWillReceiveProps(): Assigning directly to " + + "this.state is deprecated (except inside a component's " + + "constructor). Use setState instead.", + componentName + ); + } + } + + classComponentUpdater.enqueueReplaceState( + instance, + instance.state, + null + ); + } + } // Invokes the mount life-cycles on a previously never rendered instance. + + function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { + { + checkClassInstance(workInProgress, ctor, newProps); + } + + var instance = workInProgress.stateNode; + instance.props = newProps; + instance.state = workInProgress.memoizedState; + instance.refs = {}; + initializeUpdateQueue(workInProgress); + var contextType = ctor.contextType; + + if (typeof contextType === "object" && contextType !== null) { + instance.context = readContext(contextType); + } else { + instance.context = emptyContextObject; + } + + { + if (instance.state === newProps) { + var componentName = getComponentNameFromType(ctor) || "Component"; + + if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) { + didWarnAboutDirectlyAssigningPropsToState.add(componentName); + + error( + "%s: It is not recommended to assign props directly to state " + + "because updates to props won't be reflected in state. " + + "In most cases, it is better to use props directly.", + componentName + ); + } + } + + if (workInProgress.mode & StrictLegacyMode) { + ReactStrictModeWarnings.recordLegacyContextWarning( + workInProgress, + instance + ); + } + + ReactStrictModeWarnings.recordUnsafeLifecycleWarnings( + workInProgress, + instance + ); + } + + instance.state = workInProgress.memoizedState; + var getDerivedStateFromProps = ctor.getDerivedStateFromProps; + + if (typeof getDerivedStateFromProps === "function") { + applyDerivedStateFromProps( + workInProgress, + ctor, + getDerivedStateFromProps, + newProps + ); + instance.state = workInProgress.memoizedState; + } // In order to support react-lifecycles-compat polyfilled components, + // Unsafe lifecycles should not be invoked for components using the new APIs. + + if ( + typeof ctor.getDerivedStateFromProps !== "function" && + typeof instance.getSnapshotBeforeUpdate !== "function" && + (typeof instance.UNSAFE_componentWillMount === "function" || + typeof instance.componentWillMount === "function") + ) { + callComponentWillMount(workInProgress, instance); // If we had additional state updates during this life-cycle, let's + // process them now. + + processUpdateQueue(workInProgress, newProps, instance, renderLanes); + suspendIfUpdateReadFromEntangledAsyncAction(); + instance.state = workInProgress.memoizedState; + } + + if (typeof instance.componentDidMount === "function") { + workInProgress.flags |= Update | LayoutStatic; + } + + if ((workInProgress.mode & StrictEffectsMode) !== NoMode) { + workInProgress.flags |= MountLayoutDev; + } + } + + function resumeMountClassInstance( + workInProgress, + ctor, + newProps, + renderLanes + ) { + var instance = workInProgress.stateNode; + var oldProps = workInProgress.memoizedProps; + instance.props = oldProps; + var oldContext = instance.context; + var contextType = ctor.contextType; + var nextContext = emptyContextObject; + + if (typeof contextType === "object" && contextType !== null) { + nextContext = readContext(contextType); + } + + var getDerivedStateFromProps = ctor.getDerivedStateFromProps; + var hasNewLifecycles = + typeof getDerivedStateFromProps === "function" || + typeof instance.getSnapshotBeforeUpdate === "function"; // Note: During these life-cycles, instance.props/instance.state are what + // ever the previously attempted to render - not the "current". However, + // during componentDidUpdate we pass the "current" props. + // In order to support react-lifecycles-compat polyfilled components, + // Unsafe lifecycles should not be invoked for components using the new APIs. + + if ( + !hasNewLifecycles && + (typeof instance.UNSAFE_componentWillReceiveProps === "function" || + typeof instance.componentWillReceiveProps === "function") + ) { + if (oldProps !== newProps || oldContext !== nextContext) { + callComponentWillReceiveProps( + workInProgress, + instance, + newProps, + nextContext + ); + } + } + + resetHasForceUpdateBeforeProcessing(); + var oldState = workInProgress.memoizedState; + var newState = (instance.state = oldState); + processUpdateQueue(workInProgress, newProps, instance, renderLanes); + suspendIfUpdateReadFromEntangledAsyncAction(); + newState = workInProgress.memoizedState; + + if ( + oldProps === newProps && + oldState === newState && + !hasContextChanged() && + !checkHasForceUpdateAfterProcessing() + ) { + // 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 | LayoutStatic; + } + + if ((workInProgress.mode & StrictEffectsMode) !== NoMode) { + workInProgress.flags |= MountLayoutDev; + } + + return false; + } + + if (typeof getDerivedStateFromProps === "function") { + applyDerivedStateFromProps( + workInProgress, + ctor, + getDerivedStateFromProps, + newProps + ); + newState = workInProgress.memoizedState; + } + + var shouldUpdate = + checkHasForceUpdateAfterProcessing() || + checkShouldComponentUpdate( + workInProgress, + ctor, + oldProps, + newProps, + oldState, + newState, + nextContext + ); + + if (shouldUpdate) { + // In order to support react-lifecycles-compat polyfilled components, + // Unsafe lifecycles should not be invoked for components using the new APIs. + if ( + !hasNewLifecycles && + (typeof instance.UNSAFE_componentWillMount === "function" || + typeof instance.componentWillMount === "function") + ) { + if (typeof instance.componentWillMount === "function") { + instance.componentWillMount(); + } + + if (typeof instance.UNSAFE_componentWillMount === "function") { + instance.UNSAFE_componentWillMount(); + } + } + + if (typeof instance.componentDidMount === "function") { + workInProgress.flags |= Update | LayoutStatic; + } + + if ((workInProgress.mode & StrictEffectsMode) !== NoMode) { + workInProgress.flags |= MountLayoutDev; + } + } 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 | LayoutStatic; + } + + if ((workInProgress.mode & StrictEffectsMode) !== NoMode) { + workInProgress.flags |= MountLayoutDev; + } // If shouldComponentUpdate returned false, we should still update the + // memoized state to indicate that this work can be reused. + + workInProgress.memoizedProps = newProps; + workInProgress.memoizedState = newState; + } // Update the existing instance's state, props, and context pointers even + // if shouldComponentUpdate returns false. + + instance.props = newProps; + instance.state = newState; + instance.context = nextContext; + return shouldUpdate; + } // Invokes the update life-cycles and returns false if it shouldn't rerender. + + function updateClassInstance( + current, + workInProgress, + ctor, + newProps, + renderLanes + ) { + var instance = workInProgress.stateNode; + cloneUpdateQueue(current, workInProgress); + var unresolvedOldProps = workInProgress.memoizedProps; + var oldProps = + workInProgress.type === workInProgress.elementType + ? unresolvedOldProps + : resolveDefaultProps(workInProgress.type, unresolvedOldProps); + instance.props = oldProps; + var unresolvedNewProps = workInProgress.pendingProps; + var oldContext = instance.context; + var contextType = ctor.contextType; + var nextContext = emptyContextObject; + + if (typeof contextType === "object" && contextType !== null) { + nextContext = readContext(contextType); + } + + var getDerivedStateFromProps = ctor.getDerivedStateFromProps; + var hasNewLifecycles = + typeof getDerivedStateFromProps === "function" || + typeof instance.getSnapshotBeforeUpdate === "function"; // Note: During these life-cycles, instance.props/instance.state are what + // ever the previously attempted to render - not the "current". However, + // during componentDidUpdate we pass the "current" props. + // In order to support react-lifecycles-compat polyfilled components, + // Unsafe lifecycles should not be invoked for components using the new APIs. + + if ( + !hasNewLifecycles && + (typeof instance.UNSAFE_componentWillReceiveProps === "function" || + typeof instance.componentWillReceiveProps === "function") + ) { + if ( + unresolvedOldProps !== unresolvedNewProps || + oldContext !== nextContext + ) { + callComponentWillReceiveProps( + workInProgress, + instance, + newProps, + nextContext + ); + } + } + + resetHasForceUpdateBeforeProcessing(); + var oldState = workInProgress.memoizedState; + var newState = (instance.state = oldState); + processUpdateQueue(workInProgress, newProps, instance, renderLanes); + suspendIfUpdateReadFromEntangledAsyncAction(); + newState = workInProgress.memoizedState; + + if ( + unresolvedOldProps === unresolvedNewProps && + oldState === newState && + !hasContextChanged() && + !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. + if (typeof instance.componentDidUpdate === "function") { + if ( + unresolvedOldProps !== current.memoizedProps || + oldState !== current.memoizedState + ) { + workInProgress.flags |= Update; + } + } + + if (typeof instance.getSnapshotBeforeUpdate === "function") { + if ( + unresolvedOldProps !== current.memoizedProps || + oldState !== current.memoizedState + ) { + workInProgress.flags |= Snapshot; + } + } + + return false; + } + + if (typeof getDerivedStateFromProps === "function") { + applyDerivedStateFromProps( + workInProgress, + ctor, + getDerivedStateFromProps, + newProps + ); + newState = workInProgress.memoizedState; + } + + var shouldUpdate = + checkHasForceUpdateAfterProcessing() || + checkShouldComponentUpdate( + workInProgress, + ctor, + oldProps, + newProps, + 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, + // Unsafe lifecycles should not be invoked for components using the new APIs. + if ( + !hasNewLifecycles && + (typeof instance.UNSAFE_componentWillUpdate === "function" || + typeof instance.componentWillUpdate === "function") + ) { + if (typeof instance.componentWillUpdate === "function") { + instance.componentWillUpdate(newProps, newState, nextContext); + } + + if (typeof instance.UNSAFE_componentWillUpdate === "function") { + instance.UNSAFE_componentWillUpdate( + newProps, + newState, + nextContext + ); + } + } + + if (typeof instance.componentDidUpdate === "function") { + workInProgress.flags |= Update; + } + + if (typeof instance.getSnapshotBeforeUpdate === "function") { + workInProgress.flags |= Snapshot; + } + } 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.componentDidUpdate === "function") { + if ( + unresolvedOldProps !== current.memoizedProps || + oldState !== current.memoizedState + ) { + workInProgress.flags |= Update; + } + } + + if (typeof instance.getSnapshotBeforeUpdate === "function") { + if ( + unresolvedOldProps !== current.memoizedProps || + oldState !== current.memoizedState + ) { + workInProgress.flags |= Snapshot; + } + } // If shouldComponentUpdate returned false, we should still update the + // memoized props/state to indicate that this work can be reused. + + workInProgress.memoizedProps = newProps; + workInProgress.memoizedState = newState; + } // Update the existing instance's state, props, and context pointers even + // if shouldComponentUpdate returns false. + + instance.props = newProps; + instance.state = newState; + instance.context = nextContext; + return shouldUpdate; + } + + var CapturedStacks = new WeakMap(); + function createCapturedValueAtFiber(value, source) { + // If the value is an error, call this function immediately after it is thrown + // so the stack is accurate. + var stack; + + if (typeof value === "object" && value !== null) { + var capturedStack = CapturedStacks.get(value); + + if (typeof capturedStack === "string") { + stack = capturedStack; + } else { + stack = getStackByFiberInDevAndProd(source); + CapturedStacks.set(value, stack); + } + } else { + stack = getStackByFiberInDevAndProd(source); + } + + return { + value: value, + source: source, + stack: stack, + digest: null + }; + } + function createCapturedValueFromError(value, digest, stack) { + if (typeof stack === "string") { + CapturedStacks.set(value, stack); + } + + return { + value: value, + source: null, + stack: stack != null ? stack : null, + digest: digest != null ? digest : null + }; + } + + if ( + typeof ReactNativePrivateInterface.ReactFiberErrorDialog + .showErrorDialog !== "function" + ) { + throw new Error( + "Expected ReactFiberErrorDialog.showErrorDialog to be a function." + ); + } + + 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 + ); + } + + 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 (logError === false) { + return; + } + + var error = errorInfo.value; + + if (true) { + var source = errorInfo.source; + var stack = errorInfo.stack; + var componentStack = stack !== null ? stack : ""; // TODO: There's no longer a way to silence these warnings e.g. for tests. + // See https://github.com/facebook/react/pull/13384 + + 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://react.dev/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 + + "."); + } // In development, we provide our own message which includes the component stack + // in addition to the error. + + console["error"]( + // Don't transform to our wrapper + "%o\n\n%s\n%s\n\n%s", + error, + componentNameMessage, + componentStack, + errorBoundaryMessage + ); + } + } 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; + }); + } + } + + function createRootErrorUpdate(fiber, errorInfo, lane) { + var update = createUpdate(lane); // Unmount the root by rendering null. + + update.tag = CaptureUpdate; // Caution: React DevTools currently depends on this property + // being called "element". + + update.payload = { + element: null + }; + var error = errorInfo.value; + + update.callback = function () { + onUncaughtError(error); + logCapturedError(fiber, errorInfo); + }; + + return update; + } + + function createClassErrorUpdate(fiber, errorInfo, lane) { + var update = createUpdate(lane); + update.tag = CaptureUpdate; + var getDerivedStateFromError = fiber.type.getDerivedStateFromError; + + if (typeof getDerivedStateFromError === "function") { + var error$1 = errorInfo.value; + + update.payload = function () { + return getDerivedStateFromError(error$1); + }; + + update.callback = function () { + { + markFailedErrorBoundaryForHotReloading(fiber); + } + + logCapturedError(fiber, errorInfo); + }; + } + + var inst = fiber.stateNode; + + if (inst !== null && typeof inst.componentDidCatch === "function") { + // $FlowFixMe[missing-this-annot] + update.callback = function callback() { + { + markFailedErrorBoundaryForHotReloading(fiber); + } + + logCapturedError(fiber, errorInfo); + + 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); + } + + var error$1 = errorInfo.value; + var stack = errorInfo.stack; + this.componentDidCatch(error$1, { + componentStack: stack !== null ? stack : "" + }); + + { + 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" + ); + } + } + } + }; + } + + return update; + } + + function resetSuspendedComponent(sourceFiber, rootRenderLanes) { + // A legacy mode Suspense quirk, only relevant to hook components. + + var tag = sourceFiber.tag; + + if ( + (sourceFiber.mode & ConcurrentMode) === NoMode && + (tag === FunctionComponent || + tag === ForwardRef || + tag === SimpleMemoComponent) + ) { + var currentSource = sourceFiber.alternate; + + if (currentSource) { + sourceFiber.updateQueue = currentSource.updateQueue; + sourceFiber.memoizedState = currentSource.memoizedState; + sourceFiber.lanes = currentSource.lanes; + } else { + sourceFiber.updateQueue = null; + sourceFiber.memoizedState = null; + } + } + } + + function markSuspenseBoundaryShouldCapture( + suspenseBoundary, + returnFiber, + sourceFiber, + root, + rootRenderLanes + ) { + // This marks a Suspense boundary so that when we're unwinding the stack, + // it captures the suspended "exception" and does a second (fallback) pass. + if ((suspenseBoundary.mode & ConcurrentMode) === NoMode) { + // Legacy Mode Suspense + // + // If the boundary is in legacy mode, we should *not* + // suspend the commit. Pretend as if the suspended component rendered + // null and keep rendering. When the Suspense boundary completes, + // we'll do a second pass to render the fallback. + if (suspenseBoundary === returnFiber) { + // Special case where we suspended while reconciling the children of + // a Suspense boundary's inner Offscreen wrapper fiber. This happens + // when a React.lazy component is a direct child of a + // Suspense boundary. + // + // Suspense boundaries are implemented as multiple fibers, but they + // are a single conceptual unit. The legacy mode behavior where we + // pretend the suspended fiber committed as `null` won't work, + // because in this case the "suspended" fiber is the inner + // Offscreen wrapper. + // + // Because the contents of the boundary haven't started rendering + // yet (i.e. nothing in the tree has partially rendered) we can + // switch to the regular, concurrent mode behavior: mark the + // boundary with ShouldCapture and enter the unwind phase. + suspenseBoundary.flags |= ShouldCapture; + } else { + suspenseBoundary.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. + + sourceFiber.flags &= ~(LifecycleEffectMask | Incomplete); + + 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(SyncLane); + update.tag = ForceUpdate; + enqueueUpdate(sourceFiber, update, SyncLane); + } + } // 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); + } + + return suspenseBoundary; + } // 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. + + suspenseBoundary.flags |= ShouldCapture; // TODO: I think we can remove this, since we now use `DidCapture` in + // the begin phase to prevent an early bailout. + + suspenseBoundary.lanes = rootRenderLanes; + return suspenseBoundary; + } + + function throwException( + root, + returnFiber, + sourceFiber, + value, + rootRenderLanes + ) { + // The source fiber did not complete. + sourceFiber.flags |= Incomplete; + + { + if (isDevToolsPresent) { + // If we have pending work still, restore the original updaters + restorePendingUpdaters(root, rootRenderLanes); + } + } + + if (value !== null && typeof value === "object") { + if (typeof value.then === "function") { + // This is a wakeable. The component suspended. + var wakeable = value; + resetSuspendedComponent(sourceFiber); + + var suspenseBoundary = getSuspenseHandler(); + + if (suspenseBoundary !== null) { + switch (suspenseBoundary.tag) { + case SuspenseComponent: { + // If this suspense boundary is not already showing a fallback, mark + // the in-progress render as suspended. We try to perform this logic + // as soon as soon as possible during the render phase, so the work + // loop can know things like whether it's OK to switch to other tasks, + // or whether it can wait for data to resolve before continuing. + // TODO: Most of these checks are already performed when entering a + // Suspense boundary. We should track the information on the stack so + // we don't have to recompute it on demand. This would also allow us + // to unify with `use` which needs to perform this logic even sooner, + // before `throwException` is called. + if (sourceFiber.mode & ConcurrentMode) { + if (getShellBoundary() === null) { + // Suspended in the "shell" of the app. This is an undesirable + // loading state. We should avoid committing this tree. + renderDidSuspendDelayIfPossible(); + } else { + // If we suspended deeper than the shell, we don't need to delay + // the commmit. However, we still call renderDidSuspend if this is + // a new boundary, to tell the work loop that a new fallback has + // appeared during this render. + // TODO: Theoretically we should be able to delete this branch. + // It's currently used for two things: 1) to throttle the + // appearance of successive loading states, and 2) in + // SuspenseList, to determine whether the children include any + // pending fallbacks. For 1, we should apply throttling to all + // retries, not just ones that render an additional fallback. For + // 2, we should check subtreeFlags instead. Then we can delete + // this branch. + var current = suspenseBoundary.alternate; + + if (current === null) { + renderDidSuspend(); + } + } + } + + suspenseBoundary.flags &= ~ForceClientRender; + markSuspenseBoundaryShouldCapture( + suspenseBoundary, + returnFiber, + sourceFiber, + root, + rootRenderLanes + ); // Retry listener + // + // If the fallback does commit, we need to attach a different type of + // listener. This one schedules an update on the Suspense boundary to + // turn the fallback state off. + // + // Stash the wakeable on the boundary fiber so we can access it in the + // commit phase. + // + // When the wakeable resolves, we'll attempt to render the boundary + // again ("retry"). + // Check if this is a Suspensey resource. We do not attach retry + // listeners to these, because we don't actually need them for + // rendering. Only for committing. Instead, if a fallback commits + // and the only thing that suspended was a Suspensey resource, we + // retry immediately. + // TODO: Refactor throwException so that we don't have to do this type + // check. The caller already knows what the cause was. + + var isSuspenseyResource = + wakeable === noopSuspenseyCommitThenable; + + if (isSuspenseyResource) { + suspenseBoundary.flags |= ScheduleRetry; + } else { + var retryQueue = suspenseBoundary.updateQueue; + + if (retryQueue === null) { + suspenseBoundary.updateQueue = new Set([wakeable]); + } else { + retryQueue.add(wakeable); + } // We only attach ping listeners in concurrent mode. Legacy + // Suspense always commits fallbacks synchronously, so there are + // no pings. + + if (suspenseBoundary.mode & ConcurrentMode) { + attachPingListener(root, wakeable, rootRenderLanes); + } + } + + return false; + } + + case OffscreenComponent: { + if (suspenseBoundary.mode & ConcurrentMode) { + suspenseBoundary.flags |= ShouldCapture; + + var _isSuspenseyResource = + wakeable === noopSuspenseyCommitThenable; + + if (_isSuspenseyResource) { + suspenseBoundary.flags |= ScheduleRetry; + } else { + var offscreenQueue = suspenseBoundary.updateQueue; + + if (offscreenQueue === null) { + var newOffscreenQueue = { + transitions: null, + markerInstances: null, + retryQueue: new Set([wakeable]) + }; + suspenseBoundary.updateQueue = newOffscreenQueue; + } else { + var _retryQueue = offscreenQueue.retryQueue; + + if (_retryQueue === null) { + offscreenQueue.retryQueue = new Set([wakeable]); + } else { + _retryQueue.add(wakeable); + } + } + + attachPingListener(root, wakeable, rootRenderLanes); + } + + return false; + } + } + } + + throw new Error( + "Unexpected Suspense handler tag (" + + suspenseBoundary.tag + + "). This " + + "is a bug in React." + ); + } else { + // No boundary was found. Unless this is a sync update, this is OK. + // We can suspend and wait for more data to arrive. + if (root.tag === ConcurrentRoot) { + // In a concurrent root, suspending without a Suspense boundary is + // allowed. It will suspend indefinitely without committing. + // + // TODO: Should we have different behavior for discrete updates? What + // about flushSync? Maybe it should put the tree into an inert state, + // and potentially log a warning. Revisit this for a future release. + attachPingListener(root, wakeable, rootRenderLanes); + renderDidSuspendDelayIfPossible(); + return false; + } else { + // In a legacy root, suspending without a boundary is always an error. + var uncaughtSuspenseError = new Error( + "A component suspended while responding to synchronous input. This " + + "will cause the UI to be replaced with a loading indicator. To " + + "fix, updates that suspend should be wrapped " + + "with startTransition." + ); + value = uncaughtSuspenseError; + } + } + } + } // This is a regular error, not a Suspense wakeable. + + value = createCapturedValueAtFiber(value, sourceFiber); + renderDidError(value); // 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. + + if (returnFiber === null) { + // There's no return fiber, which means the root errored. This should never + // happen. Return `true` to trigger a fatal error (panic). + return true; + } + + var workInProgress = returnFiber; + + do { + switch (workInProgress.tag) { + case HostRoot: { + var _errorInfo = value; + workInProgress.flags |= ShouldCapture; + var lane = pickArbitraryLane(rootRenderLanes); + workInProgress.lanes = mergeLanes(workInProgress.lanes, lane); + var update = createRootErrorUpdate( + workInProgress, + _errorInfo, + lane + ); + enqueueCapturedUpdate(workInProgress, update); + return false; + } + + case ClassComponent: + // Capture and retry + var errorInfo = value; + var ctor = workInProgress.type; + var instance = workInProgress.stateNode; + + if ( + (workInProgress.flags & DidCapture) === NoFlags$1 && + (typeof ctor.getDerivedStateFromError === "function" || + (instance !== null && + typeof instance.componentDidCatch === "function" && + !isAlreadyFailedLegacyErrorBoundary(instance))) + ) { + workInProgress.flags |= ShouldCapture; + + var _lane = pickArbitraryLane(rootRenderLanes); + + workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane); // Schedule the error boundary to re-render using updated state + + var _update = createClassErrorUpdate( + workInProgress, + errorInfo, + _lane + ); + + enqueueCapturedUpdate(workInProgress, _update); + return false; + } + + break; + } // $FlowFixMe[incompatible-type] we bail out when we get a null + + workInProgress = workInProgress.return; + } while (workInProgress !== null); + + return false; + } + + var ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner; // A special exception that's used to unwind the stack when an update flows + // into a dehydrated boundary. + + var SelectiveHydrationException = new Error( + "This is not a real error. It's an implementation detail of React's " + + "selective hydration feature. If this leaks into userspace, it's a bug in " + + "React. Please file an issue." + ); + var didReceiveUpdate = false; + var didWarnAboutBadClass; + var didWarnAboutModulePatternComponent; + var didWarnAboutContextTypeOnFunctionComponent; + var didWarnAboutGetDerivedStateOnFunctionComponent; + var didWarnAboutFunctionRefs; + var didWarnAboutReassigningProps; + var didWarnAboutRevealOrder; + var didWarnAboutTailOptions; + var didWarnAboutDefaultPropsOnFunctionComponent; + + { + didWarnAboutBadClass = {}; + didWarnAboutModulePatternComponent = {}; + didWarnAboutContextTypeOnFunctionComponent = {}; + didWarnAboutGetDerivedStateOnFunctionComponent = {}; + didWarnAboutFunctionRefs = {}; + didWarnAboutReassigningProps = false; + didWarnAboutRevealOrder = {}; + didWarnAboutTailOptions = {}; + didWarnAboutDefaultPropsOnFunctionComponent = {}; + } + + 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. + var render = Component.render; + var ref = workInProgress.ref; + var propsWithoutRef; + + { + propsWithoutRef = nextProps; + } // The rest is a fork of updateFunctionComponent + + var nextChildren; + prepareToReadContext(workInProgress, renderLanes); + + { + ReactCurrentOwner$2.current = workInProgress; + setIsRendering(true); + nextChildren = renderWithHooks( + current, + workInProgress, + render, + propsWithoutRef, + ref, + renderLanes + ); + setIsRendering(false); + } + + if (current !== null && !didReceiveUpdate) { + bailoutHooks(current, workInProgress, renderLanes); + return bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderLanes + ); + } + + workInProgress.flags |= PerformedWork; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; + } + + function updateMemoComponent( + current, + workInProgress, + Component, + nextProps, + 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, + renderLanes + ); + } + + { + if (Component.defaultProps !== undefined) { + var componentName = getComponentNameFromType(type) || "Unknown"; + + if (!didWarnAboutDefaultPropsOnFunctionComponent[componentName]) { + error( + "%s: Support for defaultProps will be removed from memo components " + + "in a future major release. Use JavaScript default parameters instead.", + componentName + ); + + didWarnAboutDefaultPropsOnFunctionComponent[componentName] = true; + } + } + } + + var child = createFiberFromTypeAndProps( + Component.type, + null, + nextProps, + workInProgress, + workInProgress.mode, + renderLanes + ); + child.ref = workInProgress.ref; + child.return = workInProgress; + workInProgress.child = child; + return child; + } + + var currentChild = current.child; // This is always exactly one child + + var hasScheduledUpdateOrContext = checkScheduledUpdateOrContext( + current, + renderLanes + ); + + if (!hasScheduledUpdateOrContext) { + // 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, + 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 (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; // The props are shallowly equal. Reuse the previous props object, like we + // would during a normal fiber bailout. + // + // We don't have strong guarantees that the props object is referentially + // equal during updates where we can't bail out anyway — like if the props + // are shallowly equal, but there's a local state or context update in the + // same batch. + // + // However, as a principle, we should aim to make the behavior consistent + // across different ways of memoizing a component. For example, React.memo + // has a different internal Fiber layout if you pass a normal function + // component (SimpleMemoComponent) versus if you pass a different type + // like forwardRef (MemoComponent). But this is an implementation detail. + // Wrapping a component in forwardRef (or React.lazy, etc) shouldn't + // affect whether the props object is reused during a bailout. + + workInProgress.pendingProps = nextProps = prevProps; + + if (!checkScheduledUpdateOrContext(current, renderLanes)) { + // The pending lanes were cleared at the beginning of beginWork. We're + // 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 accumulated 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$1 + ) { + // 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 nextIsDetached = + (workInProgress.stateNode._pendingVisibility & OffscreenDetached) !== 0; + var prevState = current !== null ? current.memoizedState : null; + markRef(current, workInProgress); + + if (nextProps.mode === "hidden" || enableLegacyHidden || nextIsDetached) { + // Rendering a hidden tree. + var didSuspend = (workInProgress.flags & DidCapture) !== NoFlags$1; + + if (didSuspend) { + // Something suspended inside a hidden tree + // Include the base lanes from the last render + var nextBaseLanes = + prevState !== null + ? mergeLanes(prevState.baseLanes, renderLanes) + : renderLanes; + + if (current !== null) { + // Reset to the current children + var currentChild = (workInProgress.child = current.child); // The current render suspended, but there may be other lanes with + // pending work. We can't read `childLanes` from the current Offscreen + // fiber because we reset it when it was deferred; however, we can read + // the pending lanes from the child fibers. + + var currentChildLanes = NoLanes; + + while (currentChild !== null) { + currentChildLanes = mergeLanes( + mergeLanes(currentChildLanes, currentChild.lanes), + currentChild.childLanes + ); + currentChild = currentChild.sibling; + } + + var lanesWeJustAttempted = nextBaseLanes; + var remainingChildLanes = removeLanes( + currentChildLanes, + lanesWeJustAttempted + ); + workInProgress.childLanes = remainingChildLanes; + } else { + workInProgress.childLanes = NoLanes; + workInProgress.child = null; + } + + return deferHiddenOffscreenComponent( + current, + workInProgress, + nextBaseLanes + ); + } + + if ((workInProgress.mode & ConcurrentMode) === NoMode) { + // In legacy sync mode, don't defer the subtree. Render it now. + // TODO: Consider how Offscreen should work with transitions in the future + var nextState = { + baseLanes: NoLanes, + cachePool: null + }; + workInProgress.memoizedState = nextState; + + reuseHiddenContextOnStack(workInProgress); + pushOffscreenSuspenseHandler(workInProgress); + } else if (!includesSomeLane(renderLanes, OffscreenLane)) { + // We're hidden, and we're not rendering at Offscreen. We will bail out + // and resume this tree later. + // Schedule this fiber to re-render at Offscreen priority + workInProgress.lanes = workInProgress.childLanes = + laneToLanes(OffscreenLane); // Include the base lanes from the last render + + var _nextBaseLanes = + prevState !== null + ? mergeLanes(prevState.baseLanes, renderLanes) + : renderLanes; + + return deferHiddenOffscreenComponent( + current, + workInProgress, + _nextBaseLanes + ); + } else { + // This is the second render. The surrounding visible content has already + // committed. Now we resume rendering the hidden tree. + // Rendering at offscreen, so we can clear the base lanes. + var _nextState = { + baseLanes: NoLanes, + cachePool: null + }; + workInProgress.memoizedState = _nextState; + + if (prevState !== null) { + pushHiddenContext(workInProgress, prevState); + } else { + reuseHiddenContextOnStack(workInProgress); + } + + pushOffscreenSuspenseHandler(workInProgress); + } + } else { + // Rendering a visible tree. + if (prevState !== null) { + pushHiddenContext(workInProgress, prevState); + reuseSuspenseHandlerOnStack(workInProgress); // Since we're not hidden anymore, reset the state + + workInProgress.memoizedState = null; + } else { + // to avoid a push/pop misalignment. + + reuseHiddenContextOnStack(workInProgress); + reuseSuspenseHandlerOnStack(workInProgress); + } + } + + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; + } + + function deferHiddenOffscreenComponent( + current, + workInProgress, + nextBaseLanes, + renderLanes + ) { + var nextState = { + baseLanes: nextBaseLanes, + // Save the cache pool so we can resume later. + cachePool: null + }; + workInProgress.memoizedState = nextState; + // to avoid a push/pop misalignment. + + reuseHiddenContextOnStack(workInProgress); + pushOffscreenSuspenseHandler(workInProgress); + + return null; + } // Note: These happen to have identical begin phases, for now. We shouldn't hold + + function updateFragment(current, workInProgress, renderLanes) { + var nextChildren = workInProgress.pendingProps; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; + } + + function updateMode(current, workInProgress, renderLanes) { + var nextChildren = workInProgress.pendingProps.children; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; + } + + function updateProfiler(current, workInProgress, renderLanes) { + { + workInProgress.flags |= Update; + + { + // Reset effect durations for the next eventual effect phase. + // These are reset during render to allow the DevTools commit hook a chance to read them, + var stateNode = workInProgress.stateNode; + stateNode.effectDuration = 0; + stateNode.passiveEffectDuration = 0; + } + } + + var nextProps = workInProgress.pendingProps; + var nextChildren = nextProps.children; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; + } + + function markRef(current, workInProgress) { + // TODO: Check props.ref instead of fiber.ref when enableRefAsProp is on. + var ref = workInProgress.ref; + + if (ref === null) { + if (current !== null && current.ref !== null) { + // Schedule a Ref effect + workInProgress.flags |= Ref | RefStatic; + } + } else { + if (typeof ref !== "function" && typeof ref !== "object") { + throw new Error( + "Expected ref to be a function, an object returned by React.createRef(), or undefined/null." + ); + } + + if (current === null || current.ref !== ref) { + // Schedule a Ref effect + workInProgress.flags |= Ref | RefStatic; + } + } + } + + function updateFunctionComponent( + current, + workInProgress, + Component, + nextProps, + renderLanes + ) { + var context; + + var nextChildren; + prepareToReadContext(workInProgress, renderLanes); + + { + ReactCurrentOwner$2.current = workInProgress; + setIsRendering(true); + nextChildren = renderWithHooks( + current, + workInProgress, + Component, + nextProps, + context, + renderLanes + ); + setIsRendering(false); + } + + if (current !== null && !didReceiveUpdate) { + bailoutHooks(current, workInProgress, renderLanes); + return bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderLanes + ); + } + + workInProgress.flags |= PerformedWork; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; + } + + function replayFunctionComponent( + current, + workInProgress, + nextProps, + Component, + secondArg, + renderLanes + ) { + // This function is used to replay a component that previously suspended, + // after its data resolves. It's a simplified version of + // updateFunctionComponent that reuses the hooks from the previous attempt. + prepareToReadContext(workInProgress, renderLanes); + + var nextChildren = replaySuspendedComponentWithHooks( + current, + workInProgress, + Component, + nextProps, + secondArg + ); + + if (current !== null && !didReceiveUpdate) { + bailoutHooks(current, workInProgress, renderLanes); + return bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderLanes + ); + } + + workInProgress.flags |= PerformedWork; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; + } + + function updateClassComponent( + current, + workInProgress, + Component, + nextProps, + renderLanes + ) { + { + // This is used by DevTools to force a boundary to error. + switch (shouldError(workInProgress)) { + case false: { + var _instance = workInProgress.stateNode; + var ctor = workInProgress.type; // TODO This way of resetting the error boundary state is a hack. + // Is there a better way to do this? + + var tempInstance = new ctor( + workInProgress.memoizedProps, + _instance.context + ); + var state = tempInstance.state; + + _instance.updater.enqueueSetState(_instance, state, null); + + break; + } + + case true: { + workInProgress.flags |= DidCapture; + workInProgress.flags |= ShouldCapture; // eslint-disable-next-line react-internal/prod-error-codes + + var error$1 = new Error("Simulated error coming from DevTools"); + var lane = pickArbitraryLane(renderLanes); + workInProgress.lanes = mergeLanes(workInProgress.lanes, lane); // Schedule the error boundary to re-render using updated state + + var update = createClassErrorUpdate( + workInProgress, + createCapturedValueAtFiber(error$1, workInProgress), + lane + ); + enqueueCapturedUpdate(workInProgress, update); + break; + } + } + } // Push context providers early to prevent context stack mismatches. + // During mounting we don't know the child context yet as the instance doesn't exist. + // We will invalidate the child context in finishClassComponent() right after rendering. + + var hasContext; + + if (isContextProvider()) { + hasContext = true; + } else { + hasContext = false; + } + + prepareToReadContext(workInProgress, renderLanes); + var instance = workInProgress.stateNode; + var shouldUpdate; + + if (instance === null) { + resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress); // 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, + workInProgress, + Component, + shouldUpdate, + 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.", + getComponentNameFromFiber(workInProgress) || "a component" + ); + } + + didWarnAboutReassigningProps = true; + } + } + + return nextUnitOfWork; + } + + function finishClassComponent( + current, + workInProgress, + Component, + shouldUpdate, + hasContext, + renderLanes + ) { + // Refs should update even if shouldComponentUpdate returns false + markRef(current, workInProgress); + var didCaptureError = (workInProgress.flags & DidCapture) !== NoFlags$1; + + if (!shouldUpdate && !didCaptureError) { + return bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderLanes + ); + } + + var instance = workInProgress.stateNode; // Rerender + + ReactCurrentOwner$2.current = workInProgress; + var nextChildren; + + if ( + didCaptureError && + typeof Component.getDerivedStateFromError !== "function" + ) { + // If we captured an error, but getDerivedStateFromError is not defined, + // unmount all the children. componentDidCatch will schedule an update to + // re-render a fallback. This is temporary until we migrate everyone to + // the new API. + // TODO: Warn in a future release. + nextChildren = null; + + { + stopProfilerTimerIfRunning(); + } + } else { + { + setIsRendering(true); + nextChildren = instance.render(); + + if (workInProgress.mode & StrictLegacyMode) { + setIsStrictModeForDevtools(true); + + try { + instance.render(); + } finally { + setIsStrictModeForDevtools(false); + } + } + + setIsRendering(false); + } + } // React DevTools reads this flag. + + workInProgress.flags |= PerformedWork; + + if (current !== null && didCaptureError) { + // If we're recovering from an error, reconcile without reusing any of + // the existing children. Conceptually, the normal children and the children + // that are shown on error are two different sets, so we shouldn't reuse + // normal children even if their identities match. + forceUnmountCurrentAndReconcile( + current, + workInProgress, + nextChildren, + renderLanes + ); + } else { + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + } // Memoize state using the values we just used to render. + // TODO: Restructure so we never read values from the instance. + + workInProgress.memoizedState = instance.state; // The context might have changed so we need to recalculate it. + + return workInProgress.child; + } + + function pushHostRootContext(workInProgress) { + var root = workInProgress.stateNode; + + pushHostContainer(workInProgress, root.containerInfo); + } + + function updateHostRoot(current, workInProgress, renderLanes) { + pushHostRootContext(workInProgress); + + if (current === null) { + throw new Error("Should have a current fiber. This is a bug in React."); + } + + var nextProps = workInProgress.pendingProps; + var prevState = workInProgress.memoizedState; + var prevChildren = prevState.element; + cloneUpdateQueue(current, workInProgress); + processUpdateQueue(workInProgress, nextProps, null, renderLanes); + var nextState = workInProgress.memoizedState; + // it needs to happen after the `pushCacheProvider` call above to avoid a + // context stack mismatch. A bit unfortunate. + + suspendIfUpdateReadFromEntangledAsyncAction(); // Caution: React DevTools currently depends on this property + // being called "element". + + var nextChildren = nextState.element; + + { + if (nextChildren === prevChildren) { + return bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderLanes + ); + } + + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + } + + return workInProgress.child; + } + + function updateHostComponent$1(current, workInProgress, renderLanes) { + pushHostContext(workInProgress); + var nextProps = workInProgress.pendingProps; + var prevProps = current !== null ? current.memoizedProps : null; + var nextChildren = nextProps.children; + + if (prevProps !== null && shouldSetTextContent()) { + // If we're switching from a direct text child to a normal child, or to + // empty, we need to schedule the text content to be reset. + workInProgress.flags |= ContentReset; + } + + markRef(current, workInProgress); + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; + } + + function updateHostText$1(current, workInProgress) { + // immediately after. + + return null; + } + + function mountLazyComponent( + _current, + workInProgress, + elementType, + renderLanes + ) { + resetSuspendedCurrentOnMountInLegacyMode(_current, workInProgress); + 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; + } + + case ForwardRef: { + { + workInProgress.type = Component = + resolveForwardRefForHotReloading(Component); + } + + child = updateForwardRef( + null, + workInProgress, + Component, + resolvedProps, + renderLanes + ); + return child; + } + + case MemoComponent: { + child = updateMemoComponent( + null, + workInProgress, + Component, + resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too + renderLanes + ); + return child; + } + } + + var hint = ""; + + { + if ( + Component !== null && + typeof Component === "object" && + Component.$$typeof === REACT_LAZY_TYPE + ) { + hint = " Did you wrap a component in React.lazy() more than once?"; + } + } // This message intentionally doesn't mention ForwardRef or MemoComponent + // because the fact that it's a separate type of work is an + // implementation detail. + + throw new Error( + "Element type is invalid. Received a promise that resolves to: " + + Component + + ". " + + ("Lazy element type must resolve to a class or function." + hint) + ); + } + + function mountIncompleteClassComponent( + _current, + workInProgress, + Component, + nextProps, + renderLanes + ) { + resetSuspendedCurrentOnMountInLegacyMode(_current, workInProgress); // Promote the fiber to a class and try rendering again. + + workInProgress.tag = ClassComponent; // The rest of this function is a fork of `updateClassComponent` + // Push context providers early to prevent context stack mismatches. + // During mounting we don't know the child context yet as the instance doesn't exist. + // We will invalidate the child context in finishClassComponent() right after rendering. + + var hasContext; + + if (isContextProvider()) { + hasContext = true; + } else { + hasContext = false; + } + + prepareToReadContext(workInProgress, renderLanes); + constructClassInstance(workInProgress, Component, nextProps); + mountClassInstance(workInProgress, Component, nextProps, renderLanes); + return finishClassComponent( + null, + workInProgress, + Component, + true, + hasContext, + renderLanes + ); + } + + function mountIndeterminateComponent( + _current, + workInProgress, + Component, + renderLanes + ) { + resetSuspendedCurrentOnMountInLegacyMode(_current, workInProgress); + var props = workInProgress.pendingProps; + var context; + + prepareToReadContext(workInProgress, renderLanes); + var value; + + { + if ( + Component.prototype && + typeof Component.prototype.render === "function" + ) { + var componentName = getComponentNameFromType(Component) || "Unknown"; + + if (!didWarnAboutBadClass[componentName]) { + error( + "The <%s /> component appears to have a render method, but doesn't extend React.Component. " + + "This is likely to cause errors. Change %s to extend React.Component instead.", + componentName, + componentName + ); + + didWarnAboutBadClass[componentName] = true; + } + } + + if (workInProgress.mode & StrictLegacyMode) { + ReactStrictModeWarnings.recordLegacyContextWarning( + workInProgress, + null + ); + } + + setIsRendering(true); + ReactCurrentOwner$2.current = workInProgress; + value = renderWithHooks( + null, + workInProgress, + Component, + props, + context, + renderLanes + ); + setIsRendering(false); + } + + workInProgress.flags |= PerformedWork; + + { + // Support for module components is deprecated and is removed behind a flag. + // Whether or not it would crash later, we want to show a good message in DEV first. + if ( + typeof value === "object" && + value !== null && + typeof value.render === "function" && + value.$$typeof === undefined + ) { + var _componentName = 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; + } + } + } + + 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"; + + if (!didWarnAboutModulePatternComponent[_componentName2]) { + error( + "The <%s /> component appears to be a function component that returns a class instance. " + + "Change %s to a class that extends React.Component instead. " + + "If you can't use a class try assigning the prototype on the function as a workaround. " + + "`%s.prototype = React.Component.prototype`. Don't use an arrow function since it " + + "cannot be called with `new` by React.", + _componentName2, + _componentName2, + _componentName2 + ); + + didWarnAboutModulePatternComponent[_componentName2] = true; + } + } // Proceed under the assumption that this is a class instance + + workInProgress.tag = ClassComponent; // Throw out any hooks that were used. + + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; // Push context providers early to prevent context stack mismatches. + // During mounting we don't know the child context yet as the instance doesn't exist. + // We will invalidate the child context in finishClassComponent() right after rendering. + + var hasContext = false; + + if (isContextProvider()) { + hasContext = true; + } 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, + Component, + true, + hasContext, + renderLanes + ); + } else { + // Proceed under the assumption that this is a function component + workInProgress.tag = FunctionComponent; + + { + if (Component.contextTypes) { + error( + "%s uses the legacy contextTypes API which is no longer supported. " + + "Use React.createContext() with React.useContext() instead.", + getComponentNameFromType(Component) || "Unknown" + ); + } + } + + reconcileChildren(null, workInProgress, value, renderLanes); + + { + validateFunctionComponentInDev(workInProgress, Component); + } + + return workInProgress.child; + } + } + + function validateFunctionComponentInDev(workInProgress, Component) { + { + if (Component) { + if (Component.childContextTypes) { + error( + "childContextTypes cannot be defined on a function component.\n" + + " %s.childContextTypes = ...", + Component.displayName || Component.name || "Component" + ); + } + } + + if (workInProgress.ref !== null) { + var info = ""; + var componentName = getComponentNameFromType(Component) || "Unknown"; + var ownerName = getCurrentFiberOwnerNameInDevOrNull(); + + if (ownerName) { + info += "\n\nCheck the render method of `" + ownerName + "`."; + } + + var warningKey = componentName + "|" + (ownerName || ""); + + 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 + ); + } + } + + if (Component.defaultProps !== undefined) { + var _componentName3 = + getComponentNameFromType(Component) || "Unknown"; + + if (!didWarnAboutDefaultPropsOnFunctionComponent[_componentName3]) { + error( + "%s: Support for defaultProps will be removed from function components " + + "in a future major release. Use JavaScript default parameters instead.", + _componentName3 + ); + + didWarnAboutDefaultPropsOnFunctionComponent[_componentName3] = true; + } + } + + if (typeof Component.getDerivedStateFromProps === "function") { + var _componentName4 = + getComponentNameFromType(Component) || "Unknown"; + + if ( + !didWarnAboutGetDerivedStateOnFunctionComponent[_componentName4] + ) { + error( + "%s: Function components do not support getDerivedStateFromProps.", + _componentName4 + ); + + didWarnAboutGetDerivedStateOnFunctionComponent[_componentName4] = + true; + } + } + + if ( + typeof Component.contextType === "object" && + Component.contextType !== null + ) { + var _componentName5 = + getComponentNameFromType(Component) || "Unknown"; + + if (!didWarnAboutContextTypeOnFunctionComponent[_componentName5]) { + error( + "%s: Function components do not support contextType.", + _componentName5 + ); + + didWarnAboutContextTypeOnFunctionComponent[_componentName5] = true; + } + } + } + } + + var SUSPENDED_MARKER = { + dehydrated: null, + treeContext: null, + retryLane: NoLane + }; + + function mountSuspenseOffscreenState(renderLanes) { + return { + baseLanes: renderLanes, + cachePool: getSuspendedCache() + }; + } + + function updateSuspenseOffscreenState(prevOffscreenState, renderLanes) { + var cachePool = null; + + return { + baseLanes: mergeLanes(prevOffscreenState.baseLanes, renderLanes), + cachePool: cachePool + }; + } // TODO: Probably should inline this back + + function shouldRemainOnFallback(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. + // TODO: For compatibility with offscreen prerendering, this should also check + // whether the current fiber (if it exists) was visible in the previous tree. + if (current !== null) { + var suspenseState = current.memoizedState; + + if (suspenseState === null) { + // Currently showing content. Don't hide it, even if ForceSuspenseFallback + // 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 suspenseContext = suspenseStackCursor.current; + return hasSuspenseListContext(suspenseContext, ForceSuspenseFallback); + } + + function getRemainingWorkInPrimaryTree( + current, + primaryTreeDidDefer, + renderLanes + ) { + var remainingLanes = + current !== null + ? removeLanes(current.childLanes, renderLanes) + : NoLanes; + + if (primaryTreeDidDefer) { + // A useDeferredValue hook spawned a deferred task inside the primary tree. + // Ensure that we retry this component at the deferred priority. + // TODO: We could make this a per-subtree value instead of a global one. + // Would need to track it on the context stack somehow, similar to what + // we'd have to do for resumable contexts. + remainingLanes = mergeLanes(remainingLanes, peekDeferredLane()); + } + + return remainingLanes; + } + + 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 showFallback = false; + var didSuspend = (workInProgress.flags & DidCapture) !== NoFlags$1; + + if (didSuspend || shouldRemainOnFallback(current)) { + // Something in this boundary's subtree already suspended. Switch to + // rendering the fallback children. + showFallback = true; + workInProgress.flags &= ~DidCapture; + } // Check if the primary children spawned a deferred task (useDeferredValue) + // during the first pass. + + var didPrimaryChildrenDefer = + (workInProgress.flags & DidDefer) !== NoFlags$1; + workInProgress.flags &= ~DidDefer; // OK, the next part is confusing. We're about to reconcile the Suspense + // boundary's children. This involves some custom reconciliation 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) { + var nextPrimaryChildren = nextProps.children; + var nextFallbackChildren = nextProps.fallback; + + if (showFallback) { + pushFallbackTreeSuspenseHandler(workInProgress); + var fallbackFragment = mountSuspenseFallbackChildren( + workInProgress, + nextPrimaryChildren, + nextFallbackChildren, + renderLanes + ); + var primaryChildFragment = workInProgress.child; + primaryChildFragment.memoizedState = + mountSuspenseOffscreenState(renderLanes); + primaryChildFragment.childLanes = getRemainingWorkInPrimaryTree( + current, + didPrimaryChildrenDefer, + renderLanes + ); + workInProgress.memoizedState = SUSPENDED_MARKER; + + return fallbackFragment; + } else { + pushPrimaryTreeSuspenseHandler(workInProgress); + return mountSuspensePrimaryChildren( + workInProgress, + nextPrimaryChildren + ); + } + } else { + // This is an update. + // Special path for hydration + var prevState = current.memoizedState; + + if (prevState !== null) { + var _dehydrated = prevState.dehydrated; + + if (_dehydrated !== null) { + return updateDehydratedSuspenseComponent( + current, + workInProgress, + didSuspend, + didPrimaryChildrenDefer, + nextProps, + _dehydrated, + prevState, + renderLanes + ); + } + } + + if (showFallback) { + pushFallbackTreeSuspenseHandler(workInProgress); + var _nextFallbackChildren = nextProps.fallback; + var _nextPrimaryChildren = nextProps.children; + var fallbackChildFragment = updateSuspenseFallbackChildren( + current, + workInProgress, + _nextPrimaryChildren, + _nextFallbackChildren, + renderLanes + ); + var _primaryChildFragment2 = workInProgress.child; + var prevOffscreenState = current.child.memoizedState; + _primaryChildFragment2.memoizedState = + prevOffscreenState === null + ? mountSuspenseOffscreenState(renderLanes) + : updateSuspenseOffscreenState(prevOffscreenState, renderLanes); + + _primaryChildFragment2.childLanes = getRemainingWorkInPrimaryTree( + current, + didPrimaryChildrenDefer, + renderLanes + ); + workInProgress.memoizedState = SUSPENDED_MARKER; + return fallbackChildFragment; + } else { + pushPrimaryTreeSuspenseHandler(workInProgress); + var _nextPrimaryChildren2 = nextProps.children; + + var _primaryChildFragment3 = updateSuspensePrimaryChildren( + current, + workInProgress, + _nextPrimaryChildren2, + renderLanes + ); + + workInProgress.memoizedState = null; + return _primaryChildFragment3; + } + } + } + + function mountSuspensePrimaryChildren( + workInProgress, + primaryChildren, + renderLanes + ) { + var mode = workInProgress.mode; + var primaryChildProps = { + mode: "visible", + children: primaryChildren + }; + var primaryChildFragment = mountWorkInProgressOffscreenFiber( + primaryChildProps, + mode + ); + primaryChildFragment.return = workInProgress; + workInProgress.child = primaryChildFragment; + return primaryChildFragment; + } + + 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; + } + + fallbackChildFragment = createFiberFromFragment( + fallbackChildren, + mode, + renderLanes, + null + ); + } else { + primaryChildFragment = mountWorkInProgressOffscreenFiber( + primaryChildProps, + mode + ); + fallbackChildFragment = createFiberFromFragment( + fallbackChildren, + mode, + renderLanes, + null + ); + } + + primaryChildFragment.return = workInProgress; + fallbackChildFragment.return = workInProgress; + primaryChildFragment.sibling = fallbackChildFragment; + workInProgress.child = primaryChildFragment; + return fallbackChildFragment; + } + + function mountWorkInProgressOffscreenFiber( + offscreenProps, + mode, + renderLanes + ) { + // The props argument to `createFiberFromOffscreen` is `any` typed, so we use + // this wrapper function to constrain it. + return createFiberFromOffscreen(offscreenProps, mode, NoLanes, null); + } + + function updateWorkInProgressOffscreenFiber(current, offscreenProps) { + // The props argument to `createWorkInProgress` is `any` typed, so we use this + // wrapper function to constrain it. + return createWorkInProgress(current, offscreenProps); + } + + function updateSuspensePrimaryChildren( + current, + workInProgress, + primaryChildren, + renderLanes + ) { + var currentPrimaryChildFragment = current.child; + var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; + var primaryChildFragment = updateWorkInProgressOffscreenFiber( + currentPrimaryChildFragment, + { + mode: "visible", + children: primaryChildren + } + ); + + if ((workInProgress.mode & ConcurrentMode) === NoMode) { + primaryChildFragment.lanes = renderLanes; + } + + primaryChildFragment.return = workInProgress; + primaryChildFragment.sibling = null; + + if (currentFallbackChildFragment !== null) { + // Delete the fallback child fragment + var deletions = workInProgress.deletions; + + if (deletions === null) { + workInProgress.deletions = [currentFallbackChildFragment]; + workInProgress.flags |= ChildDeletion; + } else { + deletions.push(currentFallbackChildFragment); + } + } + + workInProgress.child = primaryChildFragment; + return primaryChildFragment; + } + + function updateSuspenseFallbackChildren( + current, + workInProgress, + primaryChildren, + fallbackChildren, + renderLanes + ) { + var mode = workInProgress.mode; + var currentPrimaryChildFragment = current.child; + var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; + var primaryChildProps = { + mode: "hidden", + children: primaryChildren + }; + var primaryChildFragment; + + if ( + // In legacy mode, we commit the primary tree as if it successfully + // completed, even though it's in an inconsistent state. + (mode & 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 (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. + + workInProgress.deletions = null; + } else { + primaryChildFragment = updateWorkInProgressOffscreenFiber( + currentPrimaryChildFragment, + primaryChildProps + ); // Since we're reusing a current tree, we need to reuse the flags, too. + // (We don't do this in legacy mode, because in legacy mode we don't re-use + // the current tree; see previous branch.) + + primaryChildFragment.subtreeFlags = + currentPrimaryChildFragment.subtreeFlags & StaticMask; + } + + 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. + + fallbackChildFragment.flags |= Placement; + } + + fallbackChildFragment.return = workInProgress; + primaryChildFragment.return = workInProgress; + primaryChildFragment.sibling = fallbackChildFragment; + workInProgress.child = primaryChildFragment; + return fallbackChildFragment; + } + + function retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + recoverableError + ) { + // Falling back to client rendering. Because this has performance + // implications, it's considered a recoverable error, even though the user + // likely won't observe anything wrong with the UI. + // + // The error is passed in as an argument to enforce that every caller provide + // a custom message, or explicitly opt out (currently the only path that opts + // out is legacy mode; every concurrent path provides an error). + if (recoverableError !== null) { + queueHydrationError(recoverableError); + } // This will add the old fiber to the deletion list + + reconcileChildFibers(workInProgress, current.child, null, renderLanes); // We're now not suspended nor dehydrated. + + var nextProps = workInProgress.pendingProps; + var primaryChildren = nextProps.children; + var primaryChildFragment = mountSuspensePrimaryChildren( + workInProgress, + primaryChildren + ); // Needs a placement effect because the parent (the Suspense boundary) already + // mounted but this is a new fiber. + + primaryChildFragment.flags |= Placement; + workInProgress.memoizedState = null; + return primaryChildFragment; + } + + function mountSuspenseFallbackAfterRetryWithoutHydrating( + current, + workInProgress, + primaryChildren, + fallbackChildren, + renderLanes + ) { + var fiberMode = workInProgress.mode; + var primaryChildProps = { + mode: "visible", + children: primaryChildren + }; + var primaryChildFragment = mountWorkInProgressOffscreenFiber( + primaryChildProps, + fiberMode + ); + var fallbackChildFragment = createFiberFromFragment( + fallbackChildren, + fiberMode, + renderLanes, + null + ); // Needs a placement effect because the parent (the Suspense + // boundary) already mounted but this is a new fiber. + + fallbackChildFragment.flags |= Placement; + primaryChildFragment.return = workInProgress; + fallbackChildFragment.return = workInProgress; + primaryChildFragment.sibling = fallbackChildFragment; + workInProgress.child = primaryChildFragment; + + if ((workInProgress.mode & ConcurrentMode) !== NoMode) { + // We will have dropped the effect list which contains the + // deletion. We need to reconcile to delete the current child. + reconcileChildFibers(workInProgress, current.child, null, renderLanes); + } + + return fallbackChildFragment; + } + + function updateDehydratedSuspenseComponent( + current, + workInProgress, + didSuspend, + didPrimaryChildrenDefer, + nextProps, + suspenseInstance, + suspenseState, + renderLanes + ) { + if (!didSuspend) { + // This is the first render pass. Attempt to hydrate. + pushPrimaryTreeSuspenseHandler(workInProgress); // We should never be hydrating at this point because it is the first pass, + + if ((workInProgress.mode & ConcurrentMode) === NoMode) { + return retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + null + ); + } + + if (isSuspenseInstanceFallback()) { + // This boundary is in a permanent fallback state. In this case, we'll never + // get an update and we'll never be able to hydrate the final content. Let's just try the + // client side render instead. + var digest; + var message, stack; + + { + var _getSuspenseInstanceF = + getSuspenseInstanceFallbackErrorDetails(); + + digest = _getSuspenseInstanceF.digest; + message = _getSuspenseInstanceF.message; + stack = _getSuspenseInstanceF.stack; + } + + var capturedValue = null; // TODO: Figure out a better signal than encoding a magic digest value. + + { + var error; + + if (message) { + // eslint-disable-next-line react-internal/prod-error-codes + error = new Error(message); + } else { + error = new Error( + "The server could not finish this Suspense boundary, likely " + + "due to an error during server rendering. Switched to " + + "client rendering." + ); + } + + error.digest = digest; + capturedValue = createCapturedValueFromError(error, digest, stack); + } + + return retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + capturedValue + ); + } + // any context has changed, we need to treat is as if the input might have changed. + + var hasContextChanged = includesSomeLane( + renderLanes, + current.childLanes + ); + + if (didReceiveUpdate || hasContextChanged) { + // This boundary has changed since the first render. This means that we are now unable to + // hydrate it. We might still be able to hydrate it using a higher priority lane. + var root = getWorkInProgressRoot(); + + if (root !== null) { + var attemptHydrationAtLane = getBumpedLaneForHydration( + root, + renderLanes + ); + + if ( + attemptHydrationAtLane !== NoLane && + attemptHydrationAtLane !== suspenseState.retryLane + ) { + // Intentionally mutating since this render will get interrupted. This + // is one of the very rare times where we mutate the current tree + // during the render phase. + suspenseState.retryLane = attemptHydrationAtLane; + enqueueConcurrentRenderForLane(current, attemptHydrationAtLane); + scheduleUpdateOnFiber(root, current, attemptHydrationAtLane); // Throw a special object that signals to the work loop that it should + // interrupt the current render. + // + // Because we're inside a React-only execution stack, we don't + // strictly need to throw here — we could instead modify some internal + // work loop state. But using an exception means we don't need to + // check for this case on every iteration of the work loop. So doing + // it this way moves the check out of the fast path. + + throw SelectiveHydrationException; + } + } // If we did not selectively hydrate, we'll continue rendering without + // hydrating. Mark this tree as suspended to prevent it from committing + // outside a transition. + // + // This path should only happen if the hydration lane already suspended. + // Currently, it also happens during sync updates because there is no + // hydration lane for sync updates. + // TODO: We should ideally have a sync hydration lane that we can apply to do + // a pass where we hydrate this subtree in place using the previous Context and then + // reapply the update afterwards. + + if (isSuspenseInstancePending()); + else { + renderDidSuspendDelayIfPossible(); + } + + return retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + null + ); + } else if (isSuspenseInstancePending()) { + // This component is still pending more data from the server, so we can't hydrate its + // content. We treat it as if this component suspended itself. It might seem as if + // we could just try to render it client-side instead. However, this will perform a + // lot of unnecessary work and is unlikely to complete since it often will suspend + // on missing data anyway. Additionally, the server might be able to render more + // than we can on the client yet. In that case we'd end up with more fallback states + // on the client than if we just leave it alone. If the server times out or errors + // these should update this boundary to the permanent Fallback state instead. + // Mark it as having captured (i.e. suspended). + workInProgress.flags |= DidCapture; // Leave the child in place. I.e. the dehydrated fragment. + + workInProgress.child = current.child; // Register a callback to retry this boundary once the server has sent the result. + + retryDehydratedSuspenseBoundary.bind(null, current); + registerSuspenseInstanceRetry(); + return null; + } else { + var primaryChildren = nextProps.children; + var primaryChildFragment = mountSuspensePrimaryChildren( + workInProgress, + primaryChildren + ); // Mark the children as hydrating. This is a fast path to know whether this + // tree is part of a hydrating tree. This is used to determine if a child + // node has fully mounted yet, and for scheduling event replaying. + // Conceptually this is similar to Placement in that a new subtree is + // inserted into the React tree here. It just happens to not need DOM + // mutations because it already exists. + + primaryChildFragment.flags |= Hydrating; + return primaryChildFragment; + } + } else { + // This is the second render pass. We already attempted to hydrated, but + // something either suspended or errored. + if (workInProgress.flags & ForceClientRender) { + // Something errored during hydration. Try again without hydrating. + pushPrimaryTreeSuspenseHandler(workInProgress); + workInProgress.flags &= ~ForceClientRender; + + var _capturedValue = createCapturedValueFromError( + new Error( + "There was an error while hydrating this Suspense boundary. " + + "Switched to client rendering." + ) + ); + + return retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + _capturedValue + ); + } else if (workInProgress.memoizedState !== null) { + // Something suspended and we should still be in dehydrated mode. + // Leave the existing child in place. + // Push to avoid a mismatch + pushFallbackTreeSuspenseHandler(workInProgress); + workInProgress.child = current.child; // The dehydrated completion pass expects this flag to be there + // but the normal suspense pass doesn't. + + workInProgress.flags |= DidCapture; + return null; + } else { + // Suspended but we should no longer be in dehydrated mode. + // Therefore we now have to render the fallback. + pushFallbackTreeSuspenseHandler(workInProgress); + var nextPrimaryChildren = nextProps.children; + var nextFallbackChildren = nextProps.fallback; + var fallbackChildFragment = + mountSuspenseFallbackAfterRetryWithoutHydrating( + current, + workInProgress, + nextPrimaryChildren, + nextFallbackChildren, + renderLanes + ); + var _primaryChildFragment4 = workInProgress.child; + _primaryChildFragment4.memoizedState = + mountSuspenseOffscreenState(renderLanes); + _primaryChildFragment4.childLanes = getRemainingWorkInPrimaryTree( + current, + didPrimaryChildrenDefer, + renderLanes + ); + workInProgress.memoizedState = SUSPENDED_MARKER; + return fallbackChildFragment; + } + } + } + + function scheduleSuspenseWorkOnFiber(fiber, renderLanes, propagationRoot) { + fiber.lanes = mergeLanes(fiber.lanes, renderLanes); + var alternate = fiber.alternate; + + if (alternate !== null) { + alternate.lanes = mergeLanes(alternate.lanes, renderLanes); + } + + scheduleContextWorkOnParentPath( + fiber.return, + renderLanes, + propagationRoot + ); + } + + 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; + + while (node !== null) { + if (node.tag === SuspenseComponent) { + var state = node.memoizedState; + + if (state !== null) { + scheduleSuspenseWorkOnFiber(node, renderLanes, workInProgress); + } + } 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. + scheduleSuspenseWorkOnFiber(node, renderLanes, workInProgress); + } else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; + } + + if (node === workInProgress) { + return; + } // $FlowFixMe[incompatible-use] found when upgrading Flow + + while (node.sibling === null) { + // $FlowFixMe[incompatible-use] found when upgrading Flow + if (node.return === null || node.return === workInProgress) { + return; + } + + node = node.return; + } // $FlowFixMe[incompatible-use] found when upgrading Flow + + node.sibling.return = node.return; + node = node.sibling; + } + } + + function findLastContentRow(firstChild) { + // This is going to find the last row among these children that is already + // showing content on the screen, as opposed to being in fallback state or + // new. If a row has multiple Suspense boundaries, any of them being in the + // fallback state, counts as the whole row being in a fallback state. + // Note that the "rows" will be workInProgress, but any nested children + // will still be current since we haven't rendered them yet. The mounted + // order may not be the same as the new order. We use the new order. + var row = firstChild; + var lastContentRow = null; + + while (row !== null) { + var currentRow = row.alternate; // New rows can't be content rows. + + if (currentRow !== null && findFirstSuspended(currentRow) === null) { + lastContentRow = row; + } + + row = row.sibling; + } + + return lastContentRow; + } + + function validateRevealOrder(revealOrder) { + { + if ( + revealOrder !== undefined && + revealOrder !== "forwards" && + revealOrder !== "backwards" && + revealOrder !== "together" && + !didWarnAboutRevealOrder[revealOrder] + ) { + didWarnAboutRevealOrder[revealOrder] = true; + + if (typeof revealOrder === "string") { + switch (revealOrder.toLowerCase()) { + case "together": + case "forwards": + case "backwards": { + error( + '"%s" is not a valid value for revealOrder on . ' + + 'Use lowercase "%s" instead.', + revealOrder, + revealOrder.toLowerCase() + ); + + break; + } + + case "forward": + case "backward": { + error( + '"%s" is not a valid value for revealOrder on . ' + + 'React uses the -s suffix in the spelling. Use "%ss" instead.', + revealOrder, + revealOrder.toLowerCase() + ); + + break; + } + + default: + error( + '"%s" is not a supported revealOrder on . ' + + 'Did you mean "together", "forwards" or "backwards"?', + revealOrder + ); + + break; + } + } else { + error( + "%s is not a supported value for revealOrder on . " + + 'Did you mean "together", "forwards" or "backwards"?', + revealOrder + ); + } + } + } + } + + function validateTailOptions(tailMode, revealOrder) { + { + if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) { + if (tailMode !== "collapsed" && tailMode !== "hidden") { + didWarnAboutTailOptions[tailMode] = true; + + 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 + ); + } + } + } + } + + function validateSuspenseListNestedChild(childSlot, index) { + { + var isAnArray = isArray(childSlot); + var isIterable = + !isAnArray && typeof getIteratorFn(childSlot) === "function"; + + if (isAnArray || isIterable) { + var type = isAnArray ? "array" : "iterable"; + + error( + "A nested %s was passed to row #%s in . Wrap it in " + + "an additional SuspenseList to configure its revealOrder: " + + " ... " + + "{%s} ... " + + "", + type, + index, + type + ); + + return false; + } + } + + return true; + } + + 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); + + if (typeof iteratorFn === "function") { + var childrenIterator = iteratorFn.call(children); + + if (childrenIterator) { + var step = childrenIterator.next(); + var _i = 0; + + for (; !step.done; step = childrenIterator.next()) { + if (!validateSuspenseListNestedChild(step.value, _i)) { + return; + } + + _i++; + } + } + } else { + error( + 'A single row was passed to a . ' + + "This is not useful since it needs multiple rows. " + + "Did you mean to pass multiple children or an array?", + revealOrder + ); + } + } + } + } + } + + function initSuspenseListRenderState( + workInProgress, + isBackwards, + tail, + lastContentRow, + tailMode + ) { + var renderState = workInProgress.memoizedState; + + if (renderState === null) { + workInProgress.memoizedState = { + isBackwards: isBackwards, + rendering: null, + renderingStartTime: 0, + last: lastContentRow, + tail: tail, + tailMode: tailMode + }; + } else { + // We can reuse the existing object from previous renders. + renderState.isBackwards = isBackwards; + renderState.rendering = null; + renderState.renderingStartTime = 0; + renderState.last = lastContentRow; + renderState.tail = tail; + renderState.tailMode = tailMode; + } + } // This can end up rendering this component multiple passes. + // The first pass splits the children fibers into two sets. A head and tail. + // We first render the head. If anything is in fallback state, we do another + // pass through beginWork to rerender all children (including the tail) with + // the force suspend context. If the first render didn't have anything in + // in fallback state. Then we render each row in the tail one-by-one. + // That happens in the completeWork phase without going back to beginWork. + + 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 = hasSuspenseListContext( + suspenseContext, + ForceSuspenseFallback + ); + + if (shouldForceFallback) { + suspenseContext = setShallowSuspenseListContext( + suspenseContext, + ForceSuspenseFallback + ); + workInProgress.flags |= DidCapture; + } else { + var didSuspendBefore = + current !== null && (current.flags & DidCapture) !== NoFlags$1; + + if (didSuspendBefore) { + // If we previously forced a fallback, we need to schedule work + // on any nested boundaries to let them know to try to render + // again. This is the same as context updating. + propagateSuspenseContextChange( + workInProgress, + workInProgress.child, + renderLanes + ); + } + + suspenseContext = setDefaultShallowSuspenseListContext(suspenseContext); + } + + pushSuspenseListContext(workInProgress, suspenseContext); + + 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 { + switch (revealOrder) { + case "forwards": { + var lastContentRow = findLastContentRow(workInProgress.child); + var tail; + + if (lastContentRow === null) { + // The whole list is part of the tail. + // TODO: We could fast path by just rendering the tail now. + tail = workInProgress.child; + workInProgress.child = null; + } else { + // Disconnect the tail rows after the content row. + // We're going to render them separately later. + tail = lastContentRow.sibling; + lastContentRow.sibling = null; + } + + initSuspenseListRenderState( + workInProgress, + false, // isBackwards + tail, + lastContentRow, + tailMode + ); + break; + } + + case "backwards": { + // We're going to find the first row that has existing content. + // At the same time we're going to reverse the list of everything + // we pass in the meantime. That's going to be our tail in reverse + // order. + var _tail = null; + var row = workInProgress.child; + workInProgress.child = null; + + while (row !== null) { + var currentRow = row.alternate; // New rows can't be content rows. + + if ( + currentRow !== null && + findFirstSuspended(currentRow) === null + ) { + // This is the beginning of the main content. + workInProgress.child = row; + break; + } + + var nextRow = row.sibling; + row.sibling = _tail; + _tail = row; + row = nextRow; + } // TODO: If workInProgress.child is null, we can continue on the tail immediately. + + initSuspenseListRenderState( + workInProgress, + true, // isBackwards + _tail, + null, // last + tailMode + ); + break; + } + + case "together": { + initSuspenseListRenderState( + workInProgress, + false, // isBackwards + null, // tail + null, // last + undefined + ); + break; + } + + default: { + // The default reveal order is the same as not having + // a boundary. + workInProgress.memoizedState = null; + } + } + } + + return workInProgress.child; + } + + function updatePortalComponent(current, workInProgress, renderLanes) { + pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); + var nextChildren = workInProgress.pendingProps; + + if (current === null) { + // Portals are special because we don't append the children during mount + // but at commit. Therefore we need to track insertions which the normal + // flow doesn't do during mount. This doesn't happen at the root because + // the root always starts with a "current" with a null child. + // TODO: Consider unifying this with how the root works. + workInProgress.child = reconcileChildFibers( + workInProgress, + null, + nextChildren, + renderLanes + ); + } else { + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + } + + return workInProgress.child; + } + + var hasWarnedAboutUsingNoValuePropOnContextProvider = false; + + function updateContextProvider(current, workInProgress, renderLanes) { + var context; + + { + context = workInProgress.type._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?" + ); + } + } + } + + 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); + } + } + } + + var newChildren = newProps.children; + reconcileChildren(current, workInProgress, newChildren, renderLanes); + return workInProgress.child; + } + + function updateContextConsumer(current, workInProgress, renderLanes) { + var context; + + { + context = workInProgress.type; + + { + if (context._context !== undefined) { + context = context._context; + } + } + } + + 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." + ); + } + } + + prepareToReadContext(workInProgress, renderLanes); + var newValue = readContext(context); + + var newChildren; + + { + ReactCurrentOwner$2.current = workInProgress; + setIsRendering(true); + newChildren = render(newValue); + setIsRendering(false); + } + + workInProgress.flags |= PerformedWork; + reconcileChildren(current, workInProgress, newChildren, renderLanes); + return workInProgress.child; + } + + function markWorkInProgressReceivedUpdate() { + didReceiveUpdate = true; + } + + function resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress) { + if ((workInProgress.mode & ConcurrentMode) === NoMode) { + if (current !== null) { + // A lazy component only mounts if it suspended inside a non- + // concurrent tree, in an inconsistent state. We want to treat it like + // a new mount, even though an empty version of it already committed. + // Disconnect the alternate pointers. + current.alternate = null; + workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect + + workInProgress.flags |= Placement; + } + } + } + + function bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderLanes + ) { + if (current !== null) { + // Reuse previous dependencies + 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. + { + 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) { + { + var returnFiber = oldWorkInProgress.return; + + if (returnFiber === null) { + // eslint-disable-next-line react-internal/prod-error-codes + throw new Error("Cannot swap the root fiber."); + } // Disconnect from the old current. + // It will get deleted. + + current.alternate = null; + oldWorkInProgress.alternate = null; // Connect to the new tree. + + newWorkInProgress.index = oldWorkInProgress.index; + newWorkInProgress.sibling = oldWorkInProgress.sibling; + newWorkInProgress.return = oldWorkInProgress.return; + newWorkInProgress.ref = oldWorkInProgress.ref; + + { + newWorkInProgress._debugInfo = oldWorkInProgress._debugInfo; + } // Replace the child/sibling pointers above it. + + if (oldWorkInProgress === returnFiber.child) { + returnFiber.child = newWorkInProgress; + } else { + var prevSibling = returnFiber.child; + + if (prevSibling === null) { + // eslint-disable-next-line react-internal/prod-error-codes + throw new Error("Expected parent to have a child."); + } // $FlowFixMe[incompatible-use] found when upgrading Flow + + while (prevSibling.sibling !== oldWorkInProgress) { + // $FlowFixMe[incompatible-use] found when upgrading Flow + prevSibling = prevSibling.sibling; + + if (prevSibling === null) { + // eslint-disable-next-line react-internal/prod-error-codes + throw new Error("Expected to find the previous sibling."); + } + } // $FlowFixMe[incompatible-use] found when upgrading Flow + + prevSibling.sibling = newWorkInProgress; + } // Delete the old fiber and place the new one. + // Since the old fiber is disconnected, we have to schedule it manually. + + var deletions = returnFiber.deletions; + + if (deletions === null) { + returnFiber.deletions = [current]; + returnFiber.flags |= ChildDeletion; + } else { + deletions.push(current); + } + + newWorkInProgress.flags |= Placement; // Restart work from the new fiber. + + return newWorkInProgress; + } + } + + function checkScheduledUpdateOrContext(current, renderLanes) { + // Before performing an early bailout, we must check if there are pending + // updates or context. + var updateLanes = current.lanes; + + if (includesSomeLane(updateLanes, renderLanes)) { + return true; + } // No pending update, but because context is propagated lazily, we need + + return false; + } + + function attemptEarlyBailoutIfNoScheduledUpdate( + current, + workInProgress, + renderLanes + ) { + // This fiber does not have any pending work. Bailout without entering + // the begin phase. There's still some bookkeeping we that needs to be done + // in this optimized path, mostly pushing stuff onto the stack. + switch (workInProgress.tag) { + case HostRoot: + pushHostRootContext(workInProgress); + break; + + case HostSingleton: + case HostComponent: + pushHostContext(workInProgress); + break; + + case ClassComponent: { + break; + } + + case HostPortal: + pushHostContainer( + workInProgress, + workInProgress.stateNode.containerInfo + ); + break; + + case ContextProvider: { + var newValue = workInProgress.memoizedProps.value; + var context; + + { + context = workInProgress.type._context; + } + + pushProvider(workInProgress, context, newValue); + break; + } + + case Profiler: + { + // Profiler should only call onRender when one of its descendants actually rendered. + var hasChildWork = includesSomeLane( + renderLanes, + workInProgress.childLanes + ); + + if (hasChildWork) { + workInProgress.flags |= Update; + } + + { + // Reset effect durations for the next eventual effect phase. + // These are reset during render to allow the DevTools commit hook a chance to read them, + var stateNode = workInProgress.stateNode; + stateNode.effectDuration = 0; + stateNode.passiveEffectDuration = 0; + } + } + + break; + + case SuspenseComponent: { + var state = workInProgress.memoizedState; + + if (state !== null) { + if (state.dehydrated !== null) { + // We're not going to render the children, so this is just to maintain + // push/pop symmetry + pushPrimaryTreeSuspenseHandler(workInProgress); // We know that this component will suspend again because if it has + // been unsuspended it has committed as a resolved Suspense component. + // If it needs to be retried, it should have work scheduled on it. + + workInProgress.flags |= DidCapture; // We should never render the children of a dehydrated boundary until we + // upgrade it. We return null instead of bailoutOnAlreadyFinishedWork. + + return null; + } // If this boundary is currently timed out, we need to decide + // whether to retry the primary children, or to skip over it and + // go straight to the fallback. Check the priority of the primary + // child fragment. + + var primaryChildFragment = workInProgress.child; + var primaryChildLanes = primaryChildFragment.childLanes; + + if (includesSomeLane(renderLanes, primaryChildLanes)) { + // The primary children have pending work. Use the normal path + // to attempt to render the primary children again. + return updateSuspenseComponent( + current, + workInProgress, + renderLanes + ); + } else { + // The primary child fragment does not have pending work marked + // on it + pushPrimaryTreeSuspenseHandler(workInProgress); // The primary children do not have pending work with sufficient + // priority. Bailout. + + var child = bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderLanes + ); + + if (child !== null) { + // The fallback children have pending work. Skip over the + // primary children and work on the fallback. + return child.sibling; + } else { + // 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 { + pushPrimaryTreeSuspenseHandler(workInProgress); + } + + break; + } + + case SuspenseListComponent: { + var didSuspendBefore = (current.flags & DidCapture) !== NoFlags$1; + + var _hasChildWork = includesSomeLane( + renderLanes, + workInProgress.childLanes + ); + + if (didSuspendBefore) { + if (_hasChildWork) { + // If something was in fallback state last time, and we have all the + // same children then we're still in progressive loading state. + // Something might get unblocked by state updates or retries in the + // tree which will affect the tail. So we need to use the normal + // path to compute the correct tail. + return updateSuspenseListComponent( + current, + workInProgress, + renderLanes + ); + } // If none of the children had any work, that means that none of + // them got retried so they'll still be blocked in the same way + // as before. We can fast bail out. + + workInProgress.flags |= DidCapture; + } // If nothing suspended before and we're rendering the same children, + // then the tail doesn't matter. Anything new that suspends will work + // in the "together" mode, so we can continue from the state we had. + + var renderState = workInProgress.memoizedState; + + if (renderState !== null) { + // Reset to the "together" mode in case we've started a different + // update in the past but didn't complete it. + renderState.rendering = null; + renderState.tail = null; + renderState.lastEffect = null; + } + + pushSuspenseListContext(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; + } + } + + 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); + } + } + + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + } + + function beginWork(current, workInProgress, 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 + ) + ); + } + } + + 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 { + // Neither props nor legacy context changes. Check if there's a pending + // update or context change. + var hasScheduledUpdateOrContext = checkScheduledUpdateOrContext( + current, + renderLanes + ); + + if ( + !hasScheduledUpdateOrContext && // If this is the second pass of an error or suspense boundary, there + // may not be work scheduled on `current`, so we check for this flag. + (workInProgress.flags & DidCapture) === NoFlags$1 + ) { + // No pending updates or context. Bail out now. + didReceiveUpdate = false; + return attemptEarlyBailoutIfNoScheduledUpdate( + current, + workInProgress, + renderLanes + ); + } + + if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags$1) { + // 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. + + workInProgress.lanes = NoLanes; + + switch (workInProgress.tag) { + case IndeterminateComponent: { + return mountIndeterminateComponent( + current, + workInProgress, + workInProgress.type, + renderLanes + ); + } + + case LazyComponent: { + var elementType = workInProgress.elementType; + return mountLazyComponent( + current, + workInProgress, + elementType, + renderLanes + ); + } + + 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 ClassComponent: { + var _Component = workInProgress.type; + var _unresolvedProps = workInProgress.pendingProps; + + var _resolvedProps = + workInProgress.elementType === _Component + ? _unresolvedProps + : resolveDefaultProps(_Component, _unresolvedProps); + + return updateClassComponent( + current, + workInProgress, + _Component, + _resolvedProps, + renderLanes + ); + } + + case HostRoot: + return updateHostRoot(current, workInProgress, renderLanes); + + case HostHoistable: + + // Fall through + + case HostSingleton: + + // Fall through + + case HostComponent: + return updateHostComponent$1(current, workInProgress, renderLanes); + + case HostText: + return updateHostText$1(); + + case SuspenseComponent: + return updateSuspenseComponent(current, workInProgress, renderLanes); + + case HostPortal: + return updatePortalComponent(current, workInProgress, renderLanes); + + case ForwardRef: { + var type = workInProgress.type; + var _unresolvedProps2 = workInProgress.pendingProps; + + var _resolvedProps2 = + workInProgress.elementType === type + ? _unresolvedProps2 + : resolveDefaultProps(type, _unresolvedProps2); + + return updateForwardRef( + current, + workInProgress, + type, + _resolvedProps2, + renderLanes + ); + } + + case Fragment: + return updateFragment(current, workInProgress, renderLanes); + + case Mode: + return updateMode(current, workInProgress, renderLanes); + + case Profiler: + return updateProfiler(current, workInProgress, renderLanes); + + case ContextProvider: + return updateContextProvider(current, workInProgress, renderLanes); + + case ContextConsumer: + return updateContextConsumer(current, workInProgress, renderLanes); + + case MemoComponent: { + var _type = workInProgress.type; + var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props. + + var _resolvedProps3 = resolveDefaultProps(_type, _unresolvedProps3); + + _resolvedProps3 = resolveDefaultProps(_type.type, _resolvedProps3); + return updateMemoComponent( + current, + workInProgress, + _type, + _resolvedProps3, + renderLanes + ); + } + + case SimpleMemoComponent: { + return updateSimpleMemoComponent( + current, + workInProgress, + workInProgress.type, + workInProgress.pendingProps, + renderLanes + ); + } + + case IncompleteClassComponent: { + var _Component2 = workInProgress.type; + var _unresolvedProps4 = workInProgress.pendingProps; + + var _resolvedProps4 = + workInProgress.elementType === _Component2 + ? _unresolvedProps4 + : resolveDefaultProps(_Component2, _unresolvedProps4); + + return mountIncompleteClassComponent( + current, + workInProgress, + _Component2, + _resolvedProps4, + renderLanes + ); + } + + case SuspenseListComponent: { + return updateSuspenseListComponent( + current, + workInProgress, + renderLanes + ); + } + + case ScopeComponent: { + break; + } + + case OffscreenComponent: { + return updateOffscreenComponent(current, workInProgress, renderLanes); + } + } + + throw new Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in " + + "React. Please file an issue." + ); + } + + var valueCursor = createCursor(null); + + var renderer2CursorDEV; + + { + renderer2CursorDEV = createCursor(null); + } + + var rendererSigil; + + { + // Use this to detect multiple renderers using the same context + rendererSigil = {}; + } + + var currentlyRenderingFiber = null; + var lastContextDependency = 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; + lastFullyObservedContext = null; + + { + isDisallowedContextReadInDEV = false; + } + } + function enterDisallowedContextReadInDEV() { + { + isDisallowedContextReadInDEV = true; + } + } + function exitDisallowedContextReadInDEV() { + { + isDisallowedContextReadInDEV = false; + } + } + function pushProvider(providerFiber, context, nextValue) { + { + push(valueCursor, context._currentValue2, providerFiber); + context._currentValue2 = nextValue; + + { + push(renderer2CursorDEV, context._currentRenderer2, providerFiber); + + if ( + context._currentRenderer2 !== undefined && + context._currentRenderer2 !== null && + context._currentRenderer2 !== rendererSigil + ) { + error( + "Detected multiple renderers concurrently rendering the " + + "same context provider. This is currently unsupported." + ); + } + + context._currentRenderer2 = rendererSigil; + } + } + } + function popProvider(context, providerFiber) { + var currentValue = valueCursor.current; + + { + context._currentValue2 = currentValue; + + { + var currentRenderer2 = renderer2CursorDEV.current; + pop(renderer2CursorDEV, providerFiber); + context._currentRenderer2 = currentRenderer2; + } + } + + pop(valueCursor, providerFiber); + } + function scheduleContextWorkOnParentPath( + parent, + renderLanes, + propagationRoot + ) { + // Update the child lanes of all the ancestors, including the alternates. + var node = parent; + + while (node !== null) { + var alternate = node.alternate; + + if (!isSubsetOfLanes(node.childLanes, renderLanes)) { + node.childLanes = mergeLanes(node.childLanes, renderLanes); + + if (alternate !== null) { + alternate.childLanes = mergeLanes( + alternate.childLanes, + renderLanes + ); + } + } else if ( + alternate !== null && + !isSubsetOfLanes(alternate.childLanes, renderLanes) + ) { + alternate.childLanes = mergeLanes(alternate.childLanes, renderLanes); + } else; + + if (node === propagationRoot) { + break; + } + + node = node.return; + } + + { + if (node !== propagationRoot) { + error( + "Expected to find the propagation root when scheduling context work. " + + "This error is likely caused by a bug in React. Please file an issue." + ); + } + } + } + function propagateContextChange(workInProgress, context, renderLanes) { + { + propagateContextChange_eager(workInProgress, context, renderLanes); + } + } + + function propagateContextChange_eager( + workInProgress, + context, + renderLanes + ) { + var fiber = workInProgress.child; + + if (fiber !== null) { + // Set the return pointer of the child to the work-in-progress fiber. + fiber.return = workInProgress; + } + + while (fiber !== null) { + var nextFiber = void 0; // Visit this fiber. + + var list = fiber.dependencies; + + if (list !== null) { + nextFiber = fiber.child; + var dependency = list.firstContext; + + while (dependency !== null) { + // Check if the context matches. + 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 lane = pickArbitraryLane(renderLanes); + var update = createUpdate(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; + } + + sharedQueue.pending = update; + } + } + + fiber.lanes = mergeLanes(fiber.lanes, renderLanes); + var alternate = fiber.alternate; + + if (alternate !== null) { + alternate.lanes = mergeLanes(alternate.lanes, renderLanes); + } + + scheduleContextWorkOnParentPath( + fiber.return, + renderLanes, + workInProgress + ); // Mark the updated lanes on the list, too. + + list.lanes = mergeLanes(list.lanes, renderLanes); // Since we already found a match, we can stop traversing the + // dependency list. + + break; + } + + dependency = dependency.next; + } + } else if (fiber.tag === ContextProvider) { + // Don't scan deeper if this is a matching provider + nextFiber = fiber.type === workInProgress.type ? null : fiber.child; + } else if (fiber.tag === DehydratedFragment) { + // If a dehydrated suspense boundary is in this subtree, we don't know + // if it will have any context consumers in it. The best we can do is + // mark it as having updates. + var parentSuspense = fiber.return; + + if (parentSuspense === null) { + throw new Error( + "We just came from a parent so we must have had a parent. This is a bug in React." + ); + } + + parentSuspense.lanes = mergeLanes(parentSuspense.lanes, renderLanes); + var _alternate = parentSuspense.alternate; + + if (_alternate !== null) { + _alternate.lanes = mergeLanes(_alternate.lanes, renderLanes); + } // This is intentionally passing this fiber as the parent + // because we want to schedule this fiber as having work + // on its children. We'll use the childLanes on + // this fiber to indicate that a context has changed. + + scheduleContextWorkOnParentPath( + parentSuspense, + renderLanes, + workInProgress + ); + nextFiber = fiber.sibling; + } else { + // Traverse down. + nextFiber = fiber.child; + } + + if (nextFiber !== null) { + // Set the return pointer of the child to the work-in-progress fiber. + nextFiber.return = fiber; + } else { + // No child. Traverse to next sibling. + nextFiber = fiber; + + while (nextFiber !== null) { + if (nextFiber === workInProgress) { + // We're back to the root of this subtree. Exit. + nextFiber = null; + break; + } + + var sibling = nextFiber.sibling; + + if (sibling !== null) { + // Set the return pointer of the sibling to the work-in-progress fiber. + sibling.return = nextFiber.return; + nextFiber = sibling; + break; + } // No more siblings. Traverse up. + + nextFiber = nextFiber.return; + } + } + + fiber = nextFiber; + } + } + function prepareToReadContext(workInProgress, renderLanes) { + currentlyRenderingFiber = workInProgress; + lastContextDependency = null; + lastFullyObservedContext = null; + var dependencies = workInProgress.dependencies; + + if (dependencies !== null) { + { + 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 + + dependencies.firstContext = null; + } + } + } + } + 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. + if (isDisallowedContextReadInDEV) { + 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()." + ); + } + } + + return readContextForConsumer(currentlyRenderingFiber, context); + } + function readContextDuringReconciliation(consumer, context, renderLanes) { + if (currentlyRenderingFiber === null) { + prepareToReadContext(consumer, renderLanes); + } + + return readContextForConsumer(consumer, context); + } + + function readContextForConsumer(consumer, context) { + var value = context._currentValue2; + + if (lastFullyObservedContext === context); + else { + var contextItem = { + context: context, + memoizedValue: value, + next: null + }; + + if (lastContextDependency === null) { + if (consumer === null) { + throw new Error( + "Context can only be read while React is rendering. " + + "In classes, you can read it in the render method or getDerivedStateFromProps. " + + "In function components, you can read it directly in the function body, but not " + + "inside Hooks like useReducer() or useMemo()." + ); + } // This is the first dependency for this component. Create a new list. + + lastContextDependency = contextItem; + consumer.dependencies = { + lanes: NoLanes, + firstContext: contextItem + }; + } else { + // Append a new context item. + lastContextDependency = lastContextDependency.next = contextItem; + } + } + + return value; + } + + var ReactCurrentBatchConfig$1 = + ReactSharedInternals.ReactCurrentBatchConfig; + function requestCurrentTransition() { + var transition = ReactCurrentBatchConfig$1.transition; + + if (transition !== null) { + // Whenever a transition update is scheduled, register a callback on the + // transition object so we can get the return value of the scope function. + transition._callbacks.add(handleAsyncAction); + } + + return transition; + } + + function handleAsyncAction(transition, thenable) {} + + function notifyTransitionCallbacks(transition, returnValue) { + var callbacks = transition._callbacks; + callbacks.forEach(function (callback) { + return callback(transition, returnValue); + }); + } // When retrying a Suspense/Offscreen boundary, we restore the cache that was + function getSuspendedCache() { + { + return null; + } // This function is called when a Suspense boundary suspends. It returns the + } + + /** + * Tag the fiber with an update effect. This turns a Placement into + * a PlacementAndUpdate. + */ + + function markUpdate(workInProgress) { + workInProgress.flags |= Update; + } + /** + * In persistent mode, return whether this update needs to clone the subtree. + */ + + function doesRequireClone(current, completedWork) { + var didBailout = + current !== null && current.child === completedWork.child; + + if (didBailout) { + return false; + } + + if ((completedWork.flags & ChildDeletion) !== NoFlags$1) { + return true; + } // TODO: If we move the `doesRequireClone` call after `bubbleProperties` + // then we only have to check the `completedWork.subtreeFlags`. + + var child = completedWork.child; + + while (child !== null) { + if ( + (child.flags & MutationMask) !== NoFlags$1 || + (child.subtreeFlags & MutationMask) !== NoFlags$1 + ) { + return true; + } + + child = child.sibling; + } + + return false; + } + + function appendAllChildren( + parent, + workInProgress, + needsVisibilityToggle, + isHidden + ) { + { + // We only have the top Fiber that was created but we need recurse down its + // children to find all the terminal nodes. + var _node = workInProgress.child; + + while (_node !== null) { + if (_node.tag === HostComponent) { + var instance = _node.stateNode; + + if (needsVisibilityToggle && isHidden) { + instance = cloneHiddenInstance(instance); + } + + appendInitialChild(parent, instance); + } else if (_node.tag === HostText) { + var _instance = _node.stateNode; + + if (needsVisibilityToggle && isHidden) { + _instance = cloneHiddenTextInstance(); + } + + appendInitialChild(parent, _instance); + } else if (_node.tag === HostPortal); + else if ( + _node.tag === OffscreenComponent && + _node.memoizedState !== null + ) { + // The children in this boundary are hidden. Toggle their visibility + // before appending. + var child = _node.child; + + if (child !== null) { + child.return = _node; + } + + appendAllChildren( + parent, + _node, + /* needsVisibilityToggle */ + true, + /* isHidden */ + true + ); + } else if (_node.child !== null) { + _node.child.return = _node; + _node = _node.child; + continue; + } + + if (_node === workInProgress) { + return; + } // $FlowFixMe[incompatible-use] found when upgrading Flow + + while (_node.sibling === null) { + // $FlowFixMe[incompatible-use] found when upgrading Flow + if (_node.return === null || _node.return === workInProgress) { + return; + } + + _node = _node.return; + } // $FlowFixMe[incompatible-use] found when upgrading Flow + + _node.sibling.return = _node.return; + _node = _node.sibling; + } + } + } // An unfortunate fork of appendAllChildren because we have two different parent types. + + function appendAllChildrenToContainer( + containerChildSet, + workInProgress, + needsVisibilityToggle, + isHidden + ) { + { + // We only have the top Fiber that was created but we need recurse down its + // children to find all the terminal nodes. + var node = workInProgress.child; + + while (node !== null) { + // eslint-disable-next-line no-labels + if (node.tag === HostComponent) { + var instance = node.stateNode; + + if (needsVisibilityToggle && isHidden) { + instance = cloneHiddenInstance(instance); + } + + appendChildToContainerChildSet(containerChildSet, instance); + } else if (node.tag === HostText) { + var _instance2 = node.stateNode; + + if (needsVisibilityToggle && isHidden) { + _instance2 = cloneHiddenTextInstance(); + } + + appendChildToContainerChildSet(containerChildSet, _instance2); + } else if (node.tag === HostPortal); + else if ( + node.tag === OffscreenComponent && + node.memoizedState !== null + ) { + // The children in this boundary are hidden. Toggle their visibility + // before appending. + var child = node.child; + + if (child !== null) { + child.return = node; + } // If Offscreen is not in manual mode, detached tree is hidden from user space. + + var _needsVisibilityToggle = !isOffscreenManual(node); + + appendAllChildrenToContainer( + containerChildSet, + node, + /* needsVisibilityToggle */ + _needsVisibilityToggle, + /* isHidden */ + true + ); + } else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; + } + + node = node; + + if (node === workInProgress) { + return; + } // $FlowFixMe[incompatible-use] found when upgrading Flow + + while (node.sibling === null) { + // $FlowFixMe[incompatible-use] found when upgrading Flow + if (node.return === null || node.return === workInProgress) { + return; + } + + node = node.return; + } // $FlowFixMe[incompatible-use] found when upgrading Flow + + node.sibling.return = node.return; + node = node.sibling; + } + } + } + + function updateHostContainer(current, workInProgress) { + { + if (doesRequireClone(current, workInProgress)) { + var portalOrRoot = workInProgress.stateNode; + var container = portalOrRoot.containerInfo; + var newChildSet = createContainerChildSet(); // If children might have changed, we have to add them all to the set. + + appendAllChildrenToContainer( + newChildSet, + workInProgress, + /* needsVisibilityToggle */ + false, + /* isHidden */ + false + ); + portalOrRoot.pendingChildren = newChildSet; // Schedule an update on the container to swap out the container. + + markUpdate(workInProgress); + finalizeContainerChildren(container, newChildSet); + } + } + } + + function updateHostComponent( + current, + workInProgress, + type, + newProps, + renderLanes + ) { + { + var currentInstance = current.stateNode; + var _oldProps = current.memoizedProps; // If there are no effects associated with this node, then none of our children had any updates. + // This guarantees that we can reuse all of them. + + var requiresClone = doesRequireClone(current, workInProgress); + + if (!requiresClone && _oldProps === newProps) { + // No changes, just reuse the existing instance. + // Note that this might release a previous clone. + workInProgress.stateNode = currentInstance; + return; + } + + getHostContext(); + var newChildSet = null; + + if (requiresClone && passChildrenWhenCloningPersistedNodes) { + newChildSet = createContainerChildSet(); // If children might have changed, we have to add them all to the set. + + appendAllChildrenToContainer( + newChildSet, + workInProgress, + /* needsVisibilityToggle */ + false, + /* isHidden */ + false + ); + } + + var newInstance = cloneInstance( + currentInstance, + type, + _oldProps, + newProps, + !requiresClone, + newChildSet + ); + + if (newInstance === currentInstance) { + // No changes, just reuse the existing instance. + // Note that this might release a previous clone. + workInProgress.stateNode = currentInstance; + return; + } // Certain renderers require commit-time effects for initial mount. + + workInProgress.stateNode = newInstance; + + if (!requiresClone) { + // If there are no other effects in this tree, we need to flag this node as having one. + // Even though we're not going to use it for anything. + // Otherwise parents won't know that there are new children to propagate upwards. + markUpdate(workInProgress); + } else { + // If children might have changed, we have to add them all to the set. + appendAllChildren( + newInstance, + workInProgress, + /* needsVisibilityToggle */ + false, + /* isHidden */ + false + ); + } + } + } // This function must be called at the very end of the complete phase, because + // it might throw to suspend, and if the resource immediately loads, the work + // loop will resume rendering as if the work-in-progress completed. So it must + // fully complete. + // TODO: This should ideally move to begin phase, but currently the instance is + // not created until the complete phase. For our existing use cases, host nodes + // that suspend don't have children, so it doesn't matter. But that might not + // always be true in the future. + + function preloadInstanceAndSuspendIfNeeded( + workInProgress, + type, + props, + renderLanes + ) { + { + // If this flag was set previously, we can remove it. The flag + // represents whether this particular set of props might ever need to + // suspend. The safest thing to do is for maySuspendCommit to always + // return true, but if the renderer is reasonably confident that the + // underlying resource won't be evicted, it can return false as a + // performance optimization. + workInProgress.flags &= ~MaySuspendCommit; + return; + } // Mark this fiber with a flag. This gets set on all host instances + } + + function scheduleRetryEffect(workInProgress, retryQueue) { + var wakeables = retryQueue; + + if (wakeables !== null) { + // Schedule an effect to attach a retry listener to the promise. + // TODO: Move to passive phase + workInProgress.flags |= Update; + } else { + // This boundary suspended, but no wakeables were added to the retry + // queue. Check if the renderer suspended commit. If so, this means + // that once the fallback is committed, we can immediately retry + // rendering again, because rendering wasn't actually blocked. Only + // the commit phase. + // TODO: Consider a model where we always schedule an immediate retry, even + // for normal Suspense. That way the retry can partially render up to the + // first thing that suspends. + if (workInProgress.flags & ScheduleRetry) { + var retryLane = // TODO: This check should probably be moved into claimNextRetryLane + // I also suspect that we need some further consolidation of offscreen + // and retry lanes. + workInProgress.tag !== OffscreenComponent + ? claimNextRetryLane() + : OffscreenLane; + workInProgress.lanes = mergeLanes(workInProgress.lanes, retryLane); + } + } + } + + function updateHostText(current, workInProgress, oldText, newText) { + { + if (oldText !== newText) { + // If the text content differs, we'll create a new text instance for it. + var rootContainerInstance = getRootHostContainer(); + var currentHostContext = getHostContext(); + workInProgress.stateNode = createTextInstance( + newText, + rootContainerInstance, + currentHostContext, + workInProgress + ); // We'll have to mark it as having an effect, even though we won't use the effect for anything. + // This lets the parents know that at least one of their children has changed. + + markUpdate(workInProgress); + } else { + workInProgress.stateNode = current.stateNode; + } + } + } + + function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { + switch (renderState.tailMode) { + case "hidden": { + // Any insertions at the end of the tail list after this point + // should be invisible. If there are already mounted boundaries + // anything before them are not considered for collapsing. + // Therefore we need to go through the whole tail to find if + // there are any. + var tailNode = renderState.tail; + var lastTailNode = null; + + while (tailNode !== null) { + if (tailNode.alternate !== null) { + lastTailNode = tailNode; + } + + tailNode = tailNode.sibling; + } // Next we're simply going to delete all insertions after the + // last rendered item. + + if (lastTailNode === null) { + // All remaining items in the tail are insertions. + renderState.tail = null; + } else { + // Detach the insertion after the last node that was already + // inserted. + lastTailNode.sibling = null; + } + + break; + } + + case "collapsed": { + // Any insertions at the end of the tail list after this point + // should be invisible. If there are already mounted boundaries + // anything before them are not considered for collapsing. + // Therefore we need to go through the whole tail to find if + // there are any. + var _tailNode = renderState.tail; + var _lastTailNode = null; + + while (_tailNode !== null) { + if (_tailNode.alternate !== null) { + _lastTailNode = _tailNode; + } + + _tailNode = _tailNode.sibling; + } // Next we're simply going to delete all insertions after the + // last rendered item. + + if (_lastTailNode === null) { + // All remaining items in the tail are insertions. + if (!hasRenderedATailFallback && renderState.tail !== null) { + // We suspended during the head. We want to show at least one + // row at the tail. So we'll keep on and cut off the rest. + renderState.tail.sibling = null; + } else { + renderState.tail = null; + } + } else { + // Detach the insertion after the last node that was already + // inserted. + _lastTailNode.sibling = null; + } + + break; + } + } + } + + function bubbleProperties(completedWork) { + var didBailout = + completedWork.alternate !== null && + completedWork.alternate.child === completedWork.child; + var newChildLanes = NoLanes; + var subtreeFlags = NoFlags$1; + + 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. + // $FlowFixMe[unsafe-addition] addition with possible null/undefined value + + actualDuration += child.actualDuration; // $FlowFixMe[unsafe-addition] addition with possible null/undefined value + + 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; // $FlowFixMe[unsafe-addition] addition with possible null/undefined value + + _treeBaseDuration += _child2.treeBaseDuration; + _child2 = _child2.sibling; + } + + completedWork.treeBaseDuration = _treeBaseDuration; + } else { + var _child3 = completedWork.child; + + while (_child3 !== null) { + newChildLanes = mergeLanes( + newChildLanes, + mergeLanes(_child3.lanes, _child3.childLanes) + ); // "Static" flags share the lifetime of the fiber/hook they belong to, + // so we should bubble those up even during a bailout. All the other + // flags have a lifetime only of a single render + commit, so we should + // ignore them. + + subtreeFlags |= _child3.subtreeFlags & StaticMask; + subtreeFlags |= _child3.flags & StaticMask; // Update the return pointer so the tree is consistent. This is a code + // smell because it assumes the commit phase is never concurrent with + // the render phase. Will address during refactor to alternate model. + + _child3.return = completedWork; + _child3 = _child3.sibling; + } + } + + completedWork.subtreeFlags |= subtreeFlags; + } + + completedWork.childLanes = newChildLanes; + return didBailout; + } + + function completeDehydratedSuspenseBoundary( + current, + workInProgress, + nextState + ) { + var wasHydrated = popHydrationState(); + + if (nextState !== null && nextState.dehydrated !== null) { + // We might be inside a hydration state the first time we're picking up this + // Suspense boundary, and also after we've reentered it for further hydration. + if (current === null) { + if (!wasHydrated) { + throw new Error( + "A dehydrated suspense component was completed without a hydrated node. " + + "This is probably a bug in React." + ); + } + + prepareToHydrateHostSuspenseInstance(); + bubbleProperties(workInProgress); + + { + if ((workInProgress.mode & ProfileMode) !== NoMode) { + var isTimedOutSuspense = nextState !== null; + + if (isTimedOutSuspense) { + // Don't count time spent in a timed out Suspense subtree as part of the base duration. + var primaryChildFragment = workInProgress.child; + + if (primaryChildFragment !== null) { + // $FlowFixMe[unsafe-arithmetic] Flow doesn't support type casting in combination with the -= operator + workInProgress.treeBaseDuration -= + primaryChildFragment.treeBaseDuration; + } + } + } + } + + return false; + } else { + if ((workInProgress.flags & DidCapture) === NoFlags$1) { + // This boundary did not suspend so it's now hydrated and unsuspended. + workInProgress.memoizedState = null; + } // If nothing suspended, we need to schedule an effect to mark this boundary + // as having hydrated so events know that they're free to be invoked. + // It's also a signal to replay events and the suspense callback. + // If something suspended, schedule an effect to attach retry listeners. + // So we might as well always mark this. + + workInProgress.flags |= Update; + bubbleProperties(workInProgress); + + { + if ((workInProgress.mode & ProfileMode) !== NoMode) { + var _isTimedOutSuspense = nextState !== null; + + if (_isTimedOutSuspense) { + // Don't count time spent in a timed out Suspense subtree as part of the base duration. + var _primaryChildFragment = workInProgress.child; + + if (_primaryChildFragment !== null) { + // $FlowFixMe[unsafe-arithmetic] Flow doesn't support type casting in combination with the -= operator + workInProgress.treeBaseDuration -= + _primaryChildFragment.treeBaseDuration; + } + } + } + } + + return false; + } + } else { + // Successfully completed this tree. If this was a forced client render, + // there may have been recoverable errors during first hydration + // attempt. If so, add them to a queue so we can log them in the + // commit phase. + upgradeHydrationErrorsToRecoverable(); // Fall through to normal Suspense path + + return true; + } + } + + function completeWork(current, workInProgress, renderLanes) { + var newProps = workInProgress.pendingProps; // Note: This intentionally doesn't check if we're hydrating because comparing + + switch (workInProgress.tag) { + case IndeterminateComponent: + case LazyComponent: + case SimpleMemoComponent: + case FunctionComponent: + case ForwardRef: + case Fragment: + case Mode: + case Profiler: + case ContextConsumer: + case MemoComponent: + bubbleProperties(workInProgress); + return null; + + case ClassComponent: { + bubbleProperties(workInProgress); + return null; + } + + case HostRoot: { + var fiberRoot = workInProgress.stateNode; + popHostContainer(workInProgress); + + if (fiberRoot.pendingContext) { + fiberRoot.context = fiberRoot.pendingContext; + fiberRoot.pendingContext = null; + } + + if (current === null || current.child === null) { + // If we hydrated, pop so that we can delete any remaining children + // that weren't hydrated. + var wasHydrated = popHydrationState(); + + if (wasHydrated) { + // If we hydrated, then we'll need to schedule an update for + // the commit side-effects on the root. + markUpdate(workInProgress); + } else { + if (current !== null) { + var prevState = current.memoizedState; + + if ( + // Check if this is a client root + !prevState.isDehydrated || // Check if we reverted to client rendering (e.g. due to an error) + (workInProgress.flags & ForceClientRender) !== NoFlags$1 + ) { + // Schedule an effect to clear this container at the start of the + // next commit. This handles the case of React rendering into a + // container with previous children. It's also safe to do for + // updates too, because current.child would only be null if the + // previous render was null (so the container would already + // be empty). + workInProgress.flags |= Snapshot; // If this was a forced client render, there may have been + // recoverable errors during first hydration attempt. If so, add + // them to a queue so we can log them in the commit phase. + + upgradeHydrationErrorsToRecoverable(); + } + } + } + } + + updateHostContainer(current, workInProgress); + bubbleProperties(workInProgress); + + return null; + } + + case HostHoistable: + + case HostSingleton: + + case HostComponent: { + popHostContext(workInProgress); + var _type2 = workInProgress.type; + + if (current !== null && workInProgress.stateNode != null) { + updateHostComponent(current, workInProgress, _type2, newProps); + } else { + if (!newProps) { + if (workInProgress.stateNode === null) { + throw new Error( + "We must have new props for new mounts. This error is likely " + + "caused by a bug in React. Please file an issue." + ); + } // This can happen when we abort work. + + bubbleProperties(workInProgress); + return null; + } + + var _currentHostContext = getHostContext(); // TODO: Move createInstance to beginWork and keep it on a context + // "stack" as the parent. Then append children as we go in beginWork + // or completeWork depending on whether we want to add them top->down or + // bottom->up. Top->down is faster in IE11. + + var _wasHydrated2 = popHydrationState(); + + if (_wasHydrated2) { + // TODO: Move this and createInstance step into the beginPhase + // to consolidate. + prepareToHydrateHostInstance(); + } else { + var _rootContainerInstance = getRootHostContainer(); + + var _instance3 = createInstance( + _type2, + newProps, + _rootContainerInstance, + _currentHostContext, + workInProgress + ); // TODO: For persistent renderers, we should pass children as part + // of the initial instance creation + + appendAllChildren(_instance3, workInProgress, false, false); + workInProgress.stateNode = _instance3; // Certain renderers require commit-time effects for initial mount. + } + } + + bubbleProperties(workInProgress); // This must come at the very end of the complete phase, because it might + // throw to suspend, and if the resource immediately loads, the work loop + // will resume rendering as if the work-in-progress completed. So it must + // fully complete. + + preloadInstanceAndSuspendIfNeeded(workInProgress); + return null; + } + + case HostText: { + var newText = newProps; + + if (current && workInProgress.stateNode != null) { + var oldText = current.memoizedProps; // If we have an alternate, that means this is an update and we need + // to schedule a side-effect to do the updates. + + updateHostText(current, workInProgress, oldText, newText); + } else { + if (typeof newText !== "string") { + if (workInProgress.stateNode === null) { + throw new Error( + "We must have new props for new mounts. This error is likely " + + "caused by a bug in React. Please file an issue." + ); + } // This can happen when we abort work. + } + + var _rootContainerInstance2 = getRootHostContainer(); + + var _currentHostContext2 = getHostContext(); + + var _wasHydrated3 = popHydrationState(); + + if (_wasHydrated3) { + if (prepareToHydrateHostTextInstance()) { + markUpdate(workInProgress); + } + } else { + workInProgress.stateNode = createTextInstance( + newText, + _rootContainerInstance2, + _currentHostContext2, + workInProgress + ); + } + } + + bubbleProperties(workInProgress); + return null; + } + + case SuspenseComponent: { + var nextState = workInProgress.memoizedState; // Special path for dehydrated boundaries. We may eventually move this + // to its own fiber type so that we can add other kinds of hydration + // boundaries that aren't associated with a Suspense tree. In anticipation + // of such a refactor, all the hydration logic is contained in + // this branch. + + if ( + current === null || + (current.memoizedState !== null && + current.memoizedState.dehydrated !== null) + ) { + var fallthroughToNormalSuspensePath = + completeDehydratedSuspenseBoundary( + current, + workInProgress, + nextState + ); + + if (!fallthroughToNormalSuspensePath) { + if (workInProgress.flags & ForceClientRender) { + popSuspenseHandler(workInProgress); // Special case. There were remaining unhydrated nodes. We treat + // this as a mismatch. Revert to client rendering. + + return workInProgress; + } else { + popSuspenseHandler(workInProgress); // Did not finish hydrating, either because this is the initial + // render or because something suspended. + + return null; + } + } // Continue with the normal Suspense path. + } + + popSuspenseHandler(workInProgress); + + if ((workInProgress.flags & DidCapture) !== NoFlags$1) { + // Something suspended. Re-render with the fallback children. + workInProgress.lanes = renderLanes; // Do not reset the effect list. + + if ((workInProgress.mode & ProfileMode) !== NoMode) { + transferActualDuration(workInProgress); + } // Don't bubble properties in this case. + + return workInProgress; + } + + var nextDidTimeout = nextState !== null; + var prevDidTimeout = + current !== null && current.memoizedState !== null; + // a passive effect, which is when we process the transitions + + if (nextDidTimeout !== prevDidTimeout) { + // an effect to toggle the subtree's visibility. When we switch from + // fallback -> primary, the inner Offscreen fiber schedules this effect + // as part of its normal complete phase. But when we switch from + // primary -> fallback, the inner Offscreen fiber does not have a complete + // phase. So we need to schedule its effect here. + // + // We also use this flag to connect/disconnect the effects, but the same + // logic applies: when re-connecting, the Offscreen fiber's complete + // phase will handle scheduling the effect. It's only when the fallback + // is active that we have to do anything special. + + if (nextDidTimeout) { + var _offscreenFiber2 = workInProgress.child; + _offscreenFiber2.flags |= Visibility; + } + } + + var retryQueue = workInProgress.updateQueue; + scheduleRetryEffect(workInProgress, retryQueue); + + bubbleProperties(workInProgress); + + { + if ((workInProgress.mode & ProfileMode) !== NoMode) { + if (nextDidTimeout) { + // Don't count time spent in a timed out Suspense subtree as part of the base duration. + var primaryChildFragment = workInProgress.child; + + if (primaryChildFragment !== null) { + // $FlowFixMe[unsafe-arithmetic] Flow doesn't support type casting in combination with the -= operator + workInProgress.treeBaseDuration -= + primaryChildFragment.treeBaseDuration; + } + } + } + } + + return null; + } + + case HostPortal: + popHostContainer(workInProgress); + updateHostContainer(current, workInProgress); + + bubbleProperties(workInProgress); + return null; + + case ContextProvider: + // Pop provider fiber + var context; + + { + context = workInProgress.type._context; + } + + popProvider(context, workInProgress); + bubbleProperties(workInProgress); + return null; + + case IncompleteClassComponent: { + bubbleProperties(workInProgress); + return null; + } + + case SuspenseListComponent: { + popSuspenseListContext(workInProgress); + var renderState = workInProgress.memoizedState; + + if (renderState === null) { + // We're running in the default, "independent" mode. + // We don't do anything in this mode. + bubbleProperties(workInProgress); + return null; + } + + var didSuspendAlready = + (workInProgress.flags & DidCapture) !== NoFlags$1; + var renderedTail = renderState.rendering; + + if (renderedTail === null) { + // We just rendered the head. + if (!didSuspendAlready) { + // This is the first pass. We need to figure out if anything is still + // suspended in the rendered set. + // If new content unsuspended, but there's still some content that + // didn't. Then we need to do a second pass that forces everything + // to keep showing their fallbacks. + // We might be suspended if something in this render pass suspended, or + // something in the previous committed pass suspended. Otherwise, + // there's no chance so we can skip the expensive call to + // findFirstSuspended. + var cannotBeSuspended = + renderHasNotSuspendedYet() && + (current === null || + (current.flags & DidCapture) === NoFlags$1); + + if (!cannotBeSuspended) { + var row = workInProgress.child; + + while (row !== null) { + var suspended = findFirstSuspended(row); + + if (suspended !== null) { + didSuspendAlready = true; + workInProgress.flags |= DidCapture; + cutOffTailIfNeeded(renderState, false); // If this is a newly suspended tree, it might not get committed as + // part of the second pass. In that case nothing will subscribe to + // its thenables. Instead, we'll transfer its thenables to the + // SuspenseList so that it can retry if they resolve. + // There might be multiple of these in the list but since we're + // going to wait for all of them anyway, it doesn't really matter + // which ones gets to ping. In theory we could get clever and keep + // track of how many dependencies remain but it gets tricky because + // in the meantime, we can add/remove/change items and dependencies. + // We might bail out of the loop before finding any but that + // doesn't matter since that means that the other boundaries that + // we did find already has their listeners attached. + + var _retryQueue = suspended.updateQueue; + workInProgress.updateQueue = _retryQueue; + scheduleRetryEffect(workInProgress, _retryQueue); // Rerender the whole list, but this time, we'll force fallbacks + // to stay in place. + // Reset the effect flags before doing the second pass since that's now invalid. + // Reset the child fibers to their original state. + + workInProgress.subtreeFlags = NoFlags$1; + resetChildFibers(workInProgress, renderLanes); // Set up the Suspense List Context to force suspense and + // immediately rerender the children. + + pushSuspenseListContext( + workInProgress, + setShallowSuspenseListContext( + suspenseStackCursor.current, + ForceSuspenseFallback + ) + ); // Don't bubble properties in this case. + + return workInProgress.child; + } + + row = row.sibling; + } + } + + if ( + renderState.tail !== null && + now$1() > getRenderTargetTime() + ) { + // We have already passed our CPU deadline but we still have rows + // left in the tail. We'll just give up further attempts to render + // the main content and only render fallbacks. + workInProgress.flags |= DidCapture; + didSuspendAlready = true; + cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this + // to get it started back up to attempt the next item. While in terms + // of priority this work has the same priority as this current render, + // it's not part of the same transition once the transition has + // committed. If it's sync, we still want to yield so that it can be + // painted. Conceptually, this is really the same as pinging. + // We can use any RetryLane even if it's the one currently rendering + // since we're leaving it behind on this node. + + workInProgress.lanes = SomeRetryLane; + } + } else { + cutOffTailIfNeeded(renderState, false); + } // Next we're going to render the tail. + } else { + // Append the rendered row to the child list. + if (!didSuspendAlready) { + var _suspended = findFirstSuspended(renderedTail); + + if (_suspended !== null) { + workInProgress.flags |= DidCapture; + didSuspendAlready = true; // Ensure we transfer the update queue to the parent so that it doesn't + // get lost if this row ends up dropped during a second pass. + + var _retryQueue2 = _suspended.updateQueue; + workInProgress.updateQueue = _retryQueue2; + scheduleRetryEffect(workInProgress, _retryQueue2); + cutOffTailIfNeeded(renderState, true); // This might have been modified. + + if ( + renderState.tail === null && + renderState.tailMode === "hidden" && + !renderedTail.alternate && + !getIsHydrating() // We don't cut it if we're hydrating. + ) { + // We're done. + bubbleProperties(workInProgress); + return null; + } + } else if ( + // The time it took to render last row is greater than the remaining + // time we have to render. So rendering one more row would likely + // exceed it. + now$1() * 2 - renderState.renderingStartTime > + getRenderTargetTime() && + renderLanes !== OffscreenLane + ) { + // We have now passed our CPU deadline and we'll just give up further + // attempts to render the main content and only render fallbacks. + // The assumption is that this is usually faster. + workInProgress.flags |= DidCapture; + didSuspendAlready = true; + cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this + // to get it started back up to attempt the next item. While in terms + // of priority this work has the same priority as this current render, + // it's not part of the same transition once the transition has + // committed. If it's sync, we still want to yield so that it can be + // painted. Conceptually, this is really the same as pinging. + // We can use any RetryLane even if it's the one currently rendering + // since we're leaving it behind on this node. + + workInProgress.lanes = SomeRetryLane; + } + } + + if (renderState.isBackwards) { + // The effect list of the backwards tail will have been added + // to the end. This breaks the guarantee that life-cycles fire in + // sibling order but that isn't a strong guarantee promised by React. + // Especially since these might also just pop in during future commits. + // Append to the beginning of the list. + renderedTail.sibling = workInProgress.child; + workInProgress.child = renderedTail; + } else { + var previousSibling = renderState.last; + + if (previousSibling !== null) { + previousSibling.sibling = renderedTail; + } else { + workInProgress.child = renderedTail; + } + + renderState.last = renderedTail; + } + } + + if (renderState.tail !== null) { + // We still have tail rows to render. + // Pop a row. + var next = renderState.tail; + renderState.rendering = next; + renderState.tail = next.sibling; + renderState.renderingStartTime = now$1(); + next.sibling = null; // Restore the context. + // TODO: We can probably just avoid popping it instead and only + // setting it the first time we go from not suspended to suspended. + + var suspenseContext = suspenseStackCursor.current; + + if (didSuspendAlready) { + suspenseContext = setShallowSuspenseListContext( + suspenseContext, + ForceSuspenseFallback + ); + } else { + suspenseContext = + setDefaultShallowSuspenseListContext(suspenseContext); + } + + pushSuspenseListContext(workInProgress, suspenseContext); // Do a pass over the next row. + // Don't bubble properties in this case. + + return next; + } + + bubbleProperties(workInProgress); + return null; + } + + case ScopeComponent: { + break; + } + + case OffscreenComponent: + case LegacyHiddenComponent: { + popSuspenseHandler(workInProgress); + popHiddenContext(workInProgress); + var _nextState = workInProgress.memoizedState; + var nextIsHidden = _nextState !== null; // Schedule a Visibility effect if the visibility has changed + + { + if (current !== null) { + var _prevState = current.memoizedState; + var prevIsHidden = _prevState !== null; + + if (prevIsHidden !== nextIsHidden) { + workInProgress.flags |= Visibility; + } + } else { + // On initial mount, we only need a Visibility effect if the tree + // is hidden. + if (nextIsHidden) { + workInProgress.flags |= Visibility; + } + } + } + + if ( + !nextIsHidden || + (workInProgress.mode & ConcurrentMode) === NoMode + ) { + bubbleProperties(workInProgress); + } else { + // Don't bubble properties for hidden children unless we're rendering + // at offscreen priority. + if ( + includesSomeLane(renderLanes, OffscreenLane) && // Also don't bubble if the tree suspended + (workInProgress.flags & DidCapture) === NoLanes + ) { + bubbleProperties(workInProgress); // Check if there was an insertion or update in the hidden subtree. + // If so, we need to hide those nodes in the commit phase, so + // schedule a visibility effect. + + if (workInProgress.subtreeFlags & (Placement | Update)) { + workInProgress.flags |= Visibility; + } + } + } + + var offscreenQueue = workInProgress.updateQueue; + + if (offscreenQueue !== null) { + var _retryQueue3 = offscreenQueue.retryQueue; + scheduleRetryEffect(workInProgress, _retryQueue3); + } + return null; + } + + case CacheComponent: { + return null; + } + + case TracingMarkerComponent: { + return null; + } + } + + throw new Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in " + + "React. Please file an issue." + ); + } + + function unwindWork(current, workInProgress, renderLanes) { + switch (workInProgress.tag) { + case ClassComponent: { + var flags = workInProgress.flags; + + if (flags & ShouldCapture) { + workInProgress.flags = (flags & ~ShouldCapture) | DidCapture; + + if ((workInProgress.mode & ProfileMode) !== NoMode) { + transferActualDuration(workInProgress); + } + + return workInProgress; + } + + return null; + } + + case HostRoot: { + popHostContainer(workInProgress); + var _flags = workInProgress.flags; + + if ( + (_flags & ShouldCapture) !== NoFlags$1 && + (_flags & DidCapture) === NoFlags$1 + ) { + // There was an error during render that wasn't captured by a suspense + // boundary. Do a second pass on the root to unmount the children. + workInProgress.flags = (_flags & ~ShouldCapture) | DidCapture; + return workInProgress; + } // We unwound to the root without completing it. Exit. + + return null; + } + + case HostHoistable: + case HostSingleton: + case HostComponent: { + // TODO: popHydrationState + popHostContext(workInProgress); + return null; + } + + case SuspenseComponent: { + popSuspenseHandler(workInProgress); + var suspenseState = workInProgress.memoizedState; + + if (suspenseState !== null && suspenseState.dehydrated !== null) { + if (workInProgress.alternate === null) { + throw new Error( + "Threw in newly mounted dehydrated component. This is likely a bug in " + + "React. Please file an issue." + ); + } + } + + var _flags2 = workInProgress.flags; + + if (_flags2 & ShouldCapture) { + workInProgress.flags = (_flags2 & ~ShouldCapture) | DidCapture; // Captured a suspense effect. Re-render the boundary. + + if ((workInProgress.mode & ProfileMode) !== NoMode) { + transferActualDuration(workInProgress); + } + + return workInProgress; + } + + return null; + } + + case SuspenseListComponent: { + popSuspenseListContext(workInProgress); // SuspenseList doesn't actually catch anything. It should've been + // caught by a nested boundary. If not, it should bubble through. + + return null; + } + + case HostPortal: + popHostContainer(workInProgress); + return null; + + case ContextProvider: + var context; + + { + context = workInProgress.type._context; + } + + popProvider(context, workInProgress); + return null; + + case OffscreenComponent: + case LegacyHiddenComponent: { + popSuspenseHandler(workInProgress); + popHiddenContext(workInProgress); + var _flags3 = workInProgress.flags; + + if (_flags3 & ShouldCapture) { + workInProgress.flags = (_flags3 & ~ShouldCapture) | DidCapture; // Captured a suspense effect. Re-render the boundary. + + if ((workInProgress.mode & ProfileMode) !== NoMode) { + transferActualDuration(workInProgress); + } + + return workInProgress; + } + + return null; + } + + case CacheComponent: + return null; + + case TracingMarkerComponent: + return null; + + default: + return null; + } + } + + function unwindInterruptedWork(current, interruptedWork, renderLanes) { + switch (interruptedWork.tag) { + case ClassComponent: { + break; + } + + case HostRoot: { + popHostContainer(interruptedWork); + break; + } + + case HostHoistable: + case HostSingleton: + case HostComponent: { + popHostContext(interruptedWork); + break; + } + + case HostPortal: + popHostContainer(interruptedWork); + break; + + case SuspenseComponent: + popSuspenseHandler(interruptedWork); + break; + + case SuspenseListComponent: + popSuspenseListContext(interruptedWork); + break; + + case ContextProvider: + var context; + + { + context = interruptedWork.type._context; + } + + popProvider(context, interruptedWork); + break; + + case OffscreenComponent: + case LegacyHiddenComponent: + popSuspenseHandler(interruptedWork); + popHiddenContext(interruptedWork); + break; + } + } + + var didWarnAboutUndefinedSnapshotBeforeUpdate = null; + + { + didWarnAboutUndefinedSnapshotBeforeUpdate = new Set(); + } // Used during the commit phase to track the state of the Offscreen component stack. + // Allows us to avoid traversing the return path to find the nearest Offscreen ancestor. + + var offscreenSubtreeIsHidden = false; + var offscreenSubtreeWasHidden = false; + var PossiblyWeakSet = typeof WeakSet === "function" ? WeakSet : Set; + var nextEffect = null; // Used for Profiling builds to track updaters. + + var inProgressLanes = null; + var inProgressRoot = null; + + function shouldProfile(current) { + return ( + (current.mode & ProfileMode) !== NoMode && + (getExecutionContext() & CommitContext) !== NoContext + ); + } + + function callComponentWillUnmountWithTimer(current, instance) { + instance.props = current.memoizedProps; + instance.state = current.memoizedState; + + if (shouldProfile(current)) { + try { + startLayoutEffectTimer(); + instance.componentWillUnmount(); + } finally { + recordLayoutEffectDuration(current); + } + } else { + instance.componentWillUnmount(); + } + } // Capture errors so they don't interrupt unmounting. + + function safelyCallComponentWillUnmount( + current, + nearestMountedAncestor, + instance + ) { + try { + callComponentWillUnmountWithTimer(current, instance); + } catch (error) { + captureCommitPhaseError(current, nearestMountedAncestor, error); + } + } // Capture errors so they don't interrupt mounting. + + function safelyAttachRef(current, nearestMountedAncestor) { + try { + commitAttachRef(current); + } catch (error) { + captureCommitPhaseError(current, nearestMountedAncestor, error); + } + } + + function safelyDetachRef(current, nearestMountedAncestor) { + var ref = current.ref; + var refCleanup = current.refCleanup; + + if (ref !== null) { + if (typeof refCleanup === "function") { + try { + if (shouldProfile(current)) { + try { + startLayoutEffectTimer(); + refCleanup(); + } finally { + recordLayoutEffectDuration(current); + } + } else { + refCleanup(); + } + } catch (error) { + captureCommitPhaseError(current, nearestMountedAncestor, error); + } finally { + // `refCleanup` has been called. Nullify all references to it to prevent double invocation. + current.refCleanup = null; + var finishedWork = current.alternate; + + if (finishedWork != null) { + finishedWork.refCleanup = null; + } + } + } else if (typeof ref === "function") { + var retVal; + + try { + if (shouldProfile(current)) { + try { + startLayoutEffectTimer(); + retVal = ref(null); + } finally { + recordLayoutEffectDuration(current); + } + } else { + retVal = ref(null); + } + } catch (error) { + captureCommitPhaseError(current, nearestMountedAncestor, error); + } + + { + if (typeof retVal === "function") { + error( + "Unexpected return value from a callback ref in %s. " + + "A callback ref should not return a function.", + getComponentNameFromFiber(current) + ); + } + } + } else { + // $FlowFixMe[incompatible-use] unable to narrow type to RefObject + ref.current = null; + } + } + } + + function safelyCallDestroy(current, nearestMountedAncestor, destroy) { + try { + destroy(); + } catch (error) { + captureCommitPhaseError(current, nearestMountedAncestor, error); + } + } + var shouldFireAfterActiveInstanceBlur = false; + function commitBeforeMutationEffects(root, firstChild) { + nextEffect = firstChild; + commitBeforeMutationEffects_begin(); // We no longer need to track the active instance fiber + + var shouldFire = shouldFireAfterActiveInstanceBlur; + shouldFireAfterActiveInstanceBlur = false; + return shouldFire; + } + + function commitBeforeMutationEffects_begin() { + while (nextEffect !== null) { + var fiber = nextEffect; // This phase is only used for beforeActiveInstanceBlur. + + var child = fiber.child; + + if ( + (fiber.subtreeFlags & BeforeMutationMask) !== NoFlags$1 && + child !== null + ) { + child.return = fiber; + nextEffect = child; + } else { + commitBeforeMutationEffects_complete(); + } + } + } + + function commitBeforeMutationEffects_complete() { + while (nextEffect !== null) { + var fiber = nextEffect; + setCurrentFiber(fiber); + + try { + commitBeforeMutationEffectsOnFiber(fiber); + } catch (error) { + captureCommitPhaseError(fiber, fiber.return, error); + } + + resetCurrentFiber(); + var sibling = fiber.sibling; + + if (sibling !== null) { + sibling.return = fiber.return; + nextEffect = sibling; + return; + } + + nextEffect = fiber.return; + } + } + + function commitBeforeMutationEffectsOnFiber(finishedWork) { + var current = finishedWork.alternate; + var flags = finishedWork.flags; + + if ((flags & Snapshot) !== NoFlags$1) { + setCurrentFiber(finishedWork); + } + + switch (finishedWork.tag) { + case FunctionComponent: { + break; + } + + case ForwardRef: + case SimpleMemoComponent: { + break; + } + + case ClassComponent: { + if ((flags & Snapshot) !== NoFlags$1) { + 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" + ); + } + + 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" + ); + } + } + } + + var snapshot = instance.getSnapshotBeforeUpdate( + finishedWork.elementType === finishedWork.type + ? prevProps + : resolveDefaultProps(finishedWork.type, prevProps), + prevState + ); + + { + var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate; + + if ( + snapshot === undefined && + !didWarnSet.has(finishedWork.type) + ) { + didWarnSet.add(finishedWork.type); + + error( + "%s.getSnapshotBeforeUpdate(): A snapshot value (or null) " + + "must be returned. You have returned undefined.", + getComponentNameFromFiber(finishedWork) + ); + } + } + + instance.__reactInternalSnapshotBeforeUpdate = snapshot; + } + } + + break; + } + + case HostRoot: { + break; + } + + case HostComponent: + case HostHoistable: + case HostSingleton: + case HostText: + case HostPortal: + case IncompleteClassComponent: + // Nothing to do for these component types + break; + + default: { + if ((flags & Snapshot) !== NoFlags$1) { + throw new Error( + "This unit of work tag should not have side-effects. This error is " + + "likely caused by a bug in React. Please file an issue." + ); + } + } + } + + if ((flags & Snapshot) !== NoFlags$1) { + resetCurrentFiber(); + } + } + + function commitHookEffectListUnmount( + flags, + finishedWork, + nearestMountedAncestor + ) { + var updateQueue = finishedWork.updateQueue; + var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; + + if (lastEffect !== null) { + var firstEffect = lastEffect.next; + var effect = firstEffect; + + do { + if ((effect.tag & flags) === flags) { + // Unmount + var inst = effect.inst; + var destroy = inst.destroy; + + if (destroy !== undefined) { + inst.destroy = undefined; + + { + if ((flags & Insertion) !== NoFlags) { + setIsRunningInsertionEffect(true); + } + } + + safelyCallDestroy(finishedWork, nearestMountedAncestor, destroy); + + { + if ((flags & Insertion) !== NoFlags) { + setIsRunningInsertionEffect(false); + } + } + } + } + + effect = effect.next; + } while (effect !== firstEffect); + } + } + + function commitHookEffectListMount(flags, finishedWork) { + var updateQueue = finishedWork.updateQueue; + var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; + + if (lastEffect !== null) { + var firstEffect = lastEffect.next; + var effect = firstEffect; + + do { + if ((effect.tag & flags) === flags) { + var create = effect.create; + + { + if ((flags & Insertion) !== NoFlags) { + setIsRunningInsertionEffect(true); + } + } + + var inst = effect.inst; + var destroy = create(); + inst.destroy = destroy; + + { + if ((flags & Insertion) !== NoFlags) { + setIsRunningInsertionEffect(false); + } + } + + { + if (destroy !== undefined && typeof destroy !== "function") { + var hookName = void 0; + + if ((effect.tag & Layout) !== NoFlags$1) { + hookName = "useLayoutEffect"; + } else if ((effect.tag & Insertion) !== NoFlags$1) { + hookName = "useInsertionEffect"; + } else { + hookName = "useEffect"; + } + + var addendum = void 0; + + 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 " + + hookName + + "(async () => ...) or returned a Promise. " + + "Instead, write the async function inside your effect " + + "and call it immediately:\n\n" + + hookName + + "(() => {\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://react.dev/link/hooks-data-fetching"; + } else { + addendum = " You returned: " + destroy; + } + + error( + "%s must not return anything besides a function, " + + "which is used for clean-up.%s", + hookName, + addendum + ); + } + } + } + + effect = effect.next; + } while (effect !== firstEffect); + } + } + + function commitPassiveEffectDurations(finishedRoot, finishedWork) { + if (getExecutionContext() & CommitContext) { + // Only Profilers with work in their subtree will have an Update effect scheduled. + if ((finishedWork.flags & Update) !== NoFlags$1) { + switch (finishedWork.tag) { + case Profiler: { + var passiveEffectDuration = + finishedWork.stateNode.passiveEffectDuration; + var _finishedWork$memoize = finishedWork.memoizedProps, + id = _finishedWork$memoize.id, + onPostCommit = _finishedWork$memoize.onPostCommit; // This value will still reflect the previous commit phase. + // It does not get reset until the start of the next commit phase. + + var commitTime = getCommitTime(); + var phase = finishedWork.alternate === null ? "mount" : "update"; + + { + if (isCurrentUpdateNested()) { + phase = "nested-update"; + } + } + + if (typeof onPostCommit === "function") { + onPostCommit(id, phase, passiveEffectDuration, commitTime); + } // Bubble times to the next nearest ancestor Profiler. + // After we process that Profiler, we'll bubble further up. + + var parentFiber = finishedWork.return; + + outer: while (parentFiber !== null) { + switch (parentFiber.tag) { + case HostRoot: + var root = parentFiber.stateNode; + root.passiveEffectDuration += passiveEffectDuration; + break outer; + + case Profiler: + var parentStateNode = parentFiber.stateNode; + parentStateNode.passiveEffectDuration += + passiveEffectDuration; + break outer; + } + + parentFiber = parentFiber.return; + } + + break; + } + } + } + } + } + + function commitHookLayoutEffects(finishedWork, hookFlags) { + // 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. + if (shouldProfile(finishedWork)) { + try { + startLayoutEffectTimer(); + commitHookEffectListMount(hookFlags, finishedWork); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + + recordLayoutEffectDuration(finishedWork); + } else { + try { + commitHookEffectListMount(hookFlags, finishedWork); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + } + } + + function commitClassLayoutLifecycles(finishedWork, current) { + var instance = finishedWork.stateNode; + + 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" + ); + } + } + } + + if (shouldProfile(finishedWork)) { + try { + startLayoutEffectTimer(); + instance.componentDidMount(); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + + recordLayoutEffectDuration(finishedWork); + } else { + try { + instance.componentDidMount(); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + } + } 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" + ); + } + } + } + + if (shouldProfile(finishedWork)) { + try { + startLayoutEffectTimer(); + instance.componentDidUpdate( + prevProps, + prevState, + instance.__reactInternalSnapshotBeforeUpdate + ); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + + recordLayoutEffectDuration(finishedWork); + } else { + try { + instance.componentDidUpdate( + prevProps, + prevState, + instance.__reactInternalSnapshotBeforeUpdate + ); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + } + } + } + + function commitClassCallbacks(finishedWork) { + // 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 = finishedWork.stateNode; + + { + 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. + + try { + commitCallbacks(updateQueue, instance); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + } + } + + function commitHostComponentMount(finishedWork) { + var type = finishedWork.type; + var props = finishedWork.memoizedProps; + var instance = finishedWork.stateNode; + + try { + commitMount(instance, type, props, finishedWork); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + } + + function commitProfilerUpdate(finishedWork, current) { + if (getExecutionContext() & CommitContext) { + try { + 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 (enableProfilerNestedUpdatePhase) { + if (isCurrentUpdateNested()) { + phase = "nested-update"; + } + } + + if (typeof onRender === "function") { + onRender( + finishedWork.memoizedProps.id, + phase, + finishedWork.actualDuration, + finishedWork.treeBaseDuration, + finishedWork.actualStartTime, + commitTime + ); + } + + if (enableProfilerCommitHooks) { + if (typeof onCommit === "function") { + onCommit( + finishedWork.memoizedProps.id, + phase, + effectDuration, + commitTime + ); + } // Schedule a passive effect for this Profiler to call onPostCommit hooks. + // This effect should be scheduled even if there is no onPostCommit callback for this Profiler, + // because the effect is also where times bubble to parent Profilers. + + enqueuePendingPassiveProfilerEffect(finishedWork); // Propagate layout effect durations to the next nearest Profiler ancestor. + // Do not reset these values until the next render so DevTools has a chance to read them first. + + var parentFiber = finishedWork.return; + + outer: while (parentFiber !== null) { + switch (parentFiber.tag) { + case HostRoot: + var root = parentFiber.stateNode; + root.effectDuration += effectDuration; + break outer; + + case Profiler: + var parentStateNode = parentFiber.stateNode; + parentStateNode.effectDuration += effectDuration; + break outer; + } + + parentFiber = parentFiber.return; + } + } + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + } + } + + function commitLayoutEffectOnFiber( + finishedRoot, + current, + finishedWork, + committedLanes + ) { + // When updating this function, also update reappearLayoutEffects, which does + // most of the same things when an offscreen tree goes from hidden -> visible. + var flags = finishedWork.flags; + + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + recursivelyTraverseLayoutEffects(finishedRoot, finishedWork); + + if (flags & Update) { + commitHookLayoutEffects(finishedWork, Layout | HasEffect); + } + + break; + } + + case ClassComponent: { + recursivelyTraverseLayoutEffects(finishedRoot, finishedWork); + + if (flags & Update) { + commitClassLayoutLifecycles(finishedWork, current); + } + + if (flags & Callback) { + commitClassCallbacks(finishedWork); + } + + if (flags & Ref) { + safelyAttachRef(finishedWork, finishedWork.return); + } + + break; + } + + case HostRoot: { + recursivelyTraverseLayoutEffects(finishedRoot, finishedWork); + + if (flags & Callback) { + // 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 HostSingleton: + case HostComponent: + instance = getPublicInstance(finishedWork.child.stateNode); + break; + + case ClassComponent: + instance = finishedWork.child.stateNode; + break; + } + } + + try { + commitCallbacks(updateQueue, instance); + } catch (error) { + captureCommitPhaseError( + finishedWork, + finishedWork.return, + error + ); + } + } + } + + break; + } + + case HostHoistable: + + case HostSingleton: + case HostComponent: { + recursivelyTraverseLayoutEffects(finishedRoot, finishedWork); // 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 && flags & Update) { + commitHostComponentMount(finishedWork); + } + + if (flags & Ref) { + safelyAttachRef(finishedWork, finishedWork.return); + } + + break; + } + + case Profiler: { + recursivelyTraverseLayoutEffects(finishedRoot, finishedWork); // TODO: Should this fire inside an offscreen tree? Or should it wait to + // fire when the tree becomes visible again. + + if (flags & Update) { + commitProfilerUpdate(finishedWork, current); + } + + break; + } + + case SuspenseComponent: { + recursivelyTraverseLayoutEffects(finishedRoot, finishedWork); + + break; + } + + case OffscreenComponent: { + var isModernRoot = (finishedWork.mode & ConcurrentMode) !== NoMode; + + if (isModernRoot) { + var isHidden = finishedWork.memoizedState !== null; + var newOffscreenSubtreeIsHidden = + isHidden || offscreenSubtreeIsHidden; + + if (newOffscreenSubtreeIsHidden); + else { + // The Offscreen tree is visible. + var wasHidden = + current !== null && current.memoizedState !== null; + var newOffscreenSubtreeWasHidden = + wasHidden || offscreenSubtreeWasHidden; + var prevOffscreenSubtreeIsHidden = offscreenSubtreeIsHidden; + var prevOffscreenSubtreeWasHidden = offscreenSubtreeWasHidden; + offscreenSubtreeIsHidden = newOffscreenSubtreeIsHidden; + offscreenSubtreeWasHidden = newOffscreenSubtreeWasHidden; + + if (offscreenSubtreeWasHidden && !prevOffscreenSubtreeWasHidden) { + // This is the root of a reappearing boundary. As we continue + // traversing the layout effects, we must also re-mount layout + // effects that were unmounted when the Offscreen subtree was + // hidden. So this is a superset of the normal commitLayoutEffects. + var includeWorkInProgressEffects = + (finishedWork.subtreeFlags & LayoutMask) !== NoFlags$1; + recursivelyTraverseReappearLayoutEffects( + finishedRoot, + finishedWork, + includeWorkInProgressEffects + ); + } else { + recursivelyTraverseLayoutEffects(finishedRoot, finishedWork); + } + + offscreenSubtreeIsHidden = prevOffscreenSubtreeIsHidden; + offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden; + } + } else { + recursivelyTraverseLayoutEffects(finishedRoot, finishedWork); + } + + if (flags & Ref) { + var props = finishedWork.memoizedProps; + + if (props.mode === "manual") { + safelyAttachRef(finishedWork, finishedWork.return); + } else { + safelyDetachRef(finishedWork, finishedWork.return); + } + } + + break; + } + + default: { + recursivelyTraverseLayoutEffects(finishedRoot, finishedWork); + break; + } + } + } + + function commitAttachRef(finishedWork) { + var ref = finishedWork.ref; + + if (ref !== null) { + var instance = finishedWork.stateNode; + var instanceToUse; + + switch (finishedWork.tag) { + case HostHoistable: + case HostSingleton: + case HostComponent: + instanceToUse = getPublicInstance(instance); + break; + + default: + instanceToUse = instance; + } // Moved outside to ensure DCE works with this flag + + if (typeof ref === "function") { + if (shouldProfile(finishedWork)) { + try { + startLayoutEffectTimer(); + finishedWork.refCleanup = ref(instanceToUse); + } finally { + recordLayoutEffectDuration(finishedWork); + } + } else { + finishedWork.refCleanup = ref(instanceToUse); + } + } else { + { + // TODO: We should move these warnings to happen during the render + // phase (markRef). + if (!ref.hasOwnProperty("current")) { + error( + "Unexpected ref object provided for %s. " + + "Use either a ref-setter function or React.createRef().", + getComponentNameFromFiber(finishedWork) + ); + } + } // $FlowFixMe[incompatible-use] unable to narrow type to the non-function case + + ref.current = instanceToUse; + } + } + } + + 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 (alternate !== null) { + alternate.return = null; + } + + fiber.return = null; + } + + function detachFiberAfterEffects(fiber) { + var alternate = fiber.alternate; + + if (alternate !== null) { + fiber.alternate = null; + detachFiberAfterEffects(alternate); + } // Clear cyclical Fiber fields. This level alone is designed to roughly + // approximate the planned Fiber refactor. In that world, `setState` will be + // bound to a special "instance" object instead of a Fiber. The Instance + // object will not have any of these fields. It will only be connected to + // the fiber tree via a single link at the root. So if this level alone is + // sufficient to fix memory issues, that bodes well for our plans. + + fiber.child = null; + fiber.deletions = null; + fiber.sibling = null; // The `stateNode` is cyclical because on host nodes it points to the host + + fiber.stateNode = null; + + { + fiber._debugOwner = null; + } // Theoretically, nothing in here should be necessary, because we already + // disconnected the fiber from the tree. So even if something leaks this + // particular fiber, it won't leak anything else. + + fiber.return = null; + fiber.dependencies = null; + fiber.memoizedProps = null; + fiber.memoizedState = null; + fiber.pendingProps = null; + fiber.stateNode = null; // TODO: Move to `commitPassiveUnmountInsideDeletedTreeOnFiber` instead. + + fiber.updateQueue = null; + } + + function emptyPortalContainer(current) { + createContainerChildSet(); + } + + function commitPlacement(finishedWork) { + { + return; + } + } + + function commitDeletionEffects(root, returnFiber, deletedFiber) { + { + // Detach refs and call componentWillUnmount() on the whole subtree. + commitDeletionEffectsOnFiber(root, returnFiber, deletedFiber); + } + + detachFiberMutation(deletedFiber); + } + + function recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + parent + ) { + // TODO: Use a static flag to skip trees that don't have unmount effects + var child = parent.child; + + while (child !== null) { + commitDeletionEffectsOnFiber( + finishedRoot, + nearestMountedAncestor, + child + ); + child = child.sibling; + } + } + + function commitDeletionEffectsOnFiber( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ) { + onCommitUnmount(deletedFiber); // The cases in this outer switch modify the stack before they traverse + // into their subtree. There are simpler cases in the inner switch + // that don't modify the stack. + + switch (deletedFiber.tag) { + case HostHoistable: + + case HostSingleton: + + case HostComponent: { + if (!offscreenSubtreeWasHidden) { + safelyDetachRef(deletedFiber, nearestMountedAncestor); + } // Intentional fallthrough to next branch + } + + case HostText: { + // We only need to remove the nearest host child. Set the host parent + // to `null` on the stack to indicate that nested children don't + // need to be removed. + { + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + } + + return; + } + + case DehydratedFragment: { + return; + } + + case HostPortal: { + { + emptyPortalContainer(); + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + } + + return; + } + + case FunctionComponent: + case ForwardRef: + case MemoComponent: + case SimpleMemoComponent: { + if (!offscreenSubtreeWasHidden) { + var updateQueue = deletedFiber.updateQueue; + + if (updateQueue !== null) { + var lastEffect = updateQueue.lastEffect; + + if (lastEffect !== null) { + var firstEffect = lastEffect.next; + var effect = firstEffect; + + do { + var tag = effect.tag; + var inst = effect.inst; + var destroy = inst.destroy; + + if (destroy !== undefined) { + if ((tag & Insertion) !== NoFlags) { + inst.destroy = undefined; + safelyCallDestroy( + deletedFiber, + nearestMountedAncestor, + destroy + ); + } else if ((tag & Layout) !== NoFlags) { + if (shouldProfile(deletedFiber)) { + startLayoutEffectTimer(); + inst.destroy = undefined; + safelyCallDestroy( + deletedFiber, + nearestMountedAncestor, + destroy + ); + recordLayoutEffectDuration(deletedFiber); + } else { + inst.destroy = undefined; + safelyCallDestroy( + deletedFiber, + nearestMountedAncestor, + destroy + ); + } + } + } + + effect = effect.next; + } while (effect !== firstEffect); + } + } + } + + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + return; + } + + case ClassComponent: { + if (!offscreenSubtreeWasHidden) { + safelyDetachRef(deletedFiber, nearestMountedAncestor); + var instance = deletedFiber.stateNode; + + if (typeof instance.componentWillUnmount === "function") { + safelyCallComponentWillUnmount( + deletedFiber, + nearestMountedAncestor, + instance + ); + } + } + + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + return; + } + + case ScopeComponent: { + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + return; + } + + case OffscreenComponent: { + safelyDetachRef(deletedFiber, nearestMountedAncestor); + + if (deletedFiber.mode & ConcurrentMode) { + // If this offscreen component is hidden, we already unmounted it. Before + // deleting the children, track that it's already unmounted so that we + // don't attempt to unmount the effects again. + // TODO: If the tree is hidden, in most cases we should be able to skip + // over the nested children entirely. An exception is we haven't yet found + // the topmost host node to delete, which we already track on the stack. + // But the other case is portals, which need to be detached no matter how + // deeply they are nested. We should use a subtree flag to track whether a + // subtree includes a nested portal. + var prevOffscreenSubtreeWasHidden = offscreenSubtreeWasHidden; + offscreenSubtreeWasHidden = + prevOffscreenSubtreeWasHidden || + deletedFiber.memoizedState !== null; + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden; + } else { + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + } + + break; + } + + default: { + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + return; + } + } + } + + function commitSuspenseCallback(finishedWork) {} + + function getRetryCache(finishedWork) { + // TODO: Unify the interface for the retry cache so we don't have to switch + // on the tag like this. + switch (finishedWork.tag) { + case SuspenseComponent: + case SuspenseListComponent: { + var retryCache = finishedWork.stateNode; + + if (retryCache === null) { + retryCache = finishedWork.stateNode = new PossiblyWeakSet(); + } + + return retryCache; + } + + case OffscreenComponent: { + var instance = finishedWork.stateNode; + var _retryCache = instance._retryCache; + + if (_retryCache === null) { + _retryCache = instance._retryCache = new PossiblyWeakSet(); + } + + return _retryCache; + } + + default: { + throw new Error( + "Unexpected Suspense handler tag (" + + finishedWork.tag + + "). This is a " + + "bug in React." + ); + } + } + } + + function detachOffscreenInstance(instance) { + var fiber = instance._current; + + if (fiber === null) { + throw new Error( + "Calling Offscreen.detach before instance handle has been set." + ); + } + + if ((instance._pendingVisibility & OffscreenDetached) !== NoFlags$1) { + // The instance is already detached, this is a noop. + return; + } // TODO: There is an opportunity to optimise this by not entering commit phase + // and unmounting effects directly. + + var root = enqueueConcurrentRenderForLane(fiber, SyncLane); + + if (root !== null) { + instance._pendingVisibility |= OffscreenDetached; + scheduleUpdateOnFiber(root, fiber, SyncLane); + } + } + function attachOffscreenInstance(instance) { + var fiber = instance._current; + + if (fiber === null) { + throw new Error( + "Calling Offscreen.detach before instance handle has been set." + ); + } + + if ((instance._pendingVisibility & OffscreenDetached) === NoFlags$1) { + // The instance is already attached, this is a noop. + return; + } + + var root = enqueueConcurrentRenderForLane(fiber, SyncLane); + + if (root !== null) { + instance._pendingVisibility &= ~OffscreenDetached; + scheduleUpdateOnFiber(root, fiber, SyncLane); + } + } + + function attachSuspenseRetryListeners(finishedWork, wakeables) { + // 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 retryCache = getRetryCache(finishedWork); + wakeables.forEach(function (wakeable) { + // Memoize using the boundary fiber to prevent redundant listeners. + var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable); + + if (!retryCache.has(wakeable)) { + retryCache.add(wakeable); + + { + if (isDevToolsPresent) { + if (inProgressLanes !== null && inProgressRoot !== null) { + // If we have pending work still, associate the original updaters with it. + restorePendingUpdaters(inProgressRoot, inProgressLanes); + } else { + throw Error( + "Expected finished root and lanes to be set. This is a bug in React." + ); + } + } + } + + wakeable.then(retry, retry); + } + }); + } // This function detects when a Suspense boundary goes from visible to hidden. + function commitMutationEffects(root, finishedWork, committedLanes) { + inProgressLanes = committedLanes; + inProgressRoot = root; + setCurrentFiber(finishedWork); + commitMutationEffectsOnFiber(finishedWork, root); + setCurrentFiber(finishedWork); + inProgressLanes = null; + inProgressRoot = null; + } + + function recursivelyTraverseMutationEffects(root, parentFiber, lanes) { + // Deletions effects can be scheduled on any fiber type. They need to happen + // before the children effects hae fired. + var deletions = parentFiber.deletions; + + if (deletions !== null) { + for (var i = 0; i < deletions.length; i++) { + var childToDelete = deletions[i]; + + try { + commitDeletionEffects(root, parentFiber, childToDelete); + } catch (error) { + captureCommitPhaseError(childToDelete, parentFiber, error); + } + } + } + + var prevDebugFiber = getCurrentFiber(); + + if (parentFiber.subtreeFlags & MutationMask) { + var child = parentFiber.child; + + while (child !== null) { + setCurrentFiber(child); + commitMutationEffectsOnFiber(child, root); + child = child.sibling; + } + } + + setCurrentFiber(prevDebugFiber); + } + + function commitMutationEffectsOnFiber(finishedWork, root, lanes) { + var current = finishedWork.alternate; + var flags = finishedWork.flags; // The effect flag should be checked *after* we refine the type of fiber, + // because the fiber tag is more specific. An exception is any flag related + // to reconciliation, because those can be set on all fiber types. + + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case MemoComponent: + case SimpleMemoComponent: { + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + + if (flags & Update) { + try { + commitHookEffectListUnmount( + Insertion | HasEffect, + finishedWork, + finishedWork.return + ); + commitHookEffectListMount(Insertion | HasEffect, finishedWork); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } // Layout effects are destroyed during the mutation phase so that all + // destroy functions for all fibers are called before any create functions. + // This prevents sibling component effects from interfering with each other, + // e.g. a destroy function in one component should never override a ref set + // by a create function in another component during the same commit. + + if (shouldProfile(finishedWork)) { + try { + startLayoutEffectTimer(); + commitHookEffectListUnmount( + Layout | HasEffect, + finishedWork, + finishedWork.return + ); + } catch (error) { + captureCommitPhaseError( + finishedWork, + finishedWork.return, + error + ); + } + + recordLayoutEffectDuration(finishedWork); + } else { + try { + commitHookEffectListUnmount( + Layout | HasEffect, + finishedWork, + finishedWork.return + ); + } catch (error) { + captureCommitPhaseError( + finishedWork, + finishedWork.return, + error + ); + } + } + } + + return; + } + + case ClassComponent: { + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + + if (flags & Ref) { + if (current !== null) { + safelyDetachRef(current, current.return); + } + } + + if (flags & Callback && offscreenSubtreeIsHidden) { + var updateQueue = finishedWork.updateQueue; + + if (updateQueue !== null) { + deferHiddenCallbacks(updateQueue); + } + } + + return; + } + + case HostHoistable: + + case HostSingleton: + + case HostComponent: { + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + + if (flags & Ref) { + if (current !== null) { + safelyDetachRef(current, current.return); + } + } + + return; + } + + case HostText: { + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + + return; + } + + case HostRoot: { + { + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + } + + if (flags & Update) { + { + var containerInfo = root.containerInfo; + var pendingChildren = root.pendingChildren; + + try { + replaceContainerChildren(containerInfo, pendingChildren); + } catch (error) { + captureCommitPhaseError( + finishedWork, + finishedWork.return, + error + ); + } + } + } + + return; + } + + case HostPortal: { + { + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + } + + if (flags & Update) { + { + var portal = finishedWork.stateNode; + var _containerInfo = portal.containerInfo; + var _pendingChildren = portal.pendingChildren; + + try { + replaceContainerChildren(_containerInfo, _pendingChildren); + } catch (error) { + captureCommitPhaseError( + finishedWork, + finishedWork.return, + error + ); + } + } + } + + return; + } + + case SuspenseComponent: { + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); // TODO: We should mark a flag on the Suspense fiber itself, rather than + // relying on the Offscreen fiber having a flag also being marked. The + // reason is that this offscreen fiber might not be part of the work-in- + // progress tree! It could have been reused from a previous render. This + // doesn't lead to incorrect behavior because we don't rely on the flag + // check alone; we also compare the states explicitly below. But for + // modeling purposes, we _should_ be able to rely on the flag check alone. + // So this is a bit fragile. + // + // Also, all this logic could/should move to the passive phase so it + // doesn't block paint. + + var offscreenFiber = finishedWork.child; + + if (offscreenFiber.flags & Visibility) { + // Throttle the appearance and disappearance of Suspense fallbacks. + var isShowingFallback = finishedWork.memoizedState !== null; + var wasShowingFallback = + current !== null && current.memoizedState !== null; + + { + if (isShowingFallback && !wasShowingFallback) { + // Old behavior. Only mark when a fallback appears, not when + // it disappears. + markCommitTimeOfFallback(); + } + } + } + + if (flags & Update) { + try { + commitSuspenseCallback(finishedWork); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + + var retryQueue = finishedWork.updateQueue; + + if (retryQueue !== null) { + finishedWork.updateQueue = null; + attachSuspenseRetryListeners(finishedWork, retryQueue); + } + } + + return; + } + + case OffscreenComponent: { + if (flags & Ref) { + if (current !== null) { + safelyDetachRef(current, current.return); + } + } + + var newState = finishedWork.memoizedState; + var isHidden = newState !== null; + var wasHidden = current !== null && current.memoizedState !== null; + + if (finishedWork.mode & ConcurrentMode) { + // Before committing the children, track on the stack whether this + // offscreen subtree was already hidden, so that we don't unmount the + // effects again. + var prevOffscreenSubtreeIsHidden = offscreenSubtreeIsHidden; + var prevOffscreenSubtreeWasHidden = offscreenSubtreeWasHidden; + offscreenSubtreeIsHidden = prevOffscreenSubtreeIsHidden || isHidden; + offscreenSubtreeWasHidden = + prevOffscreenSubtreeWasHidden || wasHidden; + recursivelyTraverseMutationEffects(root, finishedWork); + offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden; + offscreenSubtreeIsHidden = prevOffscreenSubtreeIsHidden; + } else { + recursivelyTraverseMutationEffects(root, finishedWork); + } + + commitReconciliationEffects(finishedWork); + var offscreenInstance = finishedWork.stateNode; // TODO: Add explicit effect flag to set _current. + + offscreenInstance._current = finishedWork; // Offscreen stores pending changes to visibility in `_pendingVisibility`. This is + // to support batching of `attach` and `detach` calls. + + offscreenInstance._visibility &= ~OffscreenDetached; + offscreenInstance._visibility |= + offscreenInstance._pendingVisibility & OffscreenDetached; + + if (flags & Visibility) { + // Track the current state on the Offscreen instance so we can + // read it during an event + if (isHidden) { + offscreenInstance._visibility &= ~OffscreenVisible; + } else { + offscreenInstance._visibility |= OffscreenVisible; + } + + if (isHidden) { + var isUpdate = current !== null; + var wasHiddenByAncestorOffscreen = + offscreenSubtreeIsHidden || offscreenSubtreeWasHidden; // Only trigger disapper layout effects if: + // - This is an update, not first mount. + // - This Offscreen was not hidden before. + // - Ancestor Offscreen was not hidden in previous commit. + + if (isUpdate && !wasHidden && !wasHiddenByAncestorOffscreen) { + if ((finishedWork.mode & ConcurrentMode) !== NoMode) { + // Disappear the layout effects of all the children + recursivelyTraverseDisappearLayoutEffects(finishedWork); + } + } + } // Offscreen with manual mode manages visibility manually. + } // TODO: Move to passive phase + + if (flags & Update) { + var offscreenQueue = finishedWork.updateQueue; + + if (offscreenQueue !== null) { + var _retryQueue = offscreenQueue.retryQueue; + + if (_retryQueue !== null) { + offscreenQueue.retryQueue = null; + attachSuspenseRetryListeners(finishedWork, _retryQueue); + } + } + } + + return; + } + + case SuspenseListComponent: { + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + + if (flags & Update) { + var _retryQueue2 = finishedWork.updateQueue; + + if (_retryQueue2 !== null) { + finishedWork.updateQueue = null; + attachSuspenseRetryListeners(finishedWork, _retryQueue2); + } + } + + return; + } + + case ScopeComponent: { + return; + } + + default: { + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + return; + } + } + } + + function commitReconciliationEffects(finishedWork) { + // Placement effects (insertions, reorders) can be scheduled on any fiber + // type. They needs to happen after the children effects have fired, but + // before the effects on this fiber have fired. + var flags = finishedWork.flags; + + if (flags & Placement) { + try { + commitPlacement(finishedWork); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } // Clear the "placement" from effect tag so that we know that this is + // inserted, before any life-cycles like componentDidMount gets called. + // TODO: findDOMNode doesn't rely on this any more but isMounted does + // and isMounted is deprecated anyway so we should be able to kill this. + + finishedWork.flags &= ~Placement; + } + + if (flags & Hydrating) { + finishedWork.flags &= ~Hydrating; + } + } + + function commitLayoutEffects(finishedWork, root, committedLanes) { + inProgressLanes = committedLanes; + inProgressRoot = root; + var current = finishedWork.alternate; + commitLayoutEffectOnFiber(root, current, finishedWork); + inProgressLanes = null; + inProgressRoot = null; + } + + function recursivelyTraverseLayoutEffects(root, parentFiber, lanes) { + var prevDebugFiber = getCurrentFiber(); + + if (parentFiber.subtreeFlags & LayoutMask) { + var child = parentFiber.child; + + while (child !== null) { + setCurrentFiber(child); + var current = child.alternate; + commitLayoutEffectOnFiber(root, current, child); + child = child.sibling; + } + } + + setCurrentFiber(prevDebugFiber); + } + + function disappearLayoutEffects(finishedWork) { + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case MemoComponent: + case SimpleMemoComponent: { + // TODO (Offscreen) Check: flags & LayoutStatic + if (shouldProfile(finishedWork)) { + try { + startLayoutEffectTimer(); + commitHookEffectListUnmount( + Layout, + finishedWork, + finishedWork.return + ); + } finally { + recordLayoutEffectDuration(finishedWork); + } + } else { + commitHookEffectListUnmount( + Layout, + finishedWork, + finishedWork.return + ); + } + + recursivelyTraverseDisappearLayoutEffects(finishedWork); + break; + } + + case ClassComponent: { + // TODO (Offscreen) Check: flags & RefStatic + safelyDetachRef(finishedWork, finishedWork.return); + var instance = finishedWork.stateNode; + + if (typeof instance.componentWillUnmount === "function") { + safelyCallComponentWillUnmount( + finishedWork, + finishedWork.return, + instance + ); + } + + recursivelyTraverseDisappearLayoutEffects(finishedWork); + break; + } + + case HostHoistable: + case HostSingleton: + case HostComponent: { + // TODO (Offscreen) Check: flags & RefStatic + safelyDetachRef(finishedWork, finishedWork.return); + recursivelyTraverseDisappearLayoutEffects(finishedWork); + break; + } + + case OffscreenComponent: { + // TODO (Offscreen) Check: flags & RefStatic + safelyDetachRef(finishedWork, finishedWork.return); + var isHidden = finishedWork.memoizedState !== null; + + if (isHidden); + else { + recursivelyTraverseDisappearLayoutEffects(finishedWork); + } + + break; + } + + default: { + recursivelyTraverseDisappearLayoutEffects(finishedWork); + break; + } + } + } + + function recursivelyTraverseDisappearLayoutEffects(parentFiber) { + // TODO (Offscreen) Check: flags & (RefStatic | LayoutStatic) + var child = parentFiber.child; + + while (child !== null) { + disappearLayoutEffects(child); + child = child.sibling; + } + } + + function reappearLayoutEffects( + finishedRoot, + current, + finishedWork, // This function visits both newly finished work and nodes that were re-used + // from a previously committed tree. We cannot check non-static flags if the + // node was reused. + includeWorkInProgressEffects + ) { + // Turn on layout effects in a tree that previously disappeared. + var flags = finishedWork.flags; + + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + recursivelyTraverseReappearLayoutEffects( + finishedRoot, + finishedWork, + includeWorkInProgressEffects + ); // TODO: Check flags & LayoutStatic + + commitHookLayoutEffects(finishedWork, Layout); + break; + } + + case ClassComponent: { + recursivelyTraverseReappearLayoutEffects( + finishedRoot, + finishedWork, + includeWorkInProgressEffects + ); // TODO: Check for LayoutStatic flag + + var instance = finishedWork.stateNode; + + if (typeof instance.componentDidMount === "function") { + try { + instance.componentDidMount(); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + } // Commit any callbacks that would have fired while the component + // was hidden. + + var updateQueue = finishedWork.updateQueue; + + if (updateQueue !== null) { + commitHiddenCallbacks(updateQueue, instance); + } // If this is newly finished work, check for setState callbacks + + if (includeWorkInProgressEffects && flags & Callback) { + commitClassCallbacks(finishedWork); + } // TODO: Check flags & RefStatic + + safelyAttachRef(finishedWork, finishedWork.return); + break; + } + // Unlike commitLayoutEffectsOnFiber, we don't need to handle HostRoot + // because this function only visits nodes that are inside an + // Offscreen fiber. + // case HostRoot: { + // ... + // } + + case HostHoistable: + case HostSingleton: + case HostComponent: { + recursivelyTraverseReappearLayoutEffects( + finishedRoot, + finishedWork, + includeWorkInProgressEffects + ); // 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 ( + includeWorkInProgressEffects && + current === null && + flags & Update + ) { + commitHostComponentMount(finishedWork); + } // TODO: Check flags & Ref + + safelyAttachRef(finishedWork, finishedWork.return); + break; + } + + case Profiler: { + recursivelyTraverseReappearLayoutEffects( + finishedRoot, + finishedWork, + includeWorkInProgressEffects + ); // TODO: Figure out how Profiler updates should work with Offscreen + + if (includeWorkInProgressEffects && flags & Update) { + commitProfilerUpdate(finishedWork, current); + } + + break; + } + + case SuspenseComponent: { + recursivelyTraverseReappearLayoutEffects( + finishedRoot, + finishedWork, + includeWorkInProgressEffects + ); // TODO: Figure out how Suspense hydration callbacks should work + + break; + } + + case OffscreenComponent: { + var offscreenState = finishedWork.memoizedState; + var isHidden = offscreenState !== null; + + if (isHidden); + else { + recursivelyTraverseReappearLayoutEffects( + finishedRoot, + finishedWork, + includeWorkInProgressEffects + ); + } // TODO: Check flags & Ref + + safelyAttachRef(finishedWork, finishedWork.return); + break; + } + + default: { + recursivelyTraverseReappearLayoutEffects( + finishedRoot, + finishedWork, + includeWorkInProgressEffects ); - flags & 2048 && + break; + } + } + } + + function recursivelyTraverseReappearLayoutEffects( + finishedRoot, + parentFiber, + includeWorkInProgressEffects + ) { + // This function visits both newly finished work and nodes that were re-used + // from a previously committed tree. We cannot check non-static flags if the + // node was reused. + var childShouldIncludeWorkInProgressEffects = + includeWorkInProgressEffects && + (parentFiber.subtreeFlags & LayoutMask) !== NoFlags$1; // TODO (Offscreen) Check: flags & (RefStatic | LayoutStatic) + + var prevDebugFiber = getCurrentFiber(); + var child = parentFiber.child; + + while (child !== null) { + var current = child.alternate; + reappearLayoutEffects( + finishedRoot, + current, + child, + childShouldIncludeWorkInProgressEffects + ); + child = child.sibling; + } + + setCurrentFiber(prevDebugFiber); + } + + function commitHookPassiveMountEffects(finishedWork, hookFlags) { + if (shouldProfile(finishedWork)) { + startPassiveEffectTimer(); + + try { + commitHookEffectListMount(hookFlags, finishedWork); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + + recordPassiveEffectDuration(finishedWork); + } else { + try { + commitHookEffectListMount(hookFlags, finishedWork); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + } + } + + function commitPassiveMountEffects( + root, + finishedWork, + committedLanes, + committedTransitions + ) { + setCurrentFiber(finishedWork); + commitPassiveMountOnFiber(root, finishedWork); + resetCurrentFiber(); + } + + function recursivelyTraversePassiveMountEffects( + root, + parentFiber, + committedLanes, + committedTransitions + ) { + var prevDebugFiber = getCurrentFiber(); + + if (parentFiber.subtreeFlags & PassiveMask) { + var child = parentFiber.child; + + while (child !== null) { + setCurrentFiber(child); + commitPassiveMountOnFiber(root, child); + child = child.sibling; + } + } + + setCurrentFiber(prevDebugFiber); + } + + function commitPassiveMountOnFiber( + finishedRoot, + finishedWork, + committedLanes, + committedTransitions + ) { + // When updating this function, also update reconnectPassiveEffects, which does + // most of the same things when an offscreen tree goes from hidden -> visible, + // or when toggling effects inside a hidden tree. + var flags = finishedWork.flags; + + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + recursivelyTraversePassiveMountEffects(finishedRoot, finishedWork); + + if (flags & Passive$1) { commitHookPassiveMountEffects(finishedWork, Passive | HasEffect); + } + break; - case 3: - recursivelyTraversePassiveMountEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - ); - flags & 2048 && - ((finishedRoot = null), - null !== finishedWork.alternate && - (finishedRoot = finishedWork.alternate.memoizedState.cache), - (finishedWork = finishedWork.memoizedState.cache), - finishedWork !== finishedRoot && - (retainCache(finishedWork), - null != finishedRoot && releaseCache(finishedRoot))); + } + + case HostRoot: { + recursivelyTraversePassiveMountEffects(finishedRoot, finishedWork); + break; - case 23: + } + + case LegacyHiddenComponent: { break; - case 22: + } + + case OffscreenComponent: { + // TODO: Pass `current` as argument to this function var _instance3 = finishedWork.stateNode; - null !== finishedWork.memoizedState - ? _instance3._visibility & 4 - ? recursivelyTraversePassiveMountEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - ) - : finishedWork.mode & 1 - ? recursivelyTraverseAtomicPassiveEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - ) - : ((_instance3._visibility |= 4), + var nextState = finishedWork.memoizedState; + var isHidden = nextState !== null; + + if (isHidden) { + if (_instance3._visibility & OffscreenPassiveEffectsConnected) { + // The effects are currently connected. Update them. + recursivelyTraversePassiveMountEffects( + finishedRoot, + finishedWork + ); + } else { + if (finishedWork.mode & ConcurrentMode); + else { + // Legacy Mode: Fire the effects even if the tree is hidden. + _instance3._visibility |= OffscreenPassiveEffectsConnected; recursivelyTraversePassiveMountEffects( finishedRoot, - finishedWork, - committedLanes, - committedTransitions - )) - : _instance3._visibility & 4 - ? recursivelyTraversePassiveMountEffects( + finishedWork + ); + } + } + } else { + // Tree is visible + if (_instance3._visibility & OffscreenPassiveEffectsConnected) { + // The effects are currently connected. Update them. + recursivelyTraversePassiveMountEffects( finishedRoot, - finishedWork, - committedLanes, - committedTransitions - ) - : ((_instance3._visibility |= 4), + finishedWork + ); + } else { + // The effects are currently disconnected. Reconnect them, while also + // firing effects inside newly mounted trees. This also applies to + // the initial render. + _instance3._visibility |= OffscreenPassiveEffectsConnected; recursivelyTraverseReconnectPassiveEffects( finishedRoot, - finishedWork, - committedLanes, - committedTransitions, - 0 !== (finishedWork.subtreeFlags & 10256) - )); - flags & 2048 && - commitOffscreenPassiveMountEffects( - finishedWork.alternate, - finishedWork - ); + finishedWork + ); + } + } + break; - case 24: - recursivelyTraversePassiveMountEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - ); - flags & 2048 && - commitCachePassiveMountEffect(finishedWork.alternate, finishedWork); + } + + case CacheComponent: { + recursivelyTraversePassiveMountEffects(finishedRoot, finishedWork); + break; - default: - recursivelyTraversePassiveMountEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - ); + } + + case TracingMarkerComponent: + + default: { + recursivelyTraversePassiveMountEffects(finishedRoot, finishedWork); + break; + } } } + function recursivelyTraverseReconnectPassiveEffects( finishedRoot, parentFiber, @@ -10856,734 +21492,1281 @@ __DEV__ && committedTransitions, includeWorkInProgressEffects ) { - includeWorkInProgressEffects = - includeWorkInProgressEffects && - 0 !== (parentFiber.subtreeFlags & 10256); - for (parentFiber = parentFiber.child; null !== parentFiber; ) - runWithFiberInDEV( - parentFiber, - reconnectPassiveEffects, - finishedRoot, - parentFiber, - committedLanes, - committedTransitions, - includeWorkInProgressEffects - ), - (parentFiber = parentFiber.sibling); + var prevDebugFiber = getCurrentFiber(); + var child = parentFiber.child; + + while (child !== null) { + reconnectPassiveEffects(finishedRoot, child); + child = child.sibling; + } + + setCurrentFiber(prevDebugFiber); } + function reconnectPassiveEffects( finishedRoot, finishedWork, committedLanes, - committedTransitions, + committedTransitions, // This function visits both newly finished work and nodes that were re-used + // from a previously committed tree. We cannot check non-static flags if the + // node was reused. includeWorkInProgressEffects ) { - var flags = finishedWork.flags; switch (finishedWork.tag) { - case 0: - case 11: - case 15: + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { recursivelyTraverseReconnectPassiveEffects( finishedRoot, - finishedWork, - committedLanes, - committedTransitions, - includeWorkInProgressEffects - ); + finishedWork + ); // TODO: Check for PassiveStatic flag + commitHookPassiveMountEffects(finishedWork, Passive); break; - case 23: + } + // Unlike commitPassiveMountOnFiber, we don't need to handle HostRoot + // because this function only visits nodes that are inside an + // Offscreen fiber. + // case HostRoot: { + // ... + // } + + case LegacyHiddenComponent: { break; - case 22: + } + + case OffscreenComponent: { var _instance4 = finishedWork.stateNode; - null !== finishedWork.memoizedState - ? _instance4._visibility & 4 - ? recursivelyTraverseReconnectPassiveEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions, - includeWorkInProgressEffects - ) - : finishedWork.mode & 1 - ? recursivelyTraverseAtomicPassiveEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - ) - : ((_instance4._visibility |= 4), - recursivelyTraverseReconnectPassiveEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions, - includeWorkInProgressEffects - )) - : ((_instance4._visibility |= 4), + var nextState = finishedWork.memoizedState; + var isHidden = nextState !== null; + + if (isHidden) { + if (_instance4._visibility & OffscreenPassiveEffectsConnected) { + // The effects are currently connected. Update them. recursivelyTraverseReconnectPassiveEffects( finishedRoot, - finishedWork, - committedLanes, - committedTransitions, - includeWorkInProgressEffects - )); - includeWorkInProgressEffects && - flags & 2048 && - commitOffscreenPassiveMountEffects( - finishedWork.alternate, + finishedWork + ); + } else { + if (finishedWork.mode & ConcurrentMode); + else { + // Legacy Mode: Fire the effects even if the tree is hidden. + _instance4._visibility |= OffscreenPassiveEffectsConnected; + recursivelyTraverseReconnectPassiveEffects( + finishedRoot, + finishedWork + ); + } + } + } else { + // Tree is visible + // Since we're already inside a reconnecting tree, it doesn't matter + // whether the effects are currently connected. In either case, we'll + // continue traversing the tree and firing all the effects. + // + // We do need to set the "connected" flag on the instance, though. + _instance4._visibility |= OffscreenPassiveEffectsConnected; + recursivelyTraverseReconnectPassiveEffects( + finishedRoot, finishedWork ); + } + break; - case 24: + } + + case CacheComponent: { recursivelyTraverseReconnectPassiveEffects( finishedRoot, - finishedWork, - committedLanes, - committedTransitions, - includeWorkInProgressEffects + finishedWork ); - includeWorkInProgressEffects && - flags & 2048 && - commitCachePassiveMountEffect(finishedWork.alternate, finishedWork); + break; - default: + } + + case TracingMarkerComponent: + + default: { recursivelyTraverseReconnectPassiveEffects( finishedRoot, - finishedWork, - committedLanes, - committedTransitions, - includeWorkInProgressEffects - ); - } - } - function recursivelyTraverseAtomicPassiveEffects( - finishedRoot, - parentFiber, - committedLanes, - committedTransitions - ) { - if (parentFiber.subtreeFlags & 10256) - for (parentFiber = parentFiber.child; null !== parentFiber; ) - runWithFiberInDEV( - parentFiber, - commitAtomicPassiveEffects, - finishedRoot, - parentFiber, - committedLanes, - committedTransitions - ), - (parentFiber = parentFiber.sibling); - } - function commitAtomicPassiveEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - ) { - var flags = finishedWork.flags; - switch (finishedWork.tag) { - case 22: - recursivelyTraverseAtomicPassiveEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - ); - flags & 2048 && - commitOffscreenPassiveMountEffects( - finishedWork.alternate, - finishedWork - ); - break; - case 24: - recursivelyTraverseAtomicPassiveEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions + finishedWork ); - flags & 2048 && - commitCachePassiveMountEffect(finishedWork.alternate, finishedWork); break; - default: - recursivelyTraverseAtomicPassiveEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - ); + } } } + + function commitPassiveUnmountEffects(finishedWork) { + setCurrentFiber(finishedWork); + commitPassiveUnmountOnFiber(finishedWork); + resetCurrentFiber(); + } // If we're inside a brand new tree, or a tree that was already visible, then we + // should only suspend host components that have a ShouldSuspendCommit flag. + // Components without it haven't changed since the last commit, so we can skip + // over those. + // + // When we enter a tree that is being revealed (going from hidden -> visible), + // we need to suspend _any_ component that _may_ suspend. Even if they're + // already in the "current" tree. Because their visibility has changed, the + // browser may not have prerendered them yet. So we check the MaySuspendCommit + // flag instead. + + var suspenseyCommitFlag = ShouldSuspendCommit; + function accumulateSuspenseyCommit(finishedWork) { + accumulateSuspenseyCommitOnFiber(finishedWork); + } + function recursivelyAccumulateSuspenseyCommit(parentFiber) { - if (parentFiber.subtreeFlags & suspenseyCommitFlag) - for (parentFiber = parentFiber.child; null !== parentFiber; ) - accumulateSuspenseyCommitOnFiber(parentFiber), - (parentFiber = parentFiber.sibling); + if (parentFiber.subtreeFlags & suspenseyCommitFlag) { + var child = parentFiber.child; + + while (child !== null) { + accumulateSuspenseyCommitOnFiber(child); + child = child.sibling; + } + } } + function accumulateSuspenseyCommitOnFiber(fiber) { switch (fiber.tag) { - case 26: + case HostHoistable: { recursivelyAccumulateSuspenseyCommit(fiber); - fiber.flags & suspenseyCommitFlag && - null !== fiber.memoizedState && - suspendResource(); + + if (fiber.flags & suspenseyCommitFlag) { + if (fiber.memoizedState !== null) { + suspendResource(); + } + } + break; - case 5: + } + + case HostComponent: { recursivelyAccumulateSuspenseyCommit(fiber); + break; - case 3: - case 4: - recursivelyAccumulateSuspenseyCommit(fiber); + } + + case HostRoot: + case HostPortal: { + { + recursivelyAccumulateSuspenseyCommit(fiber); + } + break; - case 22: - if (null === fiber.memoizedState) { + } + + case OffscreenComponent: { + var isHidden = fiber.memoizedState !== null; + + if (isHidden); + else { var current = fiber.alternate; - null !== current && null !== current.memoizedState - ? ((current = suspenseyCommitFlag), - (suspenseyCommitFlag = 16777216), - recursivelyAccumulateSuspenseyCommit(fiber), - (suspenseyCommitFlag = current)) - : recursivelyAccumulateSuspenseyCommit(fiber); + var wasHidden = current !== null && current.memoizedState !== null; + + if (wasHidden) { + // This tree is being revealed. Visit all newly visible suspensey + // instances, even if they're in the current tree. + var prevFlags = suspenseyCommitFlag; + suspenseyCommitFlag = MaySuspendCommit; + recursivelyAccumulateSuspenseyCommit(fiber); + suspenseyCommitFlag = prevFlags; + } else { + recursivelyAccumulateSuspenseyCommit(fiber); + } } + break; - default: + } + + default: { recursivelyAccumulateSuspenseyCommit(fiber); + } } } + function detachAlternateSiblings(parentFiber) { + // 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 = parentFiber.alternate; - if ( - null !== previousFiber && - ((parentFiber = previousFiber.child), null !== parentFiber) - ) { - previousFiber.child = null; - do - (previousFiber = parentFiber.sibling), - (parentFiber.sibling = null), - (parentFiber = previousFiber); - while (null !== parentFiber); + + if (previousFiber !== null) { + var detachedChild = previousFiber.child; + + if (detachedChild !== null) { + previousFiber.child = null; + + do { + // $FlowFixMe[incompatible-use] found when upgrading Flow + var detachedSibling = detachedChild.sibling; // $FlowFixMe[incompatible-use] found when upgrading Flow + + detachedChild.sibling = null; + detachedChild = detachedSibling; + } while (detachedChild !== null); + } } } + function commitHookPassiveUnmountEffects( finishedWork, nearestMountedAncestor, hookFlags ) { - shouldProfile(finishedWork) - ? ((passiveEffectStartTime = now()), - commitHookEffectListUnmount( - hookFlags, - finishedWork, - nearestMountedAncestor - ), - recordPassiveEffectDuration(finishedWork)) - : commitHookEffectListUnmount( - hookFlags, - finishedWork, - nearestMountedAncestor - ); + if (shouldProfile(finishedWork)) { + startPassiveEffectTimer(); + commitHookEffectListUnmount( + hookFlags, + finishedWork, + nearestMountedAncestor + ); + recordPassiveEffectDuration(finishedWork); + } else { + commitHookEffectListUnmount( + hookFlags, + finishedWork, + nearestMountedAncestor + ); + } } + function recursivelyTraversePassiveUnmountEffects(parentFiber) { + // Deletions effects can be scheduled on any fiber type. They need to happen + // before the children effects have fired. var deletions = parentFiber.deletions; - if (0 !== (parentFiber.flags & 16)) { - if (null !== deletions) + + if ((parentFiber.flags & ChildDeletion) !== NoFlags$1) { + if (deletions !== null) { for (var i = 0; i < deletions.length; i++) { - var childToDelete = deletions[i]; + var childToDelete = deletions[i]; // TODO: Convert this to use recursion + nextEffect = childToDelete; commitPassiveUnmountEffectsInsideOfDeletedTree_begin( childToDelete, parentFiber ); } + } + detachAlternateSiblings(parentFiber); } - if (parentFiber.subtreeFlags & 10256) - for (parentFiber = parentFiber.child; null !== parentFiber; ) - runWithFiberInDEV( - parentFiber, - commitPassiveUnmountOnFiber, - parentFiber - ), - (parentFiber = parentFiber.sibling); + + var prevDebugFiber = getCurrentFiber(); // TODO: Split PassiveMask into separate masks for mount and unmount? + + if (parentFiber.subtreeFlags & PassiveMask) { + var child = parentFiber.child; + + while (child !== null) { + setCurrentFiber(child); + commitPassiveUnmountOnFiber(child); + child = child.sibling; + } + } + + setCurrentFiber(prevDebugFiber); } + function commitPassiveUnmountOnFiber(finishedWork) { switch (finishedWork.tag) { - case 0: - case 11: - case 15: + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { recursivelyTraversePassiveUnmountEffects(finishedWork); - finishedWork.flags & 2048 && + + if (finishedWork.flags & Passive$1) { commitHookPassiveUnmountEffects( finishedWork, finishedWork.return, Passive | HasEffect ); + } + break; - case 22: + } + + case OffscreenComponent: { var instance = finishedWork.stateNode; - null !== finishedWork.memoizedState && - instance._visibility & 4 && - (null === finishedWork.return || 13 !== finishedWork.return.tag) - ? ((instance._visibility &= -5), - recursivelyTraverseDisconnectPassiveEffects(finishedWork)) - : recursivelyTraversePassiveUnmountEffects(finishedWork); + var nextState = finishedWork.memoizedState; + var isHidden = nextState !== null; + + if ( + isHidden && + instance._visibility & OffscreenPassiveEffectsConnected && // For backwards compatibility, don't unmount when a tree suspends. In + // the future we may change this to unmount after a delay. + (finishedWork.return === null || + finishedWork.return.tag !== SuspenseComponent) + ) { + // The effects are currently connected. Disconnect them. + // TODO: Add option or heuristic to delay before disconnecting the + // effects. Then if the tree reappears before the delay has elapsed, we + // can skip toggling the effects entirely. + instance._visibility &= ~OffscreenPassiveEffectsConnected; + recursivelyTraverseDisconnectPassiveEffects(finishedWork); + } else { + recursivelyTraversePassiveUnmountEffects(finishedWork); + } + break; - default: + } + + default: { recursivelyTraversePassiveUnmountEffects(finishedWork); + break; + } } } + function recursivelyTraverseDisconnectPassiveEffects(parentFiber) { + // Deletions effects can be scheduled on any fiber type. They need to happen + // before the children effects have fired. var deletions = parentFiber.deletions; - if (0 !== (parentFiber.flags & 16)) { - if (null !== deletions) + + if ((parentFiber.flags & ChildDeletion) !== NoFlags$1) { + if (deletions !== null) { for (var i = 0; i < deletions.length; i++) { - var childToDelete = deletions[i]; + var childToDelete = deletions[i]; // TODO: Convert this to use recursion + nextEffect = childToDelete; commitPassiveUnmountEffectsInsideOfDeletedTree_begin( childToDelete, parentFiber ); } + } + detachAlternateSiblings(parentFiber); } - for (parentFiber = parentFiber.child; null !== parentFiber; ) - runWithFiberInDEV(parentFiber, disconnectPassiveEffect, parentFiber), - (parentFiber = parentFiber.sibling); + + var prevDebugFiber = getCurrentFiber(); // TODO: Check PassiveStatic flag + + var child = parentFiber.child; + + while (child !== null) { + setCurrentFiber(child); + disconnectPassiveEffect(child); + child = child.sibling; + } + + setCurrentFiber(prevDebugFiber); } + function disconnectPassiveEffect(finishedWork) { switch (finishedWork.tag) { - case 0: - case 11: - case 15: + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + // TODO: Check PassiveStatic flag commitHookPassiveUnmountEffects( finishedWork, finishedWork.return, Passive - ); + ); // When disconnecting passive effects, we fire the effects in the same + // order as during a deletiong: parent before child + recursivelyTraverseDisconnectPassiveEffects(finishedWork); break; - case 22: + } + + case OffscreenComponent: { var instance = finishedWork.stateNode; - instance._visibility & 4 && - ((instance._visibility &= -5), - recursivelyTraverseDisconnectPassiveEffects(finishedWork)); + + if (instance._visibility & OffscreenPassiveEffectsConnected) { + instance._visibility &= ~OffscreenPassiveEffectsConnected; + recursivelyTraverseDisconnectPassiveEffects(finishedWork); + } + break; - default: + } + + default: { recursivelyTraverseDisconnectPassiveEffects(finishedWork); + break; + } } } + function commitPassiveUnmountEffectsInsideOfDeletedTree_begin( deletedSubtreeRoot, nearestMountedAncestor ) { - for (; null !== nextEffect; ) { - var fiber = nextEffect; - runWithFiberInDEV( - fiber, - commitPassiveUnmountInsideDeletedTreeOnFiber, + while (nextEffect !== null) { + var fiber = nextEffect; // Deletion effects fire in parent -> child order + // TODO: Check if fiber has a PassiveStatic flag + + setCurrentFiber(fiber); + commitPassiveUnmountInsideDeletedTreeOnFiber( fiber, nearestMountedAncestor ); - var child = fiber.child; - if (null !== child) (child.return = fiber), (nextEffect = child); - else - a: for (fiber = deletedSubtreeRoot; null !== nextEffect; ) { - child = nextEffect; - var sibling = child.sibling, - returnFiber = child.return; - detachFiberAfterEffects(child); - if (child === fiber) { - nextEffect = null; - break a; - } - if (null !== sibling) { - sibling.return = returnFiber; - nextEffect = sibling; - break a; - } - nextEffect = returnFiber; - } + resetCurrentFiber(); + var child = fiber.child; // TODO: Only traverse subtree if it has a PassiveStatic flag. + + if (child !== null) { + child.return = fiber; + nextEffect = child; + } else { + commitPassiveUnmountEffectsInsideOfDeletedTree_complete( + deletedSubtreeRoot + ); + } + } + } + + function commitPassiveUnmountEffectsInsideOfDeletedTree_complete( + deletedSubtreeRoot + ) { + while (nextEffect !== null) { + var fiber = nextEffect; + var sibling = fiber.sibling; + var returnFiber = fiber.return; // Recursively traverse the entire deleted tree and clean up fiber fields. + // This is more aggressive than ideal, and the long term goal is to only + // have to detach the deleted tree at the root. + + detachFiberAfterEffects(fiber); + + if (fiber === deletedSubtreeRoot) { + nextEffect = null; + return; + } + + if (sibling !== null) { + sibling.return = returnFiber; + nextEffect = sibling; + return; + } + + nextEffect = returnFiber; } } + function commitPassiveUnmountInsideDeletedTreeOnFiber( current, nearestMountedAncestor ) { switch (current.tag) { - case 0: - case 11: - case 15: + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { commitHookPassiveUnmountEffects( current, nearestMountedAncestor, Passive ); break; - case 23: - case 22: - null !== current.memoizedState && - null !== current.memoizedState.cachePool && - ((current = current.memoizedState.cachePool.pool), - null != current && retainCache(current)); - break; - case 24: - releaseCache(current.memoizedState.cache); + } } } + function invokeLayoutEffectMountInDEV(fiber) { - switch (fiber.tag) { - case 0: - case 11: - case 15: - try { - commitHookEffectListMount(Layout | HasEffect, fiber); - } catch (error$36) { - captureCommitPhaseError(fiber, fiber.return, error$36); - } - break; - case 1: - var instance = fiber.stateNode; - if ("function" === typeof instance.componentDidMount) + { + // 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: { try { - instance.componentDidMount(); - } catch (error$37) { - captureCommitPhaseError(fiber, fiber.return, error$37); + commitHookEffectListMount(Layout | HasEffect, fiber); + } catch (error) { + captureCommitPhaseError(fiber, fiber.return, error); + } + + break; + } + + case ClassComponent: { + var instance = fiber.stateNode; + + if (typeof instance.componentDidMount === "function") { + try { + instance.componentDidMount(); + } catch (error) { + captureCommitPhaseError(fiber, fiber.return, error); + } } + + break; + } + } } } + function invokePassiveEffectMountInDEV(fiber) { - switch (fiber.tag) { - case 0: - case 11: - case 15: - try { - commitHookEffectListMount(Passive | HasEffect, fiber); - } catch (error$38) { - captureCommitPhaseError(fiber, fiber.return, error$38); + { + // 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: { + try { + commitHookEffectListMount(Passive | HasEffect, fiber); + } catch (error) { + captureCommitPhaseError(fiber, fiber.return, error); + } + + break; } + } } } + function invokeLayoutEffectUnmountInDEV(fiber) { - switch (fiber.tag) { - case 0: - case 11: - case 15: - try { - commitHookEffectListUnmount( - Layout | HasEffect, - fiber, - fiber.return - ); - } catch (error$39) { - captureCommitPhaseError(fiber, fiber.return, error$39); + { + // 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: { + try { + commitHookEffectListUnmount( + Layout | HasEffect, + fiber, + fiber.return + ); + } catch (error) { + captureCommitPhaseError(fiber, fiber.return, error); + } + + break; } - break; - case 1: - var instance = fiber.stateNode; - "function" === typeof instance.componentWillUnmount && - safelyCallComponentWillUnmount(fiber, fiber.return, instance); + + case ClassComponent: { + var instance = fiber.stateNode; + + if (typeof instance.componentWillUnmount === "function") { + safelyCallComponentWillUnmount(fiber, fiber.return, instance); + } + + break; + } + } } } + function invokePassiveEffectUnmountInDEV(fiber) { - switch (fiber.tag) { - case 0: - case 11: - case 15: - try { - commitHookEffectListUnmount( - Passive | HasEffect, - fiber, - fiber.return - ); - } catch (error$40) { - captureCommitPhaseError(fiber, fiber.return, error$40); + { + // 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: { + try { + commitHookEffectListUnmount( + Passive | HasEffect, + fiber, + fiber.return + ); + } catch (error) { + captureCommitPhaseError(fiber, fiber.return, error); + } } + } } } - function isConcurrentActEnvironment() { - var isReactActEnvironmentGlobal = - "undefined" !== typeof IS_REACT_ACT_ENVIRONMENT + + if (typeof Symbol === "function" && Symbol.for) { + var symbolFor = Symbol.for; + symbolFor("selector.component"); + symbolFor("selector.has_pseudo_class"); + symbolFor("selector.role"); + symbolFor("selector.test_id"); + symbolFor("selector.text"); + } + + var ReactCurrentActQueue$1 = ReactSharedInternals.ReactCurrentActQueue; + function isLegacyActEnvironment(fiber) { + { + // Legacy mode. We preserve the behavior of React 17's act. It assumes an + // act environment whenever `jest` is defined, but you can still turn off + // spurious warnings by setting IS_REACT_ACT_ENVIRONMENT explicitly + // to false. + // $FlowFixMe[cannot-resolve-name] Flow doesn't know about IS_REACT_ACT_ENVIRONMENT global + typeof IS_REACT_ACT_ENVIRONMENT !== "undefined" // $FlowFixMe[cannot-resolve-name] ? IS_REACT_ACT_ENVIRONMENT - : void 0; - isReactActEnvironmentGlobal || - null === ReactSharedInternals.actQueue || - error$jscomp$0( - "The current testing environment is not configured to support act(...)" - ); - return isReactActEnvironmentGlobal; + : undefined; // $FlowFixMe[cannot-resolve-name] - Flow doesn't know about jest + return warnsIfNotActing; + } + } + function isConcurrentActEnvironment() { + { + var isReactActEnvironmentGlobal = // $FlowFixMe[cannot-resolve-name] Flow doesn't know about IS_REACT_ACT_ENVIRONMENT global + typeof IS_REACT_ACT_ENVIRONMENT !== "undefined" // $FlowFixMe[cannot-resolve-name] + ? IS_REACT_ACT_ENVIRONMENT + : undefined; + + if ( + !isReactActEnvironmentGlobal && + ReactCurrentActQueue$1.current !== null + ) { + // TODO: Include link to relevant documentation page. + error( + "The current testing environment is not configured to support " + + "act(...)" + ); + } + + return isReactActEnvironmentGlobal; + } + } + + var PossiblyWeakMap = typeof WeakMap === "function" ? WeakMap : Map; + var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, + ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner, + ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig, + ReactCurrentActQueue = ReactSharedInternals.ReactCurrentActQueue; + var NoContext = + /* */ + 0; + var BatchedContext = + /* */ + 1; + var RenderContext = + /* */ + 2; + var CommitContext = + /* */ + 4; + var RootInProgress = 0; + var RootFatalErrored = 1; + var RootErrored = 2; + var RootSuspended = 3; + var RootSuspendedWithDelay = 4; + var RootCompleted = 5; + var RootDidNotComplete = 6; // Describes where we are in the React execution stack + + var executionContext = NoContext; // The root we're working on + + var workInProgressRoot = null; // The fiber we're working on + + var workInProgress = null; // The lanes we're rendering + + var workInProgressRootRenderLanes = NoLanes; + var NotSuspended = 0; + var SuspendedOnError = 1; + var SuspendedOnData = 2; + var SuspendedOnImmediate = 3; + var SuspendedOnInstance = 4; + var SuspendedOnInstanceAndReadyToContinue = 5; + var SuspendedOnDeprecatedThrowPromise = 6; + var SuspendedAndReadyToContinue = 7; + var SuspendedOnHydration = 8; // When this is true, the work-in-progress fiber just suspended (or errored) and + // we've yet to unwind the stack. In some cases, we may yield to the main thread + // after this happens. If the fiber is pinged before we resume, we can retry + // immediately instead of unwinding the stack. + + var workInProgressSuspendedReason = NotSuspended; + var workInProgressThrownValue = null; // Whether a ping listener was attached during this render. This is slightly + // different that whether something suspended, because we don't add multiple + // listeners to a promise we've already seen (per root and lane). + + var workInProgressRootDidAttachPingListener = false; // A contextual version of workInProgressRootRenderLanes. It is a superset of + // the lanes that we started working on at the root. When we enter a subtree + // that is currently hidden, we add the lanes that would have committed if + // the hidden tree hadn't been deferred. This is modified by the + // HiddenContext module. + // + // Most things in the work loop should deal with workInProgressRootRenderLanes. + // Most things in begin/complete phases should deal with entangledRenderLanes. + + var entangledRenderLanes = NoLanes; // Whether to root completed, errored, suspended, etc. + + var workInProgressRootExitStatus = RootInProgress; // A fatal error, if one is thrown + + var workInProgressRootFatalError = null; // The work left over by components that were visited during this render. Only + // includes unprocessed updates, not work in bailed out children. + + var workInProgressRootSkippedLanes = NoLanes; // Lanes that were updated (in an interleaved event) during this render. + + var workInProgressRootInterleavedUpdatedLanes = NoLanes; // Lanes that were updated during the render phase (*not* an interleaved event). + + var workInProgressRootPingedLanes = NoLanes; // If this lane scheduled deferred work, this is the lane of the deferred task. + + var workInProgressDeferredLane = NoLane; // Errors that are thrown during the render phase. + + var workInProgressRootConcurrentErrors = null; // These are errors that we recovered from without surfacing them to the UI. + // We will log them once the tree commits. + + var workInProgressRootRecoverableErrors = null; // Tracks when an update occurs during the render phase. + + var workInProgressRootDidIncludeRecursiveRenderUpdate = false; // Thacks when an update occurs during the commit phase. It's a separate + // filled in with the resolved UI. This lets us throttle the appearance of new + // content as it streams in, to minimize jank. + // TODO: Think of a better name for this variable? + + var globalMostRecentFallbackTime = 0; + var FALLBACK_THROTTLE_MS = 300; // The absolute time for when we should start giving up on rendering + // more and prefer CPU suspense heuristics instead. + + var workInProgressRootRenderTargetTime = Infinity; // How long a render is supposed to take before we start following CPU + // suspense heuristics and opt out of rendering more content. + + var RENDER_TIMEOUT_MS = 500; + var workInProgressTransitions = null; + + function resetRenderTimer() { + workInProgressRootRenderTargetTime = now$1() + RENDER_TIMEOUT_MS; + } + + function getRenderTargetTime() { + return workInProgressRootRenderTargetTime; + } + var hasUncaughtError = false; + var firstUncaughtError = null; + var legacyErrorBoundariesThatAlreadyFailed = null; + var rootDoesHavePassiveEffects = false; + var rootWithPendingPassiveEffects = null; + var pendingPassiveEffectsLanes = NoLanes; + var pendingPassiveProfilerEffects = []; + + var NESTED_UPDATE_LIMIT = 50; + var nestedUpdateCount = 0; + var rootWithNestedUpdates = null; + var isFlushingPassiveEffects = false; + var didScheduleUpdateDuringPassiveEffects = false; + var NESTED_PASSIVE_UPDATE_LIMIT = 50; + var nestedPassiveUpdateCount = 0; + var rootWithPassiveNestedUpdates = null; + var isRunningInsertionEffect = false; + function getWorkInProgressRoot() { + return workInProgressRoot; + } + function getWorkInProgressRootRenderLanes() { + return workInProgressRootRenderLanes; + } + function isWorkLoopSuspendedOnData() { + return workInProgressSuspendedReason === SuspendedOnData; } function requestUpdateLane(fiber) { - if (0 === (fiber.mode & 1)) return SyncLane; - if ( + // Special cases + var mode = fiber.mode; + + if ((mode & ConcurrentMode) === NoMode) { + return SyncLane; + } else if ( (executionContext & RenderContext) !== NoContext && - 0 !== workInProgressRootRenderLanes - ) - return workInProgressRootRenderLanes & -workInProgressRootRenderLanes; - var transition = ReactSharedInternals.T; - return null !== transition - ? (transition._updatedFibers || (transition._updatedFibers = new Set()), - transition._updatedFibers.add(fiber), - (fiber = currentEntangledLane), - 0 !== fiber ? fiber : requestTransitionLane()) - : resolveUpdatePriority(); + workInProgressRootRenderLanes !== NoLanes + ) { + // This is a render phase update. These are not officially supported. The + // old behavior is to give this the same "thread" (lanes) as + // whatever is currently rendering. So if you call `setState` on a component + // that happens later in the same render, it will flush. Ideally, we want to + // remove the special case and treat them as if they came from an + // interleaved event. Regardless, this pattern is not officially supported. + // This behavior is only a fallback. The flag only exists until we can roll + // out the setState warning, since existing code might accidentally rely on + // the current behavior. + return pickArbitraryLane(workInProgressRootRenderLanes); + } + + var transition = requestCurrentTransition(); + + if (transition !== null) { + { + var batchConfigTransition = ReactCurrentBatchConfig.transition; + + if (!batchConfigTransition._updatedFibers) { + batchConfigTransition._updatedFibers = new Set(); + } + + batchConfigTransition._updatedFibers.add(fiber); + } + + var actionScopeLane = peekEntangledActionLane(); + return actionScopeLane !== NoLane // We're inside an async action scope. Reuse the same lane. + ? actionScopeLane // We may or may not be inside an async action scope. If we are, this + : // is the first update in that scope. Either way, we need to get a + // fresh transition lane. + requestTransitionLane(); + } // 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. + + var updateLane = getCurrentUpdatePriority(); + + if (updateLane !== NoLane) { + return updateLane; + } // This update originated outside React. Ask the host environment 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. + + var eventLane = getCurrentEventPriority(); + return eventLane; + } + + function requestRetryLane(fiber) { + // This is a fork of `requestUpdateLane` designed specifically for Suspense + // "retries" — a special update that attempts to flip a Suspense boundary + // from its placeholder state to its primary/resolved state. + // Special cases + var mode = fiber.mode; + + if ((mode & ConcurrentMode) === NoMode) { + return SyncLane; + } + + return claimNextRetryLane(); } + function requestDeferredLane() { - 0 === workInProgressDeferredLane && - (workInProgressDeferredLane = - 0 !== (workInProgressRootRenderLanes & OffscreenLane) - ? OffscreenLane - : claimNextTransitionLane()); - var suspenseHandler = suspenseHandlerStackCursor.current; - null !== suspenseHandler && (suspenseHandler.flags |= 32); + if (workInProgressDeferredLane === NoLane) { + // If there are multiple useDeferredValue hooks in the same render, the + // tasks that they spawn should all be batched together, so they should all + // receive the same lane. + // Check the priority of the current render to decide the priority of the + // deferred task. + // OffscreenLane is used for prerendering, but we also use OffscreenLane + // for incremental hydration. It's given the lowest priority because the + // initial HTML is the same as the final UI. But useDeferredValue during + // hydration is an exception — we need to upgrade the UI to the final + // value. So if we're currently hydrating, we treat it like a transition. + var isPrerendering = + includesSomeLane(workInProgressRootRenderLanes, OffscreenLane) && + !getIsHydrating(); + + if (isPrerendering) { + // There's only one OffscreenLane, so if it contains deferred work, we + // should just reschedule using the same lane. + workInProgressDeferredLane = OffscreenLane; + } else { + // Everything else is spawned as a transition. + workInProgressDeferredLane = claimNextTransitionLane(); + } + } // Mark the parent Suspense boundary so it knows to spawn the deferred lane. + + var suspenseHandler = getSuspenseHandler(); + + if (suspenseHandler !== null) { + // TODO: As an optimization, we shouldn't entangle the lanes at the root; we + // can entangle them using the baseLanes of the Suspense boundary instead. + // We only need to do something special if there's no Suspense boundary. + suspenseHandler.flags |= DidDefer; + } + + return workInProgressDeferredLane; + } + function peekDeferredLane() { return workInProgressDeferredLane; } function scheduleUpdateOnFiber(root, fiber, lane) { - isRunningInsertionEffect && - error$jscomp$0("useInsertionEffect must not schedule updates."); - isFlushingPassiveEffects && (didScheduleUpdateDuringPassiveEffects = !0); + { + if (isRunningInsertionEffect) { + error("useInsertionEffect must not schedule updates."); + } + } + + { + if (isFlushingPassiveEffects) { + didScheduleUpdateDuringPassiveEffects = true; + } + } // Check if the work loop is currently suspended and waiting for data to + // finish loading. + if ( + // Suspended render phase (root === workInProgressRoot && - workInProgressSuspendedReason === SuspendedOnData) || - null !== root.cancelPendingCommit - ) - prepareFreshStack(root, 0), - markRootSuspended( - root, - workInProgressRootRenderLanes, - workInProgressDeferredLane - ); + workInProgressSuspendedReason === SuspendedOnData) || // Suspended commit phase + root.cancelPendingCommit !== null + ) { + // The incoming update might unblock the current render. Interrupt the + // current attempt and restart from the top. + prepareFreshStack(root, NoLanes); + markRootSuspended( + root, + workInProgressRootRenderLanes, + workInProgressDeferredLane + ); + } // Mark that the root has a pending update. + markRootUpdated(root, lane); + if ( - 0 !== (executionContext & RenderContext) && + (executionContext & RenderContext) !== NoLanes && root === workInProgressRoot ) { - if (isRendering) - switch (fiber.tag) { - case 0: - case 11: - case 15: - root = - (workInProgress && getComponentNameFromFiber(workInProgress)) || - "Unknown"; - didWarnAboutUpdateInRenderForAnotherComponent.has(root) || - (didWarnAboutUpdateInRenderForAnotherComponent.add(root), - (fiber = getComponentNameFromFiber(fiber) || "Unknown"), - error$jscomp$0( - "Cannot update a component (`%s`) while rendering a different component (`%s`). To locate the bad setState() call inside `%s`, follow the stack trace as described in https://react.dev/link/setstate-in-render", - fiber, - root, - root - )); - break; - case 1: - didWarnAboutUpdateInRender || - (error$jscomp$0( - "Cannot update during an existing state transition (such as within `render`). Render methods should be a pure function of props and state." - ), - (didWarnAboutUpdateInRender = !0)); - } - } else - isDevToolsPresent && addFiberToLanesMap(root, fiber, lane), - warnIfUpdatesNotWrappedWithActDEV(fiber), - root === workInProgressRoot && - ((executionContext & RenderContext) === NoContext && - (workInProgressRootInterleavedUpdatedLanes |= lane), - workInProgressRootExitStatus === RootSuspendedWithDelay && - markRootSuspended( - root, - workInProgressRootRenderLanes, - workInProgressDeferredLane - )), - ensureRootIsScheduled(root), - lane !== SyncLane || - executionContext !== NoContext || - 0 !== (fiber.mode & 1) || - ReactSharedInternals.isBatchingLegacy || - ((workInProgressRootRenderTargetTime = now$1() + RENDER_TIMEOUT_MS), - flushSyncWorkAcrossRoots_impl(!0)); + // This update was dispatched during the render phase. This is a mistake + // if the update originates from user space (with the exception of local + // hook updates, which are handled differently and don't reach this + // function), but there are some internal React features that use this as + // an implementation detail, like selective hydration. + warnAboutRenderPhaseUpdatesInDEV(fiber); // Track lanes that were updated during the render phase + } else { + // This is a normal update, scheduled from outside the render phase. For + // example, during an input event. + { + if (isDevToolsPresent) { + addFiberToLanesMap(root, fiber, lane); + } + } + + warnIfUpdatesNotWrappedWithActDEV(fiber); + + if (root === workInProgressRoot) { + // Received an update to a tree that's in the middle of rendering. Mark + // that there was an interleaved update work on this root. + if ((executionContext & RenderContext) === NoContext) { + workInProgressRootInterleavedUpdatedLanes = mergeLanes( + workInProgressRootInterleavedUpdatedLanes, + lane + ); + } + + if (workInProgressRootExitStatus === RootSuspendedWithDelay) { + // The root already suspended with a delay, which means this render + // definitely won't finish. Since we have a new update, let's mark it as + // suspended now, right before marking the incoming update. This has the + // effect of interrupting the current render and switching to the update. + // TODO: Make sure this doesn't override pings that happen while we've + // already started rendering. + markRootSuspended( + root, + workInProgressRootRenderLanes, + workInProgressDeferredLane + ); + } + } + + ensureRootIsScheduled(root); + + if ( + lane === SyncLane && + executionContext === NoContext && + (fiber.mode & ConcurrentMode) === NoMode + ) { + if (ReactCurrentActQueue.isBatchingLegacy); + else { + // 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(); + flushSyncWorkOnLegacyRootsOnly(); + } + } + } } + function isUnsafeClassRenderPhaseUpdate(fiber) { + // Check if this is a render phase update. Only called by class components, + // which special (deprecated) behavior for UNSAFE_componentWillReceive props. + return (executionContext & RenderContext) !== NoContext; + } // This is the entry point for every concurrent task, i.e. anything that + // goes through Scheduler. + function performConcurrentWorkOnRoot(root, didTimeout) { - nestedUpdateScheduled = currentUpdateIsNested = !1; - if ((executionContext & (RenderContext | CommitContext)) !== NoContext) - throw Error("Should not already be working."); + { + resetNestedUpdateFlag(); + } + + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) { + throw new Error("Should not already be working."); + } // Flush any pending passive effects before deciding which lanes to work on, + // in case they schedule additional work. + var originalCallbackNode = root.callbackNode; - if (flushPassiveEffects() && root.callbackNode !== originalCallbackNode) - return null; + var didFlushPassiveEffects = flushPassiveEffects(); + + if (didFlushPassiveEffects) { + // Something in the passive effect phase may have canceled the current task. + // Check if the task node for this root was changed. + if (root.callbackNode !== originalCallbackNode) { + // The current task was canceled. Exit. We don't need to call + // `ensureRootIsScheduled` because the check above implies either that + // there's a new task, or that there's no remaining work on this root. + return null; + } + } // Determine the next lanes to work on, using the fields stored + // on the root. + // TODO: This was already computed in the caller. Pass it as an argument. + var lanes = getNextLanes( root, - root === workInProgressRoot ? workInProgressRootRenderLanes : 0 + root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes ); - if (0 === lanes) return null; + + if (lanes === NoLanes) { + // Defensive coding. This is never expected to happen. + return null; + } // 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 shouldTimeSlice = - 0 === - (lanes & - (InputContinuousHydrationLane | - InputContinuousLane | - DefaultHydrationLane | - DefaultLane)) && - 0 === (lanes & root.expiredLanes) && + !includesBlockingLane(root, lanes) && + !includesExpiredLane(root, lanes) && !didTimeout; - didTimeout = shouldTimeSlice + var exitStatus = shouldTimeSlice ? renderRootConcurrent(root, lanes) : renderRootSync(root, lanes); - if (didTimeout !== RootInProgress) { + + if (exitStatus !== RootInProgress) { var renderWasConcurrent = shouldTimeSlice; + do { - if (didTimeout === RootDidNotComplete) - markRootSuspended(root, lanes, 0); - else { - shouldTimeSlice = root.current.alternate; + if (exitStatus === RootDidNotComplete) { + // The render unwound without completing the tree. This happens in special + // cases where need to exit the current render without producing a + // consistent tree or committing. + markRootSuspended(root, lanes, NoLane); + } else { + // The render completed. + // Check if this render may have yielded to a concurrent event, and if so, + // confirm that any newly rendered stores are consistent. + // TODO: It's possible that even a concurrent render may never have yielded + // to the main thread, if it was fast enough, or if it expired. We could + // skip the consistency check in that case, too. + var finishedWork = root.current.alternate; + if ( renderWasConcurrent && - !isRenderConsistentWithExternalStores(shouldTimeSlice) + !isRenderConsistentWithExternalStores(finishedWork) ) { - didTimeout = renderRootSync(root, lanes); - renderWasConcurrent = !1; + // A store was mutated in an interleaved event. Render again, + // synchronously, to block further mutations. + exitStatus = renderRootSync(root, lanes); // We assume the tree is now consistent because we didn't yield to any + // concurrent events. + + renderWasConcurrent = false; // Need to check the exit status again. + continue; - } - if (didTimeout === RootErrored) { - renderWasConcurrent = lanes; + } // Check if something threw + + if (exitStatus === RootErrored) { + var originallyAttemptedLanes = lanes; var errorRetryLanes = getLanesToRetrySynchronouslyOnError( root, - renderWasConcurrent + originallyAttemptedLanes ); - if ( - 0 !== errorRetryLanes && - ((lanes = errorRetryLanes), - (didTimeout = recoverFromConcurrentError( - root, - renderWasConcurrent, - errorRetryLanes - )), - (renderWasConcurrent = !1), - didTimeout !== RootErrored) - ) - continue; - } - if (didTimeout === RootFatalErrored) { - prepareFreshStack(root, 0); - markRootSuspended(root, lanes, 0); - break; - } - root.finishedWork = shouldTimeSlice; - root.finishedLanes = lanes; - a: { - renderWasConcurrent = root; - switch (didTimeout) { - case RootInProgress: - case RootFatalErrored: - throw Error("Root did not complete. This is a bug in React."); - case RootSuspendedWithDelay: - if ((lanes & TransitionLanes) === lanes) { - markRootSuspended( - renderWasConcurrent, - lanes, - workInProgressDeferredLane - ); - break a; - } - break; - case RootErrored: - workInProgressRootRecoverableErrors = null; - break; - case RootSuspended: - case RootCompleted: - break; - default: - throw Error("Unknown root exit status."); - } - if (null !== ReactSharedInternals.actQueue) - commitRoot( - renderWasConcurrent, - workInProgressRootRecoverableErrors, - workInProgressTransitions, - workInProgressRootDidIncludeRecursiveRenderUpdate, - workInProgressDeferredLane - ); - else { - if ( - (lanes & RetryLanes) === lanes && - didTimeout === RootSuspended && - ((didTimeout = - globalMostRecentFallbackTime + - FALLBACK_THROTTLE_MS - - now$1()), - 10 < didTimeout) - ) { - markRootSuspended( - renderWasConcurrent, - lanes, - workInProgressDeferredLane - ); - if (0 !== getNextLanes(renderWasConcurrent, 0)) break a; - renderWasConcurrent.timeoutHandle = scheduleTimeout( - commitRootWhenReady.bind( - null, - renderWasConcurrent, - shouldTimeSlice, - workInProgressRootRecoverableErrors, - workInProgressTransitions, - workInProgressRootDidIncludeRecursiveRenderUpdate, - lanes, - workInProgressDeferredLane - ), - didTimeout - ); - break a; - } - commitRootWhenReady( - renderWasConcurrent, - shouldTimeSlice, - workInProgressRootRecoverableErrors, - workInProgressTransitions, - workInProgressRootDidIncludeRecursiveRenderUpdate, - lanes, - workInProgressDeferredLane + + if (errorRetryLanes !== NoLanes) { + lanes = errorRetryLanes; + exitStatus = recoverFromConcurrentError( + root, + originallyAttemptedLanes, + errorRetryLanes ); + renderWasConcurrent = false; } } + + if (exitStatus === RootFatalErrored) { + var fatalError = workInProgressRootFatalError; + prepareFreshStack(root, NoLanes); + markRootSuspended(root, lanes, NoLane); + ensureRootIsScheduled(root); + throw fatalError; + } // We now have a consistent tree. The next step is either to commit it, + // or, if something suspended, wait to commit it after a timeout. + + root.finishedWork = finishedWork; + root.finishedLanes = lanes; + finishConcurrentRender(root, exitStatus, finishedWork, lanes); } + break; - } while (1); + } while (true); } + ensureRootIsScheduled(root); - scheduleTaskForRootDuringMicrotask(root, now$1()); - root = - root.callbackNode === originalCallbackNode - ? performConcurrentWorkOnRoot.bind(null, root) - : null; - return root; + return getContinuationForRoot(root, originalCallbackNode); } + function recoverFromConcurrentError( root, originallyAttemptedLanes, errorRetryLanes ) { + // If an error occurred during hydration, discard server response and fall + // back to client side render. + // Before rendering again, save the errors from the previous attempt. var errorsFromFirstAttempt = workInProgressRootConcurrentErrors; - errorRetryLanes = renderRootSync(root, errorRetryLanes); - if (errorRetryLanes !== RootErrored) { - if (workInProgressRootDidAttachPingListener) - return ( - (root.errorRecoveryDisabledLanes |= originallyAttemptedLanes), - (workInProgressRootInterleavedUpdatedLanes |= - originallyAttemptedLanes), - RootSuspendedWithDelay - ); - root = workInProgressRootRecoverableErrors; - workInProgressRootRecoverableErrors = errorsFromFirstAttempt; - null !== root && queueRecoverableErrors(root); + var wasRootDehydrated = isRootDehydrated(root); + + if (wasRootDehydrated) { + // The shell failed to hydrate. Set a flag to force a client rendering + // during the next attempt. To do this, we call prepareFreshStack now + // to create the root work-in-progress fiber. This is a bit weird in terms + // of factoring, because it relies on renderRootSync not calling + // prepareFreshStack again in the call below, which happens because the + // root and lanes haven't changed. + // + // TODO: I think what we should do is set ForceClientRender inside + // throwException, like we do for nested Suspense boundaries. The reason + // it's here instead is so we can switch to the synchronous work loop, too. + // Something to consider for a future refactor. + var rootWorkInProgress = prepareFreshStack(root, errorRetryLanes); + rootWorkInProgress.flags |= ForceClientRender; + + { + errorHydratingContainer(); + } } - return errorRetryLanes; + + var exitStatus = renderRootSync(root, errorRetryLanes); + + if (exitStatus !== RootErrored) { + // Successfully finished rendering on retry + if (workInProgressRootDidAttachPingListener && !wasRootDehydrated) { + // During the synchronous render, we attached additional ping listeners. + // This is highly suggestive of an uncached promise (though it's not the + // only reason this would happen). If it was an uncached promise, then + // it may have masked a downstream error from ocurring without actually + // fixing it. Example: + // + // use(Promise.resolve('uncached')) + // throw new Error('Oops!') + // + // When this happens, there's a conflict between blocking potential + // concurrent data races and unwrapping uncached promise values. We + // have to choose one or the other. Because the data race recovery is + // a last ditch effort, we'll disable it. + root.errorRecoveryDisabledLanes = mergeLanes( + root.errorRecoveryDisabledLanes, + originallyAttemptedLanes + ); // Mark the current render as suspended and force it to restart. Once + // these lanes finish successfully, we'll re-enable the error recovery + // mechanism for subsequent updates. + + workInProgressRootInterleavedUpdatedLanes |= originallyAttemptedLanes; + return RootSuspendedWithDelay; + } // The errors from the failed first attempt have been recovered. Add + // them to the collection of recoverable errors. We'll log them in the + // commit phase. + + var errorsFromSecondAttempt = workInProgressRootRecoverableErrors; + workInProgressRootRecoverableErrors = errorsFromFirstAttempt; // The errors from the second attempt should be queued after the errors + // from the first attempt, to preserve the causal sequence. + + if (errorsFromSecondAttempt !== null) { + queueRecoverableErrors(errorsFromSecondAttempt); + } + } + + return exitStatus; } + function queueRecoverableErrors(errors) { - null === workInProgressRootRecoverableErrors - ? (workInProgressRootRecoverableErrors = errors) - : workInProgressRootRecoverableErrors.push.apply( - workInProgressRootRecoverableErrors, - errors - ); + if (workInProgressRootRecoverableErrors === null) { + workInProgressRootRecoverableErrors = errors; + } else { + // $FlowFixMe[method-unbinding] + workInProgressRootRecoverableErrors.push.apply( + workInProgressRootRecoverableErrors, + errors + ); + } + } + + function finishConcurrentRender(root, exitStatus, finishedWork, lanes) { + // TODO: The fact that most of these branches are identical suggests that some + // of the exit statuses are not best modeled as exit statuses and should be + // tracked orthogonally. + switch (exitStatus) { + case RootInProgress: + case RootFatalErrored: { + throw new Error("Root did not complete. This is a bug in React."); + } + + case RootSuspendedWithDelay: { + if (includesOnlyTransitions(lanes)) { + // This is a transition, so we should exit without committing a + // placeholder and without scheduling a timeout. Delay indefinitely + // until we receive more data. + markRootSuspended(root, lanes, workInProgressDeferredLane); + return; + } // Commit the placeholder. + + break; + } + + case RootErrored: + case RootSuspended: + case RootCompleted: { + break; + } + + default: { + throw new Error("Unknown root exit status."); + } + } + + if (shouldForceFlushFallbacksInDEV()) { + // We're inside an `act` scope. Commit immediately. + commitRoot( + root, + workInProgressRootRecoverableErrors, + workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, + workInProgressDeferredLane + ); + } else { + if (includesOnlyRetries(lanes) && exitStatus === RootSuspended) { + // This render only included retries, no updates. Throttle committing + // retries so that we don't show too many loading states too quickly. + var msUntilTimeout = + globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now$1(); // Don't bother with a very short suspense time. + + if (msUntilTimeout > 10) { + markRootSuspended(root, lanes, workInProgressDeferredLane); + var nextLanes = getNextLanes(root, NoLanes); + + if (nextLanes !== NoLanes) { + // There's additional work we can do on this root. We might as well + // attempt to work on that while we're suspended. + return; + } // The render is suspended, it hasn't timed out, and there's no + // lower priority work to do. Instead of committing the fallback + // immediately, wait for more data to arrive. + // TODO: Combine retry throttling with Suspensey commits. Right now they + // run one after the other. + + root.timeoutHandle = scheduleTimeout( + commitRootWhenReady.bind( + null, + root, + finishedWork, + workInProgressRootRecoverableErrors, + workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, + lanes, + workInProgressDeferredLane + ), + msUntilTimeout + ); + return; + } + } + + commitRootWhenReady( + root, + finishedWork, + workInProgressRootRecoverableErrors, + workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, + lanes, + workInProgressDeferredLane + ); + } } + function commitRootWhenReady( root, finishedWork, @@ -11593,9 +22776,40 @@ __DEV__ && lanes, spawnedLane ) { - lanes = finishedWork.subtreeFlags; - (lanes & 8192 || 16785408 === (lanes & 16785408)) && - accumulateSuspenseyCommitOnFiber(finishedWork); + // TODO: Combine retry throttling with Suspensey commits. Right now they run + // one after the other. + if (includesOnlyNonUrgentLanes(lanes)) { + // the suspensey resources. The renderer is responsible for accumulating + // all the load events. This all happens in a single synchronous + // transaction, so it track state in its own module scope. + + accumulateSuspenseyCommit(finishedWork); // At the end, ask the renderer if it's ready to commit, or if we should + // suspend. If it's not ready, it will return a callback to subscribe to + // a ready event. + + var schedulePendingCommit = waitForCommitToBeReady(); + + if (schedulePendingCommit !== null) { + // NOTE: waitForCommitToBeReady returns a subscribe function so that we + // only allocate a function if the commit isn't ready yet. The other + // pattern would be to always pass a callback to waitForCommitToBeReady. + // Not yet ready to commit. Delay the commit until the renderer notifies + // us that it's ready. This will be canceled if we start work on the + // root again. + root.cancelPendingCommit = schedulePendingCommit( + commitRoot.bind( + null, + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate + ) + ); + markRootSuspended(root, lanes, spawnedLane); + return; + } + } // Otherwise, commit immediately. + commitRoot( root, recoverableErrors, @@ -11604,103 +22818,162 @@ __DEV__ && spawnedLane ); } + function isRenderConsistentWithExternalStores(finishedWork) { - for (var node = finishedWork; ; ) { - if (node.flags & 16384) { + // Search the rendered tree for external store reads, and check whether the + // stores were mutated in a concurrent event. Intentionally using an iterative + // loop instead of recursion so we can exit early. + var node = finishedWork; + + while (true) { + if (node.flags & StoreConsistency) { var updateQueue = node.updateQueue; - if ( - null !== updateQueue && - ((updateQueue = updateQueue.stores), null !== updateQueue) - ) - for (var i = 0; i < updateQueue.length; i++) { - var check = updateQueue[i], - getSnapshot = check.getSnapshot; - check = check.value; - try { - if (!objectIs(getSnapshot(), check)) return !1; - } catch (error$41) { - return !1; + + if (updateQueue !== null) { + var checks = updateQueue.stores; + + if (checks !== null) { + for (var i = 0; i < checks.length; i++) { + var check = checks[i]; + var getSnapshot = check.getSnapshot; + var renderedValue = check.value; + + try { + if (!objectIs(getSnapshot(), renderedValue)) { + // Found an inconsistent store. + return false; + } + } catch (error) { + // If `getSnapshot` throws, return `false`. This will schedule + // a re-render, and the error will be rethrown during render. + return false; + } } } + } } - updateQueue = node.child; - if (node.subtreeFlags & 16384 && null !== updateQueue) - (updateQueue.return = node), (node = updateQueue); - else { - if (node === finishedWork) break; - for (; null === node.sibling; ) { - if (null === node.return || node.return === finishedWork) return !0; - node = node.return; + + var child = node.child; + + if (node.subtreeFlags & StoreConsistency && child !== null) { + child.return = node; + node = child; + continue; + } + + if (node === finishedWork) { + return true; + } + + while (node.sibling === null) { + if (node.return === null || node.return === finishedWork) { + return true; } - node.sibling.return = node.return; - node = node.sibling; + + node = node.return; } - } - return !0; - } + + node.sibling.return = node.return; + node = node.sibling; + } // Flow doesn't know this is unreachable, but eslint does + // eslint-disable-next-line no-unreachable + + return true; + } // The extra indirections around markRootUpdated and markRootSuspended is + // needed to avoid a circular dependency between this module and + // ReactFiberLane. There's probably a better way to split up these modules and + // avoid this problem. Perhaps all the root-marking functions should move into + // the work loop. + function markRootUpdated(root, updatedLanes) { - root.pendingLanes |= updatedLanes; - updatedLanes !== IdleLane && - ((root.suspendedLanes = 0), (root.pingedLanes = 0)); - executionContext & RenderContext - ? (workInProgressRootDidIncludeRecursiveRenderUpdate = !0) - : executionContext & CommitContext && - (didIncludeCommitPhaseUpdate = !0); - throwIfInfiniteUpdateLoopDetected(); + markRootUpdated$1(root, updatedLanes); } - function markRootSuspended(root, suspendedLanes, spawnedLane) { - suspendedLanes &= ~workInProgressRootPingedLanes; - suspendedLanes &= ~workInProgressRootInterleavedUpdatedLanes; - root.suspendedLanes |= suspendedLanes; - root.pingedLanes &= ~suspendedLanes; - for ( - var expirationTimes = root.expirationTimes, lanes = suspendedLanes; - 0 < lanes; - ) { - var index = 31 - clz32(lanes), - lane = 1 << index; - expirationTimes[index] = -1; - lanes &= ~lane; - } - 0 !== spawnedLane && - markSpawnedDeferredLane(root, spawnedLane, suspendedLanes); + function markRootPinged(root, pingedLanes) { + markRootPinged$1(root, pingedLanes); } + + function markRootSuspended(root, suspendedLanes, spawnedLane) { + // When suspending, we should always exclude lanes that were pinged or (more + // rarely, since we try to avoid it) updated during the render phase. + suspendedLanes = removeLanes( + suspendedLanes, + workInProgressRootPingedLanes + ); + suspendedLanes = removeLanes( + suspendedLanes, + workInProgressRootInterleavedUpdatedLanes + ); + + markRootSuspended$1(root, suspendedLanes, spawnedLane); + } // This is the entry point for synchronous tasks that don't go + // through Scheduler + function performSyncWorkOnRoot(root, lanes) { - if ((executionContext & (RenderContext | CommitContext)) !== NoContext) - throw Error("Should not already be working."); - if (flushPassiveEffects()) return ensureRootIsScheduled(root), null; - currentUpdateIsNested = nestedUpdateScheduled; - nestedUpdateScheduled = !1; + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) { + throw new Error("Should not already be working."); + } + + var didFlushPassiveEffects = flushPassiveEffects(); + + if (didFlushPassiveEffects) { + // If passive effects were flushed, exit to the outer work loop in the root + // scheduler, so we can recompute the priority. + // TODO: We don't actually need this `ensureRootIsScheduled` call because + // this path is only reachable if the root is already part of the schedule. + // I'm including it only for consistency with the other exit points from + // this function. Can address in a subsequent refactor. + ensureRootIsScheduled(root); + return null; + } + + { + syncNestedUpdateFlag(); + } + var exitStatus = renderRootSync(root, lanes); - if (0 !== root.tag && exitStatus === RootErrored) { - var originallyAttemptedLanes = lanes, - errorRetryLanes = getLanesToRetrySynchronouslyOnError( - root, - originallyAttemptedLanes - ); - 0 !== errorRetryLanes && - ((lanes = errorRetryLanes), - (exitStatus = recoverFromConcurrentError( + + if (root.tag !== LegacyRoot && exitStatus === RootErrored) { + // 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. + var originallyAttemptedLanes = lanes; + var errorRetryLanes = getLanesToRetrySynchronouslyOnError( + root, + originallyAttemptedLanes + ); + + if (errorRetryLanes !== NoLanes) { + lanes = errorRetryLanes; + exitStatus = recoverFromConcurrentError( root, originallyAttemptedLanes, errorRetryLanes - ))); + ); + } } - if (exitStatus === RootFatalErrored) - return ( - prepareFreshStack(root, 0), - markRootSuspended(root, lanes, 0), - ensureRootIsScheduled(root), - null - ); - if (exitStatus === RootDidNotComplete) - return ( - markRootSuspended(root, lanes, workInProgressDeferredLane), - ensureRootIsScheduled(root), - null - ); - root.finishedWork = root.current.alternate; + + if (exitStatus === RootFatalErrored) { + var fatalError = workInProgressRootFatalError; + prepareFreshStack(root, NoLanes); + markRootSuspended(root, lanes, NoLane); + ensureRootIsScheduled(root); + throw fatalError; + } + + if (exitStatus === RootDidNotComplete) { + // The render unwound without completing the tree. This happens in special + // cases where need to exit the current render without producing a + // consistent tree or committing. + markRootSuspended(root, lanes, workInProgressDeferredLane); + ensureRootIsScheduled(root); + return null; + } // We now have a consistent tree. Because this is a sync render, we + // will commit it even if something suspended. + + var finishedWork = root.current.alternate; + root.finishedWork = finishedWork; root.finishedLanes = lanes; commitRoot( root, @@ -11708,554 +22981,1105 @@ __DEV__ && workInProgressTransitions, workInProgressRootDidIncludeRecursiveRenderUpdate, workInProgressDeferredLane - ); + ); // Before exiting, make sure there's a callback scheduled for the next + // pending level. + ensureRootIsScheduled(root); return null; } - function flushSyncWork() { - return (executionContext & (RenderContext | CommitContext)) === NoContext - ? (flushSyncWorkAcrossRoots_impl(!1), !1) - : !0; + function getExecutionContext() { + return executionContext; + } + function batchedUpdates(fn, a) { + var prevExecutionContext = executionContext; + executionContext |= BatchedContext; + + try { + return fn(a); + } finally { + executionContext = prevExecutionContext; // If there were legacy sync updates, flush them at the end of the outer + // most batchedUpdates-like method. + + if ( + executionContext === NoContext && // Treat `act` as if it's inside `batchedUpdates`, even in legacy mode. + !ReactCurrentActQueue.isBatchingLegacy + ) { + resetRenderTimer(); + flushSyncWorkOnLegacyRootsOnly(); + } + } + } + // Warning, this opts-out of checking the function body. + // eslint-disable-next-line no-unused-vars + // eslint-disable-next-line no-redeclare + // eslint-disable-next-line no-redeclare + + function flushSync(fn) { + // In legacy mode, we flush pending passive effects at the beginning of the + // next event, not at the end of the previous one. + if ( + rootWithPendingPassiveEffects !== null && + rootWithPendingPassiveEffects.tag === LegacyRoot && + (executionContext & (RenderContext | CommitContext)) === NoContext + ) { + flushPassiveEffects(); + } + + var prevExecutionContext = executionContext; + executionContext |= BatchedContext; + var prevTransition = ReactCurrentBatchConfig.transition; + var previousPriority = getCurrentUpdatePriority(); + + try { + ReactCurrentBatchConfig.transition = null; + setCurrentUpdatePriority(DiscreteEventPriority); + + if (fn) { + return fn(); + } else { + return undefined; + } + } finally { + setCurrentUpdatePriority(previousPriority); + ReactCurrentBatchConfig.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 + ) { + flushSyncWorkOnAllRoots(); + } + } + } + // hidden subtree. The stack logic is managed there because that's the only + // place that ever modifies it. Which module it lives in doesn't matter for + // performance because this function will get inlined regardless + + function setEntangledRenderLanes(newEntangledRenderLanes) { + entangledRenderLanes = newEntangledRenderLanes; + } + function getEntangledRenderLanes() { + return entangledRenderLanes; } + function resetWorkInProgressStack() { - if (null !== workInProgress) { - if (workInProgressSuspendedReason === NotSuspended) - var interruptedWork = workInProgress.return; - else - (interruptedWork = workInProgress), - resetContextDependencies(), - resetHooksOnUnwind(interruptedWork), - (thenableState$1 = null), - (thenableIndexCounter$1 = 0), - (interruptedWork = workInProgress); - for (; null !== interruptedWork; ) - unwindInterruptedWork(interruptedWork.alternate, interruptedWork), - (interruptedWork = interruptedWork.return); - workInProgress = null; + if (workInProgress === null) return; + var interruptedWork; + + if (workInProgressSuspendedReason === NotSuspended) { + // Normal case. Work-in-progress hasn't started yet. Unwind all + // its parents. + interruptedWork = workInProgress.return; + } else { + // Work-in-progress is in suspended state. Reset the work loop and unwind + // both the suspended fiber and all its parents. + resetSuspendedWorkLoopOnUnwind(workInProgress); + interruptedWork = workInProgress; } + + while (interruptedWork !== null) { + var current = interruptedWork.alternate; + unwindInterruptedWork(current, interruptedWork); + interruptedWork = interruptedWork.return; + } + + workInProgress = null; } + function prepareFreshStack(root, lanes) { root.finishedWork = null; - root.finishedLanes = 0; + root.finishedLanes = NoLanes; var timeoutHandle = root.timeoutHandle; - -1 !== timeoutHandle && - ((root.timeoutHandle = -1), cancelTimeout(timeoutHandle)); - timeoutHandle = root.cancelPendingCommit; - null !== timeoutHandle && - ((root.cancelPendingCommit = null), timeoutHandle()); + + if (timeoutHandle !== noTimeout) { + // The root previous suspended and scheduled a timeout to commit a fallback + // state. Now that we have additional work, cancel the timeout. + root.timeoutHandle = noTimeout; // $FlowFixMe[incompatible-call] Complains noTimeout is not a TimeoutID, despite the check above + + cancelTimeout(timeoutHandle); + } + + var cancelPendingCommit = root.cancelPendingCommit; + + if (cancelPendingCommit !== null) { + root.cancelPendingCommit = null; + cancelPendingCommit(); + } + resetWorkInProgressStack(); workInProgressRoot = root; - workInProgress = timeoutHandle = createWorkInProgress(root.current, null); + var rootWorkInProgress = createWorkInProgress(root.current, null); + workInProgress = rootWorkInProgress; workInProgressRootRenderLanes = lanes; workInProgressSuspendedReason = NotSuspended; workInProgressThrownValue = null; - workInProgressRootDidAttachPingListener = !1; + workInProgressRootDidAttachPingListener = false; workInProgressRootExitStatus = RootInProgress; - workInProgressDeferredLane = - workInProgressRootPingedLanes = - workInProgressRootInterleavedUpdatedLanes = - workInProgressRootSkippedLanes = - 0; - workInProgressRootRecoverableErrors = workInProgressRootConcurrentErrors = - null; - workInProgressRootDidIncludeRecursiveRenderUpdate = !1; - 0 !== (lanes & InputContinuousLane) && (lanes |= lanes & DefaultLane); - var allEntangledLanes = root.entangledLanes; - if (0 !== allEntangledLanes) - for ( - root = root.entanglements, allEntangledLanes &= lanes; - 0 < allEntangledLanes; + workInProgressRootFatalError = null; + workInProgressRootSkippedLanes = NoLanes; + workInProgressRootInterleavedUpdatedLanes = NoLanes; + workInProgressRootPingedLanes = NoLanes; + workInProgressDeferredLane = NoLane; + workInProgressRootConcurrentErrors = null; + workInProgressRootRecoverableErrors = null; + workInProgressRootDidIncludeRecursiveRenderUpdate = false; // Get the lanes that are entangled with whatever we're about to render. We + // track these separately so we can distinguish the priority of the render + // task from the priority of the lanes it is entangled with. For example, a + // transition may not be allowed to finish unless it includes the Sync lane, + // which is currently suspended. We should be able to render the Transition + // and Sync lane in the same batch, but at Transition priority, because the + // Sync lane already suspended. - ) { - var index = 31 - clz32(allEntangledLanes), - lane = 1 << index; - lanes |= root[index]; - allEntangledLanes &= ~lane; - } - entangledRenderLanes = lanes; + entangledRenderLanes = getEntangledLanes(root, lanes); finishQueueingConcurrentUpdates(); - ReactStrictModeWarnings.discardPendingWarnings(); - return timeoutHandle; + + { + ReactStrictModeWarnings.discardPendingWarnings(); + } + + return rootWorkInProgress; + } + + function resetSuspendedWorkLoopOnUnwind(fiber) { + // Reset module-level state that was set during the render phase. + resetContextDependencies(); + resetHooksOnUnwind(fiber); + resetChildReconcilerOnUnwind(); } + function handleThrow(root, thrownValue) { - currentlyRenderingFiber$1 = null; - ReactSharedInternals.H = ContextOnlyDispatcher; - ReactSharedInternals.getCurrentStack = null; - isRendering = !1; - current = null; + // A component threw an exception. Usually this is because it suspended, but + // it also includes regular program errors. + // + // We're either going to unwind the stack to show a Suspense or error + // boundary, or we're going to replay the component again. Like after a + // promise resolves. + // + // Until we decide whether we're going to unwind or replay, we should preserve + // the current state of the work loop without resetting anything. + // + // If we do decide to unwind the stack, module-level variables will be reset + // in resetSuspendedWorkLoopOnUnwind. + // These should be reset immediately because they're only supposed to be set + // when React is executing user code. + resetHooksAfterThrow(); + resetCurrentFiber(); + ReactCurrentOwner$1.current = null; + if (thrownValue === SuspenseException) { + // This is a special type of exception used for Suspense. For historical + // reasons, the rest of the Suspense implementation expects the thrown value + // to be a thenable, because before `use` existed that was the (unstable) + // API for suspending. This implementation detail can change later, once we + // deprecate the old API in favor of `use`. thrownValue = getSuspendedThenable(); - var handler = suspenseHandlerStackCursor.current; workInProgressSuspendedReason = - (null !== handler && - ((workInProgressRootRenderLanes & TransitionLanes) === - workInProgressRootRenderLanes - ? null !== shellBoundary - : ((workInProgressRootRenderLanes & RetryLanes) !== - workInProgressRootRenderLanes && - 0 === (workInProgressRootRenderLanes & OffscreenLane)) || - handler !== shellBoundary)) || - 0 !== (workInProgressRootSkippedLanes & 134217727) || - 0 !== (workInProgressRootInterleavedUpdatedLanes & 134217727) - ? SuspendedOnImmediate - : SuspendedOnData; - } else - thrownValue === SuspenseyCommitException - ? ((thrownValue = getSuspendedThenable()), - (workInProgressSuspendedReason = SuspendedOnInstance)) - : (workInProgressSuspendedReason = - thrownValue === SelectiveHydrationException - ? SuspendedOnHydration - : null !== thrownValue && - "object" === typeof thrownValue && - "function" === typeof thrownValue.then - ? SuspendedOnDeprecatedThrowPromise - : SuspendedOnError); + shouldRemainOnPreviousScreen() && // Check if there are other pending updates that might possibly unblock this + // component from suspending. This mirrors the check in + // renderDidSuspendDelayIfPossible. We should attempt to unify them somehow. + // TODO: Consider unwinding immediately, using the + // SuspendedOnHydration mechanism. + !includesNonIdleWork(workInProgressRootSkippedLanes) && + !includesNonIdleWork(workInProgressRootInterleavedUpdatedLanes) // Suspend work loop until data resolves + ? SuspendedOnData // Don't suspend work loop, except to check if the data has + : // immediately resolved (i.e. in a microtask). Otherwise, trigger the + // nearest Suspense fallback. + SuspendedOnImmediate; + } else if (thrownValue === SuspenseyCommitException) { + thrownValue = getSuspendedThenable(); + workInProgressSuspendedReason = SuspendedOnInstance; + } else if (thrownValue === SelectiveHydrationException) { + // An update flowed into a dehydrated boundary. Before we can apply the + // update, we need to finish hydrating. Interrupt the work-in-progress + // render so we can restart at the hydration lane. + // + // The ideal implementation would be able to switch contexts without + // unwinding the current stack. + // + // We could name this something more general but as of now it's the only + // case where we think this should happen. + workInProgressSuspendedReason = SuspendedOnHydration; + } else { + // This is a regular error. + var isWakeable = + thrownValue !== null && + typeof thrownValue === "object" && + typeof thrownValue.then === "function"; + workInProgressSuspendedReason = isWakeable // A wakeable object was thrown by a legacy Suspense implementation. + ? // This has slightly different behavior than suspending with `use`. + SuspendedOnDeprecatedThrowPromise // This is a regular error. If something earlier in the component already + : // suspended, we must clear the thenable state to unblock the work loop. + SuspendedOnError; + } + workInProgressThrownValue = thrownValue; - handler = workInProgress; - if (null === handler) - (workInProgressRootExitStatus = RootFatalErrored), - logUncaughtError( - root, - createCapturedValueAtFiber(thrownValue, root.current) - ); - else - switch ( - (handler.mode & 2 && - stopProfilerTimerIfRunningAndRecordDelta(handler, !0), - markComponentRenderStopped(), - workInProgressSuspendedReason) - ) { - case SuspendedOnError: - null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markComponentErrored && - injectedProfilingHooks.markComponentErrored( - handler, - thrownValue, - workInProgressRootRenderLanes - ); - break; - case SuspendedOnData: - case SuspendedOnImmediate: - case SuspendedOnDeprecatedThrowPromise: - case SuspendedAndReadyToContinue: - null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markComponentSuspended && - injectedProfilingHooks.markComponentSuspended( - handler, - thrownValue, - workInProgressRootRenderLanes - ); + var erroredWork = workInProgress; + + if (erroredWork === null) { + // This is a fatal error + workInProgressRootExitStatus = RootFatalErrored; + workInProgressRootFatalError = thrownValue; + return; + } + + if (erroredWork.mode & ProfileMode) { + // Record the time spent rendering before an error was thrown. This + // avoids inaccurate Profiler durations in the case of a + // suspended render. + stopProfilerTimerIfRunningAndRecordDelta(erroredWork, true); + } + } + + function shouldRemainOnPreviousScreen() { + // This is asking whether it's better to suspend the transition and remain + // on the previous screen, versus showing a fallback as soon as possible. It + // takes into account both the priority of render and also whether showing a + // fallback would produce a desirable user experience. + var handler = getSuspenseHandler(); + + if (handler === null) { + // There's no Suspense boundary that can provide a fallback. We have no + // choice but to remain on the previous screen. + // NOTE: We do this even for sync updates, for lack of any better option. In + // the future, we may change how we handle this, like by putting the whole + // root into a "detached" mode. + return true; + } // TODO: Once `use` has fully replaced the `throw promise` pattern, we should + // be able to remove the equivalent check in finishConcurrentRender, and rely + // just on this one. + + if (includesOnlyTransitions(workInProgressRootRenderLanes)) { + if (getShellBoundary() === null) { + // We're rendering inside the "shell" of the app. Activating the nearest + // fallback would cause visible content to disappear. It's better to + // suspend the transition and remain on the previous screen. + return true; + } else { + // We're rendering content that wasn't part of the previous screen. + // Rather than block the transition, it's better to show a fallback as + // soon as possible. The appearance of any nested fallbacks will be + // throttled to avoid jank. + return false; } + } + + if ( + includesOnlyRetries(workInProgressRootRenderLanes) || // In this context, an OffscreenLane counts as a Retry + // TODO: It's become increasingly clear that Retries and Offscreen are + // deeply connected. They probably can be unified further. + includesSomeLane(workInProgressRootRenderLanes, OffscreenLane) + ) { + // During a retry, we can suspend rendering if the nearest Suspense boundary + // is the boundary of the "shell", because we're guaranteed not to block + // any new content from appearing. + // + // The reason we must check if this is a retry is because it guarantees + // that suspending the work loop won't block an actual update, because + // retries don't "update" anything; they fill in fallbacks that were left + // behind by a previous transition. + return handler === getShellBoundary(); + } // For all other Lanes besides Transitions and Retries, we should not wait + // for the data to load. + + return false; + } + + function pushDispatcher(container) { + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = ContextOnlyDispatcher; + + if (prevDispatcher === null) { + // The React isomorphic package does not include a default dispatcher. + // Instead the first renderer will lazily attach one, in order to give + // nicer error messages. + return ContextOnlyDispatcher; + } else { + return prevDispatcher; + } + } + + function popDispatcher(prevDispatcher) { + ReactCurrentDispatcher.current = prevDispatcher; + } + + function markCommitTimeOfFallback() { + globalMostRecentFallbackTime = now$1(); } - function pushDispatcher() { - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = ContextOnlyDispatcher; - return null === prevDispatcher ? ContextOnlyDispatcher : prevDispatcher; + function markSkippedUpdateLanes(lane) { + workInProgressRootSkippedLanes = mergeLanes( + lane, + workInProgressRootSkippedLanes + ); } - function pushAsyncDispatcher() { - var prevAsyncDispatcher = ReactSharedInternals.A; - ReactSharedInternals.A = DefaultAsyncDispatcher; - return prevAsyncDispatcher; + function renderDidSuspend() { + if (workInProgressRootExitStatus === RootInProgress) { + workInProgressRootExitStatus = RootSuspended; + } } function renderDidSuspendDelayIfPossible() { - workInProgressRootExitStatus = RootSuspendedWithDelay; - (0 === (workInProgressRootSkippedLanes & 134217727) && - 0 === (workInProgressRootInterleavedUpdatedLanes & 134217727)) || - null === workInProgressRoot || + workInProgressRootExitStatus = RootSuspendedWithDelay; // Check if there are updates that we skipped tree that might have unblocked + // this render. + + if ( + (includesNonIdleWork(workInProgressRootSkippedLanes) || + includesNonIdleWork(workInProgressRootInterleavedUpdatedLanes)) && + workInProgressRoot !== null + ) { + // Mark the current render as suspended so that we switch to working on + // the updates that were skipped. Usually we only suspend at the end of + // the render phase. + // TODO: We should probably always mark the root as suspended immediately + // (inside this function), since by suspending at the end of the render + // phase introduces a potential mistake where we suspend lanes that were + // pinged or updated while we were rendering. + // TODO: Consider unwinding immediately, using the + // SuspendedOnHydration mechanism. markRootSuspended( workInProgressRoot, workInProgressRootRenderLanes, workInProgressDeferredLane ); + } } + function renderDidError(error) { + if (workInProgressRootExitStatus !== RootSuspendedWithDelay) { + workInProgressRootExitStatus = RootErrored; + } + + if (workInProgressRootConcurrentErrors === null) { + workInProgressRootConcurrentErrors = [error]; + } else { + workInProgressRootConcurrentErrors.push(error); + } + } // Called during render to determine if anything has suspended. + // Returns false if we're not sure. + + function renderHasNotSuspendedYet() { + // If something errored or completed, we can't really be sure, + // so those are false. + return workInProgressRootExitStatus === RootInProgress; + } // TODO: Over time, this function and renderRootConcurrent have become more + // and more similar. Not sure it makes sense to maintain forked paths. Consider + // unifying them again. + function renderRootSync(root, lanes) { var prevExecutionContext = executionContext; executionContext |= RenderContext; - var prevDispatcher = pushDispatcher(), - prevAsyncDispatcher = pushAsyncDispatcher(); + var prevDispatcher = pushDispatcher(); + // and prepare a fresh one. Otherwise we'll continue where we left off. + if ( workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes ) { - if (isDevToolsPresent) { - var memoizedUpdaters = root.memoizedUpdaters; - 0 < memoizedUpdaters.size && - (restorePendingUpdaters(root, workInProgressRootRenderLanes), - memoizedUpdaters.clear()); - movePendingFibersToMemoized(root, lanes); + { + if (isDevToolsPresent) { + var memoizedUpdaters = root.memoizedUpdaters; + + if (memoizedUpdaters.size > 0) { + restorePendingUpdaters(root, workInProgressRootRenderLanes); + memoizedUpdaters.clear(); + } // At this point, move Fibers that scheduled the upcoming work from the Map to the Set. + // If we bailout on this work, we'll move them back (like above). + // It's important to move them now in case the work spawns more work at the same priority with different updaters. + // That way we can keep the current update and future updates separate. + + movePendingFibersToMemoized(root, lanes); + } } - workInProgressTransitions = null; + + workInProgressTransitions = getTransitionsForLanes(); prepareFreshStack(root, lanes); } - markRenderStarted(lanes); - lanes = !1; - a: do + + var didSuspendInShell = false; + + outer: do { try { if ( workInProgressSuspendedReason !== NotSuspended && - null !== workInProgress + workInProgress !== null ) { - memoizedUpdaters = workInProgress; + // The work loop is suspended. During a synchronous render, we don't + // yield to the main thread. Immediately unwind the stack. This will + // trigger either a fallback or an error boundary. + // TODO: For discrete and "default" updates (anything that's not + // flushSync), we want to wait for the microtasks the flush before + // unwinding. Will probably implement this using renderRootConcurrent, + // or merge renderRootSync and renderRootConcurrent into the same + // function and fork the behavior some other way. + var unitOfWork = workInProgress; var thrownValue = workInProgressThrownValue; + switch (workInProgressSuspendedReason) { - case SuspendedOnHydration: + case SuspendedOnHydration: { + // Selective hydration. An update flowed into a dehydrated tree. + // Interrupt the current render so the work loop can switch to the + // hydration lane. resetWorkInProgressStack(); workInProgressRootExitStatus = RootDidNotComplete; - break a; + break outer; + } + case SuspendedOnImmediate: - case SuspendedOnData: - lanes || - null !== suspenseHandlerStackCursor.current || - (lanes = !0); - default: - (workInProgressSuspendedReason = NotSuspended), - (workInProgressThrownValue = null), - throwAndUnwindWorkLoop(root, memoizedUpdaters, thrownValue); + case SuspendedOnData: { + if (!didSuspendInShell && getSuspenseHandler() === null) { + didSuspendInShell = true; + } // Intentional fallthrough + } + + default: { + // Unwind then continue with the normal work loop. + workInProgressSuspendedReason = NotSuspended; + workInProgressThrownValue = null; + throwAndUnwindWorkLoop(root, unitOfWork, thrownValue); + break; + } } } + workLoopSync(); break; - } catch (thrownValue$42) { - handleThrow(root, thrownValue$42); + } catch (thrownValue) { + handleThrow(root, thrownValue); } - while (1); - lanes && root.shellSuspendCounter++; + } while (true); // Check if something suspended in the shell. We use this to detect an + // infinite ping loop caused by an uncached promise. + // + // Only increment this counter once per synchronous render attempt across the + // whole tree. Even if there are many sibling components that suspend, this + // counter only gets incremented once. + + if (didSuspendInShell) { + root.shellSuspendCounter++; + } + resetContextDependencies(); executionContext = prevExecutionContext; - ReactSharedInternals.H = prevDispatcher; - ReactSharedInternals.A = prevAsyncDispatcher; - if (null !== workInProgress) - throw Error( - "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." + popDispatcher(prevDispatcher); + + if (workInProgress !== null) { + // This is a sync render, so we should have finished the whole tree. + throw new Error( + "Cannot commit an incomplete root. This error is likely caused by a " + + "bug in React. Please file an issue." ); - markRenderStopped(); + } + workInProgressRoot = null; - workInProgressRootRenderLanes = 0; + workInProgressRootRenderLanes = NoLanes; // It's safe to process the queue now that the render phase is complete. + finishQueueingConcurrentUpdates(); return workInProgressRootExitStatus; - } + } // The work loop is an extremely hot path. Tell Closure not to inline it. + + /** @noinline */ + function workLoopSync() { - for (; null !== workInProgress; ) performUnitOfWork(workInProgress); + // Perform work without checking if we need to yield between fiber. + while (workInProgress !== null) { + performUnitOfWork(workInProgress); + } } + function renderRootConcurrent(root, lanes) { var prevExecutionContext = executionContext; executionContext |= RenderContext; - var prevDispatcher = pushDispatcher(), - prevAsyncDispatcher = pushAsyncDispatcher(); + var prevDispatcher = pushDispatcher(); + // and prepare a fresh one. Otherwise we'll continue where we left off. + if ( workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes ) { - if (isDevToolsPresent) { - var memoizedUpdaters = root.memoizedUpdaters; - 0 < memoizedUpdaters.size && - (restorePendingUpdaters(root, workInProgressRootRenderLanes), - memoizedUpdaters.clear()); - movePendingFibersToMemoized(root, lanes); + { + if (isDevToolsPresent) { + var memoizedUpdaters = root.memoizedUpdaters; + + if (memoizedUpdaters.size > 0) { + restorePendingUpdaters(root, workInProgressRootRenderLanes); + memoizedUpdaters.clear(); + } // At this point, move Fibers that scheduled the upcoming work from the Map to the Set. + // If we bailout on this work, we'll move them back (like above). + // It's important to move them now in case the work spawns more work at the same priority with different updaters. + // That way we can keep the current update and future updates separate. + + movePendingFibersToMemoized(root, lanes); + } } - workInProgressTransitions = null; - workInProgressRootRenderTargetTime = now$1() + RENDER_TIMEOUT_MS; + + workInProgressTransitions = getTransitionsForLanes(); + resetRenderTimer(); prepareFreshStack(root, lanes); } - markRenderStarted(lanes); - a: do + + outer: do { try { if ( workInProgressSuspendedReason !== NotSuspended && - null !== workInProgress - ) - b: switch ( - ((lanes = workInProgress), - (memoizedUpdaters = workInProgressThrownValue), - workInProgressSuspendedReason) - ) { - case SuspendedOnError: + workInProgress !== null + ) { + // The work loop is suspended. We need to either unwind the stack or + // replay the suspended component. + var unitOfWork = workInProgress; + var thrownValue = workInProgressThrownValue; + + resumeOrUnwind: switch (workInProgressSuspendedReason) { + case SuspendedOnError: { + // Unwind then continue with the normal work loop. workInProgressSuspendedReason = NotSuspended; workInProgressThrownValue = null; - throwAndUnwindWorkLoop(root, lanes, memoizedUpdaters); + throwAndUnwindWorkLoop(root, unitOfWork, thrownValue); break; - case SuspendedOnData: - if (isThenableResolved(memoizedUpdaters)) { + } + + case SuspendedOnData: { + var thenable = thrownValue; + + if (isThenableResolved(thenable)) { + // The data resolved. Try rendering the component again. workInProgressSuspendedReason = NotSuspended; workInProgressThrownValue = null; - replaySuspendedUnitOfWork(lanes); + replaySuspendedUnitOfWork(unitOfWork); break; - } - lanes = function () { - workInProgressSuspendedReason === SuspendedOnData && - workInProgressRoot === root && - (workInProgressSuspendedReason = - SuspendedAndReadyToContinue); + } // The work loop is suspended on data. We should wait for it to + // resolve before continuing to render. + // TODO: Handle the case where the promise resolves synchronously. + // Usually this is handled when we instrument the promise to add a + // `status` field, but if the promise already has a status, we won't + // have added a listener until right here. + + var onResolution = function () { + // Check if the root is still suspended on this promise. + if ( + workInProgressSuspendedReason === SuspendedOnData && + workInProgressRoot === root + ) { + // Mark the root as ready to continue rendering. + workInProgressSuspendedReason = SuspendedAndReadyToContinue; + } // Ensure the root is scheduled. We should do this even if we're + // currently working on a different root, so that we resume + // rendering later. + ensureRootIsScheduled(root); }; - memoizedUpdaters.then(lanes, lanes); - break a; - case SuspendedOnImmediate: + + thenable.then(onResolution, onResolution); + break outer; + } + + case SuspendedOnImmediate: { + // If this fiber just suspended, it's possible the data is already + // cached. Yield to the main thread to give it a chance to ping. If + // it does, we can retry immediately without unwinding the stack. workInProgressSuspendedReason = SuspendedAndReadyToContinue; - break a; - case SuspendedOnInstance: + break outer; + } + + case SuspendedOnInstance: { workInProgressSuspendedReason = SuspendedOnInstanceAndReadyToContinue; - break a; - case SuspendedAndReadyToContinue: - isThenableResolved(memoizedUpdaters) - ? ((workInProgressSuspendedReason = NotSuspended), - (workInProgressThrownValue = null), - replaySuspendedUnitOfWork(lanes)) - : ((workInProgressSuspendedReason = NotSuspended), - (workInProgressThrownValue = null), - throwAndUnwindWorkLoop(root, lanes, memoizedUpdaters)); + break outer; + } + + case SuspendedAndReadyToContinue: { + var _thenable = thrownValue; + + if (isThenableResolved(_thenable)) { + // The data resolved. Try rendering the component again. + workInProgressSuspendedReason = NotSuspended; + workInProgressThrownValue = null; + replaySuspendedUnitOfWork(unitOfWork); + } else { + // Otherwise, unwind then continue with the normal work loop. + workInProgressSuspendedReason = NotSuspended; + workInProgressThrownValue = null; + throwAndUnwindWorkLoop(root, unitOfWork, thrownValue); + } + break; - case SuspendedOnInstanceAndReadyToContinue: - var resource = null; + } + + case SuspendedOnInstanceAndReadyToContinue: { switch (workInProgress.tag) { - case 26: - resource = workInProgress.memoizedState; - case 5: - case 27: + case HostComponent: + case HostHoistable: + case HostSingleton: { + // Before unwinding the stack, check one more time if the + // instance is ready. It may have loaded when React yielded to + // the main thread. + // Assigning this to a constant so Flow knows the binding won't + // be mutated by `preloadInstance`. var hostFiber = workInProgress; - if (resource ? preloadResource(resource) : 1) { + var type = hostFiber.type; + var props = hostFiber.pendingProps; + var isReady = preloadInstance(type, props); + + if (isReady) { + // The data resolved. Resume the work loop as if nothing + // suspended. Unlike when a user component suspends, we don't + // have to replay anything because the host fiber + // already completed. workInProgressSuspendedReason = NotSuspended; workInProgressThrownValue = null; var sibling = hostFiber.sibling; - if (null !== sibling) workInProgress = sibling; - else { + + if (sibling !== null) { + workInProgress = sibling; + } else { var returnFiber = hostFiber.return; - null !== returnFiber - ? ((workInProgress = returnFiber), - completeUnitOfWork(returnFiber)) - : (workInProgress = null); + + if (returnFiber !== null) { + workInProgress = returnFiber; + completeUnitOfWork(returnFiber); + } else { + workInProgress = null; + } } - break b; + + break resumeOrUnwind; } + break; - default: - error$jscomp$0( - "Unexpected type of fiber triggered a suspensey commit. This is a bug in React." - ); - } + } + + default: { + // This will fail gracefully but it's not correct, so log a + // warning in dev. + if (true) { + error( + "Unexpected type of fiber triggered a suspensey commit. " + + "This is a bug in React." + ); + } + + break; + } + } // Otherwise, unwind then continue with the normal work loop. + workInProgressSuspendedReason = NotSuspended; workInProgressThrownValue = null; - throwAndUnwindWorkLoop(root, lanes, memoizedUpdaters); + throwAndUnwindWorkLoop(root, unitOfWork, thrownValue); break; - case SuspendedOnDeprecatedThrowPromise: + } + + case SuspendedOnDeprecatedThrowPromise: { + // Suspended by an old implementation that uses the `throw promise` + // pattern. The newer replaying behavior can cause subtle issues + // like infinite ping loops. So we maintain the old behavior and + // always unwind. workInProgressSuspendedReason = NotSuspended; workInProgressThrownValue = null; - throwAndUnwindWorkLoop(root, lanes, memoizedUpdaters); + throwAndUnwindWorkLoop(root, unitOfWork, thrownValue); break; - case SuspendedOnHydration: + } + + case SuspendedOnHydration: { + // Selective hydration. An update flowed into a dehydrated tree. + // Interrupt the current render so the work loop can switch to the + // hydration lane. resetWorkInProgressStack(); workInProgressRootExitStatus = RootDidNotComplete; - break a; - default: - throw Error( + break outer; + } + + default: { + throw new Error( "Unexpected SuspendedReason. This is a bug in React." ); + } } - null !== ReactSharedInternals.actQueue - ? workLoopSync() - : workLoopConcurrent(); + } + + if (true && ReactCurrentActQueue.current !== null) { + // `act` special case: If we're inside an `act` scope, don't consult + // `shouldYield`. Always keep working until the render is complete. + // This is not just an optimization: in a unit test environment, we + // can't trust the result of `shouldYield`, because the host I/O is + // likely mocked. + workLoopSync(); + } else { + workLoopConcurrent(); + } + break; - } catch (thrownValue$43) { - handleThrow(root, thrownValue$43); + } catch (thrownValue) { + handleThrow(root, thrownValue); } - while (1); + } while (true); + resetContextDependencies(); - ReactSharedInternals.H = prevDispatcher; - ReactSharedInternals.A = prevAsyncDispatcher; + popDispatcher(prevDispatcher); executionContext = prevExecutionContext; - if (null !== workInProgress) - return ( - null !== injectedProfilingHooks && - "function" === typeof injectedProfilingHooks.markRenderYielded && - injectedProfilingHooks.markRenderYielded(), - RootInProgress - ); - markRenderStopped(); - workInProgressRoot = null; - workInProgressRootRenderLanes = 0; - finishQueueingConcurrentUpdates(); - return workInProgressRootExitStatus; + + if (workInProgress !== null) { + return RootInProgress; + } else { + workInProgressRoot = null; + workInProgressRootRenderLanes = NoLanes; // It's safe to process the queue now that the render phase is complete. + + finishQueueingConcurrentUpdates(); // Return the final exit status. + + return workInProgressRootExitStatus; + } } + /** @noinline */ + function workLoopConcurrent() { - for (; null !== workInProgress && !shouldYield(); ) + // Perform work until Scheduler asks us to yield + while (workInProgress !== null && !shouldYield()) { + // $FlowFixMe[incompatible-call] found when upgrading Flow performUnitOfWork(workInProgress); + } } + function performUnitOfWork(unitOfWork) { + // The current, flushed, state of this fiber is the alternate. Ideally + // nothing should rely on this, but relying on it here means that we don't + // need an additional field on the work in progress. var current = unitOfWork.alternate; - 0 !== (unitOfWork.mode & 2) - ? (startProfilerTimer(unitOfWork), - (current = runWithFiberInDEV( - unitOfWork, - beginWork, - current, - unitOfWork, - entangledRenderLanes - )), - stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, !0)) - : (current = runWithFiberInDEV( - unitOfWork, - beginWork, - current, - unitOfWork, - entangledRenderLanes - )); + setCurrentFiber(unitOfWork); + var next; + + if ((unitOfWork.mode & ProfileMode) !== NoMode) { + startProfilerTimer(unitOfWork); + next = beginWork(current, unitOfWork, entangledRenderLanes); + stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true); + } else { + next = beginWork(current, unitOfWork, entangledRenderLanes); + } + + resetCurrentFiber(); unitOfWork.memoizedProps = unitOfWork.pendingProps; - null === current - ? completeUnitOfWork(unitOfWork) - : (workInProgress = current); + + if (next === null) { + // If this doesn't spawn new work, complete the current work. + completeUnitOfWork(unitOfWork); + } else { + workInProgress = next; + } + + ReactCurrentOwner$1.current = null; } + function replaySuspendedUnitOfWork(unitOfWork) { - var next = runWithFiberInDEV(unitOfWork, replayBeginWork, unitOfWork); - unitOfWork.memoizedProps = unitOfWork.pendingProps; - null === next ? completeUnitOfWork(unitOfWork) : (workInProgress = next); - } - function replayBeginWork(unitOfWork) { - var current = unitOfWork.alternate, - isProfilingMode = 0 !== (unitOfWork.mode & 2); - isProfilingMode && startProfilerTimer(unitOfWork); + // This is a fork of performUnitOfWork specifcally for replaying a fiber that + // just suspended. + // + var current = unitOfWork.alternate; + setCurrentFiber(unitOfWork); + var next; + setCurrentFiber(unitOfWork); + var isProfilingMode = (unitOfWork.mode & ProfileMode) !== NoMode; + + if (isProfilingMode) { + startProfilerTimer(unitOfWork); + } + switch (unitOfWork.tag) { - case 15: - case 0: - current = replayFunctionComponent( + case IndeterminateComponent: { + // Because it suspended with `use`, we can assume it's a + // function component. + unitOfWork.tag = FunctionComponent; // Fallthrough to the next branch. + } + + case SimpleMemoComponent: + case FunctionComponent: { + // Resolve `defaultProps`. This logic is copied from `beginWork`. + // TODO: Consider moving this switch statement into that module. Also, + // could maybe use this as an opportunity to say `use` doesn't work with + // `defaultProps` :) + var Component = unitOfWork.type; + var unresolvedProps = unitOfWork.pendingProps; + var resolvedProps = + unitOfWork.elementType === Component + ? unresolvedProps + : resolveDefaultProps(Component, unresolvedProps); + var context; + + next = replayFunctionComponent( current, unitOfWork, - unitOfWork.pendingProps, - unitOfWork.type, - void 0, + resolvedProps, + Component, + context, workInProgressRootRenderLanes ); break; - case 11: - current = replayFunctionComponent( + } + + case ForwardRef: { + // Resolve `defaultProps`. This logic is copied from `beginWork`. + // TODO: Consider moving this switch statement into that module. Also, + // could maybe use this as an opportunity to say `use` doesn't work with + // `defaultProps` :) + var _Component = unitOfWork.type.render; + var _unresolvedProps = unitOfWork.pendingProps; + + var _resolvedProps = + unitOfWork.elementType === _Component + ? _unresolvedProps + : resolveDefaultProps(_Component, _unresolvedProps); + + next = replayFunctionComponent( current, unitOfWork, - unitOfWork.pendingProps, - unitOfWork.type.render, + _resolvedProps, + _Component, unitOfWork.ref, workInProgressRootRenderLanes ); break; - case 5: - resetHooksOnUnwind(unitOfWork); - default: - unwindInterruptedWork(current, unitOfWork), - (unitOfWork = workInProgress = - resetWorkInProgress(unitOfWork, entangledRenderLanes)), - (current = beginWork(current, unitOfWork, entangledRenderLanes)); + } + + case HostComponent: { + // Some host components are stateful (that's how we implement form + // actions) but we don't bother to reuse the memoized state because it's + // not worth the extra code. The main reason to reuse the previous hooks + // is to reuse uncached promises, but we happen to know that the only + // promises that a host component might suspend on are definitely cached + // because they are controlled by us. So don't bother. + resetHooksOnUnwind(unitOfWork); // Fallthrough to the next branch. + } + + default: { + // Other types besides function components are reset completely before + // being replayed. Currently this only happens when a Usable type is + // reconciled — the reconciler will suspend. + // + // We reset the fiber back to its original state; however, this isn't + // a full "unwind" because we're going to reuse the promises that were + // reconciled previously. So it's intentional that we don't call + // resetSuspendedWorkLoopOnUnwind here. + unwindInterruptedWork(current, unitOfWork); + unitOfWork = workInProgress = resetWorkInProgress( + unitOfWork, + entangledRenderLanes + ); + next = beginWork(current, unitOfWork, entangledRenderLanes); + break; + } } - isProfilingMode && - stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, !0); - return current; + + if (isProfilingMode) { + stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true); + } // The begin phase finished successfully without suspending. Return to the + // normal work loop. + + resetCurrentFiber(); + unitOfWork.memoizedProps = unitOfWork.pendingProps; + + if (next === null) { + // If this doesn't spawn new work, complete the current work. + completeUnitOfWork(unitOfWork); + } else { + workInProgress = next; + } + + ReactCurrentOwner$1.current = null; } + function throwAndUnwindWorkLoop(root, unitOfWork, thrownValue) { - resetContextDependencies(); - resetHooksOnUnwind(unitOfWork); - thenableState$1 = null; - thenableIndexCounter$1 = 0; + // This is a fork of performUnitOfWork specifcally for unwinding a fiber + // that threw an exception. + // + // Return to the normal work loop. This will unwind the stack, and potentially + // result in showing a fallback. + resetSuspendedWorkLoopOnUnwind(unitOfWork); var returnFiber = unitOfWork.return; + try { - if ( - throwException( - root, - returnFiber, - unitOfWork, - thrownValue, - workInProgressRootRenderLanes - ) - ) { - workInProgressRootExitStatus = RootFatalErrored; - logUncaughtError( - root, - createCapturedValueAtFiber(thrownValue, root.current) - ); - workInProgress = null; - return; - } - } catch (error$44) { - if (null !== returnFiber) - throw ((workInProgress = returnFiber), error$44); - workInProgressRootExitStatus = RootFatalErrored; - logUncaughtError( + // Find and mark the nearest Suspense or error boundary that can handle + // this "exception". + var didFatal = throwException( root, - createCapturedValueAtFiber(thrownValue, root.current) + returnFiber, + unitOfWork, + thrownValue, + workInProgressRootRenderLanes ); - workInProgress = null; - return; + + if (didFatal) { + panicOnRootError(thrownValue); + return; + } + } catch (error) { + // We had trouble processing the error. An example of this happening is + // when accessing the `componentDidCatch` property of an error boundary + // throws an error. A weird edge case. There's a regression test for this. + // To prevent an infinite loop, bubble the error up to the next parent. + if (returnFiber !== null) { + workInProgress = returnFiber; + throw error; + } else { + panicOnRootError(thrownValue); + return; + } } - if (unitOfWork.flags & 32768) - a: { - root = unitOfWork; - do { - unitOfWork = unwindWork(root.alternate, root); - if (null !== unitOfWork) { - unitOfWork.flags &= 32767; - workInProgress = unitOfWork; - break a; - } - if (0 !== (root.mode & 2)) { - stopProfilerTimerIfRunningAndRecordDelta(root, !1); - unitOfWork = root.actualDuration; - for (thrownValue = root.child; null !== thrownValue; ) - (unitOfWork += thrownValue.actualDuration), - (thrownValue = thrownValue.sibling); - root.actualDuration = unitOfWork; - } - root = root.return; - null !== root && - ((root.flags |= 32768), - (root.subtreeFlags = 0), - (root.deletions = null)); - workInProgress = root; - } while (null !== root); - workInProgressRootExitStatus = RootDidNotComplete; - workInProgress = null; - } - else completeUnitOfWork(unitOfWork); + + if (unitOfWork.flags & Incomplete) { + // Unwind the stack until we reach the nearest boundary. + unwindUnitOfWork(unitOfWork); + } else { + // Although the fiber suspended, we're intentionally going to commit it in + // an inconsistent state. We can do this safely in cases where we know the + // inconsistent tree will be hidden. + // + // This currently only applies to Legacy Suspense implementation, but we may + // port a version of this to concurrent roots, too, when performing a + // synchronous render. Because that will allow us to mutate the tree as we + // go instead of buffering mutations until the end. Though it's unclear if + // this particular path is how that would be implemented. + completeUnitOfWork(unitOfWork); + } + } + + function panicOnRootError(error) { + // There's no ancestor that can handle this exception. This should never + // happen because the root is supposed to capture all errors that weren't + // caught by an error boundary. This is a fatal error, or panic condition, + // because we've run out of ways to recover. + workInProgressRootExitStatus = RootFatalErrored; + workInProgressRootFatalError = error; // Set `workInProgress` to null. This represents advancing to the next + // sibling, or the parent if there are no siblings. But since the root + // has no siblings nor a parent, we set it to null. Usually this is + // handled by `completeUnitOfWork` or `unwindWork`, but since we're + // intentionally not calling those, we need set it here. + // TODO: Consider calling `unwindWork` to pop the contexts. + + workInProgress = null; } + function completeUnitOfWork(unitOfWork) { + // Attempt to complete the current unit of work, then move to the next + // sibling. If there are no more siblings, return to the parent fiber. var completedWork = unitOfWork; + do { - 0 !== (completedWork.flags & 32768) && - error$jscomp$0( - "Internal React error: Expected this fiber to be complete, but it isn't. It should have been unwound. This is a bug in React." - ); + { + if ((completedWork.flags & Incomplete) !== NoFlags$1) { + // NOTE: If we re-enable sibling prerendering in some cases, this branch + // is where we would switch to the unwinding path. + error( + "Internal React error: Expected this fiber to be complete, but " + + "it isn't. It should have been unwound. This is a bug in React." + ); + } + } // The current, flushed, state of this fiber is the alternate. Ideally + // nothing should rely on this, but relying on it here means that we don't + // need an additional field on the work in progress. + var current = completedWork.alternate; - unitOfWork = completedWork.return; - 0 === (completedWork.mode & 2) - ? (current = runWithFiberInDEV( - completedWork, - completeWork, - current, - completedWork, - entangledRenderLanes - )) - : (startProfilerTimer(completedWork), - (current = runWithFiberInDEV( - completedWork, - completeWork, - current, - completedWork, - entangledRenderLanes - )), - stopProfilerTimerIfRunningAndRecordDelta(completedWork, !1)); - if (null !== current) { - workInProgress = current; - return; + var returnFiber = completedWork.return; + setCurrentFiber(completedWork); + var next = void 0; + + if ((completedWork.mode & ProfileMode) === NoMode) { + next = completeWork(current, completedWork, entangledRenderLanes); + } else { + startProfilerTimer(completedWork); + next = completeWork(current, completedWork, entangledRenderLanes); // Update render duration assuming we didn't error. + + stopProfilerTimerIfRunningAndRecordDelta(completedWork, false); } - completedWork = completedWork.sibling; - if (null !== completedWork) { - workInProgress = completedWork; + + resetCurrentFiber(); + + if (next !== null) { + // Completing this fiber spawned new work. Work on that next. + workInProgress = next; return; } - workInProgress = completedWork = unitOfWork; - } while (null !== completedWork); - workInProgressRootExitStatus === RootInProgress && - (workInProgressRootExitStatus = RootCompleted); + + var siblingFiber = completedWork.sibling; + + if (siblingFiber !== null) { + // If there is more work to do in this returnFiber, do that next. + workInProgress = siblingFiber; + return; + } // Otherwise, return to the parent + // $FlowFixMe[incompatible-type] we bail out when we get a null + + completedWork = returnFiber; // Update the next thing we're working on in case something throws. + + workInProgress = completedWork; + } while (completedWork !== null); // We've reached the root. + + if (workInProgressRootExitStatus === RootInProgress) { + workInProgressRootExitStatus = RootCompleted; + } + } + + function unwindUnitOfWork(unitOfWork) { + var incompleteWork = unitOfWork; + + do { + // The current, flushed, state of this fiber is the alternate. Ideally + // nothing should rely on this, but relying on it here means that we don't + // need an additional field on the work in progress. + var current = incompleteWork.alternate; // This fiber did not complete because something threw. Pop values off + // the stack without entering the complete phase. If this is a boundary, + // capture values if possible. + + var next = unwindWork(current, incompleteWork); // Because this fiber did not complete, don't reset its lanes. + + if (next !== null) { + // Found a boundary that can handle this exception. Re-renter the + // begin phase. This branch will return us to the normal work loop. + // + // Since we're restarting, remove anything that is not a host effect + // from the effect tag. + next.flags &= HostEffectMask; + workInProgress = next; + return; + } // Keep unwinding until we reach either a boundary or the root. + + if ((incompleteWork.mode & ProfileMode) !== NoMode) { + // Record the render duration for the fiber that errored. + stopProfilerTimerIfRunningAndRecordDelta(incompleteWork, false); // Include the time spent working on failed children before continuing. + + var actualDuration = incompleteWork.actualDuration; + var child = incompleteWork.child; + + while (child !== null) { + // $FlowFixMe[unsafe-addition] addition with possible null/undefined value + actualDuration += child.actualDuration; + child = child.sibling; + } + + incompleteWork.actualDuration = actualDuration; + } // TODO: Once we stop prerendering siblings, instead of resetting the parent + // of the node being unwound, we should be able to reset node itself as we + // unwind the stack. Saves an additional null check. + + var returnFiber = incompleteWork.return; + + if (returnFiber !== null) { + // Mark the parent fiber as incomplete and clear its subtree flags. + // TODO: Once we stop prerendering siblings, we may be able to get rid of + // the Incomplete flag because unwinding to the nearest boundary will + // happen synchronously. + returnFiber.flags |= Incomplete; + returnFiber.subtreeFlags = NoFlags$1; + returnFiber.deletions = null; + } // NOTE: If we re-enable sibling prerendering in some cases, here we + // would switch to the normal completion path: check if a sibling + // exists, and if so, begin work on it. + // Otherwise, return to the parent + // $FlowFixMe[incompatible-type] we bail out when we get a null + + incompleteWork = returnFiber; // Update the next thing we're working on in case something throws. + + workInProgress = incompleteWork; + } while (incompleteWork !== null); // We've unwound all the way to the root. + + workInProgressRootExitStatus = RootDidNotComplete; + workInProgress = null; } + function commitRoot( root, recoverableErrors, @@ -12263,25 +24087,30 @@ __DEV__ && didIncludeRenderPhaseUpdate, spawnedLane ) { - var prevTransition = ReactSharedInternals.T, - previousUpdateLanePriority = currentUpdatePriority; + // 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.transition; + try { - (currentUpdatePriority = DiscreteEventPriority), - (ReactSharedInternals.T = null), - commitRootImpl( - root, - recoverableErrors, - transitions, - didIncludeRenderPhaseUpdate, - previousUpdateLanePriority, - spawnedLane - ); + ReactCurrentBatchConfig.transition = null; + setCurrentUpdatePriority(DiscreteEventPriority); + commitRootImpl( + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate, + previousUpdateLanePriority, + spawnedLane + ); } finally { - (ReactSharedInternals.T = prevTransition), - (currentUpdatePriority = previousUpdateLanePriority); + ReactCurrentBatchConfig.transition = prevTransition; + setCurrentUpdatePriority(previousUpdateLanePriority); } + return null; } + function commitRootImpl( root, recoverableErrors, @@ -12290,4175 +24119,3124 @@ __DEV__ && renderPriorityLevel, spawnedLane ) { - do flushPassiveEffects(); - while (null !== rootWithPendingPassiveEffects); - ReactStrictModeWarnings.flushLegacyContextWarning(); - ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings(); - if ((executionContext & (RenderContext | CommitContext)) !== NoContext) - throw Error("Should not already be working."); - var finishedWork = root.finishedWork, - lanes = root.finishedLanes; - null !== injectedProfilingHooks && - "function" === typeof injectedProfilingHooks.markCommitStarted && - injectedProfilingHooks.markCommitStarted(lanes); - if (null === finishedWork) return markCommitStopped(), null; - 0 === lanes && - error$jscomp$0( - "root.finishedLanes should not be empty during a commit. This is a bug in React." - ); + do { + // `flushPassiveEffects` will call `flushSyncUpdateQueue` at the end, which + // means `flushPassiveEffects` will sometimes result in additional + // passive effects. So we need to keep flushing in a loop until there are + // no more pending effects. + // TODO: Might be better if `flushPassiveEffects` did not automatically + // flush synchronous work at the end, to avoid factoring hazards like this. + flushPassiveEffects(); + } while (rootWithPendingPassiveEffects !== null); + + flushRenderPhaseStrictModeWarningsInDEV(); + + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) { + throw new Error("Should not already be working."); + } + + var finishedWork = root.finishedWork; + var lanes = root.finishedLanes; + + 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; - root.finishedLanes = 0; - if (finishedWork === root.current) - throw Error( - "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." + root.finishedLanes = NoLanes; + + if (finishedWork === root.current) { + throw new Error( + "Cannot commit the same tree as before. This error is likely caused by " + + "a bug in React. Please file an issue." ); + } // 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; - root.callbackPriority = 0; - root.cancelPendingCommit = null; - var remainingLanes = finishedWork.lanes | finishedWork.childLanes; - remainingLanes |= concurrentlyUpdatedLanes; - markRootFinished(root, remainingLanes, spawnedLane); - didIncludeCommitPhaseUpdate = !1; - root === workInProgressRoot && - ((workInProgress = workInProgressRoot = null), - (workInProgressRootRenderLanes = 0)); - (0 === (finishedWork.subtreeFlags & 10256) && - 0 === (finishedWork.flags & 10256)) || - rootDoesHavePassiveEffects || - ((rootDoesHavePassiveEffects = !0), - (pendingPassiveEffectsRemainingLanes = remainingLanes), - (pendingPassiveTransitions = transitions), - scheduleCallback(NormalPriority$1, function () { - flushPassiveEffects(); - return null; - })); - transitions = 0 !== (finishedWork.flags & 15990); - if (0 !== (finishedWork.subtreeFlags & 15990) || transitions) { - transitions = ReactSharedInternals.T; - ReactSharedInternals.T = null; - spawnedLane = currentUpdatePriority; - currentUpdatePriority = DiscreteEventPriority; + root.callbackPriority = NoLane; + root.cancelPendingCommit = null; // Check which lanes no longer have any work scheduled on them, and mark + // those as finished. + + var remainingLanes = mergeLanes( + finishedWork.lanes, + finishedWork.childLanes + ); // Make sure to account for lanes that were updated by a concurrent event + // during the render phase; don't mark them as finished. + + var concurrentlyUpdatedLanes = getConcurrentlyUpdatedLanes(); + remainingLanes = mergeLanes(remainingLanes, concurrentlyUpdatedLanes); + markRootFinished(root, remainingLanes, spawnedLane); // Reset this before firing side effects so we can detect recursive updates. + + if (root === workInProgressRoot) { + // We can reset these now that they are finished. + workInProgressRoot = null; + workInProgress = null; + workInProgressRootRenderLanes = NoLanes; + } // 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 ( + (finishedWork.subtreeFlags & PassiveMask) !== NoFlags$1 || + (finishedWork.flags & PassiveMask) !== NoFlags$1 + ) { + if (!rootDoesHavePassiveEffects) { + rootDoesHavePassiveEffects = true; + scheduleCallback(NormalPriority, function () { + flushPassiveEffects(); // This render triggered passive effects: release the root cache pool + // *after* passive effects fire to avoid freeing a cache pool that may + // be referenced by a node in the tree (HostRoot, Cache boundary etc) + + 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 satisfy 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$1; + var rootHasEffect = + (finishedWork.flags & + (BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !== + NoFlags$1; + + if (subtreeHasEffects || rootHasEffect) { + var prevTransition = ReactCurrentBatchConfig.transition; + ReactCurrentBatchConfig.transition = null; + var previousPriority = getCurrentUpdatePriority(); + setCurrentUpdatePriority(DiscreteEventPriority); var prevExecutionContext = executionContext; - executionContext |= CommitContext; + executionContext |= CommitContext; // Reset this to null before calling lifecycles + + ReactCurrentOwner$1.current = null; // The commit phase is broken into several sub-phases. We do a separate pass + // of the effect list for each phase: all mutation effects come before all + // layout effects, and so on. + // The first phase a "before mutation" phase. We use this phase to read the + // state of the host tree right before we mutate it. This is where + // getSnapshotBeforeUpdate is called. + commitBeforeMutationEffects(root, finishedWork); - commitTime = now(); + + { + // 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. + commitMutationEffects(root, finishedWork, lanes); - root.current = finishedWork; - null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markLayoutEffectsStarted && - injectedProfilingHooks.markLayoutEffectsStarted(lanes); + // the mutation phase, so that the previous tree is still current during + // componentWillUnmount, but before the layout phase, so that the finished + // work is current during componentDidMount/Update. + + root.current = finishedWork; // The next phase is the layout phase, where we call effects that read + commitLayoutEffects(finishedWork, root, lanes); - null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markLayoutEffectsStopped && - injectedProfilingHooks.markLayoutEffectsStopped(); + // opportunity to paint. + requestPaint(); - executionContext = prevExecutionContext; - currentUpdatePriority = spawnedLane; - ReactSharedInternals.T = transitions; - } else (root.current = finishedWork), (commitTime = now()); - (transitions = rootDoesHavePassiveEffects) - ? ((rootDoesHavePassiveEffects = !1), - (rootWithPendingPassiveEffects = root), - (pendingPassiveEffectsLanes = lanes)) - : (releaseRootPooledCache(root, remainingLanes), - (nestedPassiveUpdateCount = 0), - (rootWithPassiveNestedUpdates = null)); - remainingLanes = root.pendingLanes; - 0 === remainingLanes && (legacyErrorBoundariesThatAlreadyFailed = null); - transitions || commitDoubleInvokeEffectsInDEV(root, !1); + executionContext = prevExecutionContext; // Reset the priority to the previous non-sync value. + + setCurrentUpdatePriority(previousPriority); + ReactCurrentBatchConfig.transition = prevTransition; + } else { + // No effects. + root.current = finishedWork; // Measure these anyway so the flamegraph explicitly shows that there were + // no effects. + // TODO: Maybe there's a better way to report this. + + { + recordCommitTime(); + } + } + + 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; + } else { + { + nestedPassiveUpdateCount = 0; + rootWithPassiveNestedUpdates = null; + } + } // Read this again, since an effect might have updated it + + remainingLanes = root.pendingLanes; // Check if there's remaining work on this root + // TODO: This is part of the `componentDidCatch` implementation. Its purpose + // is to detect whether something might have called setState inside + // `componentDidCatch`. The mechanism is known to be flawed because `setState` + // inside `componentDidCatch` is itself flawed — that's why we recommend + // `getDerivedStateFromError` instead. However, it could be improved by + // checking if remainingLanes includes Sync work, instead of whether there's + // any work remaining at all (which would also include stuff like Suspense + // retries or transitions). It's been like this for a while, though, so fixing + // it probably isn't that urgent. + + if (remainingLanes === NoLanes) { + // If there's no remaining work, we can clear the set of already failed + // error boundaries. + legacyErrorBoundariesThatAlreadyFailed = null; + } + + { + if (!rootDidHavePassiveEffects) { + commitDoubleInvokeEffectsInDEV(root, false); + } + } + onCommitRoot(finishedWork.stateNode, renderPriorityLevel); - isDevToolsPresent && root.memoizedUpdaters.clear(); + + { + if (isDevToolsPresent) { + root.memoizedUpdaters.clear(); + } + } + // additional work on this root is scheduled. + ensureRootIsScheduled(root); - if (null !== recoverableErrors) - for ( - renderPriorityLevel = root.onRecoverableError, finishedWork = 0; - finishedWork < recoverableErrors.length; - finishedWork++ - ) - (remainingLanes = recoverableErrors[finishedWork]), - (transitions = makeErrorInfo(remainingLanes.stack)), - runWithFiberInDEV( - remainingLanes.source, - renderPriorityLevel, - remainingLanes.value, - transitions - ); - 0 !== (pendingPassiveEffectsLanes & (SyncLane | SyncHydrationLane)) && - 0 !== root.tag && - flushPassiveEffects(); - remainingLanes = root.pendingLanes; - didIncludeRenderPhaseUpdate || - didIncludeCommitPhaseUpdate || - (0 !== (lanes & UpdateLanes) && 0 !== (remainingLanes & SyncUpdateLanes)) - ? ((nestedUpdateScheduled = !0), - root === rootWithNestedUpdates - ? nestedUpdateCount++ - : ((nestedUpdateCount = 0), (rootWithNestedUpdates = root))) - : (nestedUpdateCount = 0); - flushSyncWorkAcrossRoots_impl(!1); - markCommitStopped(); - return null; - } - function makeErrorInfo(componentStack) { - componentStack = { componentStack: componentStack }; - Object.defineProperty(componentStack, "digest", { - get: function () { - error$jscomp$0( - 'You are accessing "digest" from the errorInfo object passed to onRecoverableError. This property is no longer provided as part of errorInfo but can be accessed as a property of the Error instance itself.' + + if (recoverableErrors !== null) { + // There were errors during this render, but recovered from them without + // needing to surface it to the UI. We log them here. + var onRecoverableError = root.onRecoverableError; + + for (var i = 0; i < recoverableErrors.length; i++) { + var recoverableError = recoverableErrors[i]; + var errorInfo = makeErrorInfo( + recoverableError.digest, + recoverableError.stack ); + onRecoverableError(recoverableError.value, errorInfo); } - }); - return componentStack; + } + + if (hasUncaughtError) { + hasUncaughtError = false; + var error$1 = firstUncaughtError; + firstUncaughtError = null; + throw error$1; + } // 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 ( + includesSyncLane(pendingPassiveEffectsLanes) && + root.tag !== LegacyRoot + ) { + flushPassiveEffects(); + } // Read this again, since a passive effect might have updated it + + remainingLanes = root.pendingLanes; // Check if this render scheduled a cascading synchronous update. This is a + // heurstic to detect infinite update loops. We are intentionally excluding + // hydration lanes in this check, because render triggered by selective + // hydration is conceptually not an update. + + if ( + // Check if there was a recursive update spawned by this render, in either + // the render phase or the commit phase. We track these explicitly because + // we can't infer from the remaining lanes alone. + // Was the finished render the result of an update (not hydration)? + includesSomeLane(lanes, UpdateLanes) && // Did it schedule a sync update? + includesSomeLane(remainingLanes, SyncUpdateLanes) + ) { + { + markNestedUpdateScheduled(); + } // Count the number of times the root synchronously re-renders without + // finishing. If there are too many, it indicates an infinite update loop. + + if (root === rootWithNestedUpdates) { + nestedUpdateCount++; + } else { + nestedUpdateCount = 0; + rootWithNestedUpdates = root; + } + } else { + nestedUpdateCount = 0; + } // If layout work was scheduled, flush it now. + + flushSyncWorkOnAllRoots(); + + return null; } - function releaseRootPooledCache(root, remainingLanes) { - 0 === (root.pooledCacheLanes &= remainingLanes) && - ((remainingLanes = root.pooledCache), - null != remainingLanes && - ((root.pooledCache = null), releaseCache(remainingLanes))); + + function makeErrorInfo(digest, componentStack) { + { + var errorInfo = { + componentStack: componentStack, + digest: digest + }; + Object.defineProperty(errorInfo, "digest", { + configurable: false, + enumerable: true, + get: function () { + error( + 'You are accessing "digest" from the errorInfo object passed to onRecoverableError.' + + " This property is deprecated and will be removed in a future version of React." + + " To access the digest of an Error look for this property on the Error instance itself." + ); + + return digest; + } + }); + return errorInfo; + } } + function flushPassiveEffects() { - if (null !== rootWithPendingPassiveEffects) { - var root = rootWithPendingPassiveEffects, - remainingLanes = pendingPassiveEffectsRemainingLanes; - pendingPassiveEffectsRemainingLanes = 0; - var renderPriority = lanesToEventPriority(pendingPassiveEffectsLanes), - priority = - 0 === DefaultEventPriority || DefaultEventPriority > renderPriority - ? DefaultEventPriority - : renderPriority; - renderPriority = ReactSharedInternals.T; - var previousPriority = currentUpdatePriority; + // Returns whether passive effects were flushed. + // 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.transition; + var previousPriority = getCurrentUpdatePriority(); + try { - currentUpdatePriority = priority; - ReactSharedInternals.T = null; - if (null === rootWithPendingPassiveEffects) - var JSCompiler_inline_result = !1; - else { - var transitions = pendingPassiveTransitions; - pendingPassiveTransitions = null; - priority = rootWithPendingPassiveEffects; - var lanes = pendingPassiveEffectsLanes; - rootWithPendingPassiveEffects = null; - pendingPassiveEffectsLanes = 0; - if ( - (executionContext & (RenderContext | CommitContext)) !== - NoContext - ) - throw Error( - "Cannot flush passive effects while already rendering." - ); - isFlushingPassiveEffects = !0; - didScheduleUpdateDuringPassiveEffects = !1; - null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markPassiveEffectsStarted && - injectedProfilingHooks.markPassiveEffectsStarted(lanes); - var prevExecutionContext = executionContext; - executionContext |= CommitContext; - var finishedWork = priority.current; - runWithFiberInDEV( - finishedWork, - commitPassiveUnmountOnFiber, - finishedWork - ); - var finishedWork$jscomp$0 = priority.current; - runWithFiberInDEV( - finishedWork$jscomp$0, - commitPassiveMountOnFiber, - priority, - finishedWork$jscomp$0, - lanes, - transitions - ); - finishedWork = pendingPassiveProfilerEffects; - pendingPassiveProfilerEffects = []; - for ( - finishedWork$jscomp$0 = 0; - finishedWork$jscomp$0 < finishedWork.length; - finishedWork$jscomp$0++ - ) { - var finishedWork$jscomp$1 = finishedWork[finishedWork$jscomp$0]; - if ( - executionContext & CommitContext && - 0 !== (finishedWork$jscomp$1.flags & 4) - ) - switch (finishedWork$jscomp$1.tag) { - case 12: - var passiveEffectDuration = - finishedWork$jscomp$1.stateNode.passiveEffectDuration, - _finishedWork$memoize = - finishedWork$jscomp$1.memoizedProps, - id = _finishedWork$memoize.id, - onPostCommit = _finishedWork$memoize.onPostCommit; - transitions = commitTime; - var phase = - null === finishedWork$jscomp$1.alternate - ? "mount" - : "update"; - currentUpdateIsNested && (phase = "nested-update"); - "function" === typeof onPostCommit && - onPostCommit( - id, - phase, - passiveEffectDuration, - transitions - ); - var parentFiber = finishedWork$jscomp$1.return; - b: for (; null !== parentFiber; ) { - switch (parentFiber.tag) { - case 3: - parentFiber.stateNode.passiveEffectDuration += - passiveEffectDuration; - break b; - case 12: - parentFiber.stateNode.passiveEffectDuration += - passiveEffectDuration; - break b; - } - parentFiber = parentFiber.return; - } - } - } - null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markPassiveEffectsStopped && - injectedProfilingHooks.markPassiveEffectsStopped(); - commitDoubleInvokeEffectsInDEV(priority, !0); - executionContext = prevExecutionContext; - flushSyncWorkAcrossRoots_impl(!1); - didScheduleUpdateDuringPassiveEffects - ? priority === rootWithPassiveNestedUpdates - ? nestedPassiveUpdateCount++ - : ((nestedPassiveUpdateCount = 0), - (rootWithPassiveNestedUpdates = priority)) - : (nestedPassiveUpdateCount = 0); - didScheduleUpdateDuringPassiveEffects = isFlushingPassiveEffects = - !1; - if ( - injectedHook && - "function" === typeof injectedHook.onPostCommitFiberRoot - ) - try { - injectedHook.onPostCommitFiberRoot(rendererID, priority); - } catch (err) { - hasLoggedError || - ((hasLoggedError = !0), - error$jscomp$0( - "React instrumentation encountered an error: %s", - err - )); - } - var stateNode = priority.current.stateNode; - stateNode.effectDuration = 0; - stateNode.passiveEffectDuration = 0; - JSCompiler_inline_result = !0; - } - return JSCompiler_inline_result; + ReactCurrentBatchConfig.transition = null; + setCurrentUpdatePriority(priority); + return flushPassiveEffectsImpl(); } finally { - (currentUpdatePriority = previousPriority), - (ReactSharedInternals.T = renderPriority), - releaseRootPooledCache(root, remainingLanes); + setCurrentUpdatePriority(previousPriority); + ReactCurrentBatchConfig.transition = prevTransition; // Once passive effects have run for the tree - giving components a } } - return !1; + + return false; } function enqueuePendingPassiveProfilerEffect(fiber) { - pendingPassiveProfilerEffects.push(fiber); - rootDoesHavePassiveEffects || - ((rootDoesHavePassiveEffects = !0), - scheduleCallback(NormalPriority$1, function () { - flushPassiveEffects(); - return null; - })); + { + pendingPassiveProfilerEffects.push(fiber); + + if (!rootDoesHavePassiveEffects) { + rootDoesHavePassiveEffects = true; + scheduleCallback(NormalPriority, function () { + flushPassiveEffects(); + return null; + }); + } + } } - function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { - sourceFiber = createCapturedValueAtFiber(error, sourceFiber); - sourceFiber = createRootErrorUpdate( - rootFiber.stateNode, - sourceFiber, - SyncLane + + function flushPassiveEffectsImpl() { + if (rootWithPendingPassiveEffects === null) { + return false; + } // Cache and clear the transitions flag + var root = rootWithPendingPassiveEffects; + 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) { + throw new Error( + "Cannot flush passive effects while already rendering." + ); + } + + { + isFlushingPassiveEffects = true; + didScheduleUpdateDuringPassiveEffects = false; + } + + var prevExecutionContext = executionContext; + executionContext |= CommitContext; + commitPassiveUnmountEffects(root.current); + commitPassiveMountEffects(root, root.current); // TODO: Move to commitPassiveMountEffects + + { + var profilerEffects = pendingPassiveProfilerEffects; + pendingPassiveProfilerEffects = []; + + for (var i = 0; i < profilerEffects.length; i++) { + var fiber = profilerEffects[i]; + commitPassiveEffectDurations(root, fiber); + } + } + + { + commitDoubleInvokeEffectsInDEV(root, true); + } + + executionContext = prevExecutionContext; + flushSyncWorkOnAllRoots(); + + { + // If additional passive effects were scheduled, increment a counter. If this + // exceeds the limit, we'll fire a warning. + if (didScheduleUpdateDuringPassiveEffects) { + if (root === rootWithPassiveNestedUpdates) { + nestedPassiveUpdateCount++; + } else { + nestedPassiveUpdateCount = 0; + rootWithPassiveNestedUpdates = root; + } + } else { + nestedPassiveUpdateCount = 0; + } + + isFlushingPassiveEffects = false; + didScheduleUpdateDuringPassiveEffects = false; + } // TODO: Move to commitPassiveMountEffects + + onPostCommitRoot(root); + + { + var stateNode = root.current.stateNode; + stateNode.effectDuration = 0; + stateNode.passiveEffectDuration = 0; + } + + return true; + } + + function isAlreadyFailedLegacyErrorBoundary(instance) { + return ( + legacyErrorBoundariesThatAlreadyFailed !== null && + legacyErrorBoundariesThatAlreadyFailed.has(instance) ); - rootFiber = enqueueUpdate(rootFiber, sourceFiber, SyncLane); - null !== rootFiber && - (markRootUpdated(rootFiber, SyncLane), - ensureRootIsScheduled(rootFiber)); } + function markLegacyErrorBoundaryAsFailed(instance) { + if (legacyErrorBoundariesThatAlreadyFailed === null) { + legacyErrorBoundariesThatAlreadyFailed = new Set([instance]); + } else { + legacyErrorBoundariesThatAlreadyFailed.add(instance); + } + } + + function prepareToThrowUncaughtError(error) { + if (!hasUncaughtError) { + hasUncaughtError = true; + firstUncaughtError = error; + } + } + + var onUncaughtError = prepareToThrowUncaughtError; + + function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { + var errorInfo = createCapturedValueAtFiber(error, sourceFiber); + var update = createRootErrorUpdate(rootFiber, errorInfo, SyncLane); + var root = enqueueUpdate(rootFiber, update, SyncLane); + + if (root !== null) { + markRootUpdated(root, SyncLane); + ensureRootIsScheduled(root); + } + } + function captureCommitPhaseError( sourceFiber, nearestMountedAncestor, error$1 ) { - isRunningInsertionEffect = !1; - if (3 === sourceFiber.tag) + { + setIsRunningInsertionEffect(false); + } + + 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$1); - else { - for (; null !== nearestMountedAncestor; ) { - if (3 === nearestMountedAncestor.tag) { - captureCommitPhaseErrorOnRoot( - nearestMountedAncestor, - sourceFiber, - error$1 - ); - return; - } - if (1 === nearestMountedAncestor.tag) { - var instance = nearestMountedAncestor.stateNode; - if ( - "function" === - typeof nearestMountedAncestor.type.getDerivedStateFromError || - ("function" === typeof instance.componentDidCatch && - (null === legacyErrorBoundariesThatAlreadyFailed || - !legacyErrorBoundariesThatAlreadyFailed.has(instance))) - ) { - sourceFiber = createCapturedValueAtFiber(error$1, sourceFiber); - error$1 = createClassErrorUpdate(SyncLane); - instance = enqueueUpdate( - nearestMountedAncestor, - error$1, - SyncLane - ); - null !== instance && - (initializeClassErrorUpdate( - error$1, - instance, - nearestMountedAncestor, - sourceFiber - ), - markRootUpdated(instance, SyncLane), - ensureRootIsScheduled(instance)); - return; + return; + } + + var fiber = nearestMountedAncestor; + + while (fiber !== null) { + if (fiber.tag === HostRoot) { + captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error$1); + return; + } else if (fiber.tag === ClassComponent) { + var ctor = fiber.type; + var instance = fiber.stateNode; + + if ( + typeof ctor.getDerivedStateFromError === "function" || + (typeof instance.componentDidCatch === "function" && + !isAlreadyFailedLegacyErrorBoundary(instance)) + ) { + var errorInfo = createCapturedValueAtFiber(error$1, sourceFiber); + var update = createClassErrorUpdate(fiber, errorInfo, SyncLane); + var root = enqueueUpdate(fiber, update, SyncLane); + + if (root !== null) { + markRootUpdated(root, SyncLane); + ensureRootIsScheduled(root); } + + return; } - nearestMountedAncestor = nearestMountedAncestor.return; } - error$jscomp$0( - "Internal React error: Attempted to capture a commit phase error inside a detached tree. This indicates a bug in React. Potential causes include deleting the same fiber more than once, committing an already-finished tree, or an inconsistent return pointer.\n\nError message:\n\n%s", + + fiber = fiber.return; + } + + { + error( + "Internal React error: Attempted to capture a commit phase error " + + "inside a detached tree. This indicates a bug in React. Potential " + + "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 attachPingListener(root, wakeable, lanes) { + // Attach a ping listener + // + // The data might resolve before we have a chance to commit the fallback. Or, + // in the case of a refresh, we'll never commit a fallback. So we need to + // attach a listener now. When it resolves ("pings"), we can decide whether to + // try rendering the tree again. + // + // Only attach a listener if one does not already exist for the lanes + // we're currently rendering (which acts like a "thread ID" here). + // + // We only need to do this in concurrent mode. Legacy Suspense always + // commits fallbacks synchronously, so there are no pings. var pingCache = root.pingCache; - if (null === pingCache) { + var threadIDs; + + if (pingCache === null) { pingCache = root.pingCache = new PossiblyWeakMap(); - var threadIDs = new Set(); + threadIDs = new Set(); pingCache.set(wakeable, threadIDs); - } else - (threadIDs = pingCache.get(wakeable)), - void 0 === threadIDs && - ((threadIDs = new Set()), pingCache.set(wakeable, threadIDs)); - threadIDs.has(lanes) || - ((workInProgressRootDidAttachPingListener = !0), - threadIDs.add(lanes), - (pingCache = pingSuspendedRoot.bind(null, root, wakeable, lanes)), - isDevToolsPresent && restorePendingUpdaters(root, lanes), - wakeable.then(pingCache, pingCache)); + } else { + threadIDs = pingCache.get(wakeable); + + if (threadIDs === undefined) { + threadIDs = new Set(); + pingCache.set(wakeable, threadIDs); + } + } + + if (!threadIDs.has(lanes)) { + workInProgressRootDidAttachPingListener = true; // Memoize using the thread ID to prevent redundant listeners. + + threadIDs.add(lanes); + var ping = pingSuspendedRoot.bind(null, root, wakeable, lanes); + + { + if (isDevToolsPresent) { + // If we have pending work still, restore the original updaters + restorePendingUpdaters(root, lanes); + } + } + + wakeable.then(ping, ping); + } } + function pingSuspendedRoot(root, wakeable, pingedLanes) { var pingCache = root.pingCache; - null !== pingCache && pingCache.delete(wakeable); - root.pingedLanes |= root.suspendedLanes & pingedLanes; - executionContext & RenderContext - ? (workInProgressRootDidIncludeRecursiveRenderUpdate = !0) - : executionContext & CommitContext && - (didIncludeCommitPhaseUpdate = !0); - throwIfInfiniteUpdateLoopDetected(); - 0 !== root.tag && - isConcurrentActEnvironment() && - null === ReactSharedInternals.actQueue && - error$jscomp$0( - "A suspended resource finished loading inside a test, but the event was not wrapped in act(...).\n\nWhen testing, code that resolves suspended data should be wrapped into act(...):\n\nact(() => {\n /* finish loading suspended data */\n});\n/* assert on the output */\n\nThis ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act" - ); - workInProgressRoot === root && - (workInProgressRootRenderLanes & pingedLanes) === pingedLanes && - (workInProgressRootExitStatus === RootSuspendedWithDelay || - (workInProgressRootExitStatus === RootSuspended && - (workInProgressRootRenderLanes & RetryLanes) === - workInProgressRootRenderLanes && - now$1() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) - ? (executionContext & RenderContext) === NoContext && - prepareFreshStack(root, 0) - : (workInProgressRootPingedLanes |= pingedLanes)); + + if (pingCache !== null) { + // The wakeable resolved, so we no longer need to memoize, because it will + // never be thrown again. + pingCache.delete(wakeable); + } + + markRootPinged(root, pingedLanes); + warnIfSuspenseResolutionNotWrappedWithActDEV(root); + + if ( + workInProgressRoot === root && + isSubsetOfLanes(workInProgressRootRenderLanes, pingedLanes) + ) { + // Received a ping at the same priority level at which we're currently + // rendering. We might want to restart this render. This should mirror + // the logic of whether or not a root suspends once it completes. + // TODO: If we're rendering sync either due to Sync, Batched or expired, + // we should probably never restart. + // If we're suspended with delay, or if it's a retry, we'll always suspend + // so we can always restart. + if ( + workInProgressRootExitStatus === RootSuspendedWithDelay || + (workInProgressRootExitStatus === RootSuspended && + includesOnlyRetries(workInProgressRootRenderLanes) && + now$1() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) + ) { + // Force a restart from the root by unwinding the stack. Unless this is + // being called from the render phase, because that would cause a crash. + if ((executionContext & RenderContext) === NoContext) { + prepareFreshStack(root, NoLanes); + } + } else { + // Even though we can't restart right now, we might get an + // opportunity later. So we mark this render as having a ping. + workInProgressRootPingedLanes = mergeLanes( + workInProgressRootPingedLanes, + pingedLanes + ); + } + } + ensureRootIsScheduled(root); } + function retryTimedOutBoundary(boundaryFiber, retryLane) { - 0 === retryLane && - (retryLane = - 0 === (boundaryFiber.mode & 1) ? SyncLane : claimNextRetryLane()); - boundaryFiber = enqueueConcurrentRenderForLane(boundaryFiber, retryLane); - null !== boundaryFiber && - (markRootUpdated(boundaryFiber, retryLane), - ensureRootIsScheduled(boundaryFiber)); + // The boundary fiber (a Suspense component or SuspenseList component) + // previously was rendered in its fallback state. One of the promises that + // suspended it has resolved, which means at least part of the tree was + // likely unblocked. Try rendering again, at a new lanes. + if (retryLane === NoLane) { + // TODO: Assign this to `suspenseState.retryLane`? to avoid + // unnecessary entanglement? + retryLane = requestRetryLane(boundaryFiber); + } // TODO: Special case idle priority? + + var root = enqueueConcurrentRenderForLane(boundaryFiber, retryLane); + + if (root !== null) { + markRootUpdated(root, retryLane); + ensureRootIsScheduled(root); + } } + function retryDehydratedSuspenseBoundary(boundaryFiber) { - var suspenseState = boundaryFiber.memoizedState, - retryLane = 0; - null !== suspenseState && (retryLane = suspenseState.retryLane); + var suspenseState = boundaryFiber.memoizedState; + var retryLane = NoLane; + + if (suspenseState !== null) { + retryLane = suspenseState.retryLane; + } + retryTimedOutBoundary(boundaryFiber, retryLane); } function resolveRetryWakeable(boundaryFiber, wakeable) { - var retryLane = 0; + var retryLane = NoLane; // Default + + var retryCache; + switch (boundaryFiber.tag) { - case 13: - var retryCache = boundaryFiber.stateNode; + case SuspenseComponent: + retryCache = boundaryFiber.stateNode; var suspenseState = boundaryFiber.memoizedState; - null !== suspenseState && (retryLane = suspenseState.retryLane); + + if (suspenseState !== null) { + retryLane = suspenseState.retryLane; + } + break; - case 19: + + case SuspenseListComponent: retryCache = boundaryFiber.stateNode; break; - case 22: - retryCache = boundaryFiber.stateNode._retryCache; + + case OffscreenComponent: { + var instance = boundaryFiber.stateNode; + retryCache = instance._retryCache; break; + } + default: - throw Error( - "Pinged unknown suspense boundary type. This is probably a bug in React." + throw new Error( + "Pinged unknown suspense boundary type. " + + "This is probably a bug in React." ); } - null !== retryCache && retryCache.delete(wakeable); + + if (retryCache !== null) { + // The wakeable resolved, so we no longer need to memoize, because it will + // never be thrown again. + retryCache.delete(wakeable); + } + retryTimedOutBoundary(boundaryFiber, retryLane); } function throwIfInfiniteUpdateLoopDetected() { - if (nestedUpdateCount > NESTED_UPDATE_LIMIT) - throw ( - ((nestedPassiveUpdateCount = nestedUpdateCount = 0), - (rootWithPassiveNestedUpdates = rootWithNestedUpdates = null), - executionContext & RenderContext && - null !== workInProgressRoot && - (workInProgressRoot.errorRecoveryDisabledLanes |= - workInProgressRootRenderLanes), - Error( - "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." - )) + if (nestedUpdateCount > NESTED_UPDATE_LIMIT) { + nestedUpdateCount = 0; + nestedPassiveUpdateCount = 0; + rootWithNestedUpdates = null; + rootWithPassiveNestedUpdates = null; + + throw new Error( + "Maximum update depth exceeded. This can happen when a component " + + "repeatedly calls setState inside componentWillUpdate or " + + "componentDidUpdate. React limits the number of nested updates to " + + "prevent infinite loops." ); - nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT && - ((nestedPassiveUpdateCount = 0), - (rootWithPassiveNestedUpdates = null), - error$jscomp$0( - "Maximum update depth exceeded. This can happen when a component calls setState inside useEffect, but useEffect either doesn't have a dependency array, or one of the dependencies changes on every render." - )); - } - function recursivelyTraverseAndDoubleInvokeEffectsInDEV( - root$jscomp$0, - parentFiber, - isInStrictMode - ) { - if (0 !== (parentFiber.subtreeFlags & 33562624)) - for (parentFiber = parentFiber.child; null !== parentFiber; ) { - var root = root$jscomp$0, - fiber = parentFiber, - isStrictModeFiber = fiber.type === REACT_STRICT_MODE_TYPE; - isStrictModeFiber = isInStrictMode || isStrictModeFiber; - 22 !== fiber.tag - ? fiber.flags & 33554432 - ? isStrictModeFiber && - runWithFiberInDEV( - fiber, - doubleInvokeEffectsOnFiber, - root, - fiber, - 0 === (fiber.mode & 64) - ) - : recursivelyTraverseAndDoubleInvokeEffectsInDEV( - root, - fiber, - isStrictModeFiber - ) - : null === fiber.memoizedState && - (isStrictModeFiber && fiber.flags & 8192 - ? runWithFiberInDEV( - fiber, - doubleInvokeEffectsOnFiber, - root, - fiber - ) - : fiber.subtreeFlags & 33554432 && - runWithFiberInDEV( - fiber, - recursivelyTraverseAndDoubleInvokeEffectsInDEV, - root, - fiber, - isStrictModeFiber - )); - parentFiber = parentFiber.sibling; - } - } - function doubleInvokeEffectsOnFiber(root, fiber) { - var shouldDoubleInvokePassiveEffects = - 2 < arguments.length && void 0 !== arguments[2] ? arguments[2] : !0; - setIsStrictModeForDevtools(!0); - disappearLayoutEffects(fiber); - shouldDoubleInvokePassiveEffects && disconnectPassiveEffect(fiber); - reappearLayoutEffects(root, fiber.alternate, fiber, !1); - shouldDoubleInvokePassiveEffects && - reconnectPassiveEffects(root, fiber, 0, null, !1); - setIsStrictModeForDevtools(!1); - } - function commitDoubleInvokeEffectsInDEV(root, hasPassiveEffects) { - 0 !== root.tag - ? ((hasPassiveEffects = !0), - 1 !== root.tag || root.current.mode & 24 || (hasPassiveEffects = !1), - recursivelyTraverseAndDoubleInvokeEffectsInDEV( - root, - root.current, - hasPassiveEffects - )) - : runWithFiberInDEV( - root.current, - legacyCommitDoubleInvokeEffectsInDEV, - root.current, - hasPassiveEffects + } + + { + if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) { + nestedPassiveUpdateCount = 0; + rootWithPassiveNestedUpdates = null; + + error( + "Maximum update depth exceeded. This can happen when a component " + + "calls setState inside useEffect, but useEffect either doesn't " + + "have a dependency array, or one of the dependencies changes on " + + "every render." ); + } + } + } + + function flushRenderPhaseStrictModeWarningsInDEV() { + { + ReactStrictModeWarnings.flushLegacyContextWarning(); + ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings(); + } + } + + function commitDoubleInvokeEffectsInDEV(root, hasPassiveEffects) { + { + { + legacyCommitDoubleInvokeEffectsInDEV(root.current, hasPassiveEffects); + } + } } + function legacyCommitDoubleInvokeEffectsInDEV(fiber, hasPassiveEffects) { - invokeEffectsInDev(fiber, 67108864, invokeLayoutEffectUnmountInDEV); - hasPassiveEffects && - invokeEffectsInDev(fiber, 134217728, invokePassiveEffectUnmountInDEV); - invokeEffectsInDev(fiber, 67108864, invokeLayoutEffectMountInDEV); - hasPassiveEffects && - invokeEffectsInDev(fiber, 134217728, invokePassiveEffectMountInDEV); + // 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) { - for (var subtreeRoot = null; null != firstChild; ) { - var primarySubtreeFlag = firstChild.subtreeFlags & fiberFlags; - firstChild !== subtreeRoot && - null != firstChild.child && - 0 !== primarySubtreeFlag - ? (firstChild = firstChild.child) - : (0 !== (firstChild.flags & fiberFlags) && - invokeEffectFn(firstChild), - (firstChild = - null !== firstChild.sibling - ? firstChild.sibling - : (subtreeRoot = firstChild.return))); + var current = firstChild; + var subtreeRoot = null; + + while (current != null) { + var primarySubtreeFlag = current.subtreeFlags & fiberFlags; + + if ( + current !== subtreeRoot && + current.child != null && + primarySubtreeFlag !== NoFlags$1 + ) { + current = current.child; + } else { + if ((current.flags & fiberFlags) !== NoFlags$1) { + invokeEffectFn(current); + } + + if (current.sibling !== null) { + current = current.sibling; + } else { + current = subtreeRoot = current.return; + } + } } } + + var didWarnStateUpdateForNotYetMountedComponent = null; function warnAboutUpdateOnNotYetMountedFiberInDEV(fiber) { - if ((executionContext & RenderContext) === NoContext && fiber.mode & 1) { + { + if ((executionContext & RenderContext) !== NoContext) { + // We let the other warning about render phase updates deal with this one. + return; + } + + if (!(fiber.mode & ConcurrentMode)) { + return; + } + var tag = fiber.tag; + if ( - 3 === tag || - 1 === tag || - 0 === tag || - 11 === tag || - 14 === tag || - 15 === tag + tag !== IndeterminateComponent && + tag !== HostRoot && + tag !== ClassComponent && + tag !== FunctionComponent && + tag !== ForwardRef && + tag !== MemoComponent && + tag !== SimpleMemoComponent ) { - tag = getComponentNameFromFiber(fiber) || "ReactComponent"; - if (null !== didWarnStateUpdateForNotYetMountedComponent) { - if (didWarnStateUpdateForNotYetMountedComponent.has(tag)) return; - didWarnStateUpdateForNotYetMountedComponent.add(tag); - } else didWarnStateUpdateForNotYetMountedComponent = new Set([tag]); - runWithFiberInDEV(fiber, function () { - error$jscomp$0( - "Can't perform a React state update on a component that hasn't mounted yet. This indicates that you have a side-effect in your render function that asynchronously later calls tries to update the component. Move this work to useEffect instead." - ); - }); + // Only warn for user-defined components, not internal ones like Suspense. + return; + } // 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 = + getComponentNameFromFiber(fiber) || "ReactComponent"; + + if (didWarnStateUpdateForNotYetMountedComponent !== null) { + if (didWarnStateUpdateForNotYetMountedComponent.has(componentName)) { + return; + } // $FlowFixMe[incompatible-use] found when upgrading Flow + + didWarnStateUpdateForNotYetMountedComponent.add(componentName); + } else { + didWarnStateUpdateForNotYetMountedComponent = new Set([ + componentName + ]); + } + + var previousFiber = current; + + try { + setCurrentFiber(fiber); + + error( + "Can't perform a React state update on a component that hasn't mounted yet. " + + "This indicates that you have a side-effect in your render function that " + + "asynchronously later calls tries to update the component. Move this work to " + + "useEffect instead." + ); + } finally { + if (previousFiber) { + setCurrentFiber(fiber); + } else { + resetCurrentFiber(); + } + } + } + } + var didWarnAboutUpdateInRender = false; + var didWarnAboutUpdateInRenderForAnotherComponent; + + { + didWarnAboutUpdateInRenderForAnotherComponent = new Set(); + } + + function warnAboutRenderPhaseUpdatesInDEV(fiber) { + { + if (isRendering) { + switch (fiber.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + var renderingComponentName = + (workInProgress && getComponentNameFromFiber(workInProgress)) || + "Unknown"; // Dedupe by the rendering component because it's the one that needs to be fixed. + + var dedupeKey = renderingComponentName; + + if ( + !didWarnAboutUpdateInRenderForAnotherComponent.has(dedupeKey) + ) { + didWarnAboutUpdateInRenderForAnotherComponent.add(dedupeKey); + var setStateComponentName = + getComponentNameFromFiber(fiber) || "Unknown"; + + error( + "Cannot update a component (`%s`) while rendering a " + + "different component (`%s`). To locate the bad setState() call inside `%s`, " + + "follow the stack trace as described in https://react.dev/link/setstate-in-render", + setStateComponentName, + renderingComponentName, + renderingComponentName + ); + } + + break; + } + + case ClassComponent: { + if (!didWarnAboutUpdateInRender) { + error( + "Cannot update during an existing state transition (such as " + + "within `render`). Render methods should be a pure " + + "function of props and state." + ); + + didWarnAboutUpdateInRender = true; + } + + break; + } + } } } } + function restorePendingUpdaters(root, lanes) { - isDevToolsPresent && - root.memoizedUpdaters.forEach(function (schedulingFiber) { - addFiberToLanesMap(root, schedulingFiber, lanes); - }); + { + if (isDevToolsPresent) { + var memoizedUpdaters = root.memoizedUpdaters; + memoizedUpdaters.forEach(function (schedulingFiber) { + addFiberToLanesMap(root, schedulingFiber, lanes); + }); // This function intentionally does not clear memoized updaters. + // Those may still be relevant to the current commit + // and a future one (e.g. Suspense). + } + } } + var fakeActCallbackNode = {}; // $FlowFixMe[missing-local-annot] + function scheduleCallback(priorityLevel, callback) { - var actQueue = ReactSharedInternals.actQueue; - return null !== actQueue - ? (actQueue.push(callback), fakeActCallbackNode) - : scheduleCallback$3(priorityLevel, callback); + { + // If we're currently inside an `act` scope, bypass Scheduler and push to + // the `act` queue instead. + var actQueue = ReactCurrentActQueue.current; + + if (actQueue !== null) { + actQueue.push(callback); + return fakeActCallbackNode; + } else { + return scheduleCallback$2(priorityLevel, callback); + } + } + } + + function shouldForceFlushFallbacksInDEV() { + // Never force flush in production. This function should get stripped out. + return ReactCurrentActQueue.current !== null; } + function warnIfUpdatesNotWrappedWithActDEV(fiber) { - fiber.mode & 1 - ? isConcurrentActEnvironment() && - null === ReactSharedInternals.actQueue && - runWithFiberInDEV(fiber, function () { - error$jscomp$0( - "An update to %s inside a test was not wrapped in act(...).\n\nWhen testing, code that causes React state updates should be wrapped into act(...):\n\nact(() => {\n /* fire events that update state */\n});\n/* assert on the output */\n\nThis ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act", + { + if (fiber.mode & ConcurrentMode) { + if (!isConcurrentActEnvironment()) { + // Not in an act environment. No need to warn. + return; + } + } else { + // Legacy mode has additional cases where we suppress a warning. + if (!isLegacyActEnvironment()) { + // Not in an act environment. No need to warn. + return; + } + + if (executionContext !== NoContext) { + // Legacy mode doesn't warn if the update is batched, i.e. + // batchedUpdates or flushSync. + return; + } + + if ( + fiber.tag !== FunctionComponent && + fiber.tag !== ForwardRef && + fiber.tag !== SimpleMemoComponent + ) { + // For backwards compatibility with pre-hooks code, legacy mode only + // warns for updates that originate from a hook. + return; + } + } + + if (ReactCurrentActQueue.current === null) { + var previousFiber = current; + + try { + setCurrentFiber(fiber); + + error( + "An update to %s inside a test was not wrapped in act(...).\n\n" + + "When testing, code that causes React state updates should be " + + "wrapped into act(...):\n\n" + + "act(() => {\n" + + " /* fire events that update state */\n" + + "});\n" + + "/* assert on the output */\n\n" + + "This ensures that you're testing the behavior the user would see " + + "in the browser." + + " Learn more at https://react.dev/link/wrap-tests-with-act", getComponentNameFromFiber(fiber) ); - }) - : "undefined" !== typeof IS_REACT_ACT_ENVIRONMENT - ? IS_REACT_ACT_ENVIRONMENT - : void 0; + } finally { + if (previousFiber) { + setCurrentFiber(fiber); + } else { + resetCurrentFiber(); + } + } + } + } + } + + function warnIfSuspenseResolutionNotWrappedWithActDEV(root) { + { + if ( + root.tag !== LegacyRoot && + isConcurrentActEnvironment() && + ReactCurrentActQueue.current === null + ) { + error( + "A suspended resource finished loading inside a test, but the event " + + "was not wrapped in act(...).\n\n" + + "When testing, code that resolves suspended data should be wrapped " + + "into act(...):\n\n" + + "act(() => {\n" + + " /* finish loading suspended data */\n" + + "});\n" + + "/* assert on the output */\n\n" + + "This ensures that you're testing the behavior the user would see " + + "in the browser." + + " Learn more at https://react.dev/link/wrap-tests-with-act" + ); + } + } } + + function setIsRunningInsertionEffect(isRunning) { + { + isRunningInsertionEffect = isRunning; + } + } + + /* eslint-disable react-internal/prod-error-codes */ + // Used by React Refresh runtime through DevTools Global Hook. + + var resolveFamily = null; + var failedBoundaries = null; + var setRefreshHandler = function (handler) { + { + resolveFamily = handler; + } + }; function resolveFunctionForHotReloading(type) { - if (null === resolveFamily) return type; - var family = resolveFamily(type); - return void 0 === family ? type : family.current; + { + if (resolveFamily === null) { + // Hot reloading is disabled. + return type; + } + + var family = resolveFamily(type); + + if (family === undefined) { + return type; + } // Use the latest known implementation. + + return family.current; + } + } + function resolveClassForHotReloading(type) { + // No implementation differences. + return resolveFunctionForHotReloading(type); } function resolveForwardRefForHotReloading(type) { - if (null === resolveFamily) return type; - var family = resolveFamily(type); - return void 0 === family - ? null !== type && - void 0 !== type && - "function" === typeof type.render && - ((family = resolveFunctionForHotReloading(type.render)), - type.render !== family) - ? ((family = { $$typeof: REACT_FORWARD_REF_TYPE, render: family }), - void 0 !== type.displayName && - (family.displayName = type.displayName), - family) - : type - : family.current; + { + if (resolveFamily === null) { + // Hot reloading is disabled. + return type; + } + + var family = resolveFamily(type); + + if (family === undefined) { + // Check if we're dealing with a real forwardRef. Don't want to crash early. + if ( + type !== null && + type !== undefined && + typeof type.render === "function" + ) { + // ForwardRef is special because its resolved .type is an object, + // but it's possible that we only have its inner render function in the map. + // If that inner render function is different, we'll build a new forwardRef type. + var currentRender = resolveFunctionForHotReloading(type.render); + + if (type.render !== currentRender) { + var syntheticType = { + $$typeof: REACT_FORWARD_REF_TYPE, + render: currentRender + }; + + if (type.displayName !== undefined) { + syntheticType.displayName = type.displayName; + } + + return syntheticType; + } + } + + return type; + } // Use the latest known implementation. + + return family.current; + } } function isCompatibleFamilyForHotReloading(fiber, element) { - if (null === resolveFamily) return !1; - var prevType = fiber.elementType; - element = element.type; - var needsCompareFamilies = !1, - $$typeofNextType = - "object" === typeof element && null !== element - ? element.$$typeof + { + if (resolveFamily === null) { + // Hot reloading is disabled. + return false; + } + + var prevType = fiber.elementType; + var nextType = element.type; // If we got here, we know types aren't === equal. + + var needsCompareFamilies = false; + var $$typeofNextType = + typeof nextType === "object" && nextType !== null + ? nextType.$$typeof : null; - switch (fiber.tag) { - case 1: - "function" === typeof element && (needsCompareFamilies = !0); - break; - case 0: - "function" === typeof element - ? (needsCompareFamilies = !0) - : $$typeofNextType === REACT_LAZY_TYPE && - (needsCompareFamilies = !0); - break; - case 11: - $$typeofNextType === REACT_FORWARD_REF_TYPE - ? (needsCompareFamilies = !0) - : $$typeofNextType === REACT_LAZY_TYPE && - (needsCompareFamilies = !0); - break; - case 14: - case 15: - $$typeofNextType === REACT_MEMO_TYPE - ? (needsCompareFamilies = !0) - : $$typeofNextType === REACT_LAZY_TYPE && - (needsCompareFamilies = !0); - break; - default: - return !1; + + switch (fiber.tag) { + case ClassComponent: { + if (typeof nextType === "function") { + needsCompareFamilies = true; + } + + break; + } + + case FunctionComponent: { + if (typeof nextType === "function") { + needsCompareFamilies = true; + } else if ($$typeofNextType === REACT_LAZY_TYPE) { + // We don't know the inner type yet. + // We're going to assume that the lazy inner type is stable, + // and so it is sufficient to avoid reconciling it away. + // We're not going to unwrap or actually use the new lazy type. + needsCompareFamilies = true; + } + + break; + } + + case ForwardRef: { + if ($$typeofNextType === REACT_FORWARD_REF_TYPE) { + needsCompareFamilies = true; + } else if ($$typeofNextType === REACT_LAZY_TYPE) { + needsCompareFamilies = true; + } + + break; + } + + case MemoComponent: + case SimpleMemoComponent: { + if ($$typeofNextType === REACT_MEMO_TYPE) { + // TODO: if it was but can no longer be simple, + // we shouldn't set this. + needsCompareFamilies = true; + } else if ($$typeofNextType === REACT_LAZY_TYPE) { + needsCompareFamilies = true; + } + + break; + } + + default: + return false; + } // Check if both types have a family and it's the same one. + + if (needsCompareFamilies) { + // Note: memo() and forwardRef() we'll compare outer rather than inner type. + // This means both of them need to be registered to preserve state. + // If we unwrapped and compared the inner types for wrappers instead, + // then we would risk falsely saying two separate memo(Foo) + // calls are equivalent because they wrap the same Foo function. + var prevFamily = resolveFamily(prevType); // $FlowFixMe[not-a-function] found when upgrading Flow + + if ( + prevFamily !== undefined && + prevFamily === resolveFamily(nextType) + ) { + return true; + } + } + + return false; } - return needsCompareFamilies && - ((fiber = resolveFamily(prevType)), - void 0 !== fiber && fiber === resolveFamily(element)) - ? !0 - : !1; } function markFailedErrorBoundaryForHotReloading(fiber) { - null !== resolveFamily && - "function" === typeof WeakSet && - (null === failedBoundaries && (failedBoundaries = new WeakSet()), - failedBoundaries.add(fiber)); + { + if (resolveFamily === null) { + // Hot reloading is disabled. + return; + } + + if (typeof WeakSet !== "function") { + return; + } + + if (failedBoundaries === null) { + failedBoundaries = new WeakSet(); + } + + failedBoundaries.add(fiber); + } } + var scheduleRefresh = function (root, update) { + { + if (resolveFamily === null) { + // Hot reloading is disabled. + return; + } + + var staleFamilies = update.staleFamilies, + updatedFamilies = update.updatedFamilies; + flushPassiveEffects(); + flushSync(function () { + scheduleFibersWithFamiliesRecursively( + root.current, + updatedFamilies, + staleFamilies + ); + }); + } + }; + var scheduleRoot = function (root, element) { + { + if (root.context !== emptyContextObject) { + // Super edge case: root has a legacy _renderSubtree context + // but we don't know the parentComponent so we can't pass it. + // Just ignore. We'll delete this with _renderSubtree code path later. + return; + } + + flushPassiveEffects(); + flushSync(function () { + updateContainer(element, root, null, null); + }); + } + }; + function scheduleFibersWithFamiliesRecursively( fiber, updatedFamilies, staleFamilies ) { - var alternate = fiber.alternate, - child = fiber.child, - sibling = fiber.sibling, - tag = fiber.tag, - type = fiber.type, - candidateType = null; - switch (tag) { - case 0: - case 15: - case 1: - candidateType = type; - break; - case 11: - candidateType = type.render; - } - if (null === resolveFamily) - throw Error("Expected resolveFamily to be set during hot reload."); - var needsRender = !1; - type = !1; - null !== candidateType && - ((candidateType = resolveFamily(candidateType)), - void 0 !== candidateType && - (staleFamilies.has(candidateType) - ? (type = !0) - : updatedFamilies.has(candidateType) && - (1 === tag ? (type = !0) : (needsRender = !0)))); - null !== failedBoundaries && - (failedBoundaries.has(fiber) || - (null !== alternate && failedBoundaries.has(alternate))) && - (type = !0); - type && (fiber._debugNeedsRemount = !0); - if (type || needsRender) - (alternate = enqueueConcurrentRenderForLane(fiber, SyncLane)), - null !== alternate && - scheduleUpdateOnFiber(alternate, fiber, SyncLane); - null === child || - type || - scheduleFibersWithFamiliesRecursively( - child, - updatedFamilies, - staleFamilies + { + var alternate = fiber.alternate, + child = fiber.child, + sibling = fiber.sibling, + tag = fiber.tag, + type = fiber.type; + var candidateType = null; + + switch (tag) { + case FunctionComponent: + case SimpleMemoComponent: + case ClassComponent: + candidateType = type; + break; + + case ForwardRef: + candidateType = type.render; + break; + } + + if (resolveFamily === null) { + throw new Error( + "Expected resolveFamily to be set during hot reload." + ); + } + + var needsRender = false; + var needsRemount = false; + + if (candidateType !== null) { + var family = resolveFamily(candidateType); + + if (family !== undefined) { + if (staleFamilies.has(family)) { + needsRemount = true; + } else if (updatedFamilies.has(family)) { + if (tag === ClassComponent) { + needsRemount = true; + } else { + needsRender = true; + } + } + } + } + + if (failedBoundaries !== null) { + if ( + failedBoundaries.has(fiber) || // $FlowFixMe[incompatible-use] found when upgrading Flow + (alternate !== null && failedBoundaries.has(alternate)) + ) { + needsRemount = true; + } + } + + if (needsRemount) { + fiber._debugNeedsRemount = true; + } + + if (needsRemount || needsRender) { + var root = enqueueConcurrentRenderForLane(fiber, SyncLane); + + if (root !== null) { + scheduleUpdateOnFiber(root, fiber, SyncLane); + } + } + + if (child !== null && !needsRemount) { + scheduleFibersWithFamiliesRecursively( + child, + updatedFamilies, + staleFamilies + ); + } + + if (sibling !== null) { + scheduleFibersWithFamiliesRecursively( + sibling, + updatedFamilies, + staleFamilies + ); + } + } + } + + var findHostInstancesForRefresh = function (root, families) { + { + var hostInstances = new Set(); + var types = new Set( + families.map(function (family) { + return family.current; + }) ); - null !== sibling && - scheduleFibersWithFamiliesRecursively( - sibling, - updatedFamilies, - staleFamilies + findHostInstancesForMatchingFibersRecursively( + root.current, + types, + hostInstances ); - } + return hostInstances; + } + }; + function findHostInstancesForMatchingFibersRecursively( fiber, types, hostInstances ) { - var child = fiber.child, - sibling = fiber.sibling, - type = fiber.type, - candidateType = null; - switch (fiber.tag) { - case 0: - case 15: - case 1: - candidateType = type; - break; - case 11: - candidateType = type.render; - } - type = !1; - null !== candidateType && types.has(candidateType) && (type = !0); - if (type) - a: { - b: for (child = fiber, candidateType = !1; ; ) { - if (5 === child.tag || 26 === child.tag) - (candidateType = !0), hostInstances.add(child.stateNode); - else if (null !== child.child) { - child.child.return = child; - child = child.child; - continue; - } - if (child === fiber) { - child = candidateType; - break b; - } - for (; null === child.sibling; ) { - if (null === child.return || child.return === fiber) { - child = candidateType; - break b; - } - child = child.return; - } - child.sibling.return = child.return; - child = child.sibling; + { + var child = fiber.child, + sibling = fiber.sibling, + tag = fiber.tag, + type = fiber.type; + var candidateType = null; + + switch (tag) { + case FunctionComponent: + case SimpleMemoComponent: + case ClassComponent: + candidateType = type; + break; + + case ForwardRef: + candidateType = type.render; + break; + } + + var didMatch = false; + + if (candidateType !== null) { + if (types.has(candidateType)) { + didMatch = true; + } + } + + if (didMatch) { + // We have a match. This only drills down to the closest host components. + // There's no need to search deeper because for the purpose of giving + // visual feedback, "flashing" outermost parent rectangles is sufficient. + findHostInstancesForFiberShallowly(fiber, hostInstances); + } else { + // If there's no match, maybe there will be one further down in the child tree. + if (child !== null) { + findHostInstancesForMatchingFibersRecursively( + child, + types, + hostInstances + ); } - if (!child) - for (;;) { - switch (fiber.tag) { - case 27: - case 5: - hostInstances.add(fiber.stateNode); - break a; - case 4: - hostInstances.add(fiber.stateNode.containerInfo); - break a; - case 3: - hostInstances.add(fiber.stateNode.containerInfo); - break a; - } - if (null === fiber.return) - throw Error("Expected to reach root first."); - fiber = fiber.return; - } } - else - null !== child && + + if (sibling !== null) { findHostInstancesForMatchingFibersRecursively( - child, + sibling, types, hostInstances ); - null !== sibling && - findHostInstancesForMatchingFibersRecursively( - sibling, - types, + } + } + } + + function findHostInstancesForFiberShallowly(fiber, hostInstances) { + { + var foundHostInstances = findChildHostInstancesForFiberShallowly( + fiber, hostInstances ); + + if (foundHostInstances) { + return; + } // If we didn't find any host children, fallback to closest host parent. + + var node = fiber; + + while (true) { + switch (node.tag) { + case HostSingleton: + case HostComponent: + hostInstances.add(node.stateNode); + return; + + case HostPortal: + hostInstances.add(node.stateNode.containerInfo); + return; + + case HostRoot: + hostInstances.add(node.stateNode.containerInfo); + return; + } + + if (node.return === null) { + throw new Error("Expected to reach root first."); + } + + node = node.return; + } + } + } + + function findChildHostInstancesForFiberShallowly(fiber, hostInstances) { + { + var node = fiber; + var foundHostInstances = false; + + while (true) { + if ( + node.tag === HostComponent || + node.tag === HostHoistable || + false + ) { + // We got a match. + foundHostInstances = true; + hostInstances.add(node.stateNode); // There may still be more, so keep searching. + } else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; + } + + if (node === fiber) { + return foundHostInstances; + } + + while (node.sibling === null) { + if (node.return === null || node.return === fiber) { + return foundHostInstances; + } + + node = node.return; + } + + node.sibling.return = node.return; + node = node.sibling; + } + } + + return false; + } + + var hasBadMapPolyfill; + + { + hasBadMapPolyfill = false; + + try { + var nonExtensibleObject = Object.preventExtensions({}); + /* eslint-disable no-new */ + + new Map([[nonExtensibleObject, null]]); + new Set([nonExtensibleObject]); + /* eslint-enable no-new */ + } catch (e) { + // TODO: Consider warning about bad polyfills + hasBadMapPolyfill = true; + } } + function FiberNode(tag, pendingProps, key, mode) { + // Instance this.tag = tag; this.key = key; - this.sibling = - this.child = - this.return = - this.stateNode = - this.type = - this.elementType = - null; + this.elementType = null; + this.type = null; + this.stateNode = null; // Fiber + + this.return = null; + this.child = null; + this.sibling = null; this.index = 0; - this.refCleanup = this.ref = null; + this.ref = null; + this.refCleanup = null; this.pendingProps = pendingProps; - this.dependencies = - this.memoizedState = - this.updateQueue = - this.memoizedProps = - null; - this.mode = mode; - this.subtreeFlags = this.flags = 0; + this.memoizedProps = null; + this.updateQueue = null; + this.memoizedState = null; + this.dependencies = null; + this.mode = mode; // Effects + + this.flags = NoFlags$1; + this.subtreeFlags = NoFlags$1; this.deletions = null; - this.childLanes = this.lanes = 0; + this.lanes = NoLanes; + this.childLanes = NoLanes; this.alternate = null; - this.actualDuration = 0; - this.actualStartTime = -1; - this.treeBaseDuration = this.selfBaseDuration = 0; - this._debugTask = - this._debugStack = - this._debugOwner = - this._debugInfo = - null; - this._debugNeedsRemount = !1; - this._debugHookTypes = null; - hasBadMapPolyfill || - "function" !== typeof Object.preventExtensions || - Object.preventExtensions(this); - } + + { + // Note: The following is done to avoid a v8 performance cliff. + // + // Initializing the fields below to smis and later updating them with + // double values will cause Fibers to end up having separate shapes. + // This behavior/bug has something to do with Object.preventExtension(). + // Fortunately this only impacts DEV builds. + // Unfortunately it makes React unusably slow for some applications. + // To work around this, initialize the fields below with doubles. + // + // Learn more about this here: + // https://github.com/facebook/react/issues/14365 + // https://bugs.chromium.org/p/v8/issues/detail?id=8538 + this.actualDuration = Number.NaN; + this.actualStartTime = Number.NaN; + this.selfBaseDuration = Number.NaN; + this.treeBaseDuration = Number.NaN; // It's okay to replace the initial doubles with smis after initialization. + // This won't trigger the performance cliff mentioned above, + // and it simplifies other profiler code (including DevTools). + + this.actualDuration = 0; + this.actualStartTime = -1; + this.selfBaseDuration = 0; + this.treeBaseDuration = 0; + } + + { + // This isn't directly used but is handy for debugging internals: + this._debugInfo = null; + this._debugOwner = null; + this._debugNeedsRemount = false; + this._debugHookTypes = null; + + if ( + !hasBadMapPolyfill && + typeof Object.preventExtensions === "function" + ) { + Object.preventExtensions(this); + } + } + } // This is a constructor function, rather than a POJO constructor, still + // please ensure we do the following: + // 1) Nobody should add any instance methods on this. Instance methods can be + // more difficult to predict when they get optimized and they are almost + // never inlined properly in static compilers. + // 2) Nobody should rely on `instanceof Fiber` for type testing. We should + // always know when it is a fiber. + // 3) We might want to experiment with using numeric keys since they are easier + // to optimize in a non-JIT environment. + // 4) We can easily go from a constructor to a createFiber object literal if that + // is faster. + // 5) It should be easy to port this to a C struct and keep a C implementation + // compatible. + function createFiber(tag, pendingProps, key, mode) { + // $FlowFixMe[invalid-constructor]: the shapes are exact here but Flow doesn't like constructors return new FiberNode(tag, pendingProps, key, mode); } + function shouldConstruct(Component) { - Component = Component.prototype; - return !(!Component || !Component.isReactComponent); + var prototype = Component.prototype; + return !!(prototype && prototype.isReactComponent); + } + + function isSimpleFunctionComponent(type) { + return ( + typeof type === "function" && + !shouldConstruct(type) && + type.defaultProps === undefined + ); } + function resolveLazyComponentTag(Component) { + if (typeof Component === "function") { + return shouldConstruct(Component) ? ClassComponent : FunctionComponent; + } else if (Component !== undefined && Component !== null) { + var $$typeof = Component.$$typeof; + + if ($$typeof === REACT_FORWARD_REF_TYPE) { + return ForwardRef; + } + + if ($$typeof === REACT_MEMO_TYPE) { + return MemoComponent; + } + } + + return IndeterminateComponent; + } // This is used to create an alternate fiber to do work on. + function createWorkInProgress(current, pendingProps) { var workInProgress = current.alternate; - null === workInProgress - ? ((workInProgress = createFiber( - current.tag, - pendingProps, - current.key, - current.mode - )), - (workInProgress.elementType = current.elementType), - (workInProgress.type = current.type), - (workInProgress.stateNode = current.stateNode), - (workInProgress._debugOwner = current._debugOwner), - (workInProgress._debugStack = current._debugStack), - (workInProgress._debugTask = current._debugTask), - (workInProgress._debugHookTypes = current._debugHookTypes), - (workInProgress.alternate = current), - (current.alternate = workInProgress)) - : ((workInProgress.pendingProps = pendingProps), - (workInProgress.type = current.type), - (workInProgress.flags = 0), - (workInProgress.subtreeFlags = 0), - (workInProgress.deletions = null), - (workInProgress.actualDuration = 0), - (workInProgress.actualStartTime = -1)); - workInProgress.flags = current.flags & 31457280; + + if (workInProgress === null) { + // We use a double buffering pooling technique because we know that we'll + // only ever need at most two versions of a tree. We pool the "other" unused + // node that we're free to reuse. This is lazily created to avoid allocating + // extra objects for things that are never updated. It also allow us to + // reclaim the extra memory if needed. + workInProgress = createFiber( + current.tag, + pendingProps, + current.key, + current.mode + ); + workInProgress.elementType = current.elementType; + workInProgress.type = current.type; + workInProgress.stateNode = current.stateNode; + + { + // DEV-only fields + workInProgress._debugOwner = current._debugOwner; + workInProgress._debugHookTypes = current._debugHookTypes; + } + + workInProgress.alternate = current; + current.alternate = workInProgress; + } else { + workInProgress.pendingProps = pendingProps; // Needed because Blocks store data on type. + + workInProgress.type = current.type; // We already have an alternate. + // Reset the effect tag. + + workInProgress.flags = NoFlags$1; // The effects are no longer valid. + + workInProgress.subtreeFlags = NoFlags$1; + workInProgress.deletions = null; + + { + // We intentionally reset, rather than copy, actualDuration & actualStartTime. + // This prevents time from endlessly accumulating in new commits. + // This has the downside of resetting values for different priority renders, + // But works for yielding (the common case) and should support resuming. + 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; workInProgress.memoizedProps = current.memoizedProps; workInProgress.memoizedState = current.memoizedState; - workInProgress.updateQueue = current.updateQueue; - pendingProps = current.dependencies; + workInProgress.updateQueue = current.updateQueue; // Clone the dependencies object. This is mutated during the render phase, so + // it cannot be shared with the current fiber. + + var currentDependencies = current.dependencies; workInProgress.dependencies = - null === pendingProps + currentDependencies === null ? null : { - lanes: pendingProps.lanes, - firstContext: pendingProps.firstContext - }; + lanes: currentDependencies.lanes, + firstContext: currentDependencies.firstContext + }; // These will be overridden during the parent's reconciliation + workInProgress.sibling = current.sibling; workInProgress.index = current.index; workInProgress.ref = current.ref; workInProgress.refCleanup = current.refCleanup; - workInProgress.selfBaseDuration = current.selfBaseDuration; - workInProgress.treeBaseDuration = current.treeBaseDuration; - workInProgress._debugInfo = current._debugInfo; - workInProgress._debugNeedsRemount = current._debugNeedsRemount; - switch (workInProgress.tag) { - case 0: - case 15: - workInProgress.type = resolveFunctionForHotReloading(current.type); - break; - case 1: - workInProgress.type = resolveFunctionForHotReloading(current.type); - break; - case 11: - workInProgress.type = resolveForwardRefForHotReloading(current.type); + + { + workInProgress.selfBaseDuration = current.selfBaseDuration; + workInProgress.treeBaseDuration = current.treeBaseDuration; + } + + { + workInProgress._debugInfo = current._debugInfo; + workInProgress._debugNeedsRemount = current._debugNeedsRemount; + + switch (workInProgress.tag) { + case IndeterminateComponent: + case FunctionComponent: + case SimpleMemoComponent: + workInProgress.type = resolveFunctionForHotReloading(current.type); + break; + + case ClassComponent: + workInProgress.type = resolveClassForHotReloading(current.type); + break; + + case ForwardRef: + workInProgress.type = resolveForwardRefForHotReloading( + current.type + ); + break; + } } + return workInProgress; - } + } // Used to reuse a Fiber for a second pass. + function resetWorkInProgress(workInProgress, renderLanes) { - workInProgress.flags &= 31457282; + // This resets the Fiber to what createFiber or createWorkInProgress would + // have set the values to before during the first pass. Ideally this wouldn't + // be necessary but unfortunately many code paths reads from the workInProgress + // when they should be reading from current and writing to workInProgress. + // We assume pendingProps, index, key, ref, return are still untouched to + // avoid doing another reconciliation. + // Reset the effect flags but keep any Placement tags, since that's something + // that child fiber is setting, not the reconciliation. + workInProgress.flags &= StaticMask | Placement; // The effects are no longer valid. + var current = workInProgress.alternate; - null === current - ? ((workInProgress.childLanes = 0), - (workInProgress.lanes = renderLanes), - (workInProgress.child = null), - (workInProgress.subtreeFlags = 0), - (workInProgress.memoizedProps = null), - (workInProgress.memoizedState = null), - (workInProgress.updateQueue = null), - (workInProgress.dependencies = null), - (workInProgress.stateNode = null), - (workInProgress.selfBaseDuration = 0), - (workInProgress.treeBaseDuration = 0)) - : ((workInProgress.childLanes = current.childLanes), - (workInProgress.lanes = current.lanes), - (workInProgress.child = current.child), - (workInProgress.subtreeFlags = 0), - (workInProgress.deletions = null), - (workInProgress.memoizedProps = current.memoizedProps), - (workInProgress.memoizedState = current.memoizedState), - (workInProgress.updateQueue = current.updateQueue), - (workInProgress.type = current.type), - (renderLanes = current.dependencies), - (workInProgress.dependencies = - null === renderLanes - ? null - : { - lanes: renderLanes.lanes, - firstContext: renderLanes.firstContext - }), - (workInProgress.selfBaseDuration = current.selfBaseDuration), - (workInProgress.treeBaseDuration = current.treeBaseDuration)); - return workInProgress; - } - function createFiberFromTypeAndProps( - type, - key, - pendingProps, - owner, - mode, - lanes - ) { - var fiberTag = 0, - resolvedType = type; - if ("function" === typeof type) - shouldConstruct(type) && (fiberTag = 1), - (resolvedType = resolveFunctionForHotReloading(resolvedType)); - else if ("string" === typeof type) fiberTag = 5; - else - a: switch (type) { - case REACT_FRAGMENT_TYPE: - return createFiberFromFragment( - pendingProps.children, - mode, - lanes, - key - ); - case REACT_STRICT_MODE_TYPE: - fiberTag = 8; - mode |= 8; - 0 !== (mode & 1) && (mode |= 16); - break; - case REACT_PROFILER_TYPE: - return ( - (owner = mode), - "string" !== typeof pendingProps.id && - error$jscomp$0( - 'Profiler must specify an "id" of type `string` as a prop. Received the type `%s` instead.', - typeof pendingProps.id - ), - (owner = createFiber(12, pendingProps, key, owner | 2)), - (owner.elementType = REACT_PROFILER_TYPE), - (owner.lanes = lanes), - (owner.stateNode = { - effectDuration: 0, - passiveEffectDuration: 0 - }), - owner - ); - case REACT_SUSPENSE_TYPE: - return ( - (owner = createFiber(13, pendingProps, key, mode)), - (owner.elementType = REACT_SUSPENSE_TYPE), - (owner.lanes = lanes), - owner - ); - case REACT_SUSPENSE_LIST_TYPE: - return ( - (owner = createFiber(19, pendingProps, key, mode)), - (owner.elementType = REACT_SUSPENSE_LIST_TYPE), - (owner.lanes = lanes), - owner - ); - case REACT_OFFSCREEN_TYPE: - return createFiberFromOffscreen(pendingProps, mode, lanes, key); - default: - if ("object" === typeof type && null !== type) - switch (type.$$typeof) { - case REACT_PROVIDER_TYPE: - case REACT_CONTEXT_TYPE: - fiberTag = 10; - break a; - case REACT_CONSUMER_TYPE: - fiberTag = 9; - break a; - case REACT_FORWARD_REF_TYPE: - fiberTag = 11; - resolvedType = resolveForwardRefForHotReloading(resolvedType); - break a; - case REACT_MEMO_TYPE: - fiberTag = 14; - break a; - case REACT_LAZY_TYPE: - fiberTag = 16; - resolvedType = null; - break a; - } - lanes = ""; - if ( - void 0 === type || - ("object" === typeof type && - null !== type && - 0 === Object.keys(type).length) - ) - lanes += - " You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports."; - null === type - ? (type = "null") - : isArrayImpl(type) - ? (type = "array") - : void 0 !== type && type.$$typeof === REACT_ELEMENT_TYPE - ? ((type = - "<" + - (getComponentNameFromType(type.type) || "Unknown") + - " />"), - (lanes = - " Did you accidentally export a JSX literal instead of a component?")) - : (type = typeof type); - owner = owner - ? "number" === typeof owner.tag - ? getComponentNameFromFiber(owner) - : "string" === typeof owner.name - ? owner.name - : null - : null; - owner && - (lanes += "\n\nCheck the render method of `" + owner + "`."); - throw Error( - "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + - (type + "." + lanes) - ); + + if (current === null) { + // Reset to createFiber's initial values. + workInProgress.childLanes = NoLanes; + workInProgress.lanes = renderLanes; + workInProgress.child = null; + workInProgress.subtreeFlags = NoFlags$1; + workInProgress.memoizedProps = null; + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; + workInProgress.dependencies = null; + workInProgress.stateNode = null; + + { + // Note: We don't reset the actualTime counts. It's useful to accumulate + // actual time across multiple render passes. + workInProgress.selfBaseDuration = 0; + workInProgress.treeBaseDuration = 0; } - key = createFiber(fiberTag, pendingProps, key, mode); - key.elementType = type; - key.type = resolvedType; - key.lanes = lanes; - key._debugOwner = owner; - return key; - } - function createFiberFromElement(element, mode, lanes) { - mode = createFiberFromTypeAndProps( - element.type, - element.key, - element.props, - element._owner, - mode, - lanes - ); - mode._debugOwner = element._owner; - mode._debugStack = element._debugStack; - mode._debugTask = element._debugTask; - return mode; - } - function createFiberFromFragment(elements, mode, lanes, key) { - elements = createFiber(7, elements, key, mode); - elements.lanes = lanes; - return elements; - } - function createFiberFromOffscreen(pendingProps, mode, lanes, key) { - pendingProps = createFiber(22, pendingProps, key, mode); - pendingProps.elementType = REACT_OFFSCREEN_TYPE; - pendingProps.lanes = lanes; - var primaryChildInstance = { - _visibility: 1, - _pendingVisibility: 1, - _pendingMarkers: null, - _retryCache: null, - _transitions: null, - _current: null, - detach: function () { - var instance = primaryChildInstance, - fiber = instance._current; - if (null === fiber) - throw Error( - "Calling Offscreen.detach before instance handle has been set." - ); - if (0 === (instance._pendingVisibility & 2)) { - var root = enqueueConcurrentRenderForLane(fiber, SyncLane); - null !== root && - ((instance._pendingVisibility |= 2), - scheduleUpdateOnFiber(root, fiber, SyncLane)); - } - }, - attach: function () { - var instance = primaryChildInstance, - fiber = instance._current; - if (null === fiber) - throw Error( - "Calling Offscreen.detach before instance handle has been set." - ); - if (0 !== (instance._pendingVisibility & 2)) { - var root = enqueueConcurrentRenderForLane(fiber, SyncLane); - null !== root && - ((instance._pendingVisibility &= -3), - scheduleUpdateOnFiber(root, fiber, SyncLane)); - } + } else { + // Reset to the cloned values that createWorkInProgress would've. + workInProgress.childLanes = current.childLanes; + workInProgress.lanes = current.lanes; + workInProgress.child = current.child; + workInProgress.subtreeFlags = NoFlags$1; + workInProgress.deletions = null; + workInProgress.memoizedProps = current.memoizedProps; + workInProgress.memoizedState = current.memoizedState; + workInProgress.updateQueue = current.updateQueue; // Needed because Blocks store data on type. + + workInProgress.type = current.type; // Clone the dependencies object. This is mutated during the render phase, so + // it cannot be shared with the current fiber. + + var currentDependencies = current.dependencies; + workInProgress.dependencies = + currentDependencies === null + ? null + : { + lanes: currentDependencies.lanes, + firstContext: currentDependencies.firstContext + }; + + { + // Note: We don't reset the actualTime counts. It's useful to accumulate + // actual time across multiple render passes. + workInProgress.selfBaseDuration = current.selfBaseDuration; + workInProgress.treeBaseDuration = current.treeBaseDuration; } - }; - pendingProps.stateNode = primaryChildInstance; - return pendingProps; - } - function createFiberFromText(content, mode, lanes) { - content = createFiber(6, content, null, mode); - content.lanes = lanes; - return content; - } - function createFiberFromPortal(portal, mode, lanes) { - mode = createFiber( - 4, - null !== portal.children ? portal.children : [], - portal.key, - mode - ); - mode.lanes = lanes; - mode.stateNode = { - containerInfo: portal.containerInfo, - pendingChildren: null, - implementation: portal.implementation - }; - return mode; - } - function FiberRootNode( - containerInfo, - tag, - hydrate, - identifierPrefix, - onUncaughtError, - onCaughtError, - onRecoverableError, - formState - ) { - this.tag = tag; - this.containerInfo = containerInfo; - this.finishedWork = - this.pingCache = - this.current = - this.pendingChildren = - null; - this.timeoutHandle = -1; - this.callbackNode = - this.next = - this.pendingContext = - this.context = - this.cancelPendingCommit = - null; - this.callbackPriority = 0; - this.expirationTimes = createLaneMap(-1); - this.entangledLanes = - this.shellSuspendCounter = - this.errorRecoveryDisabledLanes = - this.finishedLanes = - this.expiredLanes = - this.pingedLanes = - this.suspendedLanes = - this.pendingLanes = - 0; - this.entanglements = createLaneMap(0); - this.hiddenUpdates = createLaneMap(null); - this.identifierPrefix = identifierPrefix; - this.onUncaughtError = onUncaughtError; - this.onCaughtError = onCaughtError; - this.onRecoverableError = onRecoverableError; - this.pooledCache = null; - this.pooledCacheLanes = 0; - this.formState = formState; - this.incompleteTransitions = new Map(); - this.passiveEffectDuration = this.effectDuration = 0; - this.memoizedUpdaters = new Set(); - containerInfo = this.pendingUpdatersLaneMap = []; - for ( - identifierPrefix = 0; - identifierPrefix < TotalLanes; - identifierPrefix++ - ) - containerInfo.push(new Set()); - switch (tag) { - case 1: - this._debugRootType = hydrate ? "hydrateRoot()" : "createRoot()"; - break; - case 0: - this._debugRootType = hydrate ? "hydrate()" : "render()"; } + + return workInProgress; } - function testStringCoercion(value) { - return "" + value; - } - function createPortal$1(children, containerInfo, implementation) { - var key = - 3 < arguments.length && void 0 !== arguments[3] ? arguments[3] : null; - try { - testStringCoercion(key); - var JSCompiler_inline_result = !1; - } catch (e$45) { - JSCompiler_inline_result = !0; - } - JSCompiler_inline_result && - (error$jscomp$0( - "The provided key is an unsupported type %s. This value must be coerced to a string before using it here.", - ("function" === typeof Symbol && - Symbol.toStringTag && - key[Symbol.toStringTag]) || - key.constructor.name || - "Object" - ), - testStringCoercion(key)); - return { - $$typeof: REACT_PORTAL_TYPE, - key: null == key ? null : "" + key, - children: children, - containerInfo: containerInfo, - implementation: implementation - }; - } - function findHostInstanceWithWarning(component, methodName) { - var fiber = component._reactInternals; - if (void 0 === fiber) { - if ("function" === typeof component.render) - throw Error("Unable to find node on an unmounted component."); - component = Object.keys(component).join(","); - throw Error( - "Argument appears to not be a ReactComponent. Keys: " + component - ); + function createHostRootFiber( + tag, + isStrictMode, + concurrentUpdatesByDefaultOverride + ) { + var mode; + + if (tag === ConcurrentRoot) { + mode = ConcurrentMode; + + if (isStrictMode === true) { + mode |= StrictLegacyMode | StrictEffectsMode; + } + } else { + mode = NoMode; } - component = findCurrentHostFiber(fiber); - if (null === component) return null; - if (component.mode & 8) { - var componentName = getComponentNameFromFiber(fiber) || "Component"; - didWarnAboutFindNodeInStrictMode[componentName] || - ((didWarnAboutFindNodeInStrictMode[componentName] = !0), - runWithFiberInDEV(component, function () { - fiber.mode & 8 - ? error$jscomp$0( - "%s is deprecated in StrictMode. %s was passed an instance of %s which is inside StrictMode. Instead, add a ref directly to the element you want to reference. Learn more about using refs safely here: https://react.dev/link/strict-mode-find-node", - methodName, - methodName, - componentName - ) - : error$jscomp$0( - "%s is deprecated in StrictMode. %s was passed an instance of %s which renders StrictMode children. Instead, add a ref directly to the element you want to reference. Learn more about using refs safely here: https://react.dev/link/strict-mode-find-node", - methodName, - methodName, - componentName - ); - })); + + if (isDevToolsPresent) { + // Always collect profile timings when DevTools are present. + // This enables DevTools to start capturing timing at any point– + // Without some nodes in the tree having empty base times. + mode |= ProfileMode; } - return getPublicInstance(component.stateNode); - } - function updateContainer(element, container, parentComponent, callback) { - var current = container.current, - lane = requestUpdateLane(current); - updateContainerImpl( - current, - lane, - element, - container, - parentComponent, - callback - ); - return lane; + + return createFiber(HostRoot, null, null, mode); } - function updateContainerImpl( - rootFiber, - lane, - element, - container, - parentComponent, - callback + function createFiberFromTypeAndProps( + type, // React$ElementType + key, + pendingProps, + owner, + mode, + lanes ) { - if ( - injectedHook && - "function" === typeof injectedHook.onScheduleFiberRoot - ) - try { - injectedHook.onScheduleFiberRoot(rendererID, container, element); - } catch (err) { - hasLoggedError || - ((hasLoggedError = !0), - error$jscomp$0( - "React instrumentation encountered an error: %s", - err - )); - } - null !== injectedProfilingHooks && - "function" === typeof injectedProfilingHooks.markRenderScheduled && - injectedProfilingHooks.markRenderScheduled(lane); - parentComponent = emptyContextObject; - null === container.context - ? (container.context = parentComponent) - : (container.pendingContext = parentComponent); - isRendering && - null !== current && - !didWarnAboutNestedUpdates && - ((didWarnAboutNestedUpdates = !0), - error$jscomp$0( - "Render methods should be a pure function of props and state; triggering nested component updates from render is not allowed. If necessary, trigger nested updates in componentDidUpdate.\n\nCheck the render method of %s.", - getComponentNameFromFiber(current) || "Unknown" - )); - container = createUpdate(lane); - container.payload = { element: element }; - callback = void 0 === callback ? null : callback; - null !== callback && - ("function" !== typeof callback && - error$jscomp$0( - "Expected the last optional `callback` argument to be a function. Instead received: %s.", - callback - ), - (container.callback = callback)); - element = enqueueUpdate(rootFiber, container, lane); - null !== element && - (scheduleUpdateOnFiber(element, rootFiber, lane), - entangleTransitions(element, rootFiber, lane)); - } - function findHostInstanceByFiber(fiber) { - fiber = findCurrentHostFiber(fiber); - return null === fiber ? null : fiber.stateNode; - } - function emptyFindFiberByHostInstance() { - return null; - } - function getCurrentFiberForDevTools() { - return current; - } - function findNodeHandle(componentOrHandle) { - var owner = current; - null !== owner && - isRendering && - null !== owner.stateNode && - (owner.stateNode._warnedAboutRefsInRender || - error$jscomp$0( - "%s is accessing findNodeHandle inside its render(). render() should be a pure function of props and state. It should never access something that requires stale data from the previous render, such as refs. Move this logic to componentDidMount and componentDidUpdate instead.", - getComponentNameFromType(owner.type) || "A component" - ), - (owner.stateNode._warnedAboutRefsInRender = !0)); - if (null == componentOrHandle) return null; - if ("number" === typeof componentOrHandle) return componentOrHandle; - if (componentOrHandle._nativeTag) return componentOrHandle._nativeTag; - if ( - null != componentOrHandle.canonical && - null != componentOrHandle.canonical.nativeTag - ) - return componentOrHandle.canonical.nativeTag; - if ( - (owner = - ReactNativePrivateInterface.getNativeTagFromPublicInstance( - componentOrHandle - )) - ) - return owner; - componentOrHandle = findHostInstanceWithWarning( - componentOrHandle, - "findNodeHandle" - ); - return null == componentOrHandle - ? componentOrHandle - : null != componentOrHandle._nativeTag - ? componentOrHandle._nativeTag - : ReactNativePrivateInterface.getNativeTagFromPublicInstance( - componentOrHandle - ); - } - function getNodeFromInternalInstanceHandle(internalInstanceHandle) { - return ( - internalInstanceHandle && - internalInstanceHandle.stateNode && - internalInstanceHandle.stateNode.node - ); - } - function createHierarchy(fiberHierarchy) { - return fiberHierarchy.map(function (fiber$jscomp$0) { - return { - name: getComponentNameFromType(fiber$jscomp$0.type), - getInspectorData: function (findNodeHandle) { - return { - props: getHostProps(fiber$jscomp$0), - measure: function (callback) { - var hostFiber = findCurrentHostFiber(fiber$jscomp$0); - if ( - (hostFiber = - null != hostFiber && - null !== hostFiber.stateNode && - hostFiber.stateNode.node) - ) - nativeFabricUIManager.measure(hostFiber, callback); - else { - hostFiber = ReactNativePrivateInterface.UIManager; - var JSCompiler_temp_const = hostFiber.measure, - JSCompiler_inline_result; - a: { - for (var fiber = fiber$jscomp$0; fiber; ) { - null !== fiber.stateNode && - 5 === fiber.tag && - (JSCompiler_inline_result = findNodeHandle( - fiber.stateNode - )); - if (JSCompiler_inline_result) break a; - fiber = fiber.child; - } - JSCompiler_inline_result = null; - } - return JSCompiler_temp_const.call( - hostFiber, - JSCompiler_inline_result, - callback - ); - } - } - }; + var fiberTag = IndeterminateComponent; // The resolved type is set if we know what the final type will be. I.e. it's not lazy. + + var resolvedType = type; + + if (typeof type === "function") { + if (shouldConstruct(type)) { + fiberTag = ClassComponent; + + { + resolvedType = resolveClassForHotReloading(resolvedType); + } + } else { + { + resolvedType = resolveFunctionForHotReloading(resolvedType); } - }; - }); - } - function getHostProps(fiber) { - return (fiber = findCurrentHostFiber(fiber)) - ? fiber.memoizedProps || emptyObject - : emptyObject; - } - function getInspectorDataForInstance(closestInstance) { - if (!closestInstance) - return { - hierarchy: [], - props: emptyObject, - selectedIndex: null, - componentStack: "" - }; - closestInstance = findCurrentFiberUsingSlowPath(closestInstance); - if (null === closestInstance) - return { - hierarchy: [], - props: emptyObject, - selectedIndex: null, - componentStack: "" - }; - var hierarchy = []; - traverseOwnerTreeUp(hierarchy, closestInstance); - var instance; - a: { - for (instance = hierarchy.length - 1; 1 < instance; instance--) { - var instance$jscomp$0 = hierarchy[instance]; - if (5 !== instance$jscomp$0.tag) { - instance = instance$jscomp$0; - break a; - } - } - instance = hierarchy[0]; - } - instance$jscomp$0 = createHierarchy(hierarchy); - var props = getHostProps(instance); - hierarchy = hierarchy.indexOf(instance); - closestInstance = getStackByFiberInDevAndProd(closestInstance); - return { - closestInstance: instance, - hierarchy: instance$jscomp$0, - props: props, - selectedIndex: hierarchy, - componentStack: closestInstance - }; - } - function traverseOwnerTreeUp(hierarchy, instance) { - hierarchy.unshift(instance); - instance = instance._debugOwner; - null != instance && - "number" === typeof instance.tag && - traverseOwnerTreeUp(hierarchy, instance); - } - function nativeOnUncaughtError(error, errorInfo) { - !1 !== - ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog({ - errorBoundary: null, - error: error, - componentStack: - null != errorInfo.componentStack ? errorInfo.componentStack : "" - }) && - (reportGlobalError(error), - warn( - "%s\n\n%s\n", - componentName - ? "An error occurred in the <" + componentName + "> component." - : "An error occurred in one of your React components.", - "Consider adding an error boundary to your tree to customize error handling behavior.\nVisit https://react.dev/link/error-boundaries to learn more about error boundaries." - )); - } - function nativeOnCaughtError(error, errorInfo) { - !1 !== - ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog({ - errorBoundary: errorInfo.errorBoundary, - error: error, - componentStack: - null != errorInfo.componentStack ? errorInfo.componentStack : "" - }) && - error$jscomp$0( - "%o\n\n%s\n\n%s\n", - error, - componentName - ? "The above error occurred in the <" + - componentName + - "> component." - : "The above error occurred in one of your React components.", - "React will try to recreate this component tree from scratch using the error boundary you provided, " + - ((errorBoundaryName || "Anonymous") + ".") - ); - } - "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && - "function" === - typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart && - __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error()); - require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); - var React = require("react"), - ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"), - Scheduler = require("scheduler"), - ReactSharedInternals = - React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, - suppressWarning = !1, - supportsCreateTask = !!console.createTask, - isArrayImpl = Array.isArray, - REACT_LEGACY_ELEMENT_TYPE = Symbol.for("react.element"), - REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"), - REACT_PORTAL_TYPE = Symbol.for("react.portal"), - REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"), - REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"), - REACT_PROFILER_TYPE = Symbol.for("react.profiler"), - REACT_PROVIDER_TYPE = Symbol.for("react.provider"), - REACT_CONSUMER_TYPE = Symbol.for("react.consumer"), - REACT_CONTEXT_TYPE = Symbol.for("react.context"), - REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"), - REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"), - REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"), - REACT_MEMO_TYPE = Symbol.for("react.memo"), - REACT_LAZY_TYPE = Symbol.for("react.lazy"); - Symbol.for("react.scope"); - Symbol.for("react.debug_trace_mode"); - var REACT_OFFSCREEN_TYPE = Symbol.for("react.offscreen"); - Symbol.for("react.legacy_hidden"); - Symbol.for("react.tracing_marker"); - var REACT_MEMO_CACHE_SENTINEL = Symbol.for("react.memo_cache_sentinel"), - MAYBE_ITERATOR_SYMBOL = Symbol.iterator, - assign = Object.assign, - disabledDepth = 0, - prevLog, - prevInfo, - prevWarn, - prevError, - prevGroup, - prevGroupCollapsed, - prevGroupEnd; - disabledLog.__reactDisabledLog = !0; - var prefix, - reentry = !1; - var componentFrameCache = new ( - "function" === typeof WeakMap ? WeakMap : Map - )(); - var externalRegExp = /\/node_modules\/|\(\)/, - callComponentFrame = null, - callIteratorFrame = null, - callLazyInitFrame = null, - REACT_CLIENT_REFERENCE = Symbol.for("react.client.reference"), - current = null, - isRendering = !1, - hasError = !1, - caughtError = null, - getFiberCurrentPropsFromNode$1 = null, - getInstanceFromNode$1 = null, - getNodeFromInstance$1 = null; - assign(SyntheticEvent.prototype, { - preventDefault: function () { - this.defaultPrevented = !0; - var event = this.nativeEvent; - event && - (event.preventDefault - ? event.preventDefault() - : "unknown" !== typeof event.returnValue && - (event.returnValue = !1), - (this.isDefaultPrevented = functionThatReturnsTrue)); - }, - stopPropagation: function () { - var event = this.nativeEvent; - event && - (event.stopPropagation - ? event.stopPropagation() - : "unknown" !== typeof event.cancelBubble && - (event.cancelBubble = !0), - (this.isPropagationStopped = functionThatReturnsTrue)); - }, - persist: function () { - this.isPersistent = functionThatReturnsTrue; - }, - isPersistent: functionThatReturnsFalse, - destructor: function () { - var Interface = this.constructor.Interface, - propName; - for (propName in Interface) - Object.defineProperty( - this, - propName, - getPooledWarningPropertyDefinition(propName, Interface[propName]) - ); - this.nativeEvent = this._targetInst = this.dispatchConfig = null; - this.isPropagationStopped = this.isDefaultPrevented = - functionThatReturnsFalse; - this._dispatchInstances = this._dispatchListeners = null; - Object.defineProperty( - this, - "nativeEvent", - getPooledWarningPropertyDefinition("nativeEvent", null) - ); - Object.defineProperty( - this, - "isDefaultPrevented", - getPooledWarningPropertyDefinition( - "isDefaultPrevented", - functionThatReturnsFalse - ) - ); - Object.defineProperty( - this, - "isPropagationStopped", - getPooledWarningPropertyDefinition( - "isPropagationStopped", - functionThatReturnsFalse - ) - ); - Object.defineProperty( - this, - "preventDefault", - getPooledWarningPropertyDefinition("preventDefault", function () {}) - ); - Object.defineProperty( - this, - "stopPropagation", - getPooledWarningPropertyDefinition("stopPropagation", function () {}) - ); - } - }); - SyntheticEvent.Interface = { - type: null, - target: null, - currentTarget: function () { - return null; - }, - eventPhase: null, - bubbles: null, - cancelable: null, - timeStamp: function (event) { - return event.timeStamp || Date.now(); - }, - defaultPrevented: null, - isTrusted: null - }; - SyntheticEvent.extend = function (Interface) { - function E() {} - function Class() { - return Super.apply(this, arguments); - } - var Super = this; - E.prototype = Super.prototype; - var prototype = new E(); - assign(prototype, Class.prototype); - Class.prototype = prototype; - Class.prototype.constructor = Class; - Class.Interface = assign({}, Super.Interface, Interface); - Class.extend = Super.extend; - addEventPoolingTo(Class); - return Class; - }; - addEventPoolingTo(SyntheticEvent); - var ResponderSyntheticEvent = SyntheticEvent.extend({ - touchHistory: function () { - return null; } - }), - startDependencies = ["topTouchStart"], - moveDependencies = ["topTouchMove"], - endDependencies = ["topTouchCancel", "topTouchEnd"], - touchBank = [], - touchHistory = { - touchBank: touchBank, - numberActiveTouches: 0, - indexOfSingleActiveTouch: -1, - mostRecentTimeStamp: 0 - }, - 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 - ) - 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; - } - topLevelType = touchBank[touchHistory.indexOfSingleActiveTouch]; - (null != topLevelType && topLevelType.touchActive) || - error$jscomp$0("Cannot find single active touch."); - } - }, - touchHistory: touchHistory - }, - responderInst = null, - trackedTouchCount = 0, - eventTypes = { - startShouldSetResponder: { - phasedRegistrationNames: { - bubbled: "onStartShouldSetResponder", - captured: "onStartShouldSetResponderCapture" - }, - dependencies: startDependencies - }, - scrollShouldSetResponder: { - phasedRegistrationNames: { - bubbled: "onScrollShouldSetResponder", - captured: "onScrollShouldSetResponderCapture" - }, - dependencies: ["topScroll"] - }, - selectionChangeShouldSetResponder: { - phasedRegistrationNames: { - bubbled: "onSelectionChangeShouldSetResponder", - captured: "onSelectionChangeShouldSetResponderCapture" - }, - dependencies: ["topSelectionChange"] - }, - moveShouldSetResponder: { - phasedRegistrationNames: { - bubbled: "onMoveShouldSetResponder", - captured: "onMoveShouldSetResponderCapture" - }, - dependencies: moveDependencies - }, - responderStart: { - registrationName: "onResponderStart", - dependencies: startDependencies - }, - responderMove: { - registrationName: "onResponderMove", - dependencies: moveDependencies - }, - responderEnd: { - registrationName: "onResponderEnd", - dependencies: endDependencies - }, - responderRelease: { - registrationName: "onResponderRelease", - dependencies: endDependencies - }, - responderTerminationRequest: { - registrationName: "onResponderTerminationRequest", - dependencies: [] - }, - responderGrant: { - registrationName: "onResponderGrant", - dependencies: [] - }, - responderReject: { - registrationName: "onResponderReject", - dependencies: [] - }, - responderTerminate: { - registrationName: "onResponderTerminate", - dependencies: [] + } else if (typeof type === "string") { + { + fiberTag = HostComponent; } - }, - ResponderEventPlugin = { - _getResponder: function () { - return responderInst; - }, - eventTypes: eventTypes, - extractEvents: function ( - topLevelType, - targetInst, - nativeEvent, - nativeEventTarget - ) { - if (isStartish(topLevelType)) trackedTouchCount += 1; - else if ( - "topTouchEnd" === topLevelType || - "topTouchCancel" === topLevelType - ) - if (0 <= trackedTouchCount) --trackedTouchCount; - else - return ( - warn( - "Ended a touch event which was not counted in `trackedTouchCount`." - ), - null - ); - ResponderTouchHistoryStore.recordTouchTrack( - topLevelType, - nativeEvent - ); - if ( - targetInst && - (("topScroll" === topLevelType && - !nativeEvent.responderIgnoreScroll) || - (0 < trackedTouchCount && - "topSelectionChange" === topLevelType) || - isStartish(topLevelType) || - isMoveish(topLevelType)) - ) { - var shouldSetEventType = isStartish(topLevelType) - ? eventTypes.startShouldSetResponder - : isMoveish(topLevelType) - ? eventTypes.moveShouldSetResponder - : "topSelectionChange" === topLevelType - ? eventTypes.selectionChangeShouldSetResponder - : eventTypes.scrollShouldSetResponder; - if (responderInst) - b: { - var JSCompiler_temp = responderInst; - for ( - var depthA = 0, tempA = JSCompiler_temp; - tempA; - tempA = getParent$1(tempA) - ) - depthA++; - tempA = 0; - for (var tempB = targetInst; tempB; tempB = getParent$1(tempB)) - tempA++; - for (; 0 < depthA - tempA; ) - (JSCompiler_temp = getParent$1(JSCompiler_temp)), depthA--; - for (; 0 < tempA - depthA; ) - (targetInst = getParent$1(targetInst)), tempA--; - for (; depthA--; ) { - if ( - JSCompiler_temp === targetInst || - JSCompiler_temp === targetInst.alternate - ) - break b; - JSCompiler_temp = getParent$1(JSCompiler_temp); - targetInst = getParent$1(targetInst); - } - JSCompiler_temp = null; - } - else JSCompiler_temp = targetInst; - targetInst = JSCompiler_temp === responderInst; - JSCompiler_temp = ResponderSyntheticEvent.getPooled( - shouldSetEventType, - JSCompiler_temp, - nativeEvent, - nativeEventTarget + } else { + getTag: switch (type) { + case REACT_FRAGMENT_TYPE: + return createFiberFromFragment( + pendingProps.children, + mode, + lanes, + key ); - JSCompiler_temp.touchHistory = - ResponderTouchHistoryStore.touchHistory; - targetInst - ? forEachAccumulated( - JSCompiler_temp, - accumulateTwoPhaseDispatchesSingleSkipTarget - ) - : forEachAccumulated( - JSCompiler_temp, - accumulateTwoPhaseDispatchesSingle$1 - ); - b: { - shouldSetEventType = JSCompiler_temp._dispatchListeners; - targetInst = JSCompiler_temp._dispatchInstances; - validateEventDispatches(JSCompiler_temp); - if (isArrayImpl(shouldSetEventType)) - for ( - depthA = 0; - depthA < shouldSetEventType.length && - !JSCompiler_temp.isPropagationStopped(); - depthA++ - ) { - if ( - shouldSetEventType[depthA]( - JSCompiler_temp, - targetInst[depthA] - ) - ) { - shouldSetEventType = targetInst[depthA]; - break b; - } + + case REACT_STRICT_MODE_TYPE: + fiberTag = Mode; + mode |= StrictLegacyMode; + + if ((mode & ConcurrentMode) !== NoMode) { + // Strict effects should never run on legacy roots + mode |= StrictEffectsMode; + } + + break; + + case REACT_PROFILER_TYPE: + return createFiberFromProfiler(pendingProps, mode, lanes, key); + + case REACT_SUSPENSE_TYPE: + return createFiberFromSuspense(pendingProps, mode, lanes, key); + + case REACT_SUSPENSE_LIST_TYPE: + return createFiberFromSuspenseList(pendingProps, mode, lanes, key); + + case REACT_OFFSCREEN_TYPE: + return createFiberFromOffscreen(pendingProps, mode, lanes, key); + + case REACT_LEGACY_HIDDEN_TYPE: + + // Fall through + + case REACT_SCOPE_TYPE: + + // Fall through + + case REACT_CACHE_TYPE: + + // Fall through + + case REACT_TRACING_MARKER_TYPE: + + // Fall through + + case REACT_DEBUG_TRACING_MODE_TYPE: + + // Fall through + + default: { + if (typeof type === "object" && type !== null) { + switch (type.$$typeof) { + case REACT_PROVIDER_TYPE: { + fiberTag = ContextProvider; + break getTag; } - else if ( - shouldSetEventType && - shouldSetEventType(JSCompiler_temp, targetInst) - ) { - shouldSetEventType = targetInst; - break b; + + // Fall through + + case REACT_CONTEXT_TYPE: { + fiberTag = ContextConsumer; + break getTag; + } + + case REACT_CONSUMER_TYPE: + + // Fall through + + case REACT_FORWARD_REF_TYPE: + fiberTag = ForwardRef; + + { + resolvedType = + resolveForwardRefForHotReloading(resolvedType); + } + + break getTag; + + case REACT_MEMO_TYPE: + fiberTag = MemoComponent; + break getTag; + + case REACT_LAZY_TYPE: + fiberTag = LazyComponent; + resolvedType = null; + break getTag; } - shouldSetEventType = null; } - JSCompiler_temp._dispatchInstances = null; - JSCompiler_temp._dispatchListeners = null; - JSCompiler_temp.isPersistent() || - JSCompiler_temp.constructor.release(JSCompiler_temp); - if (shouldSetEventType && shouldSetEventType !== responderInst) - if ( - ((JSCompiler_temp = ResponderSyntheticEvent.getPooled( - eventTypes.responderGrant, - shouldSetEventType, - nativeEvent, - nativeEventTarget - )), - (JSCompiler_temp.touchHistory = - ResponderTouchHistoryStore.touchHistory), - forEachAccumulated( - JSCompiler_temp, - accumulateDirectDispatchesSingle$1 - ), - (targetInst = !0 === executeDirectDispatch(JSCompiler_temp)), - responderInst) - ) - if ( - ((depthA = ResponderSyntheticEvent.getPooled( - eventTypes.responderTerminationRequest, - responderInst, - nativeEvent, - nativeEventTarget - )), - (depthA.touchHistory = - ResponderTouchHistoryStore.touchHistory), - forEachAccumulated( - depthA, - accumulateDirectDispatchesSingle$1 - ), - (tempA = - !depthA._dispatchListeners || - executeDirectDispatch(depthA)), - depthA.isPersistent() || depthA.constructor.release(depthA), - tempA) - ) { - depthA = ResponderSyntheticEvent.getPooled( - eventTypes.responderTerminate, - responderInst, - nativeEvent, - nativeEventTarget - ); - depthA.touchHistory = ResponderTouchHistoryStore.touchHistory; - forEachAccumulated( - depthA, - accumulateDirectDispatchesSingle$1 - ); - var JSCompiler_temp$jscomp$0 = accumulate( - JSCompiler_temp$jscomp$0, - [JSCompiler_temp, depthA] - ); - changeResponder(shouldSetEventType, targetInst); - } else - (shouldSetEventType = ResponderSyntheticEvent.getPooled( - eventTypes.responderReject, - shouldSetEventType, - nativeEvent, - nativeEventTarget - )), - (shouldSetEventType.touchHistory = - ResponderTouchHistoryStore.touchHistory), - forEachAccumulated( - shouldSetEventType, - accumulateDirectDispatchesSingle$1 - ), - (JSCompiler_temp$jscomp$0 = accumulate( - JSCompiler_temp$jscomp$0, - shouldSetEventType - )); - else - (JSCompiler_temp$jscomp$0 = accumulate( - JSCompiler_temp$jscomp$0, - JSCompiler_temp - )), - changeResponder(shouldSetEventType, targetInst); - else JSCompiler_temp$jscomp$0 = null; - } else JSCompiler_temp$jscomp$0 = null; - shouldSetEventType = responderInst && isStartish(topLevelType); - JSCompiler_temp = responderInst && isMoveish(topLevelType); - targetInst = - responderInst && - ("topTouchEnd" === topLevelType || - "topTouchCancel" === topLevelType); - if ( - (shouldSetEventType = shouldSetEventType - ? eventTypes.responderStart - : JSCompiler_temp - ? eventTypes.responderMove - : targetInst - ? eventTypes.responderEnd - : null) - ) - (shouldSetEventType = ResponderSyntheticEvent.getPooled( - shouldSetEventType, - responderInst, - nativeEvent, - nativeEventTarget - )), - (shouldSetEventType.touchHistory = - ResponderTouchHistoryStore.touchHistory), - forEachAccumulated( - shouldSetEventType, - accumulateDirectDispatchesSingle$1 - ), - (JSCompiler_temp$jscomp$0 = accumulate( - JSCompiler_temp$jscomp$0, - shouldSetEventType - )); - shouldSetEventType = - responderInst && "topTouchCancel" === topLevelType; - if ( - (topLevelType = - responderInst && - !shouldSetEventType && - ("topTouchEnd" === topLevelType || - "topTouchCancel" === topLevelType)) - ) - a: { + + var info = ""; + + { if ( - (topLevelType = nativeEvent.touches) && - 0 !== topLevelType.length - ) - for ( - JSCompiler_temp = 0; - JSCompiler_temp < topLevelType.length; - JSCompiler_temp++ - ) - if ( - ((targetInst = topLevelType[JSCompiler_temp].target), - null !== targetInst && - void 0 !== targetInst && - 0 !== targetInst) - ) { - depthA = getInstanceFromNode$1(targetInst); - b: { - for (targetInst = responderInst; depthA; ) { - if ( - targetInst === depthA || - targetInst === depthA.alternate - ) { - targetInst = !0; - break b; - } - depthA = getParent$1(depthA); - } - targetInst = !1; - } - if (targetInst) { - topLevelType = !1; - break a; - } - } - topLevelType = !0; + type === undefined || + (typeof type === "object" && + type !== null && + Object.keys(type).length === 0) + ) { + info += + " You likely forgot to export your component from the file " + + "it's defined in, or you might have mixed up default and " + + "named imports."; + } + + var ownerName = owner ? getComponentNameFromFiber(owner) : null; + + if (ownerName) { + info += "\n\nCheck the render method of `" + ownerName + "`."; + } } - if ( - (topLevelType = shouldSetEventType - ? eventTypes.responderTerminate - : topLevelType - ? eventTypes.responderRelease - : null) - ) - (nativeEvent = ResponderSyntheticEvent.getPooled( - topLevelType, - responderInst, - nativeEvent, - nativeEventTarget - )), - (nativeEvent.touchHistory = - ResponderTouchHistoryStore.touchHistory), - forEachAccumulated( - nativeEvent, - accumulateDirectDispatchesSingle$1 - ), - (JSCompiler_temp$jscomp$0 = accumulate( - JSCompiler_temp$jscomp$0, - nativeEvent - )), - changeResponder(null); - return JSCompiler_temp$jscomp$0; - }, - GlobalResponderHandler: null, - injection: { - injectGlobalResponderHandler: function (GlobalResponderHandler) { - ResponderEventPlugin.GlobalResponderHandler = - GlobalResponderHandler; + + throw new Error( + "Element type is invalid: expected a string (for built-in " + + "components) or a class/function (for composite components) " + + ("but got: " + (type == null ? type : typeof type) + "." + info) + ); } } - }, - eventPluginOrder = null, - namesToPlugins = {}, - plugins = [], - eventNameDispatchConfigs = {}, - registrationNameModules = {}, - customBubblingEventTypes = - ReactNativePrivateInterface.ReactNativeViewConfigRegistry - .customBubblingEventTypes, - customDirectEventTypes = - ReactNativePrivateInterface.ReactNativeViewConfigRegistry - .customDirectEventTypes; - if (eventPluginOrder) - throw Error( - "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." + } + + var fiber = createFiber(fiberTag, pendingProps, key, mode); + fiber.elementType = type; + fiber.type = resolvedType; + fiber.lanes = lanes; + + { + fiber._debugOwner = owner; + } + + return fiber; + } + function createFiberFromElement(element, mode, lanes) { + var owner = null; + + { + owner = element._owner; + } + + var type = element.type; + var key = element.key; + var pendingProps = element.props; + var fiber = createFiberFromTypeAndProps( + type, + key, + pendingProps, + owner, + mode, + lanes ); - eventPluginOrder = Array.prototype.slice.call([ - "ResponderEventPlugin", - "ReactNativeBridgeEventPlugin" - ]); - recomputePluginOrdering(); - (function (injectedNamesToPlugins) { - var isOrderingDirty = !1, - pluginName; - for (pluginName in injectedNamesToPlugins) - if (injectedNamesToPlugins.hasOwnProperty(pluginName)) { - var pluginModule = injectedNamesToPlugins[pluginName]; - if ( - !namesToPlugins.hasOwnProperty(pluginName) || - namesToPlugins[pluginName] !== pluginModule - ) { - if (namesToPlugins[pluginName]) - throw Error( - "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - (pluginName + "`.") - ); - namesToPlugins[pluginName] = pluginModule; - isOrderingDirty = !0; - } - } - isOrderingDirty && recomputePluginOrdering(); - })({ - ResponderEventPlugin: ResponderEventPlugin, - ReactNativeBridgeEventPlugin: { - eventTypes: {}, - extractEvents: function ( - topLevelType, - targetInst, - nativeEvent, - nativeEventTarget - ) { - if (null == targetInst) return null; - var bubbleDispatchConfig = customBubblingEventTypes[topLevelType], - directDispatchConfig = customDirectEventTypes[topLevelType]; - if (!bubbleDispatchConfig && !directDispatchConfig) - throw Error( - 'Unsupported top level event type "' + - topLevelType + - '" dispatched' - ); - topLevelType = SyntheticEvent.getPooled( - bubbleDispatchConfig || directDispatchConfig, - targetInst, - nativeEvent, - nativeEventTarget + + { + fiber._debugOwner = element._owner; + } + + return fiber; + } + function createFiberFromFragment(elements, mode, lanes, key) { + var fiber = createFiber(Fragment, elements, key, mode); + fiber.lanes = lanes; + return fiber; + } + + function createFiberFromProfiler(pendingProps, mode, lanes, key) { + { + if (typeof pendingProps.id !== "string") { + error( + 'Profiler must specify an "id" of type `string` as a prop. Received the type `%s` instead.', + typeof pendingProps.id ); - if (bubbleDispatchConfig) - null != topLevelType && - null != topLevelType.dispatchConfig.phasedRegistrationNames && - topLevelType.dispatchConfig.phasedRegistrationNames.skipBubbling - ? topLevelType && - topLevelType.dispatchConfig.phasedRegistrationNames && - traverseTwoPhase( - topLevelType._targetInst, - accumulateDirectionalDispatches, - topLevelType, - !0 - ) - : forEachAccumulated( - topLevelType, - accumulateTwoPhaseDispatchesSingle - ); - else if (directDispatchConfig) - forEachAccumulated(topLevelType, accumulateDirectDispatchesSingle); - else return null; - return topLevelType; } } - }); - var emptyObject$1 = {}, - removedKeys = null, - removedKeyCount = 0, - deepDifferOptions = { unsafelyIgnoreFunctions: !0 }, - isInsideEventHandler = !1, - eventQueue = null, - scheduleCallback$3 = Scheduler.unstable_scheduleCallback, - cancelCallback$1 = Scheduler.unstable_cancelCallback, - shouldYield = Scheduler.unstable_shouldYield, - requestPaint = Scheduler.unstable_requestPaint, - now$1 = Scheduler.unstable_now, - ImmediatePriority = Scheduler.unstable_ImmediatePriority, - UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, - NormalPriority$1 = Scheduler.unstable_NormalPriority, - IdlePriority = Scheduler.unstable_IdlePriority, - log$1 = Scheduler.log, - unstable_setDisableYieldValue = Scheduler.unstable_setDisableYieldValue, - rendererID = null, - injectedHook = null, - injectedProfilingHooks = null, - hasLoggedError = !1, - isDevToolsPresent = "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__, - clz32 = Math.clz32 ? Math.clz32 : clz32Fallback, - log = Math.log, - LN2 = Math.LN2, - TotalLanes = 31, - SyncHydrationLane = 1, - SyncLane = 2, - InputContinuousHydrationLane = 4, - InputContinuousLane = 8, - DefaultHydrationLane = 16, - DefaultLane = 32, - SyncUpdateLanes = SyncLane | InputContinuousLane | DefaultLane, - TransitionHydrationLane = 64, - TransitionLanes = 4194176, - RetryLanes = 62914560, - SelectiveHydrationLane = 67108864, - IdleHydrationLane = 134217728, - IdleLane = 268435456, - OffscreenLane = 536870912, - DeferredLane = 1073741824, - UpdateLanes = - SyncLane | InputContinuousLane | DefaultLane | TransitionLanes, - nextTransitionLane = 128, - nextRetryLane = 4194304, - DiscreteEventPriority = SyncLane, - ContinuousEventPriority = InputContinuousLane, - DefaultEventPriority = DefaultLane, - IdleEventPriority = IdleLane, - isSuspenseInstancePending = shim$1, - isSuspenseInstanceFallback = shim$1, - getSuspenseInstanceFallbackErrorDetails = shim$1, - registerSuspenseInstanceRetry = shim$1, - preloadResource = shim, - suspendResource = shim, - _nativeFabricUIManage = nativeFabricUIManager, - createNode = _nativeFabricUIManage.createNode, - cloneNodeWithNewChildren = _nativeFabricUIManage.cloneNodeWithNewChildren, - cloneNodeWithNewChildrenAndProps = - _nativeFabricUIManage.cloneNodeWithNewChildrenAndProps, - cloneNodeWithNewProps = _nativeFabricUIManage.cloneNodeWithNewProps, - createChildNodeSet = _nativeFabricUIManage.createChildSet, - appendChildNode = _nativeFabricUIManage.appendChild, - appendChildNodeToSet = _nativeFabricUIManage.appendChildToSet, - completeRoot = _nativeFabricUIManage.completeRoot, - registerEventHandler = _nativeFabricUIManage.registerEventHandler, - FabricDiscretePriority = - _nativeFabricUIManage.unstable_DiscreteEventPriority, - fabricGetCurrentEventPriority = - _nativeFabricUIManage.unstable_getCurrentEventPriority, - getViewConfigForType = - ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get, - nextReactTag = 2; - registerEventHandler && registerEventHandler(dispatchEvent); - var currentUpdatePriority = 0, - scheduleTimeout = setTimeout, - cancelTimeout = clearTimeout, - supportsMicrotasks = - "undefined" !== typeof RN$enableMicrotasksInReact && - !!RN$enableMicrotasksInReact, - scheduleMicrotask = - "function" === typeof queueMicrotask ? queueMicrotask : scheduleTimeout; - (function ( - getFiberCurrentPropsFromNodeImpl, - getInstanceFromNodeImpl, - getNodeFromInstanceImpl + + var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode); + fiber.elementType = REACT_PROFILER_TYPE; + fiber.lanes = lanes; + + { + fiber.stateNode = { + effectDuration: 0, + passiveEffectDuration: 0 + }; + } + + return fiber; + } + + function createFiberFromSuspense(pendingProps, mode, lanes, key) { + 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); + fiber.elementType = REACT_SUSPENSE_LIST_TYPE; + fiber.lanes = lanes; + return fiber; + } + function createFiberFromOffscreen(pendingProps, mode, lanes, key) { + var fiber = createFiber(OffscreenComponent, pendingProps, key, mode); + fiber.elementType = REACT_OFFSCREEN_TYPE; + fiber.lanes = lanes; + var primaryChildInstance = { + _visibility: OffscreenVisible, + _pendingVisibility: OffscreenVisible, + _pendingMarkers: null, + _retryCache: null, + _transitions: null, + _current: null, + detach: function () { + return detachOffscreenInstance(primaryChildInstance); + }, + attach: function () { + return attachOffscreenInstance(primaryChildInstance); + } + }; + fiber.stateNode = primaryChildInstance; + return fiber; + } + function createFiberFromText(content, mode, lanes) { + var fiber = createFiber(HostText, content, null, mode); + fiber.lanes = lanes; + return fiber; + } + function createFiberFromPortal(portal, mode, lanes) { + var pendingProps = portal.children !== null ? portal.children : []; + var fiber = createFiber(HostPortal, pendingProps, portal.key, mode); + fiber.lanes = lanes; + fiber.stateNode = { + containerInfo: portal.containerInfo, + pendingChildren: null, + // Used by persistent updates + implementation: portal.implementation + }; + return fiber; + } + + function FiberRootNode( + containerInfo, // $FlowFixMe[missing-local-annot] + tag, + hydrate, + identifierPrefix, + onRecoverableError, + formState ) { - getFiberCurrentPropsFromNode$1 = getFiberCurrentPropsFromNodeImpl; - getInstanceFromNode$1 = getInstanceFromNodeImpl; - ((getNodeFromInstance$1 = getNodeFromInstanceImpl) && - getInstanceFromNode$1) || - error$jscomp$0( - "Injected module is missing getNodeFromInstance or getInstanceFromNode." - ); - })( - function (instance) { - return instance.canonical.currentProps; - }, - getInstanceFromNode, - function (fiber) { - fiber = getPublicInstance(fiber.stateNode); - if (null == fiber) - throw Error("Could not find host instance from fiber"); - return fiber; + this.tag = tag; + this.containerInfo = containerInfo; + this.pendingChildren = null; + this.current = null; + this.pingCache = null; + this.finishedWork = null; + this.timeoutHandle = noTimeout; + this.cancelPendingCommit = null; + this.context = null; + this.pendingContext = null; + this.next = null; + this.callbackNode = null; + this.callbackPriority = NoLane; + this.expirationTimes = createLaneMap(NoTimestamp); + this.pendingLanes = NoLanes; + this.suspendedLanes = NoLanes; + this.pingedLanes = NoLanes; + this.expiredLanes = NoLanes; + this.finishedLanes = NoLanes; + this.errorRecoveryDisabledLanes = NoLanes; + this.shellSuspendCounter = 0; + this.entangledLanes = NoLanes; + this.entanglements = createLaneMap(NoLanes); + this.hiddenUpdates = createLaneMap(null); + this.identifierPrefix = identifierPrefix; + this.onRecoverableError = onRecoverableError; + + this.formState = formState; + this.incompleteTransitions = new Map(); + + { + this.effectDuration = 0; + this.passiveEffectDuration = 0; } - ); - ResponderEventPlugin.injection.injectGlobalResponderHandler({ - onChange: function (from, to, blockNativeResponder) { - from && - from.stateNode && - nativeFabricUIManager.setIsJSResponder( - from.stateNode.node, - !1, - blockNativeResponder || !1 - ); - to && - to.stateNode && - nativeFabricUIManager.setIsJSResponder( - to.stateNode.node, - !0, - blockNativeResponder || !1 - ); + + { + this.memoizedUpdaters = new Set(); + var pendingUpdatersLaneMap = (this.pendingUpdatersLaneMap = []); + + for (var _i = 0; _i < TotalLanes; _i++) { + pendingUpdatersLaneMap.push(new Set()); + } } - }); - var valueStack = []; - var fiberStack = []; - var index$jscomp$0 = -1, - emptyContextObject = {}; - Object.freeze(emptyContextObject); - var objectIs = "function" === typeof Object.is ? Object.is : is, - CapturedStacks = new WeakMap(), - contextStackCursor = createCursor(null), - contextFiberStackCursor = createCursor(null), - rootInstanceStackCursor = createCursor(null), - hostTransitionProviderCursor = createCursor(null), - HostTransitionContext = { - $$typeof: REACT_CONTEXT_TYPE, - Provider: null, - Consumer: null, - _currentValue: null, - _currentValue2: null, - _threadCount: 0 - }, - needsEscaping = /["'&<>\n\t]/, - hydrationDiffRootDEV = null, - hydrationErrors = null, - concurrentQueues = [], - concurrentQueuesIndex = 0, - concurrentlyUpdatedLanes = 0, - firstScheduledRoot = null, - lastScheduledRoot = null, - didScheduleMicrotask = !1, - didScheduleMicrotask_act = !1, - mightHavePendingSyncWork = !1, - isFlushingWork = !1, - currentEventTransitionLane = 0, - fakeActCallbackNode$1 = {}, - currentEntangledListeners = null, - currentEntangledPendingCount = 0, - currentEntangledLane = 0, - currentEntangledActionThenable = null, - UpdateState = 0, - ReplaceState = 1, - ForceUpdate = 2, - CaptureUpdate = 3, - hasForceUpdate = !1; - var didWarnUpdateInsideUpdate = !1; - var currentlyProcessingQueue = null; - var didReadFromEntangledAsyncAction = !1, - hasOwnProperty = Object.prototype.hasOwnProperty, - ReactStrictModeWarnings = { - recordUnsafeLifecycleWarnings: function () {}, - flushPendingUnsafeLifecycleWarnings: function () {}, - recordLegacyContextWarning: function () {}, - flushLegacyContextWarning: function () {}, - discardPendingWarnings: function () {} - }, - pendingComponentWillMountWarnings = [], - pendingUNSAFE_ComponentWillMountWarnings = [], - pendingComponentWillReceivePropsWarnings = [], - pendingUNSAFE_ComponentWillReceivePropsWarnings = [], - pendingComponentWillUpdateWarnings = [], - pendingUNSAFE_ComponentWillUpdateWarnings = [], - didWarnAboutUnsafeLifecycles = new Set(); - ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function ( - fiber, - instance + + { + switch (tag) { + case ConcurrentRoot: + this._debugRootType = hydrate ? "hydrateRoot()" : "createRoot()"; + break; + + case LegacyRoot: + this._debugRootType = hydrate ? "hydrate()" : "render()"; + break; + } + } + } + + function createFiberRoot( + containerInfo, + tag, + hydrate, + initialChildren, + hydrationCallbacks, + isStrictMode, + concurrentUpdatesByDefaultOverride, // TODO: We have several of these arguments that are conceptually part of the + // host config, but because they are passed in at runtime, we have to thread + // them through the root constructor. Perhaps we should put them all into a + // single type, like a DynamicHostConfig that is defined by the renderer. + identifierPrefix, + onRecoverableError, + transitionCallbacks, + formState ) { - didWarnAboutUnsafeLifecycles.has(fiber.type) || - ("function" === typeof instance.componentWillMount && - !0 !== instance.componentWillMount.__suppressDeprecationWarning && - pendingComponentWillMountWarnings.push(fiber), - fiber.mode & 8 && - "function" === typeof instance.UNSAFE_componentWillMount && - pendingUNSAFE_ComponentWillMountWarnings.push(fiber), - "function" === typeof instance.componentWillReceiveProps && - !0 !== - instance.componentWillReceiveProps.__suppressDeprecationWarning && - pendingComponentWillReceivePropsWarnings.push(fiber), - fiber.mode & 8 && - "function" === typeof instance.UNSAFE_componentWillReceiveProps && - pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber), - "function" === typeof instance.componentWillUpdate && - !0 !== instance.componentWillUpdate.__suppressDeprecationWarning && - pendingComponentWillUpdateWarnings.push(fiber), - fiber.mode & 8 && - "function" === typeof instance.UNSAFE_componentWillUpdate && - pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber)); - }; - ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function () { - var componentWillMountUniqueNames = new Set(); - 0 < pendingComponentWillMountWarnings.length && - (pendingComponentWillMountWarnings.forEach(function (fiber) { - componentWillMountUniqueNames.add( - getComponentNameFromFiber(fiber) || "Component" - ); - didWarnAboutUnsafeLifecycles.add(fiber.type); - }), - (pendingComponentWillMountWarnings = [])); - var UNSAFE_componentWillMountUniqueNames = new Set(); - 0 < pendingUNSAFE_ComponentWillMountWarnings.length && - (pendingUNSAFE_ComponentWillMountWarnings.forEach(function (fiber) { - UNSAFE_componentWillMountUniqueNames.add( - getComponentNameFromFiber(fiber) || "Component" - ); - didWarnAboutUnsafeLifecycles.add(fiber.type); - }), - (pendingUNSAFE_ComponentWillMountWarnings = [])); - var componentWillReceivePropsUniqueNames = new Set(); - 0 < pendingComponentWillReceivePropsWarnings.length && - (pendingComponentWillReceivePropsWarnings.forEach(function (fiber) { - componentWillReceivePropsUniqueNames.add( - getComponentNameFromFiber(fiber) || "Component" - ); - didWarnAboutUnsafeLifecycles.add(fiber.type); - }), - (pendingComponentWillReceivePropsWarnings = [])); - var UNSAFE_componentWillReceivePropsUniqueNames = new Set(); - 0 < pendingUNSAFE_ComponentWillReceivePropsWarnings.length && - (pendingUNSAFE_ComponentWillReceivePropsWarnings.forEach( - function (fiber) { - UNSAFE_componentWillReceivePropsUniqueNames.add( - getComponentNameFromFiber(fiber) || "Component" + // $FlowFixMe[invalid-constructor] Flow no longer supports calling new on functions + var root = new FiberRootNode( + containerInfo, + tag, + hydrate, + identifierPrefix, + onRecoverableError, + formState + ); + // stateNode is any. + + var uninitializedFiber = createHostRootFiber(tag, isStrictMode); + root.current = uninitializedFiber; + uninitializedFiber.stateNode = root; + + { + var _initialState = { + element: initialChildren, + isDehydrated: hydrate, + cache: null // not enabled yet + }; + uninitializedFiber.memoizedState = _initialState; + } + + initializeUpdateQueue(uninitializedFiber); + return root; + } + + var ReactVersion = "18.3.0-canary-9372c6311-20240315"; + + function createPortal$1( + children, + containerInfo, // TODO: figure out the API for cross-renderer implementation. + implementation + ) { + var key = + arguments.length > 3 && arguments[3] !== undefined + ? arguments[3] + : null; + + { + checkKeyStringCoercion(key); + } + + return { + // This tag allow us to uniquely identify this as a React Portal + $$typeof: REACT_PORTAL_TYPE, + key: key == null ? null : "" + key, + children: children, + containerInfo: containerInfo, + implementation: implementation + }; + } + + // Might add PROFILE later. + + var didWarnAboutNestedUpdates; + var didWarnAboutFindNodeInStrictMode; + + { + didWarnAboutNestedUpdates = false; + didWarnAboutFindNodeInStrictMode = {}; + } + + function getContextForSubtree(parentComponent) { + if (!parentComponent) { + return emptyContextObject; + } + + var fiber = get(parentComponent); + var parentContext = findCurrentUnmaskedContext(); + + if (fiber.tag === ClassComponent) { + var Component = fiber.type; + + if (isContextProvider()) { + return processChildContext(fiber, Component, parentContext); + } + } + + return parentContext; + } + + function findHostInstanceWithWarning(component, methodName) { + { + var fiber = get(component); + + if (fiber === undefined) { + if (typeof component.render === "function") { + throw new Error("Unable to find node on an unmounted component."); + } else { + var keys = Object.keys(component).join(","); + throw new Error( + "Argument appears to not be a ReactComponent. Keys: " + keys ); - didWarnAboutUnsafeLifecycles.add(fiber.type); - } - ), - (pendingUNSAFE_ComponentWillReceivePropsWarnings = [])); - var componentWillUpdateUniqueNames = new Set(); - 0 < pendingComponentWillUpdateWarnings.length && - (pendingComponentWillUpdateWarnings.forEach(function (fiber) { - componentWillUpdateUniqueNames.add( - getComponentNameFromFiber(fiber) || "Component" - ); - didWarnAboutUnsafeLifecycles.add(fiber.type); - }), - (pendingComponentWillUpdateWarnings = [])); - var UNSAFE_componentWillUpdateUniqueNames = new Set(); - 0 < pendingUNSAFE_ComponentWillUpdateWarnings.length && - (pendingUNSAFE_ComponentWillUpdateWarnings.forEach(function (fiber) { - UNSAFE_componentWillUpdateUniqueNames.add( - getComponentNameFromFiber(fiber) || "Component" - ); - didWarnAboutUnsafeLifecycles.add(fiber.type); - }), - (pendingUNSAFE_ComponentWillUpdateWarnings = [])); - if (0 < UNSAFE_componentWillMountUniqueNames.size) { - var sortedNames = setToSortedString( - UNSAFE_componentWillMountUniqueNames - ); - error$jscomp$0( - "Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. See https://react.dev/link/unsafe-component-lifecycles for details.\n\n* Move code with side effects to componentDidMount, and set initial state in the constructor.\n\nPlease update the following components: %s", - sortedNames - ); + } + } + + var hostFiber = findCurrentHostFiber(fiber); + + if (hostFiber === null) { + return null; + } + + if (hostFiber.mode & StrictLegacyMode) { + var componentName = getComponentNameFromFiber(fiber) || "Component"; + + if (!didWarnAboutFindNodeInStrictMode[componentName]) { + didWarnAboutFindNodeInStrictMode[componentName] = true; + var previousFiber = current; + + try { + setCurrentFiber(hostFiber); + + if (fiber.mode & StrictLegacyMode) { + error( + "%s is deprecated in StrictMode. " + + "%s was passed an instance of %s which is inside StrictMode. " + + "Instead, add a ref directly to the element you want to reference. " + + "Learn more about using refs safely here: " + + "https://react.dev/link/strict-mode-find-node", + methodName, + methodName, + componentName + ); + } else { + error( + "%s is deprecated in StrictMode. " + + "%s was passed an instance of %s which renders StrictMode children. " + + "Instead, add a ref directly to the element you want to reference. " + + "Learn more about using refs safely here: " + + "https://react.dev/link/strict-mode-find-node", + methodName, + methodName, + componentName + ); + } + } finally { + // Ideally this should reset to previous but this shouldn't be called in + // render and there's another warning for that anyway. + if (previousFiber) { + setCurrentFiber(previousFiber); + } else { + resetCurrentFiber(); + } + } + } + } + + return getPublicInstance(hostFiber.stateNode); } - 0 < UNSAFE_componentWillReceivePropsUniqueNames.size && - ((sortedNames = setToSortedString( - UNSAFE_componentWillReceivePropsUniqueNames - )), - error$jscomp$0( - "Using UNSAFE_componentWillReceiveProps in strict mode is not recommended and may indicate bugs in your code. See https://react.dev/link/unsafe-component-lifecycles for details.\n\n* Move data fetching code or side effects to componentDidUpdate.\n* If you're updating state whenever props change, refactor your code to use memoization techniques or move it to static getDerivedStateFromProps. Learn more at: https://react.dev/link/derived-state\n\nPlease update the following components: %s", - sortedNames - )); - 0 < UNSAFE_componentWillUpdateUniqueNames.size && - ((sortedNames = setToSortedString( - UNSAFE_componentWillUpdateUniqueNames - )), - error$jscomp$0( - "Using UNSAFE_componentWillUpdate in strict mode is not recommended and may indicate bugs in your code. See https://react.dev/link/unsafe-component-lifecycles for details.\n\n* Move data fetching code or side effects to componentDidUpdate.\n\nPlease update the following components: %s", - sortedNames - )); - 0 < componentWillMountUniqueNames.size && - ((sortedNames = setToSortedString(componentWillMountUniqueNames)), - warn( - "componentWillMount has been renamed, and is not recommended for use. See https://react.dev/link/unsafe-component-lifecycles for details.\n\n* Move code with side effects to componentDidMount, and set initial state in the constructor.\n* Rename componentWillMount to UNSAFE_componentWillMount to suppress this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\nPlease update the following components: %s", - sortedNames - )); - 0 < componentWillReceivePropsUniqueNames.size && - ((sortedNames = setToSortedString( - componentWillReceivePropsUniqueNames - )), - warn( - "componentWillReceiveProps has been renamed, and is not recommended for use. See https://react.dev/link/unsafe-component-lifecycles for details.\n\n* Move data fetching code or side effects to componentDidUpdate.\n* If you're updating state whenever props change, refactor your code to use memoization techniques or move it to static getDerivedStateFromProps. Learn more at: https://react.dev/link/derived-state\n* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\nPlease update the following components: %s", - sortedNames - )); - 0 < componentWillUpdateUniqueNames.size && - ((sortedNames = setToSortedString(componentWillUpdateUniqueNames)), - warn( - "componentWillUpdate has been renamed, and is not recommended for use. See https://react.dev/link/unsafe-component-lifecycles for details.\n\n* Move data fetching code or side effects to componentDidUpdate.\n* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\nPlease update the following components: %s", - sortedNames - )); - }; - var pendingLegacyContextWarning = new Map(), - didWarnAboutLegacyContext = new Set(); - ReactStrictModeWarnings.recordLegacyContextWarning = function ( - fiber, - instance + } + + function createContainer( + containerInfo, + tag, + hydrationCallbacks, + isStrictMode, + concurrentUpdatesByDefaultOverride, + identifierPrefix, + onRecoverableError, + transitionCallbacks ) { - var strictRoot = null; - for (var node = fiber; null !== node; ) - node.mode & 8 && (strictRoot = node), (node = node.return); - null === strictRoot - ? error$jscomp$0( - "Expected to find a StrictMode component in a strict mode tree. This error is likely caused by a bug in React. Please file an issue." - ) - : !didWarnAboutLegacyContext.has(fiber.type) && - ((node = pendingLegacyContextWarning.get(strictRoot)), - null != fiber.type.contextTypes || - null != fiber.type.childContextTypes || - (null !== instance && - "function" === typeof instance.getChildContext)) && - (void 0 === node && - ((node = []), pendingLegacyContextWarning.set(strictRoot, node)), - node.push(fiber)); - }; - ReactStrictModeWarnings.flushLegacyContextWarning = function () { - pendingLegacyContextWarning.forEach(function (fiberArray) { - if (0 !== fiberArray.length) { - var firstFiber = fiberArray[0], - uniqueNames = new Set(); - fiberArray.forEach(function (fiber) { - uniqueNames.add(getComponentNameFromFiber(fiber) || "Component"); - didWarnAboutLegacyContext.add(fiber.type); - }); - var sortedNames = setToSortedString(uniqueNames); - runWithFiberInDEV(firstFiber, function () { - error$jscomp$0( - "Legacy context API has been detected within a strict-mode tree.\n\nThe old API will be supported in all 16.x releases, but applications using it should migrate to the new version.\n\nPlease update the following components: %s\n\nLearn more about this warning here: https://react.dev/link/legacy-context", - sortedNames - ); - }); - } - }); - }; - ReactStrictModeWarnings.discardPendingWarnings = function () { - pendingComponentWillMountWarnings = []; - pendingUNSAFE_ComponentWillMountWarnings = []; - pendingComponentWillReceivePropsWarnings = []; - pendingUNSAFE_ComponentWillReceivePropsWarnings = []; - pendingComponentWillUpdateWarnings = []; - pendingUNSAFE_ComponentWillUpdateWarnings = []; - pendingLegacyContextWarning = new Map(); - }; - var SuspenseException = Error( - "Suspense Exception: This is not a real error! It's an implementation detail of `use` to interrupt the current render. You must either rethrow it immediately, or move the `use` call outside of the `try/catch` block. Capturing without rethrowing will lead to unexpected behavior.\n\nTo handle async errors, wrap your component in an error boundary, or call the promise's `.catch` method and pass the result to `use`" - ), - SuspenseyCommitException = Error( - "Suspense Exception: This is not a real error, and should not leak into userspace. If you're seeing this, it's likely a bug in React." - ), - noopSuspenseyCommitThenable = { - then: function () { - error$jscomp$0( - 'Internal React error: A listener was unexpectedly attached to a "noop" thenable. This is a bug in React. Please file an issue.' + var hydrate = false; + var initialChildren = null; + return createFiberRoot( + containerInfo, + tag, + hydrate, + initialChildren, + hydrationCallbacks, + isStrictMode, + concurrentUpdatesByDefaultOverride, + identifierPrefix, + onRecoverableError, + transitionCallbacks, + null + ); + } + function updateContainer(element, container, parentComponent, callback) { + { + onScheduleRoot(container, element); + } + + var current$1 = container.current; + var lane = requestUpdateLane(current$1); + + var context = getContextForSubtree(parentComponent); + + if (container.context === null) { + container.context = context; + } else { + container.pendingContext = context; + } + + { + if (isRendering && current !== null && !didWarnAboutNestedUpdates) { + didWarnAboutNestedUpdates = true; + + error( + "Render methods should be a pure function of props and state; " + + "triggering nested component updates from render is not allowed. " + + "If necessary, trigger nested updates in componentDidUpdate.\n\n" + + "Check the render method of %s.", + getComponentNameFromFiber(current) || "Unknown" ); } - }, - suspendedThenable = null, - needsToResetSuspendedThenableDEV = !1, - thenableState$1 = null, - thenableIndexCounter$1 = 0, - currentDebugInfo = null, - didWarnAboutMaps; - var didWarnAboutGenerators = (didWarnAboutMaps = !1); - var ownerHasKeyUseWarning = {}; - var ownerHasFunctionTypeWarning = {}; - var ownerHasSymbolTypeWarning = {}; - warnForMissingKey = function (returnFiber, workInProgress, child) { - if ( - null !== child && - "object" === typeof child && - child._store && - ((!child._store.validated && null == child.key) || - 2 === child._store.validated) - ) { - if ("object" !== typeof child._store) - throw Error( - "React Component in warnForMissingKey should have a _store. This error is likely caused by a bug in React. Please file an issue." - ); - child._store.validated = 1; - var componentName = getComponentNameFromFiber(returnFiber), - componentKey = componentName || "null"; - if (!ownerHasKeyUseWarning[componentKey]) { - ownerHasKeyUseWarning[componentKey] = !0; - child = child._owner; - returnFiber = returnFiber._debugOwner; - var currentComponentErrorInfo = ""; - returnFiber && - "number" === typeof returnFiber.tag && - (componentKey = getComponentNameFromFiber(returnFiber)) && - (currentComponentErrorInfo = - "\n\nCheck the render method of `" + componentKey + "`."); - currentComponentErrorInfo || - (componentName && - (currentComponentErrorInfo = - "\n\nCheck the top-level render call using <" + - componentName + - ">.")); - var childOwnerAppendix = ""; - null != child && - returnFiber !== child && - ((componentName = null), - "number" === typeof child.tag - ? (componentName = getComponentNameFromFiber(child)) - : "string" === typeof child.name && (componentName = child.name), - componentName && - (childOwnerAppendix = - " It was passed a child from " + componentName + ".")); - runWithFiberInDEV(workInProgress, function () { - error$jscomp$0( - 'Each child in a list should have a unique "key" prop.%s%s See https://react.dev/link/warning-keys for more information.', - currentComponentErrorInfo, - childOwnerAppendix + } + + var update = createUpdate(lane); // Caution: React DevTools currently depends on this property + // being called "element". + + update.payload = { + element: element + }; + callback = callback === undefined ? null : callback; + + if (callback !== null) { + { + if (typeof callback !== "function") { + error( + "Expected the last optional `callback` argument to be a " + + "function. Instead received: %s.", + callback ); - }); + } } + + update.callback = callback; } - }; - var reconcileChildFibers = createChildReconciler(!0), - mountChildFibers = createChildReconciler(!1), - currentTreeHiddenStackCursor = createCursor(null), - prevEntangledRenderLanesCursor = createCursor(0), - suspenseHandlerStackCursor = createCursor(null), - shellBoundary = null, - SubtreeSuspenseContextMask = 1, - ForceSuspenseFallback = 2, - suspenseStackCursor = createCursor(0), - NoFlags = 0, - HasEffect = 1, - Insertion = 2, - Layout = 4, - Passive = 8, - didWarnUncachedGetSnapshot; - var didWarnAboutMismatchedHooksForComponent = new Set(); - var didWarnAboutUseWrappedInTryCatch = new Set(); - var didWarnAboutAsyncClientComponent = new Set(); - var didWarnAboutUseFormState = new Set(); - var renderLanes = 0, - currentlyRenderingFiber$1 = null, - currentHook = null, - workInProgressHook = null, - didScheduleRenderPhaseUpdate = !1, - didScheduleRenderPhaseUpdateDuringThisPass = !1, - shouldDoubleInvokeUserFnsInHooksDEV = !1, - thenableIndexCounter = 0, - thenableState = null, - globalClientIdCounter = 0, - RE_RENDER_LIMIT = 25, - currentHookNameInDev = null, - hookTypesDev = null, - hookTypesUpdateIndexDev = -1, - ignorePreviousDependencies = !1; - var createFunctionComponentUpdateQueue = function () { - return { lastEffect: null, events: null, stores: null, memoCache: null }; - }; - var ContextOnlyDispatcher = { - readContext: readContext, - use: use, - useCallback: throwInvalidHookError, - useContext: throwInvalidHookError, - useEffect: throwInvalidHookError, - useImperativeHandle: throwInvalidHookError, - useLayoutEffect: throwInvalidHookError, - useInsertionEffect: throwInvalidHookError, - useMemo: throwInvalidHookError, - useReducer: throwInvalidHookError, - useRef: throwInvalidHookError, - useState: throwInvalidHookError, - useDebugValue: throwInvalidHookError, - useDeferredValue: throwInvalidHookError, - useTransition: throwInvalidHookError, - useSyncExternalStore: throwInvalidHookError, - useId: throwInvalidHookError - }; - ContextOnlyDispatcher.useCacheRefresh = throwInvalidHookError; - ContextOnlyDispatcher.useMemoCache = throwInvalidHookError; - ContextOnlyDispatcher.useHostTransitionStatus = throwInvalidHookError; - ContextOnlyDispatcher.useFormState = throwInvalidHookError; - ContextOnlyDispatcher.useActionState = throwInvalidHookError; - ContextOnlyDispatcher.useOptimistic = throwInvalidHookError; - var HooksDispatcherOnMountInDEV = null, - HooksDispatcherOnMountWithHookTypesInDEV = null, - HooksDispatcherOnUpdateInDEV = null, - HooksDispatcherOnRerenderInDEV = null, - InvalidNestedHooksDispatcherOnMountInDEV = null, - InvalidNestedHooksDispatcherOnUpdateInDEV = null, - InvalidNestedHooksDispatcherOnRerenderInDEV = null; - HooksDispatcherOnMountInDEV = { - readContext: function (context) { - return readContext(context); - }, - use: use, - useCallback: function (callback, deps) { - currentHookNameInDev = "useCallback"; - mountHookTypesDev(); - checkDepsAreArrayDev(deps); - return mountCallback(callback, deps); - }, - useContext: function (context) { - currentHookNameInDev = "useContext"; - mountHookTypesDev(); - return readContext(context); - }, - useEffect: function (create, deps) { - currentHookNameInDev = "useEffect"; - mountHookTypesDev(); - checkDepsAreArrayDev(deps); - return mountEffect(create, deps); - }, - useImperativeHandle: function (ref, create, deps) { - currentHookNameInDev = "useImperativeHandle"; - mountHookTypesDev(); - checkDepsAreArrayDev(deps); - return mountImperativeHandle(ref, create, deps); - }, - useInsertionEffect: function (create, deps) { - currentHookNameInDev = "useInsertionEffect"; - mountHookTypesDev(); - checkDepsAreArrayDev(deps); - mountEffectImpl(4, Insertion, create, deps); - }, - useLayoutEffect: function (create, deps) { - currentHookNameInDev = "useLayoutEffect"; - mountHookTypesDev(); - checkDepsAreArrayDev(deps); - return mountLayoutEffect(create, deps); - }, - useMemo: function (create, deps) { - currentHookNameInDev = "useMemo"; - mountHookTypesDev(); - checkDepsAreArrayDev(deps); - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = InvalidNestedHooksDispatcherOnMountInDEV; - try { - return mountMemo(create, deps); - } finally { - ReactSharedInternals.H = prevDispatcher; - } - }, - useReducer: function (reducer, initialArg, init) { - currentHookNameInDev = "useReducer"; - mountHookTypesDev(); - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = InvalidNestedHooksDispatcherOnMountInDEV; - try { - return mountReducer(reducer, initialArg, init); - } finally { - ReactSharedInternals.H = prevDispatcher; - } - }, - useRef: function (initialValue) { - currentHookNameInDev = "useRef"; - mountHookTypesDev(); - return mountRef(initialValue); - }, - useState: function (initialState) { - currentHookNameInDev = "useState"; - mountHookTypesDev(); - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = InvalidNestedHooksDispatcherOnMountInDEV; - try { - return mountState(initialState); - } finally { - ReactSharedInternals.H = prevDispatcher; - } - }, - useDebugValue: function () { - currentHookNameInDev = "useDebugValue"; - mountHookTypesDev(); - }, - useDeferredValue: function (value, initialValue) { - currentHookNameInDev = "useDeferredValue"; - mountHookTypesDev(); - return mountDeferredValue(value, initialValue); - }, - useTransition: function () { - currentHookNameInDev = "useTransition"; - mountHookTypesDev(); - return mountTransition(); - }, - useSyncExternalStore: function (subscribe, getSnapshot) { - currentHookNameInDev = "useSyncExternalStore"; - mountHookTypesDev(); - return mountSyncExternalStore(subscribe, getSnapshot); - }, - useId: function () { - currentHookNameInDev = "useId"; - mountHookTypesDev(); - return mountId(); - }, - useCacheRefresh: function () { - currentHookNameInDev = "useCacheRefresh"; - mountHookTypesDev(); - return mountRefresh(); + + var root = enqueueUpdate(current$1, update, lane); + + if (root !== null) { + scheduleUpdateOnFiber(root, current$1, lane); + entangleTransitions(root, current$1, lane); } + + return lane; + } + function getPublicRootInstance(container) { + var containerFiber = container.current; + + if (!containerFiber.child) { + return null; + } + + switch (containerFiber.child.tag) { + case HostSingleton: + case HostComponent: + return getPublicInstance(containerFiber.child.stateNode); + + default: + return containerFiber.child.stateNode; + } + } + + var shouldErrorImpl = function (fiber) { + return null; }; - HooksDispatcherOnMountInDEV.useMemoCache = useMemoCache; - HooksDispatcherOnMountInDEV.useHostTransitionStatus = - useHostTransitionStatus; - HooksDispatcherOnMountInDEV.useFormState = function (action, initialState) { - currentHookNameInDev = "useFormState"; - mountHookTypesDev(); - return mountActionState(action, initialState); - }; - HooksDispatcherOnMountInDEV.useActionState = function ( - action, - initialState - ) { - currentHookNameInDev = "useActionState"; - mountHookTypesDev(); - return mountActionState(action, initialState); - }; - HooksDispatcherOnMountInDEV.useOptimistic = function (passthrough) { - currentHookNameInDev = "useOptimistic"; - mountHookTypesDev(); - return mountOptimistic(passthrough); + + function shouldError(fiber) { + return shouldErrorImpl(fiber); + } + + var shouldSuspendImpl = function (fiber) { + return false; }; - HooksDispatcherOnMountWithHookTypesInDEV = { - readContext: function (context) { - return readContext(context); - }, - use: use, - useCallback: function (callback, deps) { - currentHookNameInDev = "useCallback"; - updateHookTypesDev(); - return mountCallback(callback, deps); - }, - useContext: function (context) { - currentHookNameInDev = "useContext"; - updateHookTypesDev(); - return readContext(context); - }, - useEffect: function (create, deps) { - currentHookNameInDev = "useEffect"; - updateHookTypesDev(); - return mountEffect(create, deps); - }, - useImperativeHandle: function (ref, create, deps) { - currentHookNameInDev = "useImperativeHandle"; - updateHookTypesDev(); - return mountImperativeHandle(ref, create, deps); - }, - useInsertionEffect: function (create, deps) { - currentHookNameInDev = "useInsertionEffect"; - updateHookTypesDev(); - mountEffectImpl(4, Insertion, create, deps); - }, - useLayoutEffect: function (create, deps) { - currentHookNameInDev = "useLayoutEffect"; - updateHookTypesDev(); - return mountLayoutEffect(create, deps); - }, - useMemo: function (create, deps) { - currentHookNameInDev = "useMemo"; - updateHookTypesDev(); - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = InvalidNestedHooksDispatcherOnMountInDEV; - try { - return mountMemo(create, deps); - } finally { - ReactSharedInternals.H = prevDispatcher; + + function shouldSuspend(fiber) { + return shouldSuspendImpl(fiber); + } + var overrideHookState = null; + var overrideHookStateDeletePath = null; + var overrideHookStateRenamePath = null; + var overrideProps = null; + var overridePropsDeletePath = null; + var overridePropsRenamePath = null; + var scheduleUpdate = null; + var setErrorHandler = null; + var setSuspenseHandler = null; + + { + var copyWithDeleteImpl = function (obj, path, index) { + var key = path[index]; + var updated = isArray(obj) ? obj.slice() : assign({}, obj); + + if (index + 1 === path.length) { + if (isArray(updated)) { + updated.splice(key, 1); + } else { + delete updated[key]; + } + + return updated; + } // $FlowFixMe[incompatible-use] number or string is fine here + + updated[key] = copyWithDeleteImpl(obj[key], path, index + 1); + return updated; + }; + + var copyWithDelete = function (obj, path) { + return copyWithDeleteImpl(obj, path, 0); + }; + + var copyWithRenameImpl = function (obj, oldPath, newPath, index) { + var oldKey = oldPath[index]; + var updated = isArray(obj) ? obj.slice() : assign({}, obj); + + if (index + 1 === oldPath.length) { + var newKey = newPath[index]; // $FlowFixMe[incompatible-use] number or string is fine here + + updated[newKey] = updated[oldKey]; + + if (isArray(updated)) { + updated.splice(oldKey, 1); + } else { + delete updated[oldKey]; + } + } else { + // $FlowFixMe[incompatible-use] number or string is fine here + updated[oldKey] = copyWithRenameImpl( + // $FlowFixMe[incompatible-use] number or string is fine here + obj[oldKey], + oldPath, + newPath, + index + 1 + ); } - }, - useReducer: function (reducer, initialArg, init) { - currentHookNameInDev = "useReducer"; - updateHookTypesDev(); - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = InvalidNestedHooksDispatcherOnMountInDEV; - try { - return mountReducer(reducer, initialArg, init); - } finally { - ReactSharedInternals.H = prevDispatcher; + + return updated; + }; + + var copyWithRename = function (obj, oldPath, newPath) { + if (oldPath.length !== newPath.length) { + warn("copyWithRename() expects paths of the same length"); + + return; + } else { + for (var i = 0; i < newPath.length - 1; i++) { + if (oldPath[i] !== newPath[i]) { + warn( + "copyWithRename() expects paths to be the same except for the deepest key" + ); + + return; + } + } } - }, - useRef: function (initialValue) { - currentHookNameInDev = "useRef"; - updateHookTypesDev(); - return mountRef(initialValue); - }, - useState: function (initialState) { - currentHookNameInDev = "useState"; - updateHookTypesDev(); - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = InvalidNestedHooksDispatcherOnMountInDEV; - try { - return mountState(initialState); - } finally { - ReactSharedInternals.H = prevDispatcher; + + return copyWithRenameImpl(obj, oldPath, newPath, 0); + }; + + var copyWithSetImpl = function (obj, path, index, value) { + if (index >= path.length) { + return value; } - }, - useDebugValue: function () { - currentHookNameInDev = "useDebugValue"; - updateHookTypesDev(); - }, - useDeferredValue: function (value, initialValue) { - currentHookNameInDev = "useDeferredValue"; - updateHookTypesDev(); - return mountDeferredValue(value, initialValue); - }, - useTransition: function () { - currentHookNameInDev = "useTransition"; - updateHookTypesDev(); - return mountTransition(); - }, - useSyncExternalStore: function (subscribe, getSnapshot) { - currentHookNameInDev = "useSyncExternalStore"; - updateHookTypesDev(); - return mountSyncExternalStore(subscribe, getSnapshot); - }, - useId: function () { - currentHookNameInDev = "useId"; - updateHookTypesDev(); - return mountId(); - }, - useCacheRefresh: function () { - currentHookNameInDev = "useCacheRefresh"; - updateHookTypesDev(); - return mountRefresh(); - } - }; - HooksDispatcherOnMountWithHookTypesInDEV.useMemoCache = useMemoCache; - HooksDispatcherOnMountWithHookTypesInDEV.useHostTransitionStatus = - useHostTransitionStatus; - HooksDispatcherOnMountWithHookTypesInDEV.useFormState = function ( - action, - initialState - ) { - currentHookNameInDev = "useFormState"; - updateHookTypesDev(); - warnOnUseFormStateInDev(); - return mountActionState(action, initialState); - }; - HooksDispatcherOnMountWithHookTypesInDEV.useActionState = function ( - action, - initialState - ) { - currentHookNameInDev = "useActionState"; - updateHookTypesDev(); - return mountActionState(action, initialState); - }; - HooksDispatcherOnMountWithHookTypesInDEV.useOptimistic = function ( - passthrough - ) { - currentHookNameInDev = "useOptimistic"; - updateHookTypesDev(); - return mountOptimistic(passthrough); - }; - HooksDispatcherOnUpdateInDEV = { - readContext: function (context) { - return readContext(context); - }, - use: use, - useCallback: function (callback, deps) { - currentHookNameInDev = "useCallback"; - updateHookTypesDev(); - return updateCallback(callback, deps); - }, - useContext: function (context) { - currentHookNameInDev = "useContext"; - updateHookTypesDev(); - return readContext(context); - }, - useEffect: function (create, deps) { - currentHookNameInDev = "useEffect"; - updateHookTypesDev(); - updateEffectImpl(2048, Passive, create, deps); - }, - useImperativeHandle: function (ref, create, deps) { - currentHookNameInDev = "useImperativeHandle"; - updateHookTypesDev(); - return updateImperativeHandle(ref, create, deps); - }, - useInsertionEffect: function (create, deps) { - currentHookNameInDev = "useInsertionEffect"; - updateHookTypesDev(); - return updateEffectImpl(4, Insertion, create, deps); - }, - useLayoutEffect: function (create, deps) { - currentHookNameInDev = "useLayoutEffect"; - updateHookTypesDev(); - return updateEffectImpl(4, Layout, create, deps); - }, - useMemo: function (create, deps) { - currentHookNameInDev = "useMemo"; - updateHookTypesDev(); - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = InvalidNestedHooksDispatcherOnUpdateInDEV; - try { - return updateMemo(create, deps); - } finally { - ReactSharedInternals.H = prevDispatcher; + + var key = path[index]; + var updated = isArray(obj) ? obj.slice() : assign({}, obj); // $FlowFixMe[incompatible-use] number or string is fine here + + updated[key] = copyWithSetImpl(obj[key], path, index + 1, value); + return updated; + }; + + var copyWithSet = function (obj, path, value) { + return copyWithSetImpl(obj, path, 0, value); + }; + + var findHook = function (fiber, id) { + // For now, the "id" of stateful hooks is just the stateful hook index. + // This may change in the future with e.g. nested hooks. + var currentHook = fiber.memoizedState; + + while (currentHook !== null && id > 0) { + currentHook = currentHook.next; + id--; } - }, - useReducer: function (reducer, initialArg, init) { - currentHookNameInDev = "useReducer"; - updateHookTypesDev(); - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = InvalidNestedHooksDispatcherOnUpdateInDEV; - try { - return updateReducer(reducer, initialArg, init); - } finally { - ReactSharedInternals.H = prevDispatcher; + + return currentHook; + }; // Support DevTools editable values for useState and useReducer. + + overrideHookState = function (fiber, id, path, value) { + var hook = findHook(fiber, id); + + if (hook !== null) { + var newState = copyWithSet(hook.memoizedState, path, value); + hook.memoizedState = newState; + hook.baseState = newState; // We aren't actually adding an update to the queue, + // because there is no update we can add for useReducer hooks that won't trigger an error. + // (There's no appropriate action type for DevTools overrides.) + // As a result though, React will see the scheduled update as a noop and bailout. + // Shallow cloning props works as a workaround for now to bypass the bailout check. + + fiber.memoizedProps = assign({}, fiber.memoizedProps); + var root = enqueueConcurrentRenderForLane(fiber, SyncLane); + + if (root !== null) { + scheduleUpdateOnFiber(root, fiber, SyncLane); + } } - }, - useRef: function () { - currentHookNameInDev = "useRef"; - updateHookTypesDev(); - return updateWorkInProgressHook().memoizedState; - }, - useState: function () { - currentHookNameInDev = "useState"; - updateHookTypesDev(); - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = InvalidNestedHooksDispatcherOnUpdateInDEV; - try { - return updateReducer(basicStateReducer); - } finally { - ReactSharedInternals.H = prevDispatcher; + }; + + overrideHookStateDeletePath = function (fiber, id, path) { + var hook = findHook(fiber, id); + + if (hook !== null) { + var newState = copyWithDelete(hook.memoizedState, path); + hook.memoizedState = newState; + hook.baseState = newState; // We aren't actually adding an update to the queue, + // because there is no update we can add for useReducer hooks that won't trigger an error. + // (There's no appropriate action type for DevTools overrides.) + // As a result though, React will see the scheduled update as a noop and bailout. + // Shallow cloning props works as a workaround for now to bypass the bailout check. + + fiber.memoizedProps = assign({}, fiber.memoizedProps); + var root = enqueueConcurrentRenderForLane(fiber, SyncLane); + + if (root !== null) { + scheduleUpdateOnFiber(root, fiber, SyncLane); + } } - }, - useDebugValue: function () { - currentHookNameInDev = "useDebugValue"; - updateHookTypesDev(); - }, - useDeferredValue: function (value, initialValue) { - currentHookNameInDev = "useDeferredValue"; - updateHookTypesDev(); - return updateDeferredValue(value, initialValue); - }, - useTransition: function () { - currentHookNameInDev = "useTransition"; - updateHookTypesDev(); - return updateTransition(); - }, - useSyncExternalStore: function (subscribe, getSnapshot) { - currentHookNameInDev = "useSyncExternalStore"; - updateHookTypesDev(); - return updateSyncExternalStore(subscribe, getSnapshot); - }, - useId: function () { - currentHookNameInDev = "useId"; - updateHookTypesDev(); - return updateWorkInProgressHook().memoizedState; - }, - useCacheRefresh: function () { - currentHookNameInDev = "useCacheRefresh"; - updateHookTypesDev(); - return updateWorkInProgressHook().memoizedState; - } - }; - HooksDispatcherOnUpdateInDEV.useMemoCache = useMemoCache; - HooksDispatcherOnUpdateInDEV.useHostTransitionStatus = - useHostTransitionStatus; - HooksDispatcherOnUpdateInDEV.useFormState = function (action) { - currentHookNameInDev = "useFormState"; - updateHookTypesDev(); - warnOnUseFormStateInDev(); - return updateActionState(action); - }; - HooksDispatcherOnUpdateInDEV.useActionState = function (action) { - currentHookNameInDev = "useActionState"; - updateHookTypesDev(); - return updateActionState(action); - }; - HooksDispatcherOnUpdateInDEV.useOptimistic = function ( - passthrough, - reducer - ) { - currentHookNameInDev = "useOptimistic"; - updateHookTypesDev(); - return updateOptimistic(passthrough, reducer); - }; - HooksDispatcherOnRerenderInDEV = { - readContext: function (context) { - return readContext(context); - }, - use: use, - useCallback: function (callback, deps) { - currentHookNameInDev = "useCallback"; - updateHookTypesDev(); - return updateCallback(callback, deps); - }, - useContext: function (context) { - currentHookNameInDev = "useContext"; - updateHookTypesDev(); - return readContext(context); - }, - useEffect: function (create, deps) { - currentHookNameInDev = "useEffect"; - updateHookTypesDev(); - updateEffectImpl(2048, Passive, create, deps); - }, - useImperativeHandle: function (ref, create, deps) { - currentHookNameInDev = "useImperativeHandle"; - updateHookTypesDev(); - return updateImperativeHandle(ref, create, deps); - }, - useInsertionEffect: function (create, deps) { - currentHookNameInDev = "useInsertionEffect"; - updateHookTypesDev(); - return updateEffectImpl(4, Insertion, create, deps); - }, - useLayoutEffect: function (create, deps) { - currentHookNameInDev = "useLayoutEffect"; - updateHookTypesDev(); - return updateEffectImpl(4, Layout, create, deps); - }, - useMemo: function (create, deps) { - currentHookNameInDev = "useMemo"; - updateHookTypesDev(); - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = InvalidNestedHooksDispatcherOnRerenderInDEV; - try { - return updateMemo(create, deps); - } finally { - ReactSharedInternals.H = prevDispatcher; + }; + + overrideHookStateRenamePath = function (fiber, id, oldPath, newPath) { + var hook = findHook(fiber, id); + + if (hook !== null) { + var newState = copyWithRename(hook.memoizedState, oldPath, newPath); + hook.memoizedState = newState; + hook.baseState = newState; // We aren't actually adding an update to the queue, + // because there is no update we can add for useReducer hooks that won't trigger an error. + // (There's no appropriate action type for DevTools overrides.) + // As a result though, React will see the scheduled update as a noop and bailout. + // Shallow cloning props works as a workaround for now to bypass the bailout check. + + fiber.memoizedProps = assign({}, fiber.memoizedProps); + var root = enqueueConcurrentRenderForLane(fiber, SyncLane); + + if (root !== null) { + scheduleUpdateOnFiber(root, fiber, SyncLane); + } } - }, - useReducer: function (reducer, initialArg, init) { - currentHookNameInDev = "useReducer"; - updateHookTypesDev(); - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = InvalidNestedHooksDispatcherOnRerenderInDEV; - try { - return rerenderReducer(reducer, initialArg, init); - } finally { - ReactSharedInternals.H = prevDispatcher; + }; // Support DevTools props for function components, forwardRef, memo, host components, etc. + + overrideProps = function (fiber, path, value) { + fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value); + + if (fiber.alternate) { + fiber.alternate.pendingProps = fiber.pendingProps; } - }, - useRef: function () { - currentHookNameInDev = "useRef"; - updateHookTypesDev(); - return updateWorkInProgressHook().memoizedState; - }, - useState: function () { - currentHookNameInDev = "useState"; - updateHookTypesDev(); - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = InvalidNestedHooksDispatcherOnRerenderInDEV; - try { - return rerenderReducer(basicStateReducer); - } finally { - ReactSharedInternals.H = prevDispatcher; + + var root = enqueueConcurrentRenderForLane(fiber, SyncLane); + + if (root !== null) { + scheduleUpdateOnFiber(root, fiber, SyncLane); } - }, - useDebugValue: function () { - currentHookNameInDev = "useDebugValue"; - updateHookTypesDev(); - }, - useDeferredValue: function (value, initialValue) { - currentHookNameInDev = "useDeferredValue"; - updateHookTypesDev(); - return rerenderDeferredValue(value, initialValue); - }, - useTransition: function () { - currentHookNameInDev = "useTransition"; - updateHookTypesDev(); - return rerenderTransition(); - }, - useSyncExternalStore: function (subscribe, getSnapshot) { - currentHookNameInDev = "useSyncExternalStore"; - updateHookTypesDev(); - return updateSyncExternalStore(subscribe, getSnapshot); - }, - useId: function () { - currentHookNameInDev = "useId"; - updateHookTypesDev(); - return updateWorkInProgressHook().memoizedState; - }, - useCacheRefresh: function () { - currentHookNameInDev = "useCacheRefresh"; - updateHookTypesDev(); - return updateWorkInProgressHook().memoizedState; - } - }; - HooksDispatcherOnRerenderInDEV.useMemoCache = useMemoCache; - HooksDispatcherOnRerenderInDEV.useHostTransitionStatus = - useHostTransitionStatus; - HooksDispatcherOnRerenderInDEV.useFormState = function (action) { - currentHookNameInDev = "useFormState"; - updateHookTypesDev(); - warnOnUseFormStateInDev(); - return rerenderActionState(action); - }; - HooksDispatcherOnRerenderInDEV.useActionState = function (action) { - currentHookNameInDev = "useActionState"; - updateHookTypesDev(); - return rerenderActionState(action); - }; - HooksDispatcherOnRerenderInDEV.useOptimistic = function ( - passthrough, - reducer - ) { - currentHookNameInDev = "useOptimistic"; - updateHookTypesDev(); - return rerenderOptimistic(passthrough, reducer); - }; - InvalidNestedHooksDispatcherOnMountInDEV = { - readContext: function (context) { - warnInvalidContextAccess(); - return readContext(context); - }, - use: function (usable) { - warnInvalidHookAccess(); - return use(usable); - }, - useCallback: function (callback, deps) { - currentHookNameInDev = "useCallback"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountCallback(callback, deps); - }, - useContext: function (context) { - currentHookNameInDev = "useContext"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return readContext(context); - }, - useEffect: function (create, deps) { - currentHookNameInDev = "useEffect"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountEffect(create, deps); - }, - useImperativeHandle: function (ref, create, deps) { - currentHookNameInDev = "useImperativeHandle"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountImperativeHandle(ref, create, deps); - }, - useInsertionEffect: function (create, deps) { - currentHookNameInDev = "useInsertionEffect"; - warnInvalidHookAccess(); - mountHookTypesDev(); - mountEffectImpl(4, Insertion, create, deps); - }, - useLayoutEffect: function (create, deps) { - currentHookNameInDev = "useLayoutEffect"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountLayoutEffect(create, deps); - }, - useMemo: function (create, deps) { - currentHookNameInDev = "useMemo"; - warnInvalidHookAccess(); - mountHookTypesDev(); - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = InvalidNestedHooksDispatcherOnMountInDEV; - try { - return mountMemo(create, deps); - } finally { - ReactSharedInternals.H = prevDispatcher; + }; + + overridePropsDeletePath = function (fiber, path) { + fiber.pendingProps = copyWithDelete(fiber.memoizedProps, path); + + if (fiber.alternate) { + fiber.alternate.pendingProps = fiber.pendingProps; } - }, - useReducer: function (reducer, initialArg, init) { - currentHookNameInDev = "useReducer"; - warnInvalidHookAccess(); - mountHookTypesDev(); - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = InvalidNestedHooksDispatcherOnMountInDEV; - try { - return mountReducer(reducer, initialArg, init); - } finally { - ReactSharedInternals.H = prevDispatcher; + + var root = enqueueConcurrentRenderForLane(fiber, SyncLane); + + if (root !== null) { + scheduleUpdateOnFiber(root, fiber, SyncLane); } - }, - useRef: function (initialValue) { - currentHookNameInDev = "useRef"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountRef(initialValue); - }, - useState: function (initialState) { - currentHookNameInDev = "useState"; - warnInvalidHookAccess(); - mountHookTypesDev(); - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = InvalidNestedHooksDispatcherOnMountInDEV; - try { - return mountState(initialState); - } finally { - ReactSharedInternals.H = prevDispatcher; + }; + + overridePropsRenamePath = function (fiber, oldPath, newPath) { + fiber.pendingProps = copyWithRename( + fiber.memoizedProps, + oldPath, + newPath + ); + + if (fiber.alternate) { + fiber.alternate.pendingProps = fiber.pendingProps; } - }, - useDebugValue: function () { - currentHookNameInDev = "useDebugValue"; - warnInvalidHookAccess(); - mountHookTypesDev(); - }, - useDeferredValue: function (value, initialValue) { - currentHookNameInDev = "useDeferredValue"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountDeferredValue(value, initialValue); - }, - useTransition: function () { - currentHookNameInDev = "useTransition"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountTransition(); - }, - useSyncExternalStore: function (subscribe, getSnapshot) { - currentHookNameInDev = "useSyncExternalStore"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountSyncExternalStore(subscribe, getSnapshot); - }, - useId: function () { - currentHookNameInDev = "useId"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountId(); - }, - useCacheRefresh: function () { - currentHookNameInDev = "useCacheRefresh"; - mountHookTypesDev(); - return mountRefresh(); - }, - useMemoCache: function (size) { - warnInvalidHookAccess(); - return useMemoCache(size); + + var root = enqueueConcurrentRenderForLane(fiber, SyncLane); + + if (root !== null) { + scheduleUpdateOnFiber(root, fiber, SyncLane); + } + }; + + scheduleUpdate = function (fiber) { + var root = enqueueConcurrentRenderForLane(fiber, SyncLane); + + if (root !== null) { + scheduleUpdateOnFiber(root, fiber, SyncLane); + } + }; + + setErrorHandler = function (newShouldErrorImpl) { + shouldErrorImpl = newShouldErrorImpl; + }; + + setSuspenseHandler = function (newShouldSuspendImpl) { + shouldSuspendImpl = newShouldSuspendImpl; + }; + } + + function findHostInstanceByFiber(fiber) { + var hostFiber = findCurrentHostFiber(fiber); + + if (hostFiber === null) { + return null; } - }; - InvalidNestedHooksDispatcherOnMountInDEV.useHostTransitionStatus = - useHostTransitionStatus; - InvalidNestedHooksDispatcherOnMountInDEV.useFormState = function ( - action, - initialState - ) { - currentHookNameInDev = "useFormState"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountActionState(action, initialState); - }; - InvalidNestedHooksDispatcherOnMountInDEV.useActionState = function ( - action, - initialState - ) { - currentHookNameInDev = "useActionState"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountActionState(action, initialState); - }; - InvalidNestedHooksDispatcherOnMountInDEV.useOptimistic = function ( - passthrough - ) { - currentHookNameInDev = "useOptimistic"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountOptimistic(passthrough); - }; - InvalidNestedHooksDispatcherOnUpdateInDEV = { - readContext: function (context) { - warnInvalidContextAccess(); - return readContext(context); - }, - use: function (usable) { - warnInvalidHookAccess(); - return use(usable); - }, - useCallback: function (callback, deps) { - currentHookNameInDev = "useCallback"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateCallback(callback, deps); - }, - useContext: function (context) { - currentHookNameInDev = "useContext"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return readContext(context); - }, - useEffect: function (create, deps) { - currentHookNameInDev = "useEffect"; - warnInvalidHookAccess(); - updateHookTypesDev(); - updateEffectImpl(2048, Passive, create, deps); - }, - useImperativeHandle: function (ref, create, deps) { - currentHookNameInDev = "useImperativeHandle"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateImperativeHandle(ref, create, deps); - }, - useInsertionEffect: function (create, deps) { - currentHookNameInDev = "useInsertionEffect"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateEffectImpl(4, Insertion, create, deps); - }, - useLayoutEffect: function (create, deps) { - currentHookNameInDev = "useLayoutEffect"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateEffectImpl(4, Layout, create, deps); - }, - useMemo: function (create, deps) { - currentHookNameInDev = "useMemo"; - warnInvalidHookAccess(); - updateHookTypesDev(); - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = InvalidNestedHooksDispatcherOnUpdateInDEV; - try { - return updateMemo(create, deps); - } finally { - ReactSharedInternals.H = prevDispatcher; + + return hostFiber.stateNode; + } + + function emptyFindFiberByHostInstance(instance) { + return null; + } + + function getCurrentFiberForDevTools() { + return current; + } + + function injectIntoDevTools(devToolsConfig) { + var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance; + var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; + return injectInternals({ + bundleType: devToolsConfig.bundleType, + version: devToolsConfig.version, + rendererPackageName: devToolsConfig.rendererPackageName, + rendererConfig: devToolsConfig.rendererConfig, + overrideHookState: overrideHookState, + overrideHookStateDeletePath: overrideHookStateDeletePath, + overrideHookStateRenamePath: overrideHookStateRenamePath, + overrideProps: overrideProps, + overridePropsDeletePath: overridePropsDeletePath, + overridePropsRenamePath: overridePropsRenamePath, + setErrorHandler: setErrorHandler, + setSuspenseHandler: setSuspenseHandler, + scheduleUpdate: scheduleUpdate, + currentDispatcherRef: ReactCurrentDispatcher, + findHostInstanceByFiber: findHostInstanceByFiber, + findFiberByHostInstance: + findFiberByHostInstance || emptyFindFiberByHostInstance, + // React Refresh + findHostInstancesForRefresh: findHostInstancesForRefresh, + scheduleRefresh: scheduleRefresh, + scheduleRoot: scheduleRoot, + setRefreshHandler: setRefreshHandler, + // Enables DevTools to append owner stacks to error messages in DEV mode. + getCurrentFiber: getCurrentFiberForDevTools, + // Enables DevTools to detect reconciler version rather than renderer version + // which may not match for third party renderers. + reconcilerVersion: ReactVersion + }); + } + + var instanceCache = new Map(); + + function getInstanceFromTag(tag) { + return instanceCache.get(tag) || null; + } + + var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner; + function findHostInstance_DEPRECATED(componentOrHandle) { + { + var owner = ReactCurrentOwner.current; + + if (owner !== null && owner.stateNode !== null) { + if (!owner.stateNode._warnedAboutRefsInRender) { + error( + "%s is accessing findNodeHandle inside its render(). " + + "render() should be a pure function of props and state. It should " + + "never access something that requires stale data from the previous " + + "render, such as refs. Move this logic to componentDidMount and " + + "componentDidUpdate instead.", + getComponentNameFromType(owner.type) || "A component" + ); + } + + owner.stateNode._warnedAboutRefsInRender = true; } - }, - useReducer: function (reducer, initialArg, init) { - currentHookNameInDev = "useReducer"; - warnInvalidHookAccess(); - updateHookTypesDev(); - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = InvalidNestedHooksDispatcherOnUpdateInDEV; - try { - return updateReducer(reducer, initialArg, init); - } finally { - ReactSharedInternals.H = prevDispatcher; + } + + if (componentOrHandle == null) { + return null; + } // For compatibility with Fabric instances + + if ( + componentOrHandle.canonical && + componentOrHandle.canonical.publicInstance + ) { + // $FlowExpectedError[incompatible-return] Can't refine componentOrHandle as a Fabric instance + return componentOrHandle.canonical.publicInstance; + } // For compatibility with legacy renderer instances + + if (componentOrHandle._nativeTag) { + // $FlowFixMe[incompatible-exact] Necessary when running Flow on Fabric + // $FlowFixMe[incompatible-return] + return componentOrHandle; + } + + var hostInstance; + + { + hostInstance = findHostInstanceWithWarning( + componentOrHandle, + "findHostInstance_DEPRECATED" + ); + } // findHostInstance handles legacy vs. Fabric differences correctly + // $FlowFixMe[incompatible-exact] we need to fix the definition of `HostComponent` to use NativeMethods as an interface, not as a type. + // $FlowFixMe[incompatible-return] + + return hostInstance; + } + function findNodeHandle(componentOrHandle) { + { + var owner = ReactCurrentOwner.current; + + if (owner !== null && owner.stateNode !== null) { + if (!owner.stateNode._warnedAboutRefsInRender) { + error( + "%s is accessing findNodeHandle inside its render(). " + + "render() should be a pure function of props and state. It should " + + "never access something that requires stale data from the previous " + + "render, such as refs. Move this logic to componentDidMount and " + + "componentDidUpdate instead.", + getComponentNameFromType(owner.type) || "A component" + ); + } + + owner.stateNode._warnedAboutRefsInRender = true; } - }, - useRef: function () { - currentHookNameInDev = "useRef"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateWorkInProgressHook().memoizedState; - }, - useState: function () { - currentHookNameInDev = "useState"; - warnInvalidHookAccess(); - updateHookTypesDev(); - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = InvalidNestedHooksDispatcherOnUpdateInDEV; - try { - return updateReducer(basicStateReducer); - } finally { - ReactSharedInternals.H = prevDispatcher; + } + + if (componentOrHandle == null) { + return null; + } + + if (typeof componentOrHandle === "number") { + // Already a node handle + return componentOrHandle; + } // For compatibility with legacy renderer instances + + if (componentOrHandle._nativeTag) { + return componentOrHandle._nativeTag; + } // For compatibility with Fabric instances + + if ( + componentOrHandle.canonical != null && + componentOrHandle.canonical.nativeTag != null + ) { + return componentOrHandle.canonical.nativeTag; + } // For compatibility with Fabric public instances + + var nativeTag = + ReactNativePrivateInterface.getNativeTagFromPublicInstance( + componentOrHandle + ); + + if (nativeTag) { + return nativeTag; + } + + var hostInstance; + + { + hostInstance = findHostInstanceWithWarning( + componentOrHandle, + "findNodeHandle" + ); + } + + if (hostInstance == null) { + // $FlowFixMe[incompatible-return] Flow limitation in refining an opaque type + return hostInstance; + } + + if (hostInstance._nativeTag != null) { + // $FlowFixMe[incompatible-return] For compatibility with legacy renderer instances + return hostInstance._nativeTag; + } // $FlowFixMe[incompatible-call] Necessary when running Flow on the legacy renderer + + return ReactNativePrivateInterface.getNativeTagFromPublicInstance( + hostInstance + ); + } + function dispatchCommand(handle, command, args) { + var nativeTag = + handle._nativeTag != null + ? handle._nativeTag + : ReactNativePrivateInterface.getNativeTagFromPublicInstance(handle); + + if (nativeTag == null) { + { + error( + "dispatchCommand was called with a ref that isn't a " + + "native component. Use React.forwardRef to get access to the underlying native component" + ); } - }, - useDebugValue: function () { - currentHookNameInDev = "useDebugValue"; - warnInvalidHookAccess(); - updateHookTypesDev(); - }, - useDeferredValue: function (value, initialValue) { - currentHookNameInDev = "useDeferredValue"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateDeferredValue(value, initialValue); - }, - useTransition: function () { - currentHookNameInDev = "useTransition"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateTransition(); - }, - useSyncExternalStore: function (subscribe, getSnapshot) { - currentHookNameInDev = "useSyncExternalStore"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateSyncExternalStore(subscribe, getSnapshot); - }, - useId: function () { - currentHookNameInDev = "useId"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateWorkInProgressHook().memoizedState; - }, - useCacheRefresh: function () { - currentHookNameInDev = "useCacheRefresh"; - updateHookTypesDev(); - return updateWorkInProgressHook().memoizedState; - }, - useMemoCache: function (size) { - warnInvalidHookAccess(); - return useMemoCache(size); + + return; } - }; - InvalidNestedHooksDispatcherOnUpdateInDEV.useHostTransitionStatus = - useHostTransitionStatus; - InvalidNestedHooksDispatcherOnUpdateInDEV.useFormState = function (action) { - currentHookNameInDev = "useFormState"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateActionState(action); - }; - InvalidNestedHooksDispatcherOnUpdateInDEV.useActionState = function ( - action - ) { - currentHookNameInDev = "useActionState"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateActionState(action); - }; - InvalidNestedHooksDispatcherOnUpdateInDEV.useOptimistic = function ( - passthrough, - reducer - ) { - currentHookNameInDev = "useOptimistic"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateOptimistic(passthrough, reducer); - }; - InvalidNestedHooksDispatcherOnRerenderInDEV = { - readContext: function (context) { - warnInvalidContextAccess(); - return readContext(context); - }, - use: function (usable) { - warnInvalidHookAccess(); - return use(usable); - }, - useCallback: function (callback, deps) { - currentHookNameInDev = "useCallback"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateCallback(callback, deps); - }, - useContext: function (context) { - currentHookNameInDev = "useContext"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return readContext(context); - }, - useEffect: function (create, deps) { - currentHookNameInDev = "useEffect"; - warnInvalidHookAccess(); - updateHookTypesDev(); - updateEffectImpl(2048, Passive, create, deps); - }, - useImperativeHandle: function (ref, create, deps) { - currentHookNameInDev = "useImperativeHandle"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateImperativeHandle(ref, create, deps); - }, - useInsertionEffect: function (create, deps) { - currentHookNameInDev = "useInsertionEffect"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateEffectImpl(4, Insertion, create, deps); - }, - useLayoutEffect: function (create, deps) { - currentHookNameInDev = "useLayoutEffect"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateEffectImpl(4, Layout, create, deps); - }, - useMemo: function (create, deps) { - currentHookNameInDev = "useMemo"; - warnInvalidHookAccess(); - updateHookTypesDev(); - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = InvalidNestedHooksDispatcherOnUpdateInDEV; - try { - return updateMemo(create, deps); - } finally { - ReactSharedInternals.H = prevDispatcher; + + var node = ReactNativePrivateInterface.getNodeFromPublicInstance(handle); + + if (node != null) { + nativeFabricUIManager.dispatchCommand(node, command, args); + } else { + ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( + nativeTag, + command, + args + ); + } + } + function sendAccessibilityEvent(handle, eventType) { + var nativeTag = + handle._nativeTag != null + ? handle._nativeTag + : ReactNativePrivateInterface.getNativeTagFromPublicInstance(handle); + + if (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" + ); } - }, - useReducer: function (reducer, initialArg, init) { - currentHookNameInDev = "useReducer"; - warnInvalidHookAccess(); - updateHookTypesDev(); - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = InvalidNestedHooksDispatcherOnUpdateInDEV; - try { - return rerenderReducer(reducer, initialArg, init); - } finally { - ReactSharedInternals.H = prevDispatcher; + + return; + } + + var node = ReactNativePrivateInterface.getNodeFromPublicInstance(handle); + + if (node != null) { + nativeFabricUIManager.sendAccessibilityEvent(node, eventType); + } else { + ReactNativePrivateInterface.legacySendAccessibilityEvent( + nativeTag, + eventType + ); + } + } + function getNodeFromInternalInstanceHandle(internalInstanceHandle) { + return ( + // $FlowExpectedError[incompatible-return] internalInstanceHandle is opaque but we need to make an exception here. + internalInstanceHandle && // $FlowExpectedError[incompatible-return] + internalInstanceHandle.stateNode && // $FlowExpectedError[incompatible-use] + internalInstanceHandle.stateNode.node + ); + } // Should have been PublicInstance from ReactFiberConfigFabric + // Should have been PublicInstance from ReactFiberConfigNative + // Remove this once Paper is no longer supported and DOM Node API are enabled by default in RN. + + function isChildPublicInstance(parentInstance, childInstance) { + { + // Paper + if ( + // $FlowExpectedError[incompatible-type] + // $FlowExpectedError[prop-missing] Don't check via `instanceof ReactNativeFiberHostComponent`, so it won't be leaked to Fabric. + parentInstance._internalFiberInstanceHandleDEV && // $FlowExpectedError[incompatible-type] + // $FlowExpectedError[prop-missing] Don't check via `instanceof ReactNativeFiberHostComponent`, so it won't be leaked to Fabric. + childInstance._internalFiberInstanceHandleDEV + ) { + return doesFiberContain( + // $FlowExpectedError[incompatible-call] + parentInstance._internalFiberInstanceHandleDEV, // $FlowExpectedError[incompatible-call] + childInstance._internalFiberInstanceHandleDEV + ); + } + + var parentInternalInstanceHandle = // $FlowExpectedError[incompatible-call] Type for parentInstance should have been PublicInstance from ReactFiberConfigFabric. + ReactNativePrivateInterface.getInternalInstanceHandleFromPublicInstance( + parentInstance + ); + var childInternalInstanceHandle = // $FlowExpectedError[incompatible-call] Type for childInstance should have been PublicInstance from ReactFiberConfigFabric. + ReactNativePrivateInterface.getInternalInstanceHandleFromPublicInstance( + childInstance + ); // Fabric + + if ( + parentInternalInstanceHandle != null && + childInternalInstanceHandle != null + ) { + return doesFiberContain( + parentInternalInstanceHandle, + childInternalInstanceHandle + ); + } // Means that one instance is from Fabric and other is from Paper. + + return false; + } + } + + var emptyObject = {}; + + { + Object.freeze(emptyObject); + } // $FlowFixMe[missing-local-annot] + + function createHierarchy(fiberHierarchy) { + return fiberHierarchy.map(function (fiber) { + return { + name: getComponentNameFromType(fiber.type), + getInspectorData: function (findNodeHandle) { + return { + props: getHostProps(fiber), + measure: function (callback) { + // If this is Fabric, we'll find a shadow node and use that to measure. + var hostFiber = findCurrentHostFiber(fiber); + var node = + hostFiber != null && + hostFiber.stateNode !== null && + hostFiber.stateNode.node; + + if (node) { + nativeFabricUIManager.measure(node, callback); + } else { + return ReactNativePrivateInterface.UIManager.measure( + getHostNode(fiber, findNodeHandle), + callback + ); + } + } + }; + } + }; + }); + } // $FlowFixMe[missing-local-annot] + + function getHostNode(fiber, findNodeHandle) { + { + var hostNode; // look for children first for the hostNode + // as composite fibers do not have a hostNode + + while (fiber) { + if (fiber.stateNode !== null && fiber.tag === HostComponent) { + hostNode = findNodeHandle(fiber.stateNode); + } + + if (hostNode) { + return hostNode; + } + + fiber = fiber.child; } - }, - useRef: function () { - currentHookNameInDev = "useRef"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateWorkInProgressHook().memoizedState; - }, - useState: function () { - currentHookNameInDev = "useState"; - warnInvalidHookAccess(); - updateHookTypesDev(); - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = InvalidNestedHooksDispatcherOnUpdateInDEV; - try { - return rerenderReducer(basicStateReducer); - } finally { - ReactSharedInternals.H = prevDispatcher; + + return null; + } + } // $FlowFixMe[missing-local-annot] + + function getHostProps(fiber) { + var host = findCurrentHostFiber(fiber); + + if (host) { + return host.memoizedProps || emptyObject; + } + + return emptyObject; + } + + function getInspectorDataForInstance(closestInstance) { + { + // Handle case where user clicks outside of ReactNative + if (!closestInstance) { + return { + hierarchy: [], + props: emptyObject, + selectedIndex: null, + componentStack: "" + }; } - }, - useDebugValue: function () { - currentHookNameInDev = "useDebugValue"; - warnInvalidHookAccess(); - updateHookTypesDev(); - }, - useDeferredValue: function (value, initialValue) { - currentHookNameInDev = "useDeferredValue"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return rerenderDeferredValue(value, initialValue); - }, - useTransition: function () { - currentHookNameInDev = "useTransition"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return rerenderTransition(); - }, - useSyncExternalStore: function (subscribe, getSnapshot) { - currentHookNameInDev = "useSyncExternalStore"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateSyncExternalStore(subscribe, getSnapshot); - }, - useId: function () { - currentHookNameInDev = "useId"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateWorkInProgressHook().memoizedState; - }, - useCacheRefresh: function () { - currentHookNameInDev = "useCacheRefresh"; - updateHookTypesDev(); - return updateWorkInProgressHook().memoizedState; - }, - useMemoCache: function (size) { - warnInvalidHookAccess(); - return useMemoCache(size); + + var fiber = findCurrentFiberUsingSlowPath(closestInstance); + var fiberHierarchy = getOwnerHierarchy(fiber); + var instance = lastNonHostInstance(fiberHierarchy); + var hierarchy = createHierarchy(fiberHierarchy); + var props = getHostProps(instance); + var selectedIndex = fiberHierarchy.indexOf(instance); + var componentStack = + fiber !== null ? getStackByFiberInDevAndProd(fiber) : ""; + return { + closestInstance: instance, + hierarchy: hierarchy, + props: props, + selectedIndex: selectedIndex, + componentStack: componentStack + }; } - }; - InvalidNestedHooksDispatcherOnRerenderInDEV.useHostTransitionStatus = - useHostTransitionStatus; - InvalidNestedHooksDispatcherOnRerenderInDEV.useFormState = function ( - action - ) { - currentHookNameInDev = "useFormState"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return rerenderActionState(action); - }; - InvalidNestedHooksDispatcherOnRerenderInDEV.useActionState = function ( - action - ) { - currentHookNameInDev = "useActionState"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return rerenderActionState(action); - }; - InvalidNestedHooksDispatcherOnRerenderInDEV.useOptimistic = function ( - passthrough, - reducer - ) { - currentHookNameInDev = "useOptimistic"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return rerenderOptimistic(passthrough, reducer); - }; - var now = Scheduler.unstable_now, - commitTime = 0, - layoutEffectStartTime = -1, - profilerStartTime = -1, - passiveEffectStartTime = -1, - currentUpdateIsNested = !1, - nestedUpdateScheduled = !1, - fakeInternalInstance = {}; - var didWarnAboutStateAssignmentForComponent = new Set(); - var didWarnAboutUninitializedState = new Set(); - var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set(); - var didWarnAboutLegacyLifecyclesAndDerivedState = new Set(); - var didWarnAboutDirectlyAssigningPropsToState = new Set(); - var didWarnAboutUndefinedDerivedState = new Set(); - var didWarnAboutInvalidateContextType = new Set(); - var didWarnOnInvalidCallback = new Set(); - Object.freeze(fakeInternalInstance); - var classComponentUpdater = { - isMounted: function (component) { - var owner = current; - if (null !== owner && isRendering && 1 === owner.tag) { - var instance = owner.stateNode; - instance._warnedAboutRefsInRender || - error$jscomp$0( - "%s is accessing isMounted inside its render() function. render() should be a pure function of props and state. It should never access something that requires stale data from the previous render, such as refs. Move this logic to componentDidMount and componentDidUpdate instead.", - getComponentNameFromFiber(owner) || "A component" - ); - instance._warnedAboutRefsInRender = !0; - } - return (component = component._reactInternals) - ? getNearestMountedFiber(component) === component - : !1; - }, - enqueueSetState: function (inst, payload, callback) { - inst = inst._reactInternals; - var lane = requestUpdateLane(inst), - update = createUpdate(lane); - update.payload = payload; - void 0 !== callback && - null !== callback && - (warnOnInvalidCallback(callback), (update.callback = callback)); - payload = enqueueUpdate(inst, update, lane); - null !== payload && - (scheduleUpdateOnFiber(payload, inst, lane), - entangleTransitions(payload, inst, lane)); - markStateUpdateScheduled(inst, lane); - }, - enqueueReplaceState: function (inst, payload, callback) { - inst = inst._reactInternals; - var lane = requestUpdateLane(inst), - update = createUpdate(lane); - update.tag = ReplaceState; - update.payload = payload; - void 0 !== callback && - null !== callback && - (warnOnInvalidCallback(callback), (update.callback = callback)); - payload = enqueueUpdate(inst, update, lane); - null !== payload && - (scheduleUpdateOnFiber(payload, inst, lane), - entangleTransitions(payload, inst, lane)); - markStateUpdateScheduled(inst, lane); - }, - enqueueForceUpdate: function (inst, callback) { - inst = inst._reactInternals; - var lane = requestUpdateLane(inst), - update = createUpdate(lane); - update.tag = ForceUpdate; - void 0 !== callback && - null !== callback && - (warnOnInvalidCallback(callback), (update.callback = callback)); - callback = enqueueUpdate(inst, update, lane); - null !== callback && - (scheduleUpdateOnFiber(callback, inst, lane), - entangleTransitions(callback, inst, lane)); - null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markForceUpdateScheduled && - injectedProfilingHooks.markForceUpdateScheduled(inst, lane); + } + + function getOwnerHierarchy(instance) { + var hierarchy = []; + traverseOwnerTreeUp(hierarchy, instance); + return hierarchy; + } // $FlowFixMe[missing-local-annot] + + function lastNonHostInstance(hierarchy) { + for (var i = hierarchy.length - 1; i > 1; i--) { + var instance = hierarchy[i]; + + if (instance.tag !== HostComponent) { + return instance; } - }, - reportGlobalError = - "function" === typeof reportError - ? reportError - : function (error) { - if ( - "object" === typeof window && - "function" === typeof window.ErrorEvent - ) { - var event = new window.ErrorEvent("error", { - bubbles: !0, - cancelable: !0, - message: - "object" === typeof error && - null !== error && - "string" === typeof error.message - ? String(error.message) - : String(error), - error: error - }); - if (!window.dispatchEvent(event)) return; - } else if ( - "object" === typeof process && - "function" === typeof process.emit - ) { - process.emit("uncaughtException", error); - return; - } - console.error(error); - }, - componentName = null, - errorBoundaryName = null, - SelectiveHydrationException = Error( - "This is not a real error. It's an implementation detail of React's selective hydration feature. If this leaks into userspace, it's a bug in React. Please file an issue." - ), - didReceiveUpdate = !1; - var didWarnAboutBadClass = {}; - var didWarnAboutContextTypeOnFunctionComponent = {}; - var didWarnAboutGetDerivedStateOnFunctionComponent = {}; - var didWarnAboutReassigningProps = !1; - var didWarnAboutRevealOrder = {}; - var didWarnAboutTailOptions = {}; - var SUSPENDED_MARKER = { - dehydrated: null, - treeContext: null, - retryLane: 0 - }, - hasWarnedAboutUsingNoValuePropOnContextProvider = !1, - valueCursor = createCursor(null); - var renderer2CursorDEV = createCursor(null); - var rendererSigil = {}; - var currentlyRenderingFiber = null, - lastContextDependency = null, - lastFullyObservedContext = null, - isDisallowedContextReadInDEV = !1, - AbortControllerLocal = - "undefined" !== typeof AbortController - ? AbortController - : function () { - var listeners = [], - signal = (this.signal = { - aborted: !1, - addEventListener: function (type, listener) { - listeners.push(listener); - } - }); - this.abort = function () { - signal.aborted = !0; - listeners.forEach(function (listener) { - return listener(); - }); - }; - }, - scheduleCallback$1 = Scheduler.unstable_scheduleCallback, - NormalPriority = Scheduler.unstable_NormalPriority, - CacheContext = { - $$typeof: REACT_CONTEXT_TYPE, - Consumer: null, - Provider: null, - _currentValue: null, - _currentValue2: null, - _threadCount: 0, - _currentRenderer: null, - _currentRenderer2: null - }, - prevOnStartTransitionFinish = ReactSharedInternals.S; - ReactSharedInternals.S = function (transition, returnValue) { - "object" === typeof returnValue && - null !== returnValue && - "function" === typeof returnValue.then && - entangleAsyncAction(transition, returnValue); - null !== prevOnStartTransitionFinish && - prevOnStartTransitionFinish(transition, returnValue); - }; - var resumedCache = createCursor(null), - didWarnAboutUndefinedSnapshotBeforeUpdate = null; - didWarnAboutUndefinedSnapshotBeforeUpdate = new Set(); - var offscreenSubtreeIsHidden = !1, - offscreenSubtreeWasHidden = !1, - PossiblyWeakSet = "function" === typeof WeakSet ? WeakSet : Set, - nextEffect = null, - inProgressLanes = null, - inProgressRoot = null, - shouldFireAfterActiveInstanceBlur = !1, - suspenseyCommitFlag = 8192, - DefaultAsyncDispatcher = { - getCacheForType: function (resourceType) { - var cache = readContext(CacheContext), - cacheForType = cache.data.get(resourceType); - void 0 === cacheForType && - ((cacheForType = resourceType()), - cache.data.set(resourceType, cacheForType)); - return cacheForType; - }, - getOwner: function () { - return current; + } + + return hierarchy[0]; + } // $FlowFixMe[missing-local-annot] + + function traverseOwnerTreeUp(hierarchy, instance) { + { + if (instance) { + hierarchy.unshift(instance); + traverseOwnerTreeUp(hierarchy, instance._debugOwner); } - }; - if ("function" === typeof Symbol && Symbol.for) { - var symbolFor = Symbol.for; - symbolFor("selector.component"); - symbolFor("selector.has_pseudo_class"); - symbolFor("selector.role"); - symbolFor("selector.test_id"); - symbolFor("selector.text"); + } } - var PossiblyWeakMap = "function" === typeof WeakMap ? WeakMap : Map, - NoContext = 0, - RenderContext = 2, - CommitContext = 4, - RootInProgress = 0, - RootFatalErrored = 1, - RootErrored = 2, - RootSuspended = 3, - RootSuspendedWithDelay = 4, - RootCompleted = 5, - RootDidNotComplete = 6, - executionContext = NoContext, - workInProgressRoot = null, - workInProgress = null, - workInProgressRootRenderLanes = 0, - NotSuspended = 0, - SuspendedOnError = 1, - SuspendedOnData = 2, - SuspendedOnImmediate = 3, - SuspendedOnInstance = 4, - SuspendedOnInstanceAndReadyToContinue = 5, - SuspendedOnDeprecatedThrowPromise = 6, - SuspendedAndReadyToContinue = 7, - SuspendedOnHydration = 8, - workInProgressSuspendedReason = NotSuspended, - workInProgressThrownValue = null, - workInProgressRootDidAttachPingListener = !1, - entangledRenderLanes = 0, - workInProgressRootExitStatus = RootInProgress, - workInProgressRootSkippedLanes = 0, - workInProgressRootInterleavedUpdatedLanes = 0, - workInProgressRootPingedLanes = 0, - workInProgressDeferredLane = 0, - workInProgressRootConcurrentErrors = null, - workInProgressRootRecoverableErrors = null, - workInProgressRootDidIncludeRecursiveRenderUpdate = !1, - didIncludeCommitPhaseUpdate = !1, - globalMostRecentFallbackTime = 0, - FALLBACK_THROTTLE_MS = 300, - workInProgressRootRenderTargetTime = Infinity, - RENDER_TIMEOUT_MS = 500, - workInProgressTransitions = null, - legacyErrorBoundariesThatAlreadyFailed = null, - rootDoesHavePassiveEffects = !1, - rootWithPendingPassiveEffects = null, - pendingPassiveEffectsLanes = 0, - pendingPassiveProfilerEffects = [], - pendingPassiveEffectsRemainingLanes = 0, - pendingPassiveTransitions = null, - NESTED_UPDATE_LIMIT = 50, - nestedUpdateCount = 0, - rootWithNestedUpdates = null, - isFlushingPassiveEffects = !1, - didScheduleUpdateDuringPassiveEffects = !1, - NESTED_PASSIVE_UPDATE_LIMIT = 50, - nestedPassiveUpdateCount = 0, - rootWithPassiveNestedUpdates = null, - isRunningInsertionEffect = !1, - didWarnStateUpdateForNotYetMountedComponent = null, - didWarnAboutUpdateInRender = !1; - var didWarnAboutUpdateInRenderForAnotherComponent = new Set(); - var fakeActCallbackNode = {}, - resolveFamily = null, - failedBoundaries = null; - var hasBadMapPolyfill = !1; - try { - var nonExtensibleObject = Object.preventExtensions({}); - new Map([[nonExtensibleObject, null]]); - new Set([nonExtensibleObject]); - } catch (e) { - hasBadMapPolyfill = !0; - } - var didWarnAboutNestedUpdates = !1; - var didWarnAboutFindNodeInStrictMode = {}; - var overrideHookState = null, - overrideHookStateDeletePath = null, - overrideHookStateRenamePath = null, - overrideProps = null, - overridePropsDeletePath = null, - overridePropsRenamePath = null, - scheduleUpdate = null, - setErrorHandler = null, - setSuspenseHandler = null; - overrideHookState = function (fiber, id, path, value) { - id = findHook(fiber, id); - null !== id && - ((path = copyWithSetImpl(id.memoizedState, path, 0, value)), - (id.memoizedState = path), - (id.baseState = path), - (fiber.memoizedProps = assign({}, fiber.memoizedProps)), - (path = enqueueConcurrentRenderForLane(fiber, SyncLane)), - null !== path && scheduleUpdateOnFiber(path, fiber, SyncLane)); - }; - overrideHookStateDeletePath = function (fiber, id, path) { - id = findHook(fiber, id); - null !== id && - ((path = copyWithDeleteImpl(id.memoizedState, path, 0)), - (id.memoizedState = path), - (id.baseState = path), - (fiber.memoizedProps = assign({}, fiber.memoizedProps)), - (path = enqueueConcurrentRenderForLane(fiber, SyncLane)), - null !== path && scheduleUpdateOnFiber(path, fiber, SyncLane)); - }; - overrideHookStateRenamePath = function (fiber, id, oldPath, newPath) { - id = findHook(fiber, id); - null !== id && - ((oldPath = copyWithRename(id.memoizedState, oldPath, newPath)), - (id.memoizedState = oldPath), - (id.baseState = oldPath), - (fiber.memoizedProps = assign({}, fiber.memoizedProps)), - (oldPath = enqueueConcurrentRenderForLane(fiber, SyncLane)), - null !== oldPath && scheduleUpdateOnFiber(oldPath, fiber, SyncLane)); - }; - overrideProps = function (fiber, path, value) { - fiber.pendingProps = copyWithSetImpl(fiber.memoizedProps, path, 0, value); - fiber.alternate && (fiber.alternate.pendingProps = fiber.pendingProps); - path = enqueueConcurrentRenderForLane(fiber, SyncLane); - null !== path && scheduleUpdateOnFiber(path, fiber, SyncLane); - }; - overridePropsDeletePath = function (fiber, path) { - fiber.pendingProps = copyWithDeleteImpl(fiber.memoizedProps, path, 0); - fiber.alternate && (fiber.alternate.pendingProps = fiber.pendingProps); - path = enqueueConcurrentRenderForLane(fiber, SyncLane); - null !== path && scheduleUpdateOnFiber(path, fiber, SyncLane); - }; - overridePropsRenamePath = function (fiber, oldPath, newPath) { - fiber.pendingProps = copyWithRename( - fiber.memoizedProps, - oldPath, - newPath - ); - fiber.alternate && (fiber.alternate.pendingProps = fiber.pendingProps); - oldPath = enqueueConcurrentRenderForLane(fiber, SyncLane); - null !== oldPath && scheduleUpdateOnFiber(oldPath, fiber, SyncLane); - }; - scheduleUpdate = function (fiber) { - var root = enqueueConcurrentRenderForLane(fiber, SyncLane); - null !== root && scheduleUpdateOnFiber(root, fiber, SyncLane); - }; - setErrorHandler = function (newShouldErrorImpl) { - shouldErrorImpl = newShouldErrorImpl; - }; - setSuspenseHandler = function (newShouldSuspendImpl) { - shouldSuspendImpl = newShouldSuspendImpl; - }; - var instanceCache = new Map(), - emptyObject = {}; - Object.freeze(emptyObject); - if ( - "function" !== - typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog - ) - throw Error( - "Expected ReactFiberErrorDialog.showErrorDialog to be a function." - ); - batchedUpdatesImpl = function (fn, a) { - var prevExecutionContext = executionContext; - executionContext |= 1; - try { - return fn(a); - } finally { - (executionContext = prevExecutionContext), - executionContext !== NoContext || - ReactSharedInternals.isBatchingLegacy || - ((workInProgressRootRenderTargetTime = now$1() + RENDER_TIMEOUT_MS), - flushSyncWorkAcrossRoots_impl(!0)); + + function getInspectorDataForViewTag(viewTag) { + { + var closestInstance = getInstanceFromTag(viewTag); + return getInspectorDataForInstance(closestInstance); } - }; - var roots = new Map(); - (function (devToolsConfig) { - return injectInternals({ - bundleType: devToolsConfig.bundleType, - version: devToolsConfig.version, - rendererPackageName: devToolsConfig.rendererPackageName, - rendererConfig: devToolsConfig.rendererConfig, - overrideHookState: overrideHookState, - overrideHookStateDeletePath: overrideHookStateDeletePath, - overrideHookStateRenamePath: overrideHookStateRenamePath, - overrideProps: overrideProps, - overridePropsDeletePath: overridePropsDeletePath, - overridePropsRenamePath: overridePropsRenamePath, - setErrorHandler: setErrorHandler, - setSuspenseHandler: setSuspenseHandler, - scheduleUpdate: scheduleUpdate, - currentDispatcherRef: ReactSharedInternals, - findHostInstanceByFiber: findHostInstanceByFiber, - findFiberByHostInstance: - devToolsConfig.findFiberByHostInstance || - emptyFindFiberByHostInstance, - findHostInstancesForRefresh: findHostInstancesForRefresh, - scheduleRefresh: scheduleRefresh, - scheduleRoot: scheduleRoot, - setRefreshHandler: setRefreshHandler, - getCurrentFiber: getCurrentFiberForDevTools, - reconcilerVersion: "19.0.0-rc-fb9a90fa48-20240614" - }); - })({ - findFiberByHostInstance: getInstanceFromNode, - bundleType: 1, - version: "19.0.0-rc-fb9a90fa48-20240614", - rendererPackageName: "react-native-renderer", - rendererConfig: { - getInspectorDataForInstance: getInspectorDataForInstance, - getInspectorDataForViewTag: function (viewTag) { - viewTag = instanceCache.get(viewTag) || null; - return getInspectorDataForInstance(viewTag); - }, - getInspectorDataForViewAtPoint: function ( - findNodeHandle, - inspectedView, - locationX, - locationY, - callback - ) { - var closestInstance = null, - fabricNode = - ReactNativePrivateInterface.getNodeFromPublicInstance( - inspectedView - ); - fabricNode - ? nativeFabricUIManager.findNodeAtPoint( - fabricNode, - locationX, - locationY, - function (internalInstanceHandle) { - var node = - null != internalInstanceHandle - ? getNodeFromInternalInstanceHandle( - internalInstanceHandle - ) - : null; - if (null == internalInstanceHandle || null == node) - callback( - assign( - { - pointerY: locationY, - frame: { left: 0, top: 0, width: 0, height: 0 } - }, - getInspectorDataForInstance(closestInstance) - ) - ); - else { - closestInstance = - internalInstanceHandle.stateNode.canonical - .internalInstanceHandle; - var nativeViewTag = - internalInstanceHandle.stateNode.canonical.nativeTag; - nativeFabricUIManager.measure( - node, - function (x, y, width, height, pageX, pageY) { - x = getInspectorDataForInstance(closestInstance); - callback( - assign({}, x, { - pointerY: locationY, - frame: { - left: pageX, - top: pageY, - width: width, - height: height - }, - touchedViewTag: nativeViewTag - }) - ); + } + + function getInspectorDataForViewAtPoint( + findNodeHandle, + inspectedView, + locationX, + locationY, + callback + ) { + { + var closestInstance = null; + var fabricNode = + ReactNativePrivateInterface.getNodeFromPublicInstance(inspectedView); + + if (fabricNode) { + // For Fabric we can look up the instance handle directly and measure it. + nativeFabricUIManager.findNodeAtPoint( + fabricNode, + locationX, + locationY, + function (internalInstanceHandle) { + var node = + internalInstanceHandle != null + ? getNodeFromInternalInstanceHandle(internalInstanceHandle) + : null; + + if (internalInstanceHandle == null || node == null) { + callback( + assign( + { + pointerY: locationY, + frame: { + left: 0, + top: 0, + width: 0, + height: 0 } - ); - } - } - ) - : null != inspectedView._internalFiberInstanceHandleDEV - ? ReactNativePrivateInterface.UIManager.findSubviewIn( - findNodeHandle(inspectedView), - [locationX, locationY], - function (nativeViewTag, left, top, width, height) { - var inspectorData = getInspectorDataForInstance( - instanceCache.get(nativeViewTag) || null - ); + }, + getInspectorDataForInstance(closestInstance) + ) + ); + return; + } + + closestInstance = + 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( + node, + function (x, y, width, height, pageX, pageY) { + var inspectorData = + getInspectorDataForInstance(closestInstance); callback( assign({}, inspectorData, { pointerY: locationY, frame: { - left: left, - top: top, + left: pageX, + top: pageY, width: width, height: height }, @@ -16466,196 +27244,133 @@ __DEV__ && }) ); } - ) - : error$jscomp$0( - "getInspectorDataForViewAtPoint expects to receive a host component" ); - }.bind(null, findNodeHandle) - } - }); - exports.createPortal = function (children, containerTag) { - return createPortal$1( - children, - containerTag, - null, - 2 < arguments.length && void 0 !== arguments[2] ? arguments[2] : null - ); - }; - exports.dispatchCommand = function (handle, command, args) { - var nativeTag = - null != handle._nativeTag - ? handle._nativeTag - : ReactNativePrivateInterface.getNativeTagFromPublicInstance(handle); - null == nativeTag - ? error$jscomp$0( - "dispatchCommand was called with a ref that isn't a native component. Use React.forwardRef to get access to the underlying native component" - ) - : ((handle = - ReactNativePrivateInterface.getNodeFromPublicInstance(handle)), - null != handle - ? nativeFabricUIManager.dispatchCommand(handle, command, args) - : ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( - nativeTag, - command, - args - )); - }; - exports.findHostInstance_DEPRECATED = function (componentOrHandle) { - var owner = current; - null !== owner && - isRendering && - null !== owner.stateNode && - (owner.stateNode._warnedAboutRefsInRender || - error$jscomp$0( - "%s is accessing findNodeHandle inside its render(). render() should be a pure function of props and state. It should never access something that requires stale data from the previous render, such as refs. Move this logic to componentDidMount and componentDidUpdate instead.", - getComponentNameFromType(owner.type) || "A component" - ), - (owner.stateNode._warnedAboutRefsInRender = !0)); - return null == componentOrHandle - ? null - : componentOrHandle.canonical && - componentOrHandle.canonical.publicInstance - ? componentOrHandle.canonical.publicInstance - : componentOrHandle._nativeTag - ? componentOrHandle - : findHostInstanceWithWarning( - componentOrHandle, - "findHostInstance_DEPRECATED" + } ); - }; - exports.findNodeHandle = findNodeHandle; - exports.getInspectorDataForInstance = getInspectorDataForInstance; - exports.getNodeFromInternalInstanceHandle = - getNodeFromInternalInstanceHandle; - exports.getPublicInstanceFromInternalInstanceHandle = function ( - internalInstanceHandle - ) { - var instance = internalInstanceHandle.stateNode; - return null == instance - ? null - : 6 === internalInstanceHandle.tag - ? (null == instance.publicInstance && - (instance.publicInstance = - ReactNativePrivateInterface.createPublicTextInstance( - internalInstanceHandle - )), - instance.publicInstance) - : getPublicInstance(internalInstanceHandle.stateNode); - }; - exports.isChildPublicInstance = function (parentInstance, childInstance) { - if ( - parentInstance._internalFiberInstanceHandleDEV && - childInstance._internalFiberInstanceHandleDEV - ) - return doesFiberContain( - parentInstance._internalFiberInstanceHandleDEV, - childInstance._internalFiberInstanceHandleDEV - ); - parentInstance = - ReactNativePrivateInterface.getInternalInstanceHandleFromPublicInstance( - parentInstance - ); - childInstance = - ReactNativePrivateInterface.getInternalInstanceHandleFromPublicInstance( - childInstance - ); - return null != parentInstance && null != childInstance - ? doesFiberContain(parentInstance, childInstance) - : !1; - }; - exports.render = function ( - element, - containerTag, - callback, - concurrentRoot, - options - ) { + } else if (inspectedView._internalFiberInstanceHandleDEV != null) { + // For Paper we fall back to the old strategy using the React tag. + ReactNativePrivateInterface.UIManager.findSubviewIn( + findNodeHandle(inspectedView), + [locationX, locationY], + function (nativeViewTag, left, top, width, height) { + var inspectorData = getInspectorDataForInstance( + getInstanceFromTag(nativeViewTag) + ); + callback( + assign({}, inspectorData, { + pointerY: locationY, + frame: { + left: left, + top: top, + width: width, + height: height + }, + touchedViewTag: nativeViewTag + }) + ); + } + ); + } else { + error( + "getInspectorDataForViewAtPoint expects to receive a host component" + ); + + return; + } + } + } + + function onRecoverableError(error$1) { + // TODO: Expose onRecoverableError option to userspace + // eslint-disable-next-line react-internal/no-production-logging, react-internal/warning-args + error(error$1); + } + + function render(element, containerTag, callback, concurrentRoot) { var root = roots.get(containerTag); + if (!root) { - root = nativeOnUncaughtError; - var onCaughtError = nativeOnCaughtError, - onRecoverableError = defaultOnRecoverableError; - options && - void 0 !== options.onUncaughtError && - (root = options.onUncaughtError); - options && - void 0 !== options.onCaughtError && - (onCaughtError = options.onCaughtError); - options && - void 0 !== options.onRecoverableError && - (onRecoverableError = options.onRecoverableError); - concurrentRoot = concurrentRoot ? 1 : 0; - options = new FiberRootNode( + // 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, - concurrentRoot, - !1, + concurrentRoot ? ConcurrentRoot : LegacyRoot, + null, + false, + null, "", - root, - onCaughtError, onRecoverableError, null ); - concurrentRoot = 1 === concurrentRoot ? 1 : 0; - isDevToolsPresent && (concurrentRoot |= 2); - concurrentRoot = createFiber(3, null, null, concurrentRoot); - options.current = concurrentRoot; - concurrentRoot.stateNode = options; - root = createCache(); - retainCache(root); - options.pooledCache = root; - retainCache(root); - concurrentRoot.memoizedState = { - element: null, - isDehydrated: !1, - cache: root - }; - initializeUpdateQueue(concurrentRoot); - root = options; roots.set(containerTag, root); } + updateContainer(element, root, null, callback); - a: if (((element = root.current), element.child)) - switch (element.child.tag) { - case 27: - case 5: - element = getPublicInstance(element.child.stateNode); - break a; - default: - element = element.child.stateNode; - } - else element = null; - return element; - }; - exports.sendAccessibilityEvent = function (handle, eventType) { - var nativeTag = - null != handle._nativeTag - ? handle._nativeTag - : ReactNativePrivateInterface.getNativeTagFromPublicInstance(handle); - null == nativeTag - ? error$jscomp$0( - "sendAccessibilityEvent was called with a ref that isn't a native component. Use React.forwardRef to get access to the underlying native component" - ) - : ((handle = - ReactNativePrivateInterface.getNodeFromPublicInstance(handle)), - null != handle - ? nativeFabricUIManager.sendAccessibilityEvent(handle, eventType) - : ReactNativePrivateInterface.legacySendAccessibilityEvent( - nativeTag, - eventType - )); - }; - exports.stopSurface = function (containerTag) { + return getPublicRootInstance(root); + } // $FlowFixMe[missing-this-annot] + + function unmountComponentAtNode(containerTag) { + this.stopSurface(containerTag); + } + + function stopSurface(containerTag) { var root = roots.get(containerTag); - root && + + if (root) { + // TODO: Is it safe to reset this now or should I wait since this unmount could be deferred? updateContainer(null, root, null, function () { roots.delete(containerTag); }); - }; - exports.unmountComponentAtNode = function (containerTag) { - this.stopSurface(containerTag); - }; - "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && - "function" === - typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && - __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error()); + } + } + + function createPortal(children, containerTag) { + var key = + arguments.length > 2 && arguments[2] !== undefined + ? arguments[2] + : null; + return createPortal$1(children, containerTag, null, key); + } + + setBatchingImplementation(batchedUpdates); + var roots = new Map(); + injectIntoDevTools({ + // $FlowExpectedError[incompatible-call] The type of `Instance` in `getClosestInstanceFromNode` does not match in Fabric and the legacy renderer, so it fails to typecheck here. + findFiberByHostInstance: getInstanceFromNode, + bundleType: 1, + version: ReactVersion, + rendererPackageName: "react-native-renderer", + rendererConfig: { + getInspectorDataForInstance: getInspectorDataForInstance, + getInspectorDataForViewTag: getInspectorDataForViewTag, + getInspectorDataForViewAtPoint: getInspectorDataForViewAtPoint.bind( + null, + findNodeHandle + ) + } + }); + + exports.createPortal = createPortal; + exports.dispatchCommand = dispatchCommand; + exports.findHostInstance_DEPRECATED = findHostInstance_DEPRECATED; + exports.findNodeHandle = findNodeHandle; + exports.getInspectorDataForInstance = getInspectorDataForInstance; + exports.getNodeFromInternalInstanceHandle = + getNodeFromInternalInstanceHandle; + exports.getPublicInstanceFromInternalInstanceHandle = + getPublicInstanceFromInternalInstanceHandle; + exports.isChildPublicInstance = isChildPublicInstance; + exports.render = render; + exports.sendAccessibilityEvent = sendAccessibilityEvent; + exports.stopSurface = stopSurface; + exports.unmountComponentAtNode = unmountComponentAtNode; + /* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */ + if ( + typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined" && + typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop === + "function" + ) { + __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(new Error()); + } })(); +} diff --git a/packages/react-native/Libraries/Renderer/implementations/ReactFabric-prod.js b/packages/react-native/Libraries/Renderer/implementations/ReactFabric-prod.js index 789d4105a49c41..3e5cf860260b7c 100644 --- a/packages/react-native/Libraries/Renderer/implementations/ReactFabric-prod.js +++ b/packages/react-native/Libraries/Renderer/implementations/ReactFabric-prod.js @@ -6,10 +6,9 @@ * * @noflow * @nolint + * @providesModule ReactFabric-prod * @preventMunge - * @generated SignedSource<> - * - * This file was sync'd from the facebook/react repository. + * @generated SignedSource<<9a40170807089a671035525b144e9dcd>> */ "use strict"; @@ -18,219 +17,7 @@ var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/R React = require("react"), Scheduler = require("scheduler"), isArrayImpl = Array.isArray, - ReactSharedInternals = - React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, - REACT_LEGACY_ELEMENT_TYPE = Symbol.for("react.element"), - REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"), - REACT_PORTAL_TYPE = Symbol.for("react.portal"), - REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"), - REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"), - REACT_PROFILER_TYPE = Symbol.for("react.profiler"), - REACT_PROVIDER_TYPE = Symbol.for("react.provider"), - REACT_CONSUMER_TYPE = Symbol.for("react.consumer"), - REACT_CONTEXT_TYPE = Symbol.for("react.context"), - REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"), - REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"), - REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"), - REACT_MEMO_TYPE = Symbol.for("react.memo"), - REACT_LAZY_TYPE = Symbol.for("react.lazy"); -Symbol.for("react.scope"); -Symbol.for("react.debug_trace_mode"); -var REACT_OFFSCREEN_TYPE = Symbol.for("react.offscreen"); -Symbol.for("react.legacy_hidden"); -Symbol.for("react.tracing_marker"); -var REACT_MEMO_CACHE_SENTINEL = Symbol.for("react.memo_cache_sentinel"), - MAYBE_ITERATOR_SYMBOL = Symbol.iterator; -function getIteratorFn(maybeIterable) { - if (null === maybeIterable || "object" !== typeof maybeIterable) return null; - maybeIterable = - (MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL]) || - maybeIterable["@@iterator"]; - return "function" === typeof maybeIterable ? maybeIterable : null; -} -var assign = Object.assign, - prefix; -function describeBuiltInComponentFrame(name) { - if (void 0 === prefix) - try { - throw Error(); - } catch (x) { - var match = x.stack.trim().match(/\n( *(at )?)/); - prefix = (match && match[1]) || ""; - } - return "\n" + prefix + name; -} -var reentry = !1; -function describeNativeComponentFrame(fn, construct) { - if (!fn || reentry) return ""; - reentry = !0; - var previousPrepareStackTrace = Error.prepareStackTrace; - Error.prepareStackTrace = void 0; - var RunInRootFrame = { - DetermineComponentFrameRoot: function () { - try { - if (construct) { - var Fake = function () { - throw Error(); - }; - Object.defineProperty(Fake.prototype, "props", { - set: function () { - throw Error(); - } - }); - if ("object" === typeof Reflect && Reflect.construct) { - try { - Reflect.construct(Fake, []); - } catch (x) { - var control = x; - } - Reflect.construct(fn, [], Fake); - } else { - try { - Fake.call(); - } catch (x$0) { - control = x$0; - } - fn.call(Fake.prototype); - } - } else { - try { - throw Error(); - } catch (x$1) { - control = x$1; - } - (Fake = fn()) && - "function" === typeof Fake.catch && - Fake.catch(function () {}); - } - } catch (sample) { - if (sample && control && "string" === typeof sample.stack) - return [sample.stack, control.stack]; - } - return [null, null]; - } - }; - RunInRootFrame.DetermineComponentFrameRoot.displayName = - "DetermineComponentFrameRoot"; - var namePropDescriptor = Object.getOwnPropertyDescriptor( - RunInRootFrame.DetermineComponentFrameRoot, - "name" - ); - namePropDescriptor && - namePropDescriptor.configurable && - Object.defineProperty(RunInRootFrame.DetermineComponentFrameRoot, "name", { - value: "DetermineComponentFrameRoot" - }); - try { - var _RunInRootFrame$Deter = RunInRootFrame.DetermineComponentFrameRoot(), - sampleStack = _RunInRootFrame$Deter[0], - controlStack = _RunInRootFrame$Deter[1]; - if (sampleStack && controlStack) { - var sampleLines = sampleStack.split("\n"), - controlLines = controlStack.split("\n"); - for ( - namePropDescriptor = RunInRootFrame = 0; - RunInRootFrame < sampleLines.length && - !sampleLines[RunInRootFrame].includes("DetermineComponentFrameRoot"); - - ) - RunInRootFrame++; - for ( - ; - namePropDescriptor < controlLines.length && - !controlLines[namePropDescriptor].includes( - "DetermineComponentFrameRoot" - ); - - ) - namePropDescriptor++; - if ( - RunInRootFrame === sampleLines.length || - namePropDescriptor === controlLines.length - ) - for ( - RunInRootFrame = sampleLines.length - 1, - namePropDescriptor = controlLines.length - 1; - 1 <= RunInRootFrame && - 0 <= namePropDescriptor && - sampleLines[RunInRootFrame] !== controlLines[namePropDescriptor]; - - ) - namePropDescriptor--; - for ( - ; - 1 <= RunInRootFrame && 0 <= namePropDescriptor; - RunInRootFrame--, namePropDescriptor-- - ) - if (sampleLines[RunInRootFrame] !== controlLines[namePropDescriptor]) { - if (1 !== RunInRootFrame || 1 !== namePropDescriptor) { - do - if ( - (RunInRootFrame--, - namePropDescriptor--, - 0 > namePropDescriptor || - sampleLines[RunInRootFrame] !== - controlLines[namePropDescriptor]) - ) { - var frame = - "\n" + - sampleLines[RunInRootFrame].replace(" at new ", " at "); - fn.displayName && - frame.includes("") && - (frame = frame.replace("", fn.displayName)); - return frame; - } - while (1 <= RunInRootFrame && 0 <= namePropDescriptor); - } - break; - } - } - } finally { - (reentry = !1), (Error.prepareStackTrace = previousPrepareStackTrace); - } - return (previousPrepareStackTrace = fn ? fn.displayName || fn.name : "") - ? describeBuiltInComponentFrame(previousPrepareStackTrace) - : ""; -} -function describeFiber(fiber) { - switch (fiber.tag) { - case 26: - case 27: - case 5: - return describeBuiltInComponentFrame(fiber.type); - case 16: - return describeBuiltInComponentFrame("Lazy"); - case 13: - return describeBuiltInComponentFrame("Suspense"); - case 19: - return describeBuiltInComponentFrame("SuspenseList"); - case 0: - case 15: - return (fiber = describeNativeComponentFrame(fiber.type, !1)), fiber; - case 11: - return ( - (fiber = describeNativeComponentFrame(fiber.type.render, !1)), fiber - ); - case 1: - return (fiber = describeNativeComponentFrame(fiber.type, !0)), fiber; - default: - return ""; - } -} -function getStackByFiberInDevAndProd(workInProgress) { - try { - var info = ""; - do - (info += describeFiber(workInProgress)), - (workInProgress = workInProgress.return); - while (workInProgress); - return info; - } catch (x) { - return "\nError generating stack: " + x.message + "\n" + x.stack; - } -} -Symbol.for("react.client.reference"); -var hasError = !1, + hasError = !1, caughtError = null, getFiberCurrentPropsFromNode$1 = null, getInstanceFromNode$1 = null, @@ -257,6 +44,7 @@ function executeDirectDispatch(event) { event._dispatchInstances = null; return dispatchListener; } +var assign = Object.assign; function functionThatReturnsTrue() { return !0; } @@ -1105,7 +893,7 @@ eventPluginOrder = Array.prototype.slice.call([ "ReactNativeBridgeEventPlugin" ]); recomputePluginOrdering(); -var injectedNamesToPlugins$jscomp$inline_277 = { +var injectedNamesToPlugins$jscomp$inline_227 = { ResponderEventPlugin: ResponderEventPlugin, ReactNativeBridgeEventPlugin: { eventTypes: {}, @@ -1151,32 +939,32 @@ var injectedNamesToPlugins$jscomp$inline_277 = { } } }, - isOrderingDirty$jscomp$inline_278 = !1, - pluginName$jscomp$inline_279; -for (pluginName$jscomp$inline_279 in injectedNamesToPlugins$jscomp$inline_277) + isOrderingDirty$jscomp$inline_228 = !1, + pluginName$jscomp$inline_229; +for (pluginName$jscomp$inline_229 in injectedNamesToPlugins$jscomp$inline_227) if ( - injectedNamesToPlugins$jscomp$inline_277.hasOwnProperty( - pluginName$jscomp$inline_279 + injectedNamesToPlugins$jscomp$inline_227.hasOwnProperty( + pluginName$jscomp$inline_229 ) ) { - var pluginModule$jscomp$inline_280 = - injectedNamesToPlugins$jscomp$inline_277[pluginName$jscomp$inline_279]; + var pluginModule$jscomp$inline_230 = + injectedNamesToPlugins$jscomp$inline_227[pluginName$jscomp$inline_229]; if ( - !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_279) || - namesToPlugins[pluginName$jscomp$inline_279] !== - pluginModule$jscomp$inline_280 + !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_229) || + namesToPlugins[pluginName$jscomp$inline_229] !== + pluginModule$jscomp$inline_230 ) { - if (namesToPlugins[pluginName$jscomp$inline_279]) + if (namesToPlugins[pluginName$jscomp$inline_229]) throw Error( "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - (pluginName$jscomp$inline_279 + "`.") + (pluginName$jscomp$inline_229 + "`.") ); - namesToPlugins[pluginName$jscomp$inline_279] = - pluginModule$jscomp$inline_280; - isOrderingDirty$jscomp$inline_278 = !0; + namesToPlugins[pluginName$jscomp$inline_229] = + pluginModule$jscomp$inline_230; + isOrderingDirty$jscomp$inline_228 = !0; } } -isOrderingDirty$jscomp$inline_278 && recomputePluginOrdering(); +isOrderingDirty$jscomp$inline_228 && recomputePluginOrdering(); var emptyObject = {}, removedKeys = null, removedKeyCount = 0, @@ -1380,19 +1168,19 @@ function diffProperties(updatePayload, prevProps, nextProps, validAttributes) { ), (removedKeys = null)); } - for (var propKey$5 in prevProps) - void 0 === nextProps[propKey$5] && - (!(attributeConfig = validAttributes[propKey$5]) || - (updatePayload && void 0 !== updatePayload[propKey$5]) || - ((prevProp = prevProps[propKey$5]), + for (var propKey$1 in prevProps) + void 0 === nextProps[propKey$1] && + (!(attributeConfig = validAttributes[propKey$1]) || + (updatePayload && void 0 !== updatePayload[propKey$1]) || + ((prevProp = prevProps[propKey$1]), void 0 !== prevProp && ("object" !== typeof attributeConfig || "function" === typeof attributeConfig.diff || "function" === typeof attributeConfig.process - ? (((updatePayload || (updatePayload = {}))[propKey$5] = null), + ? (((updatePayload || (updatePayload = {}))[propKey$1] = null), removedKeys || (removedKeys = {}), - removedKeys[propKey$5] || - ((removedKeys[propKey$5] = !0), removedKeyCount++)) + removedKeys[propKey$1] || + ((removedKeys[propKey$1] = !0), removedKeyCount++)) : (updatePayload = clearNestedProperty( updatePayload, prevProp, @@ -1476,17 +1264,17 @@ function dispatchEvent(target, topLevelType, nativeEvent) { } }); } -var scheduleCallback$3 = Scheduler.unstable_scheduleCallback, +var scheduleCallback$2 = Scheduler.unstable_scheduleCallback, cancelCallback$1 = Scheduler.unstable_cancelCallback, shouldYield = Scheduler.unstable_shouldYield, requestPaint = Scheduler.unstable_requestPaint, now = Scheduler.unstable_now, ImmediatePriority = Scheduler.unstable_ImmediatePriority, UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, - NormalPriority$1 = Scheduler.unstable_NormalPriority, + NormalPriority = Scheduler.unstable_NormalPriority, IdlePriority = Scheduler.unstable_IdlePriority, - log$1 = Scheduler.log, - unstable_setDisableYieldValue = Scheduler.unstable_setDisableYieldValue, + ReactSharedInternals = + React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED, rendererID = null, injectedHook = null; function onCommitRoot(root) { @@ -1500,13 +1288,6 @@ function onCommitRoot(root) { ); } catch (err) {} } -function setIsStrictModeForDevtools(newIsStrictMode) { - "function" === typeof log$1 && unstable_setDisableYieldValue(newIsStrictMode); - if (injectedHook && "function" === typeof injectedHook.setStrictMode) - try { - injectedHook.setStrictMode(rendererID, newIsStrictMode); - } catch (err) {} -} var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback, log = Math.log, LN2 = Math.LN2; @@ -1660,6 +1441,11 @@ function createLaneMap(initial) { for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); return laneMap; } +function markRootUpdated$1(root, updateLane) { + root.pendingLanes |= updateLane; + 268435456 !== updateLane && + ((root.suspendedLanes = 0), (root.pingedLanes = 0)); +} function markRootFinished(root, remainingLanes, spawnedLane) { var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; root.pendingLanes = remainingLanes; @@ -1676,18 +1462,18 @@ function markRootFinished(root, remainingLanes, spawnedLane) { 0 < noLongerPendingLanes; ) { - var index$9 = 31 - clz32(noLongerPendingLanes), - lane = 1 << index$9; - remainingLanes[index$9] = 0; - expirationTimes[index$9] = -1; - var hiddenUpdatesForLane = hiddenUpdates[index$9]; + var index$5 = 31 - clz32(noLongerPendingLanes), + lane = 1 << index$5; + remainingLanes[index$5] = 0; + expirationTimes[index$5] = -1; + var hiddenUpdatesForLane = hiddenUpdates[index$5]; if (null !== hiddenUpdatesForLane) for ( - hiddenUpdates[index$9] = null, index$9 = 0; - index$9 < hiddenUpdatesForLane.length; - index$9++ + hiddenUpdates[index$5] = null, index$5 = 0; + index$5 < hiddenUpdatesForLane.length; + index$5++ ) { - var update = hiddenUpdatesForLane[index$9]; + var update = hiddenUpdatesForLane[index$5]; null !== update && (update.lane &= -536870913); } noLongerPendingLanes &= ~lane; @@ -1707,13 +1493,14 @@ function markSpawnedDeferredLane(root, spawnedLane, entangledLanes) { function markRootEntangled(root, entangledLanes) { var rootEntangledLanes = (root.entangledLanes |= entangledLanes); for (root = root.entanglements; rootEntangledLanes; ) { - var index$10 = 31 - clz32(rootEntangledLanes), - lane = 1 << index$10; - (lane & entangledLanes) | (root[index$10] & entangledLanes) && - (root[index$10] |= entangledLanes); + var index$6 = 31 - clz32(rootEntangledLanes), + lane = 1 << index$6; + (lane & entangledLanes) | (root[index$6] & entangledLanes) && + (root[index$6] |= entangledLanes); rootEntangledLanes &= ~lane; } } +var currentUpdatePriority = 0; function lanesToEventPriority(lanes) { lanes &= -lanes; return 2 < lanes @@ -1729,11 +1516,6 @@ function shim$1() { "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." ); } -function shim() { - throw Error( - "The current renderer does not support Resources. This error is likely caused by a bug in React. Please file an issue." - ); -} var _nativeFabricUIManage = nativeFabricUIManager, createNode = _nativeFabricUIManage.createNode, cloneNodeWithNewChildren = _nativeFabricUIManage.cloneNodeWithNewChildren, @@ -1752,7 +1534,6 @@ var _nativeFabricUIManage = nativeFabricUIManager, ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get, nextReactTag = 2; registerEventHandler && registerEventHandler(dispatchEvent); -var PROD_HOST_CONTEXT = { isInAParentText: !0 }; function createTextInstance( text, rootContainerInstance, @@ -1778,19 +1559,6 @@ function getPublicInstance(instance) { ? instance : null; } -var currentUpdatePriority = 0; -function resolveUpdatePriority() { - if (0 !== currentUpdatePriority) return currentUpdatePriority; - var currentEventPriority = fabricGetCurrentEventPriority - ? fabricGetCurrentEventPriority() - : null; - if (null != currentEventPriority) - switch (currentEventPriority) { - case FabricDiscretePriority: - return 2; - } - return 32; -} var scheduleTimeout = setTimeout, cancelTimeout = clearTimeout; function cloneHiddenInstance(instance) { @@ -1843,6 +1611,34 @@ ResponderEventPlugin.injection.injectGlobalResponderHandler({ ); } }); +var REACT_ELEMENT_TYPE = Symbol.for("react.element"), + REACT_PORTAL_TYPE = Symbol.for("react.portal"), + REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"), + REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"), + REACT_PROFILER_TYPE = Symbol.for("react.profiler"), + REACT_PROVIDER_TYPE = Symbol.for("react.provider"), + REACT_CONSUMER_TYPE = Symbol.for("react.consumer"), + REACT_CONTEXT_TYPE = Symbol.for("react.context"), + REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"), + REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"), + REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"), + REACT_MEMO_TYPE = Symbol.for("react.memo"), + REACT_LAZY_TYPE = Symbol.for("react.lazy"); +Symbol.for("react.scope"); +Symbol.for("react.debug_trace_mode"); +var REACT_OFFSCREEN_TYPE = Symbol.for("react.offscreen"); +Symbol.for("react.legacy_hidden"); +Symbol.for("react.cache"); +Symbol.for("react.tracing_marker"); +var MAYBE_ITERATOR_SYMBOL = Symbol.iterator; +function getIteratorFn(maybeIterable) { + if (null === maybeIterable || "object" !== typeof maybeIterable) return null; + maybeIterable = + (MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL]) || + maybeIterable["@@iterator"]; + return "function" === typeof maybeIterable ? maybeIterable : null; +} +Symbol.for("react.client.reference"); function getNearestMountedFiber(fiber) { var node = fiber, nearestMounted = fiber; @@ -1891,36 +1687,36 @@ function findCurrentFiberUsingSlowPath(fiber) { } if (a.return !== b.return) (a = parentA), (b = parentB); else { - for (var didFindChild = !1, child$11 = parentA.child; child$11; ) { - if (child$11 === a) { + for (var didFindChild = !1, child$7 = parentA.child; child$7; ) { + if (child$7 === a) { didFindChild = !0; a = parentA; b = parentB; break; } - if (child$11 === b) { + if (child$7 === b) { didFindChild = !0; b = parentA; a = parentB; break; } - child$11 = child$11.sibling; + child$7 = child$7.sibling; } if (!didFindChild) { - for (child$11 = parentB.child; child$11; ) { - if (child$11 === a) { + for (child$7 = parentB.child; child$7; ) { + if (child$7 === a) { didFindChild = !0; a = parentB; b = parentA; break; } - if (child$11 === b) { + if (child$7 === b) { didFindChild = !0; b = parentB; a = parentA; break; } - child$11 = child$11.sibling; + child$7 = child$7.sibling; } if (!didFindChild) throw Error( @@ -1970,34 +1766,15 @@ 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, - CapturedStacks = new WeakMap(); -function createCapturedValueAtFiber(value, source) { - if ("object" === typeof value && null !== value) { - var stack = CapturedStacks.get(value); - "string" !== typeof stack && - ((stack = getStackByFiberInDevAndProd(source)), - CapturedStacks.set(value, stack)); - } else stack = getStackByFiberInDevAndProd(source); - return { value: value, source: source, stack: stack }; -} -var contextStackCursor = createCursor(null), + contextStackCursor = createCursor(null), contextFiberStackCursor = createCursor(null), - rootInstanceStackCursor = createCursor(null), - hostTransitionProviderCursor = createCursor(null), - HostTransitionContext = { - $$typeof: REACT_CONTEXT_TYPE, - Provider: null, - Consumer: null, - _currentValue: null, - _currentValue2: null, - _threadCount: 0 - }; + rootInstanceStackCursor = createCursor(null); function pushHostContainer(fiber, nextRootInstance) { push(rootInstanceStackCursor, nextRootInstance); push(contextFiberStackCursor, fiber); push(contextStackCursor, null); pop(contextStackCursor); - push(contextStackCursor, PROD_HOST_CONTEXT); + push(contextStackCursor, { isInAParentText: !1 }); } function popHostContainer() { pop(contextStackCursor); @@ -2005,17 +1782,25 @@ function popHostContainer() { pop(rootInstanceStackCursor); } function pushHostContext(fiber) { - null !== fiber.memoizedState && push(hostTransitionProviderCursor, fiber); var context = contextStackCursor.current; - context !== context && - (push(contextFiberStackCursor, fiber), push(contextStackCursor, context)); + var JSCompiler_inline_result = fiber.type; + JSCompiler_inline_result = + "AndroidTextInput" === JSCompiler_inline_result || + "RCTMultilineTextInputView" === JSCompiler_inline_result || + "RCTSinglelineTextInputView" === JSCompiler_inline_result || + "RCTText" === JSCompiler_inline_result || + "RCTVirtualText" === JSCompiler_inline_result; + JSCompiler_inline_result = + context.isInAParentText !== JSCompiler_inline_result + ? { isInAParentText: JSCompiler_inline_result } + : context; + context !== JSCompiler_inline_result && + (push(contextFiberStackCursor, fiber), + push(contextStackCursor, JSCompiler_inline_result)); } function popHostContext(fiber) { contextFiberStackCursor.current === fiber && (pop(contextStackCursor), pop(contextFiberStackCursor)); - hostTransitionProviderCursor.current === fiber && - (pop(hostTransitionProviderCursor), - (HostTransitionContext._currentValue2 = null)); } var hydrationErrors = null, concurrentQueues = [], @@ -2056,10 +1841,6 @@ function enqueueUpdate$1(fiber, queue, update, lane) { fiber = fiber.alternate; null !== fiber && (fiber.lanes |= lane); } -function enqueueConcurrentHookUpdate(fiber, queue, update, lane) { - enqueueUpdate$1(fiber, queue, update, lane); - return getRootForUpdatedFiber(fiber); -} function enqueueConcurrentRenderForLane(fiber, lane) { enqueueUpdate$1(fiber, null, null, lane); return getRootForUpdatedFiber(fiber); @@ -2090,7 +1871,14 @@ function markUpdateLaneFromFiberToRoot(sourceFiber, update, lane) { (update.lane = lane | 536870912)); } function getRootForUpdatedFiber(sourceFiber) { - throwIfInfiniteUpdateLoopDetected(); + if (50 < nestedUpdateCount) + throw ( + ((nestedUpdateCount = 0), + (rootWithNestedUpdates = null), + Error( + "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." + )) + ); for (var parent = sourceFiber.return; null !== parent; ) (sourceFiber = parent), (parent = sourceFiber.return); return 3 === sourceFiber.tag ? sourceFiber.stateNode : null; @@ -2111,29 +1899,101 @@ function ensureRootIsScheduled(root) { didScheduleMicrotask || ((didScheduleMicrotask = !0), scheduleImmediateTask(processRootScheduleInMicrotask)); + scheduleTaskForRootDuringMicrotask(root, now()); } function flushSyncWorkAcrossRoots_impl(onlyLegacy) { if (!isFlushingWork && mightHavePendingSyncWork) { + var errors = null; isFlushingWork = !0; do { var didPerformSomeWork = !1; for (var root = firstScheduledRoot; null !== root; ) { if (!onlyLegacy || 0 === root.tag) { - var workInProgressRootRenderLanes$13 = workInProgressRootRenderLanes; - workInProgressRootRenderLanes$13 = getNextLanes( - root, - root === workInProgressRoot ? workInProgressRootRenderLanes$13 : 0 - ); - 0 !== (workInProgressRootRenderLanes$13 & 3) && - ((didPerformSomeWork = !0), - performSyncWorkOnRoot(root, workInProgressRootRenderLanes$13)); + var workInProgressRootRenderLanes$9 = workInProgressRootRenderLanes, + nextLanes = getNextLanes( + root, + root === workInProgressRoot ? workInProgressRootRenderLanes$9 : 0 + ); + if (0 !== (nextLanes & 3)) + try { + didPerformSomeWork = !0; + workInProgressRootRenderLanes$9 = root; + if (0 !== (executionContext & 6)) + throw Error("Should not already be working."); + if (!flushPassiveEffects()) { + var exitStatus = renderRootSync( + workInProgressRootRenderLanes$9, + nextLanes + ); + if ( + 0 !== workInProgressRootRenderLanes$9.tag && + 2 === exitStatus + ) { + var originallyAttemptedLanes = nextLanes, + errorRetryLanes = getLanesToRetrySynchronouslyOnError( + workInProgressRootRenderLanes$9, + originallyAttemptedLanes + ); + 0 !== errorRetryLanes && + ((nextLanes = errorRetryLanes), + (exitStatus = recoverFromConcurrentError( + workInProgressRootRenderLanes$9, + originallyAttemptedLanes, + errorRetryLanes + ))); + } + if (1 === exitStatus) + throw ( + ((originallyAttemptedLanes = workInProgressRootFatalError), + prepareFreshStack(workInProgressRootRenderLanes$9, 0), + markRootSuspended( + workInProgressRootRenderLanes$9, + nextLanes, + 0 + ), + ensureRootIsScheduled(workInProgressRootRenderLanes$9), + originallyAttemptedLanes) + ); + 6 === exitStatus + ? markRootSuspended( + workInProgressRootRenderLanes$9, + nextLanes, + workInProgressDeferredLane + ) + : ((workInProgressRootRenderLanes$9.finishedWork = + workInProgressRootRenderLanes$9.current.alternate), + (workInProgressRootRenderLanes$9.finishedLanes = nextLanes), + commitRoot( + workInProgressRootRenderLanes$9, + workInProgressRootRecoverableErrors, + workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, + workInProgressDeferredLane + )); + } + ensureRootIsScheduled(workInProgressRootRenderLanes$9); + } catch (error) { + null === errors ? (errors = [error]) : errors.push(error); + } } root = root.next; } } while (didPerformSomeWork); isFlushingWork = !1; + if (null !== errors) { + if (1 < errors.length) { + if ("function" === typeof AggregateError) + throw new AggregateError(errors); + for (onlyLegacy = 1; onlyLegacy < errors.length; onlyLegacy++) + scheduleImmediateTask(throwError.bind(null, errors[onlyLegacy])); + } + throw errors[0]; + } } } +function throwError(error) { + throw error; +} function processRootScheduleInMicrotask() { mightHavePendingSyncWork = didScheduleMicrotask = !1; for ( @@ -2163,12 +2023,12 @@ function scheduleTaskForRootDuringMicrotask(root, currentTime) { 0 < lanes; ) { - var index$7 = 31 - clz32(lanes), - lane = 1 << index$7, - expirationTime = expirationTimes[index$7]; + var index$3 = 31 - clz32(lanes), + lane = 1 << index$3, + expirationTime = expirationTimes[index$3]; if (-1 === expirationTime) { if (0 === (lane & suspendedLanes) || 0 !== (lane & pingedLanes)) - expirationTimes[index$7] = computeExpirationTime(lane, currentTime); + expirationTimes[index$3] = computeExpirationTime(lane, currentTime); } else expirationTime <= currentTime && (root.expiredLanes |= lane); lanes &= ~lane; } @@ -2211,16 +2071,16 @@ function scheduleTaskForRootDuringMicrotask(root, currentTime) { suspendedLanes = UserBlockingPriority; break; case 32: - suspendedLanes = NormalPriority$1; + suspendedLanes = NormalPriority; break; case 268435456: suspendedLanes = IdlePriority; break; default: - suspendedLanes = NormalPriority$1; + suspendedLanes = NormalPriority; } pingedLanes = performConcurrentWorkOnRoot.bind(null, root); - suspendedLanes = scheduleCallback$3(suspendedLanes, pingedLanes); + suspendedLanes = scheduleCallback$2(suspendedLanes, pingedLanes); root.callbackPriority = currentTime; root.callbackNode = suspendedLanes; return currentTime; @@ -2229,75 +2089,10 @@ function scheduleImmediateTask(cb) { supportsMicrotasks ? scheduleMicrotask(function () { 0 !== (executionContext & 6) - ? scheduleCallback$3(ImmediatePriority, cb) + ? scheduleCallback$2(ImmediatePriority, cb) : cb(); }) - : scheduleCallback$3(ImmediatePriority, cb); -} -function requestTransitionLane() { - 0 === currentEventTransitionLane && - (currentEventTransitionLane = claimNextTransitionLane()); - return currentEventTransitionLane; -} -var currentEntangledListeners = null, - currentEntangledPendingCount = 0, - currentEntangledLane = 0, - currentEntangledActionThenable = null; -function entangleAsyncAction(transition, thenable) { - if (null === currentEntangledListeners) { - var entangledListeners = (currentEntangledListeners = []); - currentEntangledPendingCount = 0; - currentEntangledLane = requestTransitionLane(); - currentEntangledActionThenable = { - status: "pending", - value: void 0, - then: function (resolve) { - entangledListeners.push(resolve); - } - }; - } - currentEntangledPendingCount++; - thenable.then(pingEngtangledActionScope, pingEngtangledActionScope); - return thenable; -} -function pingEngtangledActionScope() { - if ( - null !== currentEntangledListeners && - 0 === --currentEntangledPendingCount - ) { - null !== currentEntangledActionThenable && - (currentEntangledActionThenable.status = "fulfilled"); - var listeners = currentEntangledListeners; - currentEntangledListeners = null; - currentEntangledLane = 0; - currentEntangledActionThenable = null; - for (var i = 0; i < listeners.length; i++) (0, listeners[i])(); - } -} -function chainThenableValue(thenable, result) { - var listeners = [], - thenableWithOverride = { - status: "pending", - value: null, - reason: null, - then: function (resolve) { - listeners.push(resolve); - } - }; - thenable.then( - function () { - thenableWithOverride.status = "fulfilled"; - thenableWithOverride.value = result; - for (var i = 0; i < listeners.length; i++) (0, listeners[i])(result); - }, - function (error) { - thenableWithOverride.status = "rejected"; - thenableWithOverride.reason = error; - for (error = 0; error < listeners.length; error++) - (0, listeners[error])(void 0); - } - ); - return thenableWithOverride; + : scheduleCallback$2(ImmediatePriority, cb); } var hasForceUpdate = !1; function initializeUpdateQueue(fiber) { @@ -2394,20 +2189,12 @@ function enqueueCapturedUpdate(workInProgress, capturedUpdate) { : (workInProgress.next = capturedUpdate); queue.lastBaseUpdate = capturedUpdate; } -var didReadFromEntangledAsyncAction = !1; -function suspendIfUpdateReadFromEntangledAsyncAction() { - if (didReadFromEntangledAsyncAction) { - var entangledActionThenable = currentEntangledActionThenable; - if (null !== entangledActionThenable) throw entangledActionThenable; - } -} function processUpdateQueue( workInProgress$jscomp$0, props, instance$jscomp$0, renderLanes ) { - didReadFromEntangledAsyncAction = !1; var queue = workInProgress$jscomp$0.updateQueue; hasForceUpdate = !1; var firstBaseUpdate = queue.firstBaseUpdate, @@ -2445,9 +2232,6 @@ function processUpdateQueue( ? (workInProgressRootRenderLanes & updateLane) === updateLane : (renderLanes & updateLane) === updateLane ) { - 0 !== updateLane && - updateLane === currentEntangledLane && - (didReadFromEntangledAsyncAction = !0); null !== current && (current = current.next = { @@ -2569,6 +2353,52 @@ function shallowEqual(objA, objB) { } return !0; } +function describeComponentFrame(name, ownerName) { + var sourceInfo = ""; + ownerName && (sourceInfo = " (created by " + ownerName + ")"); + return "\n in " + (name || "Unknown") + sourceInfo; +} +function describeFunctionComponentFrame(fn) { + return fn + ? describeComponentFrame(fn.displayName || fn.name || null, null) + : ""; +} +function describeFiber(fiber) { + switch (fiber.tag) { + case 26: + case 27: + case 5: + return describeComponentFrame(fiber.type, null); + case 16: + return describeComponentFrame("Lazy", null); + case 13: + return describeComponentFrame("Suspense", null); + case 19: + return describeComponentFrame("SuspenseList", null); + case 0: + case 2: + case 15: + return describeFunctionComponentFrame(fiber.type); + case 11: + return describeFunctionComponentFrame(fiber.type.render); + case 1: + return (fiber = describeFunctionComponentFrame(fiber.type)), fiber; + default: + return ""; + } +} +function getStackByFiberInDevAndProd(workInProgress) { + try { + var info = ""; + do + (info += describeFiber(workInProgress)), + (workInProgress = workInProgress.return); + while (workInProgress); + return info; + } catch (x) { + return "\nError generating stack: " + x.message + "\n" + x.stack; + } +} var SuspenseException = Error( "Suspense Exception: This is not a real error! It's an implementation detail of `use` to interrupt the current render. You must either rethrow it immediately, or move the `use` call outside of the `try/catch` block. Capturing without rethrowing will lead to unexpected behavior.\n\nTo handle async errors, wrap your component in an error boundary, or call the promise's `.catch` method and pass the result to `use`" ), @@ -2660,15 +2490,56 @@ function unwrapThenable(thenable) { null === thenableState$1 && (thenableState$1 = []); return trackUsedThenable(thenableState$1, thenable, index); } +function convertStringRefToCallbackRef( + returnFiber, + current, + element, + mixedRef +) { + function ref(value) { + var refs = inst.refs; + null === value ? delete refs[stringRef] : (refs[stringRef] = value); + } + var stringRef = "" + mixedRef; + returnFiber = element._owner; + if (!returnFiber) + throw Error( + "Element ref was specified as a string (" + + stringRef + + ") but no owner was set. This could happen for one of the following reasons:\n1. You may be adding a ref to a function component\n2. You may be adding a ref to a component that was not created inside a component's render method\n3. You have multiple copies of React loaded\nSee https://react.dev/link/refs-must-have-owner for more information." + ); + if (1 !== returnFiber.tag) + throw Error( + "Function components cannot have string refs. We recommend using useRef() instead. Learn more about using refs safely here: https://react.dev/link/strict-mode-string-ref" + ); + var inst = returnFiber.stateNode; + if (!inst) + throw Error( + "Missing owner for string ref " + + stringRef + + ". This error is likely caused by a bug in React. Please file an issue." + ); + if ( + null !== current && + null !== current.ref && + "function" === typeof current.ref && + current.ref._stringRef === stringRef + ) + return current.ref; + ref._stringRef = stringRef; + return ref; +} function coerceRef(returnFiber, current, workInProgress, element) { - returnFiber = element.props.ref; - workInProgress.ref = void 0 !== returnFiber ? returnFiber : null; + var mixedRef = element.ref; + returnFiber = + "string" === typeof mixedRef || + "number" === typeof mixedRef || + "boolean" === typeof mixedRef + ? convertStringRefToCallbackRef(returnFiber, current, element, mixedRef) + : mixedRef; + workInProgress.ref = returnFiber; } function throwOnInvalidObjectType(returnFiber, newChild) { - if (newChild.$$typeof === REACT_LEGACY_ELEMENT_TYPE) - throw Error( - 'A React Element from an older version of React was rendered. This is not supported. It can happen if:\n- Multiple copies of the "react" package is used.\n- A library pre-bundled an old copy of "react" or "react/jsx-runtime".\n- A compiler tries to "inline" JSX instead of using the runtime.' - ); returnFiber = Object.prototype.toString.call(newChild); throw Error( "Objects are not valid as a React child (found: " + @@ -2815,8 +2686,7 @@ function createChildReconciler(shouldTrackSideEffects) { function createChild(returnFiber, newChild, lanes) { if ( ("string" === typeof newChild && "" !== newChild) || - "number" === typeof newChild || - "bigint" === typeof newChild + "number" === typeof newChild ) return ( (newChild = createFiberFromText( @@ -2855,8 +2725,7 @@ function createChildReconciler(shouldTrackSideEffects) { ); case REACT_LAZY_TYPE: var init = newChild._init; - newChild = init(newChild._payload); - return createChild(returnFiber, newChild, lanes); + return createChild(returnFiber, init(newChild._payload), lanes); } if (isArrayImpl(newChild) || getIteratorFn(newChild)) return ( @@ -2885,8 +2754,7 @@ function createChildReconciler(shouldTrackSideEffects) { var key = null !== oldFiber ? oldFiber.key : null; if ( ("string" === typeof newChild && "" !== newChild) || - "number" === typeof newChild || - "bigint" === typeof newChild + "number" === typeof newChild ) return null !== key ? null @@ -2904,8 +2772,7 @@ function createChildReconciler(shouldTrackSideEffects) { case REACT_LAZY_TYPE: return ( (key = newChild._init), - (newChild = key(newChild._payload)), - updateSlot(returnFiber, oldFiber, newChild, lanes) + updateSlot(returnFiber, oldFiber, key(newChild._payload), lanes) ); } if (isArrayImpl(newChild) || getIteratorFn(newChild)) @@ -2939,8 +2806,7 @@ function createChildReconciler(shouldTrackSideEffects) { ) { if ( ("string" === typeof newChild && "" !== newChild) || - "number" === typeof newChild || - "bigint" === typeof newChild + "number" === typeof newChild ) return ( (existingChildren = existingChildren.get(newIdx) || null), @@ -2966,12 +2832,11 @@ function createChildReconciler(shouldTrackSideEffects) { ); case REACT_LAZY_TYPE: var init = newChild._init; - newChild = init(newChild._payload); return updateFromMap( existingChildren, returnFiber, newIdx, - newChild, + init(newChild._payload), lanes ); } @@ -3094,20 +2959,25 @@ function createChildReconciler(shouldTrackSideEffects) { function reconcileChildrenIterator( returnFiber, currentFirstChild, - newChildren, + newChildrenIterable, lanes ) { - if (null == newChildren) + var iteratorFn = getIteratorFn(newChildrenIterable); + if ("function" !== typeof iteratorFn) + throw Error( + "An object is not an iterable. This error is likely caused by a bug in React. Please file an issue." + ); + newChildrenIterable = iteratorFn.call(newChildrenIterable); + if (null == newChildrenIterable) throw Error("An iterable object provided no iterator."); for ( - var resultingFirstChild = null, - previousNewFiber = null, + var previousNewFiber = (iteratorFn = null), oldFiber = currentFirstChild, newIdx = (currentFirstChild = 0), nextOldFiber = null, - step = newChildren.next(); + step = newChildrenIterable.next(); null !== oldFiber && !step.done; - newIdx++, step = newChildren.next() + newIdx++, step = newChildrenIterable.next() ) { oldFiber.index > newIdx ? ((nextOldFiber = oldFiber), (oldFiber = null)) @@ -3123,30 +2993,28 @@ function createChildReconciler(shouldTrackSideEffects) { deleteChild(returnFiber, oldFiber); currentFirstChild = placeChild(newFiber, currentFirstChild, newIdx); null === previousNewFiber - ? (resultingFirstChild = newFiber) + ? (iteratorFn = newFiber) : (previousNewFiber.sibling = newFiber); previousNewFiber = newFiber; oldFiber = nextOldFiber; } if (step.done) - return ( - deleteRemainingChildren(returnFiber, oldFiber), resultingFirstChild - ); + return deleteRemainingChildren(returnFiber, oldFiber), iteratorFn; if (null === oldFiber) { - for (; !step.done; newIdx++, step = newChildren.next()) + for (; !step.done; newIdx++, step = newChildrenIterable.next()) (step = createChild(returnFiber, step.value, lanes)), null !== step && ((currentFirstChild = placeChild(step, currentFirstChild, newIdx)), null === previousNewFiber - ? (resultingFirstChild = step) + ? (iteratorFn = step) : (previousNewFiber.sibling = step), (previousNewFiber = step)); - return resultingFirstChild; + return iteratorFn; } for ( oldFiber = mapRemainingChildren(oldFiber); !step.done; - newIdx++, step = newChildren.next() + newIdx++, step = newChildrenIterable.next() ) (step = updateFromMap(oldFiber, returnFiber, newIdx, step.value, lanes)), null !== step && @@ -3155,14 +3023,14 @@ function createChildReconciler(shouldTrackSideEffects) { oldFiber.delete(null === step.key ? newIdx : step.key), (currentFirstChild = placeChild(step, currentFirstChild, newIdx)), null === previousNewFiber - ? (resultingFirstChild = step) + ? (iteratorFn = step) : (previousNewFiber.sibling = step), (previousNewFiber = step)); shouldTrackSideEffects && oldFiber.forEach(function (child) { return deleteChild(returnFiber, child); }); - return resultingFirstChild; + return iteratorFn; } function reconcileChildFibersImpl( returnFiber, @@ -3279,11 +3147,10 @@ function createChildReconciler(shouldTrackSideEffects) { case REACT_LAZY_TYPE: return ( (child = newChild._init), - (newChild = child(newChild._payload)), reconcileChildFibersImpl( returnFiber, currentFirstChild, - newChild, + child(newChild._payload), lanes ) ); @@ -3295,20 +3162,13 @@ function createChildReconciler(shouldTrackSideEffects) { newChild, lanes ); - if (getIteratorFn(newChild)) { - child = getIteratorFn(newChild); - if ("function" !== typeof child) - throw Error( - "An object is not an iterable. This error is likely caused by a bug in React. Please file an issue." - ); - newChild = child.call(newChild); + if (getIteratorFn(newChild)) return reconcileChildrenIterator( returnFiber, currentFirstChild, newChild, lanes ); - } if ("function" === typeof newChild.then) return reconcileChildFibersImpl( returnFiber, @@ -3326,8 +3186,7 @@ function createChildReconciler(shouldTrackSideEffects) { throwOnInvalidObjectType(returnFiber, newChild); } return ("string" === typeof newChild && "" !== newChild) || - "number" === typeof newChild || - "bigint" === typeof newChild + "number" === typeof newChild ? ((newChild = "" + newChild), null !== currentFirstChild && 6 === currentFirstChild.tag ? (deleteRemainingChildren(returnFiber, currentFirstChild.sibling), @@ -3346,31 +3205,15 @@ function createChildReconciler(shouldTrackSideEffects) { : deleteRemainingChildren(returnFiber, currentFirstChild); } return function (returnFiber, currentFirstChild, newChild, lanes) { - try { - thenableIndexCounter$1 = 0; - var firstChildFiber = reconcileChildFibersImpl( - returnFiber, - currentFirstChild, - newChild, - lanes - ); - thenableState$1 = null; - return firstChildFiber; - } catch (x) { - if ( - x === SuspenseException || - (0 === (returnFiber.mode & 1) && - "object" === typeof x && - null !== x && - "function" === typeof x.then) - ) - throw x; - var fiber = createFiber(29, x, null, returnFiber.mode); - fiber.lanes = lanes; - fiber.return = returnFiber; - return fiber; - } finally { - } + thenableIndexCounter$1 = 0; + returnFiber = reconcileChildFibersImpl( + returnFiber, + currentFirstChild, + newChild, + lanes + ); + thenableState$1 = null; + return returnFiber; }; } var reconcileChildFibers = createChildReconciler(!0), @@ -3450,7 +3293,9 @@ function findFirstSuspended(row) { } return null; } -var renderLanes = 0, +var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, + ReactCurrentBatchConfig$2 = ReactSharedInternals.ReactCurrentBatchConfig, + renderLanes = 0, currentlyRenderingFiber$1 = null, currentHook = null, workInProgressHook = null, @@ -3484,7 +3329,7 @@ function renderWithHooks( workInProgress.memoizedState = null; workInProgress.updateQueue = null; workInProgress.lanes = 0; - ReactSharedInternals.H = + ReactCurrentDispatcher$1.current = null === current || null === current.memoizedState ? HooksDispatcherOnMount : HooksDispatcherOnUpdate; @@ -3502,7 +3347,7 @@ function renderWithHooks( return current; } function finishRenderingHooks() { - ReactSharedInternals.H = ContextOnlyDispatcher; + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; var didRenderTooFewHooks = null !== currentHook && null !== currentHook.next; renderLanes = 0; workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; @@ -3528,23 +3373,11 @@ function renderWithHooksAgain(workInProgress, Component, props, secondArg) { numberOfReRenders += 1; workInProgressHook = currentHook = null; workInProgress.updateQueue = null; - ReactSharedInternals.H = HooksDispatcherOnRerender; + ReactCurrentDispatcher$1.current = HooksDispatcherOnRerender; var children = Component(props, secondArg); } while (didScheduleRenderPhaseUpdateDuringThisPass); return children; } -function TransitionAwareHostComponent() { - var dispatcher = ReactSharedInternals.H, - maybeThenable = dispatcher.useState()[0]; - maybeThenable = - "function" === typeof maybeThenable.then - ? useThenable(maybeThenable) - : maybeThenable; - dispatcher = dispatcher.useState()[0]; - (null !== currentHook ? currentHook.memoizedState : null) !== dispatcher && - (currentlyRenderingFiber$1.flags |= 1024); - return maybeThenable; -} function bailoutHooks(current, workInProgress, lanes) { workInProgress.updateQueue = current.updateQueue; workInProgress.flags &= -2053; @@ -3620,23 +3453,18 @@ function updateWorkInProgressHook() { } var createFunctionComponentUpdateQueue; createFunctionComponentUpdateQueue = function () { - return { lastEffect: null, events: null, stores: null, memoCache: null }; + return { lastEffect: null, events: null, stores: null }; }; function useThenable(thenable) { var index = thenableIndexCounter; thenableIndexCounter += 1; null === thenableState && (thenableState = []); thenable = trackUsedThenable(thenableState, thenable, index); - index = currentlyRenderingFiber$1; - null === + null === currentlyRenderingFiber$1.alternate && (null === workInProgressHook - ? index.memoizedState - : workInProgressHook.next) && - ((index = index.alternate), - (ReactSharedInternals.H = - null === index || null === index.memoizedState - ? HooksDispatcherOnMount - : HooksDispatcherOnUpdate)); + ? null === currentlyRenderingFiber$1.memoizedState + : null === workInProgressHook.next) && + (ReactCurrentDispatcher$1.current = HooksDispatcherOnMount); return thenable; } function use(usable) { @@ -3646,52 +3474,16 @@ function use(usable) { } throw Error("An unsupported type was passed to use(): " + String(usable)); } -function useMemoCache(size) { - var memoCache = null, - updateQueue = currentlyRenderingFiber$1.updateQueue; - null !== updateQueue && (memoCache = updateQueue.memoCache); - if (null == memoCache) { - var current = currentlyRenderingFiber$1.alternate; - null !== current && - ((current = current.updateQueue), - null !== current && - ((current = current.memoCache), - null != current && - (memoCache = { - data: current.data.map(function (array) { - return array.slice(); - }), - index: 0 - }))); - } - null == memoCache && (memoCache = { data: [], index: 0 }); - null === updateQueue && - ((updateQueue = createFunctionComponentUpdateQueue()), - (currentlyRenderingFiber$1.updateQueue = updateQueue)); - updateQueue.memoCache = memoCache; - updateQueue = memoCache.data[memoCache.index]; - if (void 0 === updateQueue) - for ( - updateQueue = memoCache.data[memoCache.index] = Array(size), current = 0; - current < size; - current++ - ) - updateQueue[current] = REACT_MEMO_CACHE_SENTINEL; - memoCache.index++; - return updateQueue; -} function basicStateReducer(state, action) { return "function" === typeof action ? action(state) : action; } function updateReducer(reducer) { - var hook = updateWorkInProgressHook(); - return updateReducerImpl(hook, currentHook, reducer); -} -function updateReducerImpl(hook, current, reducer) { - var queue = hook.queue; + var hook = updateWorkInProgressHook(), + current = currentHook, + queue = hook.queue; if (null === queue) throw Error( - "Should have a queue. You are likely calling Hooks conditionally, which is not allowed. (https://react.dev/link/invalid-hook-call)" + "Should have a queue. This is likely a bug in React. Please file an issue." ); queue.lastRenderedReducer = reducer; var baseQueue = hook.baseQueue, @@ -3711,82 +3503,52 @@ function updateReducerImpl(hook, current, reducer) { current = baseQueue.next; var newBaseQueueFirst = (baseFirst = null), newBaseQueueLast = null, - update = current, - didReadFromEntangledAsyncAction$43 = !1; + update = current; do { var updateLane = update.lane & -536870913; if ( updateLane !== update.lane ? (workInProgressRootRenderLanes & updateLane) === updateLane : (renderLanes & updateLane) === updateLane - ) { - var revertLane = update.revertLane; - if (0 === revertLane) - null !== newBaseQueueLast && - (newBaseQueueLast = newBaseQueueLast.next = - { - lane: 0, - revertLane: 0, - action: update.action, - hasEagerState: update.hasEagerState, - eagerState: update.eagerState, - next: null - }), - updateLane === currentEntangledLane && - (didReadFromEntangledAsyncAction$43 = !0); - else if ((renderLanes & revertLane) === revertLane) { - update = update.next; - revertLane === currentEntangledLane && - (didReadFromEntangledAsyncAction$43 = !0); - continue; - } else - (updateLane = { - lane: 0, - revertLane: update.revertLane, - action: update.action, - hasEagerState: update.hasEagerState, - eagerState: update.eagerState, - next: null - }), - null === newBaseQueueLast - ? ((newBaseQueueFirst = newBaseQueueLast = updateLane), - (baseFirst = pendingQueue)) - : (newBaseQueueLast = newBaseQueueLast.next = updateLane), - (currentlyRenderingFiber$1.lanes |= revertLane), - (workInProgressRootSkippedLanes |= revertLane); - updateLane = update.action; - shouldDoubleInvokeUserFnsInHooksDEV && - reducer(pendingQueue, updateLane); - pendingQueue = update.hasEagerState - ? update.eagerState - : reducer(pendingQueue, updateLane); - } else - (revertLane = { + ) + null !== newBaseQueueLast && + (newBaseQueueLast = newBaseQueueLast.next = + { + lane: 0, + revertLane: 0, + action: update.action, + hasEagerState: update.hasEagerState, + eagerState: update.eagerState, + next: null + }), + (updateLane = update.action), + shouldDoubleInvokeUserFnsInHooksDEV && + reducer(pendingQueue, updateLane), + (pendingQueue = update.hasEagerState + ? update.eagerState + : reducer(pendingQueue, updateLane)); + else { + var clone = { lane: updateLane, revertLane: update.revertLane, action: update.action, hasEagerState: update.hasEagerState, eagerState: update.eagerState, next: null - }), - null === newBaseQueueLast - ? ((newBaseQueueFirst = newBaseQueueLast = revertLane), - (baseFirst = pendingQueue)) - : (newBaseQueueLast = newBaseQueueLast.next = revertLane), - (currentlyRenderingFiber$1.lanes |= updateLane), - (workInProgressRootSkippedLanes |= updateLane); + }; + null === newBaseQueueLast + ? ((newBaseQueueFirst = newBaseQueueLast = clone), + (baseFirst = pendingQueue)) + : (newBaseQueueLast = newBaseQueueLast.next = clone); + currentlyRenderingFiber$1.lanes |= updateLane; + workInProgressRootSkippedLanes |= updateLane; + } update = update.next; } while (null !== update && update !== current); null === newBaseQueueLast ? (baseFirst = pendingQueue) : (newBaseQueueLast.next = newBaseQueueFirst); - if ( - !objectIs(pendingQueue, hook.memoizedState) && - ((didReceiveUpdate = !0), - didReadFromEntangledAsyncAction$43 && - ((reducer = currentEntangledActionThenable), null !== reducer)) - ) - throw reducer; + objectIs(pendingQueue, hook.memoizedState) || (didReceiveUpdate = !0); hook.memoizedState = pendingQueue; hook.baseState = baseFirst; hook.baseQueue = newBaseQueueLast; @@ -3800,7 +3562,7 @@ function rerenderReducer(reducer) { queue = hook.queue; if (null === queue) throw Error( - "Should have a queue. You are likely calling Hooks conditionally, which is not allowed. (https://react.dev/link/invalid-hook-call)" + "Should have a queue. This is likely a bug in React. Please file an issue." ); queue.lastRenderedReducer = reducer; var dispatch = queue.dispatch, @@ -3895,10 +3657,7 @@ function mountStateImpl(initialState) { if ("function" === typeof initialState) { var initialStateInitializer = initialState; initialState = initialStateInitializer(); - shouldDoubleInvokeUserFnsInHooksDEV && - (setIsStrictModeForDevtools(!0), - initialStateInitializer(), - setIsStrictModeForDevtools(!1)); + shouldDoubleInvokeUserFnsInHooksDEV && initialStateInitializer(); } hook.memoizedState = hook.baseState = initialState; hook.queue = { @@ -3910,214 +3669,6 @@ function mountStateImpl(initialState) { }; return hook; } -function updateOptimisticImpl(hook, current, passthrough, reducer) { - hook.baseState = passthrough; - return updateReducerImpl( - hook, - currentHook, - "function" === typeof reducer ? reducer : basicStateReducer - ); -} -function dispatchActionState( - fiber, - actionQueue, - setPendingState, - setState, - payload -) { - if (isRenderPhaseUpdate(fiber)) - throw Error("Cannot update form state while rendering."); - fiber = actionQueue.action; - if (null !== fiber) { - var actionNode = { - payload: payload, - action: fiber, - next: null, - isTransition: !0, - status: "pending", - value: null, - reason: null, - listeners: [], - then: function (listener) { - actionNode.listeners.push(listener); - } - }; - null !== ReactSharedInternals.T - ? setPendingState(!0) - : (actionNode.isTransition = !1); - setState(actionNode); - setPendingState = actionQueue.pending; - null === setPendingState - ? ((actionNode.next = actionQueue.pending = actionNode), - runActionStateAction(actionQueue, actionNode)) - : ((actionNode.next = setPendingState.next), - (actionQueue.pending = setPendingState.next = actionNode)); - } -} -function runActionStateAction(actionQueue, node) { - var action = node.action, - payload = node.payload, - prevState = actionQueue.state; - if (node.isTransition) { - var prevTransition = ReactSharedInternals.T, - currentTransition = {}; - ReactSharedInternals.T = currentTransition; - try { - var returnValue = action(prevState, payload), - onStartTransitionFinish = ReactSharedInternals.S; - null !== onStartTransitionFinish && - onStartTransitionFinish(currentTransition, returnValue); - handleActionReturnValue(actionQueue, node, returnValue); - } catch (error) { - onActionError(actionQueue, node, error); - } finally { - ReactSharedInternals.T = prevTransition; - } - } else - try { - (prevTransition = action(prevState, payload)), - handleActionReturnValue(actionQueue, node, prevTransition); - } catch (error$47) { - onActionError(actionQueue, node, error$47); - } -} -function handleActionReturnValue(actionQueue, node, returnValue) { - null !== returnValue && - "object" === typeof returnValue && - "function" === typeof returnValue.then - ? returnValue.then( - function (nextState) { - onActionSuccess(actionQueue, node, nextState); - }, - function (error) { - return onActionError(actionQueue, node, error); - } - ) - : onActionSuccess(actionQueue, node, returnValue); -} -function onActionSuccess(actionQueue, actionNode, nextState) { - actionNode.status = "fulfilled"; - actionNode.value = nextState; - notifyActionListeners(actionNode); - actionQueue.state = nextState; - actionNode = actionQueue.pending; - null !== actionNode && - ((nextState = actionNode.next), - nextState === actionNode - ? (actionQueue.pending = null) - : ((nextState = nextState.next), - (actionNode.next = nextState), - runActionStateAction(actionQueue, nextState))); -} -function onActionError(actionQueue, actionNode, error) { - var last = actionQueue.pending; - actionQueue.pending = null; - if (null !== last) { - last = last.next; - do - (actionNode.status = "rejected"), - (actionNode.reason = error), - notifyActionListeners(actionNode), - (actionNode = actionNode.next); - while (actionNode !== last); - } - actionQueue.action = null; -} -function notifyActionListeners(actionNode) { - actionNode = actionNode.listeners; - for (var i = 0; i < actionNode.length; i++) (0, actionNode[i])(); -} -function actionStateReducer(oldState, newState) { - return newState; -} -function mountActionState(action, initialStateProp) { - var stateHook = mountWorkInProgressHook(); - stateHook.memoizedState = stateHook.baseState = initialStateProp; - var stateQueue = { - pending: null, - lanes: 0, - dispatch: null, - lastRenderedReducer: actionStateReducer, - lastRenderedState: initialStateProp - }; - stateHook.queue = stateQueue; - stateHook = dispatchSetState.bind( - null, - currentlyRenderingFiber$1, - stateQueue - ); - stateQueue.dispatch = stateHook; - stateQueue = mountStateImpl(!1); - var setPendingState = dispatchOptimisticSetState.bind( - null, - currentlyRenderingFiber$1, - !1, - stateQueue.queue - ); - stateQueue = mountWorkInProgressHook(); - var actionQueue = { - state: initialStateProp, - dispatch: null, - action: action, - pending: null - }; - stateQueue.queue = actionQueue; - stateHook = dispatchActionState.bind( - null, - currentlyRenderingFiber$1, - actionQueue, - setPendingState, - stateHook - ); - actionQueue.dispatch = stateHook; - stateQueue.memoizedState = action; - return [initialStateProp, stateHook, !1]; -} -function updateActionState(action) { - var stateHook = updateWorkInProgressHook(); - return updateActionStateImpl(stateHook, currentHook, action); -} -function updateActionStateImpl(stateHook, currentStateHook, action) { - currentStateHook = updateReducerImpl( - stateHook, - currentStateHook, - actionStateReducer - )[0]; - stateHook = updateReducer(basicStateReducer)[0]; - currentStateHook = - "object" === typeof currentStateHook && - null !== currentStateHook && - "function" === typeof currentStateHook.then - ? useThenable(currentStateHook) - : currentStateHook; - var actionQueueHook = updateWorkInProgressHook(), - actionQueue = actionQueueHook.queue, - dispatch = actionQueue.dispatch; - action !== actionQueueHook.memoizedState && - ((currentlyRenderingFiber$1.flags |= 2048), - pushEffect( - 9, - actionStateActionEffect.bind(null, actionQueue, action), - { destroy: void 0 }, - null - )); - return [currentStateHook, dispatch, stateHook]; -} -function actionStateActionEffect(actionQueue, action) { - actionQueue.action = action; -} -function rerenderActionState(action) { - var stateHook = updateWorkInProgressHook(), - currentStateHook = currentHook; - if (null !== currentStateHook) - return updateActionStateImpl(stateHook, currentStateHook, action); - updateWorkInProgressHook(); - stateHook = stateHook.memoizedState; - currentStateHook = updateWorkInProgressHook(); - var dispatch = currentStateHook.queue.dispatch; - currentStateHook.memoizedState = action; - return [stateHook, dispatch, !1]; -} function pushEffect(tag, create, inst, deps) { tag = { tag: tag, create: create, inst: inst, deps: deps, next: null }; create = currentlyRenderingFiber$1.updateQueue; @@ -4171,13 +3722,14 @@ function updateLayoutEffect(create, deps) { return updateEffectImpl(4, 4, create, deps); } function imperativeHandleEffect(create, ref) { - if ("function" === typeof ref) { - create = create(); - var refCleanup = ref(create); - return function () { - "function" === typeof refCleanup ? refCleanup() : ref(null); - }; - } + if ("function" === typeof ref) + return ( + (create = create()), + ref(create), + function () { + ref(null); + } + ); if (null !== ref && void 0 !== ref) return ( (create = create()), @@ -4208,21 +3760,18 @@ function updateMemo(nextCreate, deps) { if (null !== deps && areHookInputsEqual(deps, prevState[1])) return prevState[0]; prevState = nextCreate(); - shouldDoubleInvokeUserFnsInHooksDEV && - (setIsStrictModeForDevtools(!0), - nextCreate(), - setIsStrictModeForDevtools(!1)); + shouldDoubleInvokeUserFnsInHooksDEV && nextCreate(); hook.memoizedState = [prevState, deps]; return prevState; } function mountDeferredValueImpl(hook, value, initialValue) { - if (void 0 === initialValue || 0 !== (renderLanes & 1073741824)) - return (hook.memoizedState = value); - hook.memoizedState = initialValue; - hook = requestDeferredLane(); - currentlyRenderingFiber$1.lanes |= hook; - workInProgressRootSkippedLanes |= hook; - return initialValue; + return void 0 !== initialValue && 0 === (renderLanes & 1073741824) + ? ((hook.memoizedState = initialValue), + (hook = requestDeferredLane()), + (currentlyRenderingFiber$1.lanes |= hook), + (workInProgressRootSkippedLanes |= hook), + initialValue) + : (hook.memoizedState = value); } function updateDeferredValueImpl(hook, prevValue, value, initialValue) { if (objectIs(value, prevValue)) return value; @@ -4243,65 +3792,23 @@ function startTransition(fiber, queue, pendingState, finishedState, callback) { var previousPriority = currentUpdatePriority; currentUpdatePriority = 0 !== previousPriority && 8 > previousPriority ? previousPriority : 8; - var prevTransition = ReactSharedInternals.T, - currentTransition = {}; - ReactSharedInternals.T = currentTransition; - dispatchOptimisticSetState(fiber, !1, queue, pendingState); + var prevTransition = ReactCurrentBatchConfig$2.transition, + currentTransition = { _callbacks: new Set() }; + ReactCurrentBatchConfig$2.transition = null; + dispatchSetState(fiber, queue, pendingState); + ReactCurrentBatchConfig$2.transition = currentTransition; try { - var returnValue = callback(), - onStartTransitionFinish = ReactSharedInternals.S; - null !== onStartTransitionFinish && - onStartTransitionFinish(currentTransition, returnValue); - if ( - null !== returnValue && - "object" === typeof returnValue && - "function" === typeof returnValue.then - ) { - var thenableForFinishedState = chainThenableValue( - returnValue, - finishedState - ); - dispatchSetState(fiber, queue, thenableForFinishedState); - } else dispatchSetState(fiber, queue, finishedState); + dispatchSetState(fiber, queue, finishedState), callback(); } catch (error) { - dispatchSetState(fiber, queue, { - then: function () {}, - status: "rejected", - reason: error - }); + throw error; } finally { (currentUpdatePriority = previousPriority), - (ReactSharedInternals.T = prevTransition); + (ReactCurrentBatchConfig$2.transition = prevTransition); } } -function useHostTransitionStatus() { - var status = readContext(HostTransitionContext); - return null !== status ? status : null; -} function updateId() { return updateWorkInProgressHook().memoizedState; } -function updateRefresh() { - return updateWorkInProgressHook().memoizedState; -} -function refreshCache(fiber) { - for (var provider = fiber.return; null !== provider; ) { - switch (provider.tag) { - case 24: - case 3: - var lane = requestUpdateLane(provider); - fiber = createUpdate(lane); - var root = enqueueUpdate(provider, fiber, lane); - null !== root && - (scheduleUpdateOnFiber(root, provider, lane), - entangleTransitions(root, provider, lane)); - provider = { cache: createCache() }; - fiber.payload = provider; - return; - } - provider = provider.return; - } -} function dispatchReducerAction(fiber, queue, action) { var lane = requestUpdateLane(fiber); action = { @@ -4314,7 +3821,8 @@ function dispatchReducerAction(fiber, queue, action) { }; isRenderPhaseUpdate(fiber) ? enqueueRenderPhaseUpdate(queue, action) - : ((action = enqueueConcurrentHookUpdate(fiber, queue, action, lane)), + : (enqueueUpdate$1(fiber, queue, action, lane), + (action = getRootForUpdatedFiber(fiber)), null !== action && (scheduleUpdateOnFiber(action, fiber, lane), entangleTransitionUpdate(action, queue, lane))); @@ -4350,34 +3858,13 @@ function dispatchSetState(fiber, queue, action) { } catch (error) { } finally { } - action = enqueueConcurrentHookUpdate(fiber, queue, update, lane); + enqueueUpdate$1(fiber, queue, update, lane); + action = getRootForUpdatedFiber(fiber); null !== action && (scheduleUpdateOnFiber(action, fiber, lane), entangleTransitionUpdate(action, queue, lane)); } } -function dispatchOptimisticSetState(fiber, throwIfDuringRender, queue, action) { - action = { - lane: 2, - revertLane: requestTransitionLane(), - action: action, - hasEagerState: !1, - eagerState: null, - next: null - }; - if (isRenderPhaseUpdate(fiber)) { - if (throwIfDuringRender) - throw Error("Cannot update optimistic state while rendering."); - } else - (throwIfDuringRender = enqueueConcurrentHookUpdate( - fiber, - queue, - action, - 2 - )), - null !== throwIfDuringRender && - scheduleUpdateOnFiber(throwIfDuringRender, fiber, 2); -} function isRenderPhaseUpdate(fiber) { var alternate = fiber.alternate; return ( @@ -4404,285 +3891,237 @@ function entangleTransitionUpdate(root, queue, lane) { } } var ContextOnlyDispatcher = { - readContext: readContext, - use: use, - useCallback: throwInvalidHookError, - useContext: throwInvalidHookError, - useEffect: throwInvalidHookError, - useImperativeHandle: throwInvalidHookError, - useLayoutEffect: throwInvalidHookError, - useInsertionEffect: throwInvalidHookError, - useMemo: throwInvalidHookError, - useReducer: throwInvalidHookError, - useRef: throwInvalidHookError, - useState: throwInvalidHookError, - useDebugValue: throwInvalidHookError, - useDeferredValue: throwInvalidHookError, - useTransition: throwInvalidHookError, - useSyncExternalStore: throwInvalidHookError, - useId: throwInvalidHookError -}; -ContextOnlyDispatcher.useCacheRefresh = throwInvalidHookError; -ContextOnlyDispatcher.useMemoCache = throwInvalidHookError; -ContextOnlyDispatcher.useHostTransitionStatus = throwInvalidHookError; -ContextOnlyDispatcher.useFormState = throwInvalidHookError; -ContextOnlyDispatcher.useActionState = throwInvalidHookError; -ContextOnlyDispatcher.useOptimistic = throwInvalidHookError; -var HooksDispatcherOnMount = { - readContext: readContext, - use: use, - useCallback: function (callback, deps) { - mountWorkInProgressHook().memoizedState = [ - callback, - void 0 === deps ? null : deps - ]; - return callback; - }, - useContext: readContext, - useEffect: mountEffect, - useImperativeHandle: function (ref, create, deps) { - deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; - mountEffectImpl( - 4194308, - 4, - imperativeHandleEffect.bind(null, create, ref), - deps - ); - }, - useLayoutEffect: function (create, deps) { - return mountEffectImpl(4194308, 4, create, deps); - }, - useInsertionEffect: function (create, deps) { - mountEffectImpl(4, 2, create, deps); - }, - useMemo: function (nextCreate, deps) { - var hook = mountWorkInProgressHook(); - deps = void 0 === deps ? null : deps; - var nextValue = nextCreate(); - shouldDoubleInvokeUserFnsInHooksDEV && - (setIsStrictModeForDevtools(!0), - nextCreate(), - setIsStrictModeForDevtools(!1)); - hook.memoizedState = [nextValue, deps]; - return nextValue; - }, - useReducer: function (reducer, initialArg, init) { - var hook = mountWorkInProgressHook(); - if (void 0 !== init) { - var initialState = init(initialArg); - shouldDoubleInvokeUserFnsInHooksDEV && - (setIsStrictModeForDevtools(!0), - init(initialArg), - setIsStrictModeForDevtools(!1)); - } else initialState = initialArg; - hook.memoizedState = hook.baseState = initialState; - reducer = { - pending: null, - lanes: 0, - dispatch: null, - lastRenderedReducer: reducer, - lastRenderedState: initialState - }; - hook.queue = reducer; - reducer = reducer.dispatch = dispatchReducerAction.bind( - null, - currentlyRenderingFiber$1, - reducer - ); - return [hook.memoizedState, reducer]; - }, - useRef: function (initialValue) { - var hook = mountWorkInProgressHook(); - initialValue = { current: initialValue }; - return (hook.memoizedState = initialValue); - }, - useState: function (initialState) { - initialState = mountStateImpl(initialState); - var queue = initialState.queue, - dispatch = dispatchSetState.bind(null, currentlyRenderingFiber$1, queue); - queue.dispatch = dispatch; - return [initialState.memoizedState, dispatch]; - }, - useDebugValue: mountDebugValue, - useDeferredValue: function (value, initialValue) { - var hook = mountWorkInProgressHook(); - return mountDeferredValueImpl(hook, value, initialValue); - }, - useTransition: function () { - var stateHook = mountStateImpl(!1); - stateHook = startTransition.bind( - null, - currentlyRenderingFiber$1, - stateHook.queue, - !0, - !1 - ); - mountWorkInProgressHook().memoizedState = stateHook; - return [!1, stateHook]; + readContext: readContext, + use: use, + useCallback: throwInvalidHookError, + useContext: throwInvalidHookError, + useEffect: throwInvalidHookError, + useImperativeHandle: throwInvalidHookError, + useInsertionEffect: throwInvalidHookError, + useLayoutEffect: throwInvalidHookError, + useMemo: throwInvalidHookError, + useReducer: throwInvalidHookError, + useRef: throwInvalidHookError, + useState: throwInvalidHookError, + useDebugValue: throwInvalidHookError, + useDeferredValue: throwInvalidHookError, + useTransition: throwInvalidHookError, + useSyncExternalStore: throwInvalidHookError, + useId: throwInvalidHookError }, - useSyncExternalStore: function (subscribe, getSnapshot) { - var fiber = currentlyRenderingFiber$1, - hook = mountWorkInProgressHook(); - var nextSnapshot = getSnapshot(); - if (null === workInProgressRoot) - throw Error( - "Expected a work-in-progress root. This is a bug in React. Please file an issue." + HooksDispatcherOnMount = { + readContext: readContext, + use: use, + useCallback: function (callback, deps) { + mountWorkInProgressHook().memoizedState = [ + callback, + void 0 === deps ? null : deps + ]; + return callback; + }, + useContext: readContext, + useEffect: mountEffect, + useImperativeHandle: function (ref, create, deps) { + deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; + mountEffectImpl( + 4194308, + 4, + imperativeHandleEffect.bind(null, create, ref), + deps ); - 0 !== (workInProgressRootRenderLanes & 60) || - pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot); - hook.memoizedState = nextSnapshot; - var inst = { value: nextSnapshot, getSnapshot: getSnapshot }; - hook.queue = inst; - mountEffect(subscribeToStore.bind(null, fiber, inst, subscribe), [ - subscribe - ]); - fiber.flags |= 2048; - pushEffect( - 9, - updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot), - { destroy: void 0 }, - null - ); - return nextSnapshot; - }, - useId: function () { - var hook = mountWorkInProgressHook(), - identifierPrefix = workInProgressRoot.identifierPrefix, - globalClientId = globalClientIdCounter++; - identifierPrefix = - ":" + identifierPrefix + "r" + globalClientId.toString(32) + ":"; - return (hook.memoizedState = identifierPrefix); - }, - useCacheRefresh: function () { - return (mountWorkInProgressHook().memoizedState = refreshCache.bind( - null, - currentlyRenderingFiber$1 - )); - } -}; -HooksDispatcherOnMount.useMemoCache = useMemoCache; -HooksDispatcherOnMount.useHostTransitionStatus = useHostTransitionStatus; -HooksDispatcherOnMount.useFormState = mountActionState; -HooksDispatcherOnMount.useActionState = mountActionState; -HooksDispatcherOnMount.useOptimistic = function (passthrough) { - var hook = mountWorkInProgressHook(); - hook.memoizedState = hook.baseState = passthrough; - var queue = { - pending: null, - lanes: 0, - dispatch: null, - lastRenderedReducer: null, - lastRenderedState: null - }; - hook.queue = queue; - hook = dispatchOptimisticSetState.bind( - null, - currentlyRenderingFiber$1, - !0, - queue - ); - queue.dispatch = hook; - return [passthrough, hook]; -}; -var HooksDispatcherOnUpdate = { - readContext: readContext, - use: use, - useCallback: updateCallback, - useContext: readContext, - useEffect: updateEffect, - useImperativeHandle: updateImperativeHandle, - useInsertionEffect: updateInsertionEffect, - useLayoutEffect: updateLayoutEffect, - useMemo: updateMemo, - useReducer: updateReducer, - useRef: updateRef, - useState: function () { - return updateReducer(basicStateReducer); - }, - useDebugValue: mountDebugValue, - useDeferredValue: function (value, initialValue) { - var hook = updateWorkInProgressHook(); - return updateDeferredValueImpl( - hook, - currentHook.memoizedState, - value, - initialValue - ); - }, - useTransition: function () { - var booleanOrThenable = updateReducer(basicStateReducer)[0], - start = updateWorkInProgressHook().memoizedState; - return [ - "boolean" === typeof booleanOrThenable - ? booleanOrThenable - : useThenable(booleanOrThenable), - start - ]; - }, - useSyncExternalStore: updateSyncExternalStore, - useId: updateId -}; -HooksDispatcherOnUpdate.useCacheRefresh = updateRefresh; -HooksDispatcherOnUpdate.useMemoCache = useMemoCache; -HooksDispatcherOnUpdate.useHostTransitionStatus = useHostTransitionStatus; -HooksDispatcherOnUpdate.useFormState = updateActionState; -HooksDispatcherOnUpdate.useActionState = updateActionState; -HooksDispatcherOnUpdate.useOptimistic = function (passthrough, reducer) { - var hook = updateWorkInProgressHook(); - return updateOptimisticImpl(hook, currentHook, passthrough, reducer); -}; -var HooksDispatcherOnRerender = { - readContext: readContext, - use: use, - useCallback: updateCallback, - useContext: readContext, - useEffect: updateEffect, - useImperativeHandle: updateImperativeHandle, - useInsertionEffect: updateInsertionEffect, - useLayoutEffect: updateLayoutEffect, - useMemo: updateMemo, - useReducer: rerenderReducer, - useRef: updateRef, - useState: function () { - return rerenderReducer(basicStateReducer); - }, - useDebugValue: mountDebugValue, - useDeferredValue: function (value, initialValue) { - var hook = updateWorkInProgressHook(); - return null === currentHook - ? mountDeferredValueImpl(hook, value, initialValue) - : updateDeferredValueImpl( - hook, - currentHook.memoizedState, - value, - initialValue + }, + useLayoutEffect: function (create, deps) { + return mountEffectImpl(4194308, 4, create, deps); + }, + useInsertionEffect: function (create, deps) { + mountEffectImpl(4, 2, create, deps); + }, + useMemo: function (nextCreate, deps) { + var hook = mountWorkInProgressHook(); + deps = void 0 === deps ? null : deps; + var nextValue = nextCreate(); + shouldDoubleInvokeUserFnsInHooksDEV && nextCreate(); + hook.memoizedState = [nextValue, deps]; + return nextValue; + }, + useReducer: function (reducer, initialArg, init) { + var hook = mountWorkInProgressHook(); + if (void 0 !== init) { + var initialState = init(initialArg); + shouldDoubleInvokeUserFnsInHooksDEV && init(initialArg); + } else initialState = initialArg; + hook.memoizedState = hook.baseState = initialState; + reducer = { + pending: null, + lanes: 0, + dispatch: null, + lastRenderedReducer: reducer, + lastRenderedState: initialState + }; + hook.queue = reducer; + reducer = reducer.dispatch = dispatchReducerAction.bind( + null, + currentlyRenderingFiber$1, + reducer + ); + return [hook.memoizedState, reducer]; + }, + useRef: function (initialValue) { + var hook = mountWorkInProgressHook(); + initialValue = { current: initialValue }; + return (hook.memoizedState = initialValue); + }, + useState: function (initialState) { + initialState = mountStateImpl(initialState); + var queue = initialState.queue, + dispatch = dispatchSetState.bind( + null, + currentlyRenderingFiber$1, + queue + ); + queue.dispatch = dispatch; + return [initialState.memoizedState, dispatch]; + }, + useDebugValue: mountDebugValue, + useDeferredValue: function (value, initialValue) { + var hook = mountWorkInProgressHook(); + return mountDeferredValueImpl(hook, value, initialValue); + }, + useTransition: function () { + var stateHook = mountStateImpl(!1); + stateHook = startTransition.bind( + null, + currentlyRenderingFiber$1, + stateHook.queue, + !0, + !1 + ); + mountWorkInProgressHook().memoizedState = stateHook; + return [!1, stateHook]; + }, + useSyncExternalStore: function (subscribe, getSnapshot) { + var fiber = currentlyRenderingFiber$1, + hook = mountWorkInProgressHook(); + var nextSnapshot = getSnapshot(); + if (null === workInProgressRoot) + throw Error( + "Expected a work-in-progress root. This is a bug in React. Please file an issue." ); + 0 !== (workInProgressRootRenderLanes & 60) || + pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot); + hook.memoizedState = nextSnapshot; + var inst = { value: nextSnapshot, getSnapshot: getSnapshot }; + hook.queue = inst; + mountEffect(subscribeToStore.bind(null, fiber, inst, subscribe), [ + subscribe + ]); + fiber.flags |= 2048; + pushEffect( + 9, + updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot), + { destroy: void 0 }, + null + ); + return nextSnapshot; + }, + useId: function () { + var hook = mountWorkInProgressHook(), + identifierPrefix = workInProgressRoot.identifierPrefix, + globalClientId = globalClientIdCounter++; + identifierPrefix = + ":" + identifierPrefix + "r" + globalClientId.toString(32) + ":"; + return (hook.memoizedState = identifierPrefix); + } }, - useTransition: function () { - var booleanOrThenable = rerenderReducer(basicStateReducer)[0], - start = updateWorkInProgressHook().memoizedState; - return [ - "boolean" === typeof booleanOrThenable - ? booleanOrThenable - : useThenable(booleanOrThenable), - start - ]; + HooksDispatcherOnUpdate = { + readContext: readContext, + use: use, + useCallback: updateCallback, + useContext: readContext, + useEffect: updateEffect, + useImperativeHandle: updateImperativeHandle, + useInsertionEffect: updateInsertionEffect, + useLayoutEffect: updateLayoutEffect, + useMemo: updateMemo, + useReducer: updateReducer, + useRef: updateRef, + useState: function () { + return updateReducer(basicStateReducer); + }, + useDebugValue: mountDebugValue, + useDeferredValue: function (value, initialValue) { + var hook = updateWorkInProgressHook(); + return updateDeferredValueImpl( + hook, + currentHook.memoizedState, + value, + initialValue + ); + }, + useTransition: function () { + var booleanOrThenable = updateReducer(basicStateReducer)[0], + start = updateWorkInProgressHook().memoizedState; + return [ + "boolean" === typeof booleanOrThenable + ? booleanOrThenable + : useThenable(booleanOrThenable), + start + ]; + }, + useSyncExternalStore: updateSyncExternalStore, + useId: updateId }, - useSyncExternalStore: updateSyncExternalStore, - useId: updateId -}; -HooksDispatcherOnRerender.useCacheRefresh = updateRefresh; -HooksDispatcherOnRerender.useMemoCache = useMemoCache; -HooksDispatcherOnRerender.useHostTransitionStatus = useHostTransitionStatus; -HooksDispatcherOnRerender.useFormState = rerenderActionState; -HooksDispatcherOnRerender.useActionState = rerenderActionState; -HooksDispatcherOnRerender.useOptimistic = function (passthrough, reducer) { - var hook = updateWorkInProgressHook(); - if (null !== currentHook) - return updateOptimisticImpl(hook, currentHook, passthrough, reducer); - hook.baseState = passthrough; - return [passthrough, hook.queue.dispatch]; -}; + HooksDispatcherOnRerender = { + readContext: readContext, + use: use, + useCallback: updateCallback, + useContext: readContext, + useEffect: updateEffect, + useImperativeHandle: updateImperativeHandle, + useInsertionEffect: updateInsertionEffect, + useLayoutEffect: updateLayoutEffect, + useMemo: updateMemo, + useReducer: rerenderReducer, + useRef: updateRef, + useState: function () { + return rerenderReducer(basicStateReducer); + }, + useDebugValue: mountDebugValue, + useDeferredValue: function (value, initialValue) { + var hook = updateWorkInProgressHook(); + return null === currentHook + ? mountDeferredValueImpl(hook, value, initialValue) + : updateDeferredValueImpl( + hook, + currentHook.memoizedState, + value, + initialValue + ); + }, + useTransition: function () { + var booleanOrThenable = rerenderReducer(basicStateReducer)[0], + start = updateWorkInProgressHook().memoizedState; + return [ + "boolean" === typeof booleanOrThenable + ? booleanOrThenable + : useThenable(booleanOrThenable), + start + ]; + }, + useSyncExternalStore: updateSyncExternalStore, + useId: updateId + }; +function resolveDefaultProps(Component, baseProps) { + if (Component && Component.defaultProps) { + baseProps = assign({}, baseProps); + Component = Component.defaultProps; + for (var propName in Component) + void 0 === baseProps[propName] && + (baseProps[propName] = Component[propName]); + return baseProps; + } + return baseProps; +} function applyDerivedStateFromProps( workInProgress, ctor, @@ -4812,111 +4251,80 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { ctor !== instance.state && classComponentUpdater.enqueueReplaceState(instance, instance.state, null), processUpdateQueue(workInProgress, newProps, instance, renderLanes), - suspendIfUpdateReadFromEntangledAsyncAction(), (instance.state = workInProgress.memoizedState)); "function" === typeof instance.componentDidMount && (workInProgress.flags |= 4194308); } -function resolveClassComponentProps(Component, baseProps) { - var newProps = baseProps; - if ("ref" in baseProps) { - newProps = {}; - for (var propName in baseProps) - "ref" !== propName && (newProps[propName] = baseProps[propName]); - } - if ((Component = Component.defaultProps)) { - newProps === baseProps && (newProps = assign({}, newProps)); - for (var propName$49 in Component) - void 0 === newProps[propName$49] && - (newProps[propName$49] = Component[propName$49]); - } - return newProps; -} -var reportGlobalError = - "function" === typeof reportError - ? reportError - : function (error) { - if ( - "object" === typeof window && - "function" === typeof window.ErrorEvent - ) { - var event = new window.ErrorEvent("error", { - bubbles: !0, - cancelable: !0, - message: - "object" === typeof error && - null !== error && - "string" === typeof error.message - ? String(error.message) - : String(error), - error: error - }); - if (!window.dispatchEvent(event)) return; - } else if ( - "object" === typeof process && - "function" === typeof process.emit - ) { - process.emit("uncaughtException", error); - return; - } - console.error(error); - }; -function defaultOnRecoverableError(error) { - reportGlobalError(error); +var CapturedStacks = new WeakMap(); +function createCapturedValueAtFiber(value, source) { + if ("object" === typeof value && null !== value) { + var stack = CapturedStacks.get(value); + "string" !== typeof stack && + ((stack = getStackByFiberInDevAndProd(source)), + CapturedStacks.set(value, stack)); + } else stack = getStackByFiberInDevAndProd(source); + return { value: value, source: source, stack: stack, digest: null }; } -function logUncaughtError(root, errorInfo) { - try { - var onUncaughtError = root.onUncaughtError; - onUncaughtError(errorInfo.value, { componentStack: errorInfo.stack }); - } catch (e) { - setTimeout(function () { - throw e; - }); - } +function createCapturedValueFromError(value, digest, stack) { + "string" === typeof stack && CapturedStacks.set(value, stack); + return { + value: value, + source: null, + stack: null != stack ? stack : null, + digest: null != digest ? digest : null + }; } -function logCaughtError(root, boundary, errorInfo) { +if ( + "function" !== + typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog +) + throw Error( + "Expected ReactFiberErrorDialog.showErrorDialog to be a function." + ); +function logCapturedError(boundary, errorInfo) { try { - var onCaughtError = root.onCaughtError; - onCaughtError(errorInfo.value, { - componentStack: errorInfo.stack, - errorBoundary: 1 === boundary.tag ? boundary.stateNode : null - }); + !1 !== + ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog({ + componentStack: null !== errorInfo.stack ? errorInfo.stack : "", + error: errorInfo.value, + errorBoundary: + null !== boundary && 1 === boundary.tag ? boundary.stateNode : null + }) && console.error(errorInfo.value); } catch (e) { setTimeout(function () { throw e; }); } } -function createRootErrorUpdate(root, errorInfo, lane) { +function createRootErrorUpdate(fiber, errorInfo, lane) { lane = createUpdate(lane); lane.tag = 3; lane.payload = { element: null }; + var error = errorInfo.value; lane.callback = function () { - logUncaughtError(root, errorInfo); + hasUncaughtError || ((hasUncaughtError = !0), (firstUncaughtError = error)); + logCapturedError(fiber, errorInfo); }; return lane; } -function createClassErrorUpdate(lane) { +function createClassErrorUpdate(fiber, errorInfo, lane) { lane = createUpdate(lane); lane.tag = 3; - return lane; -} -function initializeClassErrorUpdate(update, root, fiber, errorInfo) { var getDerivedStateFromError = fiber.type.getDerivedStateFromError; if ("function" === typeof getDerivedStateFromError) { var error = errorInfo.value; - update.payload = function () { + lane.payload = function () { return getDerivedStateFromError(error); }; - update.callback = function () { - logCaughtError(root, fiber, errorInfo); + lane.callback = function () { + logCapturedError(fiber, errorInfo); }; } var inst = fiber.stateNode; null !== inst && "function" === typeof inst.componentDidCatch && - (update.callback = function () { - logCaughtError(root, fiber, errorInfo); + (lane.callback = function () { + logCapturedError(fiber, errorInfo); "function" !== typeof getDerivedStateFromError && (null === legacyErrorBoundariesThatAlreadyFailed ? (legacyErrorBoundariesThatAlreadyFailed = new Set([this])) @@ -4926,6 +4334,7 @@ function initializeClassErrorUpdate(update, root, fiber, errorInfo) { componentStack: null !== stack ? stack : "" }); }); + return lane; } function throwException( root, @@ -4967,15 +4376,12 @@ function throwException( : ((tag.flags |= 128), (sourceFiber.flags |= 131072), (sourceFiber.flags &= -52805), - 1 === sourceFiber.tag - ? null === sourceFiber.alternate + 1 === sourceFiber.tag && + (null === sourceFiber.alternate ? (sourceFiber.tag = 17) : ((returnFiber = createUpdate(2)), (returnFiber.tag = 2), - enqueueUpdate(sourceFiber, returnFiber, 2)) - : 0 === sourceFiber.tag && - null === sourceFiber.alternate && - (sourceFiber.tag = 28), + enqueueUpdate(sourceFiber, returnFiber, 2))), (sourceFiber.lanes |= 2)) : ((tag.flags |= 65536), (tag.lanes = rootRenderLanes)), value === noopSuspenseyCommitThenable @@ -5026,35 +4432,34 @@ function throwException( "A component suspended while responding to synchronous input. This will cause the UI to be replaced with a loading indicator. To fix, updates that suspend should be wrapped with startTransition." ); } - tag = createCapturedValueAtFiber( - Error( - "There was an error during concurrent rendering but React was able to recover by instead synchronously rendering the entire root.", - { cause: value } - ), - sourceFiber - ); - null === workInProgressRootConcurrentErrors - ? (workInProgressRootConcurrentErrors = [tag]) - : workInProgressRootConcurrentErrors.push(tag); + root = value = createCapturedValueAtFiber(value, sourceFiber); 4 !== workInProgressRootExitStatus && (workInProgressRootExitStatus = 2); + null === workInProgressRootConcurrentErrors + ? (workInProgressRootConcurrentErrors = [root]) + : workInProgressRootConcurrentErrors.push(root); if (null === returnFiber) return !0; - value = createCapturedValueAtFiber(value, sourceFiber); + root = returnFiber; do { - switch (returnFiber.tag) { + switch (root.tag) { case 3: return ( - (returnFiber.flags |= 65536), - (root = rootRenderLanes & -rootRenderLanes), - (returnFiber.lanes |= root), - (root = createRootErrorUpdate(returnFiber.stateNode, value, root)), - enqueueCapturedUpdate(returnFiber, root), + (root.flags |= 65536), + (rootRenderLanes &= -rootRenderLanes), + (root.lanes |= rootRenderLanes), + (rootRenderLanes = createRootErrorUpdate( + root, + value, + rootRenderLanes + )), + enqueueCapturedUpdate(root, rootRenderLanes), !1 ); case 1: if ( - ((sourceFiber = returnFiber.type), - (tag = returnFiber.stateNode), - 0 === (returnFiber.flags & 128) && + ((returnFiber = value), + (sourceFiber = root.type), + (tag = root.stateNode), + 0 === (root.flags & 128) && ("function" === typeof sourceFiber.getDerivedStateFromError || (null !== tag && "function" === typeof tag.componentDidCatch && @@ -5062,25 +4467,24 @@ function throwException( !legacyErrorBoundariesThatAlreadyFailed.has(tag))))) ) return ( - (returnFiber.flags |= 65536), + (root.flags |= 65536), (rootRenderLanes &= -rootRenderLanes), - (returnFiber.lanes |= rootRenderLanes), - (rootRenderLanes = createClassErrorUpdate(rootRenderLanes)), - initializeClassErrorUpdate( - rootRenderLanes, + (root.lanes |= rootRenderLanes), + (rootRenderLanes = createClassErrorUpdate( root, returnFiber, - value - ), - enqueueCapturedUpdate(returnFiber, rootRenderLanes), + rootRenderLanes + )), + enqueueCapturedUpdate(root, rootRenderLanes), !1 ); } - returnFiber = returnFiber.return; - } while (null !== returnFiber); + root = root.return; + } while (null !== root); return !1; } -var SelectiveHydrationException = Error( +var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner, + SelectiveHydrationException = Error( "This is not a real error. It's an implementation detail of React's selective hydration feature. If this leaks into userspace, it's a bug in React. Please file an issue." ), didReceiveUpdate = !1; @@ -5104,17 +4508,12 @@ function updateForwardRef( ) { Component = Component.render; var ref = workInProgress.ref; - if ("ref" in nextProps) { - var propsWithoutRef = {}; - for (var key in nextProps) - "ref" !== key && (propsWithoutRef[key] = nextProps[key]); - } else propsWithoutRef = nextProps; prepareToReadContext(workInProgress, renderLanes); nextProps = renderWithHooks( current, workInProgress, Component, - propsWithoutRef, + nextProps, ref, renderLanes ); @@ -5140,7 +4539,8 @@ function updateMemoComponent( "function" === typeof type && !shouldConstruct(type) && void 0 === type.defaultProps && - null === Component.compare + null === Component.compare && + void 0 === Component.defaultProps ) return ( (workInProgress.tag = 15), @@ -5238,52 +4638,35 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { } if (0 === (workInProgress.mode & 1)) (workInProgress.memoizedState = { baseLanes: 0, cachePool: null }), - null !== current && pushTransition(workInProgress, null), - reuseHiddenContextOnStack(), - pushOffscreenSuspenseHandler(workInProgress); - else if (0 !== (renderLanes & 536870912)) - (workInProgress.memoizedState = { baseLanes: 0, cachePool: null }), - null !== current && - pushTransition( + reuseHiddenContextOnStack(); + else { + if (0 === (renderLanes & 536870912)) + return ( + (workInProgress.lanes = workInProgress.childLanes = 536870912), + deferHiddenOffscreenComponent( + current, workInProgress, - null !== prevState ? prevState.cachePool : null - ), - null !== prevState - ? pushHiddenContext(workInProgress, prevState) - : reuseHiddenContextOnStack(), - pushOffscreenSuspenseHandler(workInProgress); - else - return ( - (workInProgress.lanes = workInProgress.childLanes = 536870912), - deferHiddenOffscreenComponent( - current, - workInProgress, - null !== prevState ? prevState.baseLanes | renderLanes : renderLanes - ) - ); + null !== prevState ? prevState.baseLanes | renderLanes : renderLanes + ) + ); + workInProgress.memoizedState = { baseLanes: 0, cachePool: null }; + null !== prevState + ? pushHiddenContext(workInProgress, prevState) + : reuseHiddenContextOnStack(); + } + pushOffscreenSuspenseHandler(workInProgress); } else null !== prevState - ? (pushTransition(workInProgress, prevState.cachePool), - pushHiddenContext(workInProgress, prevState), + ? (pushHiddenContext(workInProgress, prevState), reuseSuspenseHandlerOnStack(workInProgress), (workInProgress.memoizedState = null)) - : (null !== current && pushTransition(workInProgress, null), - reuseHiddenContextOnStack(), + : (reuseHiddenContextOnStack(), reuseSuspenseHandlerOnStack(workInProgress)); reconcileChildren(current, workInProgress, nextChildren, renderLanes); return workInProgress.child; } function deferHiddenOffscreenComponent(current, workInProgress, nextBaseLanes) { - var JSCompiler_inline_result = peekCacheFromPool(); - JSCompiler_inline_result = - null === JSCompiler_inline_result - ? null - : { parent: CacheContext._currentValue2, pool: JSCompiler_inline_result }; - workInProgress.memoizedState = { - baseLanes: nextBaseLanes, - cachePool: JSCompiler_inline_result - }; - null !== current && pushTransition(workInProgress, null); + workInProgress.memoizedState = { baseLanes: nextBaseLanes, cachePool: null }; reuseHiddenContextOnStack(); pushOffscreenSuspenseHandler(workInProgress); return null; @@ -5368,8 +4751,7 @@ function updateClassComponent( (nextProps = !0); else if (null === current) { var instance = workInProgress.stateNode, - unresolvedOldProps = workInProgress.memoizedProps, - oldProps = resolveClassComponentProps(Component, unresolvedOldProps); + oldProps = workInProgress.memoizedProps; instance.props = oldProps; var oldContext = instance.context, contextType = Component.contextType, @@ -5378,14 +4760,12 @@ function updateClassComponent( null !== contextType && (nextContext = readContext(contextType)); var getDerivedStateFromProps = Component.getDerivedStateFromProps; - contextType = + (contextType = "function" === typeof getDerivedStateFromProps || - "function" === typeof instance.getSnapshotBeforeUpdate; - unresolvedOldProps = workInProgress.pendingProps !== unresolvedOldProps; - contextType || + "function" === typeof instance.getSnapshotBeforeUpdate) || ("function" !== typeof instance.UNSAFE_componentWillReceiveProps && "function" !== typeof instance.componentWillReceiveProps) || - ((unresolvedOldProps || oldContext !== nextContext) && + ((oldProps !== nextProps || oldContext !== nextContext) && callComponentWillReceiveProps( workInProgress, instance, @@ -5396,9 +4776,8 @@ function updateClassComponent( var oldState = workInProgress.memoizedState; instance.state = oldState; processUpdateQueue(workInProgress, nextProps, instance, renderLanes); - suspendIfUpdateReadFromEntangledAsyncAction(); oldContext = workInProgress.memoizedState; - unresolvedOldProps || oldState !== oldContext || hasForceUpdate + oldProps !== nextProps || oldState !== oldContext || hasForceUpdate ? ("function" === typeof getDerivedStateFromProps && (applyDerivedStateFromProps( workInProgress, @@ -5442,22 +4821,26 @@ function updateClassComponent( instance = workInProgress.stateNode; cloneUpdateQueue(current, workInProgress); nextContext = workInProgress.memoizedProps; - contextType = resolveClassComponentProps(Component, nextContext); + contextType = + workInProgress.type === workInProgress.elementType + ? nextContext + : resolveDefaultProps(workInProgress.type, nextContext); instance.props = contextType; getDerivedStateFromProps = workInProgress.pendingProps; - oldState = instance.context; + var oldContext$jscomp$0 = instance.context; oldContext = Component.contextType; oldProps = emptyContextObject; "object" === typeof oldContext && null !== oldContext && (oldProps = readContext(oldContext)); - unresolvedOldProps = Component.getDerivedStateFromProps; + oldState = Component.getDerivedStateFromProps; (oldContext = - "function" === typeof unresolvedOldProps || + "function" === typeof oldState || "function" === typeof instance.getSnapshotBeforeUpdate) || ("function" !== typeof instance.UNSAFE_componentWillReceiveProps && "function" !== typeof instance.componentWillReceiveProps) || - ((nextContext !== getDerivedStateFromProps || oldState !== oldProps) && + ((nextContext !== getDerivedStateFromProps || + oldContext$jscomp$0 !== oldProps) && callComponentWillReceiveProps( workInProgress, instance, @@ -5465,19 +4848,18 @@ function updateClassComponent( oldProps )); hasForceUpdate = !1; - oldState = workInProgress.memoizedState; - instance.state = oldState; + oldContext$jscomp$0 = workInProgress.memoizedState; + instance.state = oldContext$jscomp$0; processUpdateQueue(workInProgress, nextProps, instance, renderLanes); - suspendIfUpdateReadFromEntangledAsyncAction(); var newState = workInProgress.memoizedState; nextContext !== getDerivedStateFromProps || - oldState !== newState || + oldContext$jscomp$0 !== newState || hasForceUpdate - ? ("function" === typeof unresolvedOldProps && + ? ("function" === typeof oldState && (applyDerivedStateFromProps( workInProgress, Component, - unresolvedOldProps, + oldState, nextProps ), (newState = workInProgress.memoizedState)), @@ -5488,7 +4870,7 @@ function updateClassComponent( Component, contextType, nextProps, - oldState, + oldContext$jscomp$0, newState, oldProps ) || @@ -5510,11 +4892,11 @@ function updateClassComponent( (workInProgress.flags |= 1024)) : ("function" !== typeof instance.componentDidUpdate || (nextContext === current.memoizedProps && - oldState === current.memoizedState) || + oldContext$jscomp$0 === current.memoizedState) || (workInProgress.flags |= 4), "function" !== typeof instance.getSnapshotBeforeUpdate || (nextContext === current.memoizedProps && - oldState === current.memoizedState) || + oldContext$jscomp$0 === current.memoizedState) || (workInProgress.flags |= 1024), (workInProgress.memoizedProps = nextProps), (workInProgress.memoizedState = newState)), @@ -5524,11 +4906,11 @@ function updateClassComponent( (nextProps = contextType)) : ("function" !== typeof instance.componentDidUpdate || (nextContext === current.memoizedProps && - oldState === current.memoizedState) || + oldContext$jscomp$0 === current.memoizedState) || (workInProgress.flags |= 4), "function" !== typeof instance.getSnapshotBeforeUpdate || (nextContext === current.memoizedProps && - oldState === current.memoizedState) || + oldContext$jscomp$0 === current.memoizedState) || (workInProgress.flags |= 1024), (nextProps = !1)); } @@ -5554,6 +4936,7 @@ function finishClassComponent( if (!shouldUpdate && !hasContext) return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); shouldUpdate = workInProgress.stateNode; + ReactCurrentOwner$1.current = workInProgress; Component = hasContext && "function" !== typeof Component.getDerivedStateFromError ? null @@ -5578,7 +4961,7 @@ function finishClassComponent( } var SUSPENDED_MARKER = { dehydrated: null, treeContext: null, retryLane: 0 }; function mountSuspenseOffscreenState(renderLanes) { - return { baseLanes: renderLanes, cachePool: getSuspendedCache() }; + return { baseLanes: renderLanes, cachePool: null }; } function getRemainingWorkInPrimaryTree( current, @@ -5603,248 +4986,100 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { JSCompiler_temp = 0 !== (workInProgress.flags & 32); workInProgress.flags &= -33; if (null === current) { - var nextPrimaryChildren = nextProps.children; + didSuspend = nextProps.children; nextProps = nextProps.fallback; - if (showFallback) - return ( - reuseSuspenseHandlerOnStack(workInProgress), - (showFallback = workInProgress.mode), - (didSuspend = workInProgress.child), - (nextPrimaryChildren = { - mode: "hidden", - children: nextPrimaryChildren - }), - 0 === (showFallback & 1) && null !== didSuspend - ? ((didSuspend.childLanes = 0), - (didSuspend.pendingProps = nextPrimaryChildren)) - : (didSuspend = createFiberFromOffscreen( - nextPrimaryChildren, - showFallback, - 0, - null - )), - (nextProps = createFiberFromFragment( - nextProps, - showFallback, - renderLanes, - null - )), - (didSuspend.return = workInProgress), - (nextProps.return = workInProgress), - (didSuspend.sibling = nextProps), - (workInProgress.child = didSuspend), - (nextPrimaryChildren = workInProgress.child), - (nextPrimaryChildren.memoizedState = - mountSuspenseOffscreenState(renderLanes)), - (nextPrimaryChildren.childLanes = getRemainingWorkInPrimaryTree( - current, - JSCompiler_temp, - renderLanes - )), - (workInProgress.memoizedState = SUSPENDED_MARKER), - nextProps - ); - pushPrimaryTreeSuspenseHandler(workInProgress); - return mountSuspensePrimaryChildren(workInProgress, nextPrimaryChildren); - } - nextPrimaryChildren = current.memoizedState; - if (null !== nextPrimaryChildren && null !== nextPrimaryChildren.dehydrated) { - if (didSuspend) - workInProgress.flags & 256 - ? (pushPrimaryTreeSuspenseHandler(workInProgress), - (workInProgress.flags &= -257), - (workInProgress = retrySuspenseComponentWithoutHydrating( - current, - workInProgress, - renderLanes - ))) - : null !== workInProgress.memoizedState - ? (reuseSuspenseHandlerOnStack(workInProgress), - (workInProgress.child = current.child), - (workInProgress.flags |= 128), - (workInProgress = null)) - : (reuseSuspenseHandlerOnStack(workInProgress), - (nextPrimaryChildren = nextProps.fallback), - (showFallback = workInProgress.mode), - (nextProps = createFiberFromOffscreen( - { mode: "visible", children: nextProps.children }, + if (showFallback) { + reuseSuspenseHandlerOnStack(workInProgress); + showFallback = workInProgress.mode; + var progressedPrimaryFragment = workInProgress.child; + didSuspend = { mode: "hidden", children: didSuspend }; + 0 === (showFallback & 1) && null !== progressedPrimaryFragment + ? ((progressedPrimaryFragment.childLanes = 0), + (progressedPrimaryFragment.pendingProps = didSuspend)) + : (progressedPrimaryFragment = createFiberFromOffscreen( + didSuspend, showFallback, 0, null - )), - (nextPrimaryChildren = createFiberFromFragment( - nextPrimaryChildren, - showFallback, - renderLanes, - null - )), - (nextPrimaryChildren.flags |= 2), - (nextProps.return = workInProgress), - (nextPrimaryChildren.return = workInProgress), - (nextProps.sibling = nextPrimaryChildren), - (workInProgress.child = nextProps), - 0 !== (workInProgress.mode & 1) && - reconcileChildFibers( - workInProgress, - current.child, - null, - renderLanes - ), - (nextProps = workInProgress.child), - (nextProps.memoizedState = mountSuspenseOffscreenState(renderLanes)), - (nextProps.childLanes = getRemainingWorkInPrimaryTree( - current, - JSCompiler_temp, - renderLanes - )), - (workInProgress.memoizedState = SUSPENDED_MARKER), - (workInProgress = nextPrimaryChildren)); - else if ((pushPrimaryTreeSuspenseHandler(workInProgress), shim$1())) - (JSCompiler_temp = shim$1().digest), - (nextProps = Error( - "The server could not finish this Suspense boundary, likely due to an error during server rendering. Switched to client rendering." - )), - (nextProps.stack = ""), - (nextProps.digest = JSCompiler_temp), - (JSCompiler_temp = { value: nextProps, source: null, stack: null }), - null === hydrationErrors - ? (hydrationErrors = [JSCompiler_temp]) - : hydrationErrors.push(JSCompiler_temp), - (workInProgress = retrySuspenseComponentWithoutHydrating( - current, - workInProgress, - renderLanes - )); - else if ( - ((JSCompiler_temp = 0 !== (renderLanes & current.childLanes)), - didReceiveUpdate || JSCompiler_temp) - ) { - JSCompiler_temp = workInProgressRoot; - if (null !== JSCompiler_temp) { - nextProps = renderLanes & -renderLanes; - if (0 !== (nextProps & 42)) nextProps = 1; - else - switch (nextProps) { - case 2: - nextProps = 1; - break; - case 8: - nextProps = 4; - break; - case 32: - nextProps = 16; - break; - case 128: - case 256: - case 512: - case 1024: - case 2048: - case 4096: - case 8192: - case 16384: - case 32768: - case 65536: - case 131072: - case 262144: - case 524288: - case 1048576: - case 2097152: - case 4194304: - case 8388608: - case 16777216: - case 33554432: - nextProps = 64; - break; - case 268435456: - nextProps = 134217728; - break; - default: - nextProps = 0; - } - nextProps = - 0 !== (nextProps & (JSCompiler_temp.suspendedLanes | renderLanes)) - ? 0 - : nextProps; - if (0 !== nextProps && nextProps !== nextPrimaryChildren.retryLane) - throw ( - ((nextPrimaryChildren.retryLane = nextProps), - enqueueConcurrentRenderForLane(current, nextProps), - scheduleUpdateOnFiber(JSCompiler_temp, current, nextProps), - SelectiveHydrationException) - ); - } - shim$1() || renderDidSuspendDelayIfPossible(); - workInProgress = retrySuspenseComponentWithoutHydrating( + )); + nextProps = createFiberFromFragment( + nextProps, + showFallback, + renderLanes, + null + ); + progressedPrimaryFragment.return = workInProgress; + nextProps.return = workInProgress; + progressedPrimaryFragment.sibling = nextProps; + workInProgress.child = progressedPrimaryFragment; + showFallback = workInProgress.child; + showFallback.memoizedState = mountSuspenseOffscreenState(renderLanes); + showFallback.childLanes = getRemainingWorkInPrimaryTree( + current, + JSCompiler_temp, + renderLanes + ); + workInProgress.memoizedState = SUSPENDED_MARKER; + return nextProps; + } + pushPrimaryTreeSuspenseHandler(workInProgress); + return mountSuspensePrimaryChildren(workInProgress, didSuspend); + } + progressedPrimaryFragment = current.memoizedState; + if (null !== progressedPrimaryFragment) { + var dehydrated = progressedPrimaryFragment.dehydrated; + if (null !== dehydrated) + return updateDehydratedSuspenseComponent( current, workInProgress, + didSuspend, + JSCompiler_temp, + nextProps, + dehydrated, + progressedPrimaryFragment, renderLanes ); - } else - shim$1() - ? ((workInProgress.flags |= 128), - (workInProgress.child = current.child), - retryDehydratedSuspenseBoundary.bind(null, current), - shim$1(), - (workInProgress = null)) - : ((workInProgress = mountSuspensePrimaryChildren( - workInProgress, - nextProps.children - )), - (workInProgress.flags |= 4096)); - return workInProgress; } if (showFallback) { reuseSuspenseHandlerOnStack(workInProgress); - nextPrimaryChildren = nextProps.fallback; - showFallback = workInProgress.mode; - didSuspend = current.child; - var currentFallbackChildFragment = didSuspend.sibling, - primaryChildProps = { mode: "hidden", children: nextProps.children }; - 0 === (showFallback & 1) && workInProgress.child !== didSuspend + showFallback = nextProps.fallback; + didSuspend = workInProgress.mode; + progressedPrimaryFragment = current.child; + dehydrated = progressedPrimaryFragment.sibling; + var primaryChildProps = { mode: "hidden", children: nextProps.children }; + 0 === (didSuspend & 1) && workInProgress.child !== progressedPrimaryFragment ? ((nextProps = workInProgress.child), (nextProps.childLanes = 0), (nextProps.pendingProps = primaryChildProps), (workInProgress.deletions = null)) - : ((nextProps = createWorkInProgress(didSuspend, primaryChildProps)), - (nextProps.subtreeFlags = didSuspend.subtreeFlags & 31457280)); - null !== currentFallbackChildFragment - ? (nextPrimaryChildren = createWorkInProgress( - currentFallbackChildFragment, - nextPrimaryChildren - )) - : ((nextPrimaryChildren = createFiberFromFragment( - nextPrimaryChildren, + : ((nextProps = createWorkInProgress( + progressedPrimaryFragment, + primaryChildProps + )), + (nextProps.subtreeFlags = + progressedPrimaryFragment.subtreeFlags & 31457280)); + null !== dehydrated + ? (showFallback = createWorkInProgress(dehydrated, showFallback)) + : ((showFallback = createFiberFromFragment( showFallback, + didSuspend, renderLanes, null )), - (nextPrimaryChildren.flags |= 2)); - nextPrimaryChildren.return = workInProgress; + (showFallback.flags |= 2)); + showFallback.return = workInProgress; nextProps.return = workInProgress; - nextProps.sibling = nextPrimaryChildren; + nextProps.sibling = showFallback; workInProgress.child = nextProps; - nextProps = nextPrimaryChildren; - nextPrimaryChildren = workInProgress.child; - showFallback = current.child.memoizedState; - null === showFallback - ? (showFallback = mountSuspenseOffscreenState(renderLanes)) - : ((didSuspend = showFallback.cachePool), - null !== didSuspend - ? ((currentFallbackChildFragment = CacheContext._currentValue2), - (didSuspend = - didSuspend.parent !== currentFallbackChildFragment - ? { - parent: currentFallbackChildFragment, - pool: currentFallbackChildFragment - } - : didSuspend)) - : (didSuspend = getSuspendedCache()), - (showFallback = { - baseLanes: showFallback.baseLanes | renderLanes, - cachePool: didSuspend - })); - nextPrimaryChildren.memoizedState = showFallback; - nextPrimaryChildren.childLanes = getRemainingWorkInPrimaryTree( + nextProps = showFallback; + showFallback = workInProgress.child; + didSuspend = current.child.memoizedState; + didSuspend = + null === didSuspend + ? mountSuspenseOffscreenState(renderLanes) + : { baseLanes: didSuspend.baseLanes | renderLanes, cachePool: null }; + showFallback.memoizedState = didSuspend; + showFallback.childLanes = getRemainingWorkInPrimaryTree( current, JSCompiler_temp, renderLanes @@ -5884,8 +5119,13 @@ function mountSuspensePrimaryChildren(workInProgress, primaryChildren) { function retrySuspenseComponentWithoutHydrating( current, workInProgress, - renderLanes + renderLanes, + recoverableError ) { + null !== recoverableError && + (null === hydrationErrors + ? (hydrationErrors = [recoverableError]) + : hydrationErrors.push(recoverableError)); reconcileChildFibers(workInProgress, current.child, null, renderLanes); current = mountSuspensePrimaryChildren( workInProgress, @@ -5895,6 +5135,176 @@ function retrySuspenseComponentWithoutHydrating( workInProgress.memoizedState = null; return current; } +function updateDehydratedSuspenseComponent( + current, + workInProgress, + didSuspend, + didPrimaryChildrenDefer, + nextProps, + suspenseInstance, + suspenseState, + renderLanes +) { + if (didSuspend) { + if (workInProgress.flags & 256) + return ( + pushPrimaryTreeSuspenseHandler(workInProgress), + (workInProgress.flags &= -257), + (didPrimaryChildrenDefer = createCapturedValueFromError( + Error( + "There was an error while hydrating this Suspense boundary. Switched to client rendering." + ) + )), + retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + didPrimaryChildrenDefer + ) + ); + if (null !== workInProgress.memoizedState) + return ( + reuseSuspenseHandlerOnStack(workInProgress), + (workInProgress.child = current.child), + (workInProgress.flags |= 128), + null + ); + reuseSuspenseHandlerOnStack(workInProgress); + suspenseState = nextProps.fallback; + didSuspend = workInProgress.mode; + nextProps = createFiberFromOffscreen( + { mode: "visible", children: nextProps.children }, + didSuspend, + 0, + null + ); + suspenseState = createFiberFromFragment( + suspenseState, + didSuspend, + renderLanes, + null + ); + suspenseState.flags |= 2; + nextProps.return = workInProgress; + suspenseState.return = workInProgress; + nextProps.sibling = suspenseState; + workInProgress.child = nextProps; + 0 !== (workInProgress.mode & 1) && + reconcileChildFibers(workInProgress, current.child, null, renderLanes); + nextProps = workInProgress.child; + nextProps.memoizedState = mountSuspenseOffscreenState(renderLanes); + nextProps.childLanes = getRemainingWorkInPrimaryTree( + current, + didPrimaryChildrenDefer, + renderLanes + ); + workInProgress.memoizedState = SUSPENDED_MARKER; + return suspenseState; + } + pushPrimaryTreeSuspenseHandler(workInProgress); + if (0 === (workInProgress.mode & 1)) + return retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + null + ); + if (shim$1()) + return ( + (didPrimaryChildrenDefer = shim$1().digest), + (suspenseState = Error( + "The server could not finish this Suspense boundary, likely due to an error during server rendering. Switched to client rendering." + )), + (suspenseState.digest = didPrimaryChildrenDefer), + (didPrimaryChildrenDefer = createCapturedValueFromError( + suspenseState, + didPrimaryChildrenDefer, + void 0 + )), + retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + didPrimaryChildrenDefer + ) + ); + didPrimaryChildrenDefer = 0 !== (renderLanes & current.childLanes); + if (didReceiveUpdate || didPrimaryChildrenDefer) { + didPrimaryChildrenDefer = workInProgressRoot; + if (null !== didPrimaryChildrenDefer) { + nextProps = renderLanes & -renderLanes; + if (0 !== (nextProps & 42)) nextProps = 1; + else + switch (nextProps) { + case 2: + nextProps = 1; + break; + case 8: + nextProps = 4; + break; + case 32: + nextProps = 16; + break; + case 128: + case 256: + case 512: + case 1024: + case 2048: + case 4096: + case 8192: + case 16384: + case 32768: + case 65536: + case 131072: + case 262144: + case 524288: + case 1048576: + case 2097152: + case 4194304: + case 8388608: + case 16777216: + case 33554432: + nextProps = 64; + break; + case 268435456: + nextProps = 134217728; + break; + default: + nextProps = 0; + } + nextProps = + 0 !== + (nextProps & (didPrimaryChildrenDefer.suspendedLanes | renderLanes)) + ? 0 + : nextProps; + if (0 !== nextProps && nextProps !== suspenseState.retryLane) + throw ( + ((suspenseState.retryLane = nextProps), + enqueueConcurrentRenderForLane(current, nextProps), + scheduleUpdateOnFiber(didPrimaryChildrenDefer, current, nextProps), + SelectiveHydrationException) + ); + } + shim$1() || renderDidSuspendDelayIfPossible(); + return retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + null + ); + } + if (shim$1()) + return ( + (workInProgress.flags |= 128), + (workInProgress.child = current.child), + retryDehydratedSuspenseBoundary.bind(null, current), + shim$1(), + null + ); + current = mountSuspensePrimaryChildren(workInProgress, nextProps.children); + current.flags |= 4096; + return current; +} function scheduleSuspenseWorkOnFiber(fiber, renderLanes, propagationRoot) { fiber.lanes |= renderLanes; var alternate = fiber.alternate; @@ -6046,7 +5456,6 @@ function attemptEarlyBailoutIfNoScheduledUpdate( switch (workInProgress.tag) { case 3: pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); - pushProvider(workInProgress, CacheContext, current.memoizedState.cache); break; case 27: case 5: @@ -6056,16 +5465,15 @@ function attemptEarlyBailoutIfNoScheduledUpdate( pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); break; case 10: - pushProvider( - workInProgress, - workInProgress.type, - workInProgress.memoizedProps.value - ); + var newValue = workInProgress.memoizedProps.value, + context = workInProgress.type._context; + push(valueCursor, context._currentValue2); + context._currentValue2 = newValue; break; case 13: - var state = workInProgress.memoizedState; - if (null !== state) { - if (null !== state.dehydrated) + newValue = workInProgress.memoizedState; + if (null !== newValue) { + if (null !== newValue.dehydrated) return ( pushPrimaryTreeSuspenseHandler(workInProgress), (workInProgress.flags |= 128), @@ -6084,9 +5492,9 @@ function attemptEarlyBailoutIfNoScheduledUpdate( pushPrimaryTreeSuspenseHandler(workInProgress); break; case 19: - state = 0 !== (renderLanes & workInProgress.childLanes); + newValue = 0 !== (renderLanes & workInProgress.childLanes); if (0 !== (current.flags & 128)) { - if (state) + if (newValue) return updateSuspenseListComponent( current, workInProgress, @@ -6094,13 +5502,13 @@ function attemptEarlyBailoutIfNoScheduledUpdate( ); workInProgress.flags |= 128; } - var renderState = workInProgress.memoizedState; - null !== renderState && - ((renderState.rendering = null), - (renderState.tail = null), - (renderState.lastEffect = null)); + context = workInProgress.memoizedState; + null !== context && + ((context.rendering = null), + (context.tail = null), + (context.lastEffect = null)); push(suspenseStackCursor, suspenseStackCursor.current); - if (state) break; + if (newValue) break; else return null; case 22: case 23: @@ -6108,8 +5516,6 @@ function attemptEarlyBailoutIfNoScheduledUpdate( (workInProgress.lanes = 0), updateOffscreenComponent(current, workInProgress, renderLanes) ); - case 24: - pushProvider(workInProgress, CacheContext, current.memoizedState.cache); } return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); } @@ -6135,86 +5541,132 @@ function beginWork(current, workInProgress, renderLanes) { else didReceiveUpdate = !1; workInProgress.lanes = 0; switch (workInProgress.tag) { + case 2: + var Component = workInProgress.type; + resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress); + current = workInProgress.pendingProps; + prepareToReadContext(workInProgress, renderLanes); + var value = renderWithHooks( + null, + workInProgress, + Component, + current, + void 0, + renderLanes + ); + workInProgress.flags |= 1; + "object" === typeof value && + null !== value && + "function" === typeof value.render && + void 0 === value.$$typeof + ? ((workInProgress.tag = 1), + (workInProgress.memoizedState = null), + (workInProgress.updateQueue = null), + (workInProgress.memoizedState = + null !== value.state && void 0 !== value.state + ? value.state + : null), + initializeUpdateQueue(workInProgress), + (value.updater = classComponentUpdater), + (workInProgress.stateNode = value), + (value._reactInternals = workInProgress), + mountClassInstance(workInProgress, Component, current, renderLanes), + (workInProgress = finishClassComponent( + null, + workInProgress, + Component, + !0, + !1, + renderLanes + ))) + : ((workInProgress.tag = 0), + reconcileChildren(null, workInProgress, value, renderLanes), + (workInProgress = workInProgress.child)); + return workInProgress; case 16: - var elementType = workInProgress.elementType; + Component = workInProgress.elementType; a: { resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress); current = workInProgress.pendingProps; - var init = elementType._init; - elementType = init(elementType._payload); - workInProgress.type = elementType; - if ("function" === typeof elementType) - shouldConstruct(elementType) - ? ((current = resolveClassComponentProps(elementType, current)), - (workInProgress.tag = 1), - (workInProgress = updateClassComponent( - null, - workInProgress, - elementType, - current, - renderLanes - ))) - : ((workInProgress.tag = 0), - (workInProgress = updateFunctionComponent( - null, - workInProgress, - elementType, - current, - renderLanes - ))); - else { - if (void 0 !== elementType && null !== elementType) - if ( - ((init = elementType.$$typeof), init === REACT_FORWARD_REF_TYPE) - ) { - workInProgress.tag = 11; - workInProgress = updateForwardRef( - null, - workInProgress, - elementType, - current, - renderLanes - ); - break a; - } else if (init === REACT_MEMO_TYPE) { - workInProgress.tag = 14; - workInProgress = updateMemoComponent( - null, - workInProgress, - elementType, - current, - renderLanes - ); - break a; - } - throw Error( - "Element type is invalid. Received a promise that resolves to: " + - elementType + - ". Lazy element type must resolve to a class or function." - ); + value = Component._init; + Component = value(Component._payload); + workInProgress.type = Component; + value = workInProgress.tag = resolveLazyComponentTag(Component); + current = resolveDefaultProps(Component, current); + switch (value) { + case 0: + workInProgress = updateFunctionComponent( + null, + workInProgress, + Component, + current, + renderLanes + ); + break a; + case 1: + workInProgress = updateClassComponent( + null, + workInProgress, + Component, + current, + renderLanes + ); + break a; + case 11: + workInProgress = updateForwardRef( + null, + workInProgress, + Component, + current, + renderLanes + ); + break a; + case 14: + workInProgress = updateMemoComponent( + null, + workInProgress, + Component, + resolveDefaultProps(Component.type, current), + renderLanes + ); + break a; } + throw Error( + "Element type is invalid. Received a promise that resolves to: " + + Component + + ". Lazy element type must resolve to a class or function." + ); } return workInProgress; case 0: - return updateFunctionComponent( - current, - workInProgress, - workInProgress.type, - workInProgress.pendingProps, - renderLanes + return ( + (Component = workInProgress.type), + (value = workInProgress.pendingProps), + (value = + workInProgress.elementType === Component + ? value + : resolveDefaultProps(Component, value)), + updateFunctionComponent( + current, + workInProgress, + Component, + value, + renderLanes + ) ); case 1: return ( - (elementType = workInProgress.type), - (init = resolveClassComponentProps( - elementType, - workInProgress.pendingProps - )), + (Component = workInProgress.type), + (value = workInProgress.pendingProps), + (value = + workInProgress.elementType === Component + ? value + : resolveDefaultProps(Component, value)), updateClassComponent( current, workInProgress, - elementType, - init, + Component, + value, renderLanes ) ); @@ -6222,25 +5674,18 @@ function beginWork(current, workInProgress, renderLanes) { pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); if (null === current) throw Error("Should have a current fiber. This is a bug in React."); - var nextProps = workInProgress.pendingProps; - init = workInProgress.memoizedState; - elementType = init.element; + value = workInProgress.pendingProps; + Component = workInProgress.memoizedState.element; cloneUpdateQueue(current, workInProgress); - processUpdateQueue(workInProgress, nextProps, null, renderLanes); - nextProps = workInProgress.memoizedState; - var nextCache = nextProps.cache; - pushProvider(workInProgress, CacheContext, nextCache); - nextCache !== init.cache && - propagateContextChange(workInProgress, CacheContext, renderLanes); - suspendIfUpdateReadFromEntangledAsyncAction(); - init = nextProps.element; - init === elementType + processUpdateQueue(workInProgress, value, null, renderLanes); + value = workInProgress.memoizedState.element; + value === Component ? (workInProgress = bailoutOnAlreadyFinishedWork( current, workInProgress, renderLanes )) - : (reconcileChildren(current, workInProgress, init, renderLanes), + : (reconcileChildren(current, workInProgress, value, renderLanes), (workInProgress = workInProgress.child)); return workInProgress; case 26: @@ -6248,27 +5693,9 @@ function beginWork(current, workInProgress, renderLanes) { case 5: return ( pushHostContext(workInProgress), - (elementType = workInProgress.pendingProps.children), - null !== workInProgress.memoizedState && - ((init = renderWithHooks( - current, - workInProgress, - TransitionAwareHostComponent, - null, - null, - renderLanes - )), - (HostTransitionContext._currentValue2 = init), - didReceiveUpdate && - null !== current && - current.memoizedState.memoizedState !== init && - propagateContextChange( - workInProgress, - HostTransitionContext, - renderLanes - )), + (Component = workInProgress.pendingProps.children), markRef(current, workInProgress), - reconcileChildren(current, workInProgress, elementType, renderLanes), + reconcileChildren(current, workInProgress, Component, renderLanes), workInProgress.child ); case 6: @@ -6281,29 +5708,26 @@ function beginWork(current, workInProgress, renderLanes) { workInProgress, workInProgress.stateNode.containerInfo ), - (elementType = workInProgress.pendingProps), + (Component = workInProgress.pendingProps), null === current ? (workInProgress.child = reconcileChildFibers( workInProgress, null, - elementType, + Component, renderLanes )) - : reconcileChildren( - current, - workInProgress, - elementType, - renderLanes - ), + : reconcileChildren(current, workInProgress, Component, renderLanes), workInProgress.child ); case 11: - return updateForwardRef( - current, - workInProgress, - workInProgress.type, - workInProgress.pendingProps, - renderLanes + return ( + (Component = workInProgress.type), + (value = workInProgress.pendingProps), + (value = + workInProgress.elementType === Component + ? value + : resolveDefaultProps(Component, value)), + updateForwardRef(current, workInProgress, Component, value, renderLanes) ); case 7: return ( @@ -6337,14 +5761,15 @@ function beginWork(current, workInProgress, renderLanes) { ); case 10: a: { - elementType = workInProgress.type; - init = workInProgress.pendingProps; - nextProps = workInProgress.memoizedProps; - nextCache = init.value; - pushProvider(workInProgress, elementType, nextCache); - if (null !== nextProps) - if (objectIs(nextProps.value, nextCache)) { - if (nextProps.children === init.children) { + Component = workInProgress.type._context; + value = workInProgress.pendingProps; + var oldProps = workInProgress.memoizedProps, + newValue = value.value; + push(valueCursor, Component._currentValue2); + Component._currentValue2 = newValue; + if (null !== oldProps) + if (objectIs(oldProps.value, newValue)) { + if (oldProps.children === value.children) { workInProgress = bailoutOnAlreadyFinishedWork( current, workInProgress, @@ -6353,29 +5778,111 @@ function beginWork(current, workInProgress, renderLanes) { break a; } } else - propagateContextChange(workInProgress, elementType, renderLanes); - reconcileChildren(current, workInProgress, init.children, renderLanes); + for ( + oldProps = workInProgress.child, + null !== oldProps && (oldProps.return = workInProgress); + null !== oldProps; + + ) { + var list = oldProps.dependencies; + if (null !== list) { + newValue = oldProps.child; + for ( + var dependency = list.firstContext; + null !== dependency; + + ) { + if (dependency.context === Component) { + if (1 === oldProps.tag) { + dependency = createUpdate(renderLanes & -renderLanes); + dependency.tag = 2; + var updateQueue = oldProps.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; + } + } + oldProps.lanes |= renderLanes; + dependency = oldProps.alternate; + null !== dependency && (dependency.lanes |= renderLanes); + scheduleContextWorkOnParentPath( + oldProps.return, + renderLanes, + workInProgress + ); + list.lanes |= renderLanes; + break; + } + dependency = dependency.next; + } + } else if (10 === oldProps.tag) + newValue = + oldProps.type === workInProgress.type ? null : oldProps.child; + else if (18 === oldProps.tag) { + newValue = oldProps.return; + if (null === newValue) + throw Error( + "We just came from a parent so we must have had a parent. This is a bug in React." + ); + newValue.lanes |= renderLanes; + list = newValue.alternate; + null !== list && (list.lanes |= renderLanes); + scheduleContextWorkOnParentPath( + newValue, + renderLanes, + workInProgress + ); + newValue = oldProps.sibling; + } else newValue = oldProps.child; + if (null !== newValue) newValue.return = oldProps; + else + for (newValue = oldProps; null !== newValue; ) { + if (newValue === workInProgress) { + newValue = null; + break; + } + oldProps = newValue.sibling; + if (null !== oldProps) { + oldProps.return = newValue.return; + newValue = oldProps; + break; + } + newValue = newValue.return; + } + oldProps = newValue; + } + reconcileChildren(current, workInProgress, value.children, renderLanes); workInProgress = workInProgress.child; } return workInProgress; case 9: return ( - (init = workInProgress.type._context), - (elementType = workInProgress.pendingProps.children), + (value = workInProgress.type), + (Component = workInProgress.pendingProps.children), prepareToReadContext(workInProgress, renderLanes), - (init = readContext(init)), - (elementType = elementType(init)), + (value = readContext(value)), + (Component = Component(value)), (workInProgress.flags |= 1), - reconcileChildren(current, workInProgress, elementType, renderLanes), + reconcileChildren(current, workInProgress, Component, renderLanes), workInProgress.child ); case 14: - return updateMemoComponent( - current, - workInProgress, - workInProgress.type, - workInProgress.pendingProps, - renderLanes + return ( + (Component = workInProgress.type), + (value = resolveDefaultProps(Component, workInProgress.pendingProps)), + (value = resolveDefaultProps(Component.type, value)), + updateMemoComponent( + current, + workInProgress, + Component, + value, + renderLanes + ) ); case 15: return updateSimpleMemoComponent( @@ -6387,97 +5894,30 @@ function beginWork(current, workInProgress, renderLanes) { ); case 17: return ( - (elementType = workInProgress.type), - (init = resolveClassComponentProps( - elementType, - workInProgress.pendingProps - )), + (Component = workInProgress.type), + (value = workInProgress.pendingProps), + (value = + workInProgress.elementType === Component + ? value + : resolveDefaultProps(Component, value)), resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress), (workInProgress.tag = 1), prepareToReadContext(workInProgress, renderLanes), - constructClassInstance(workInProgress, elementType, init), - mountClassInstance(workInProgress, elementType, init, renderLanes), + constructClassInstance(workInProgress, Component, value), + mountClassInstance(workInProgress, Component, value, renderLanes), finishClassComponent( null, workInProgress, - elementType, + Component, !0, !1, renderLanes ) ); - case 28: - return ( - (elementType = workInProgress.type), - (init = resolveClassComponentProps( - elementType, - workInProgress.pendingProps - )), - resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress), - (workInProgress.tag = 0), - updateFunctionComponent( - null, - workInProgress, - elementType, - init, - renderLanes - ) - ); case 19: return updateSuspenseListComponent(current, workInProgress, renderLanes); case 22: return updateOffscreenComponent(current, workInProgress, renderLanes); - case 24: - return ( - prepareToReadContext(workInProgress, renderLanes), - (elementType = readContext(CacheContext)), - null === current - ? ((init = peekCacheFromPool()), - null === init && - ((init = workInProgressRoot), - (nextProps = createCache()), - (init.pooledCache = nextProps), - nextProps.refCount++, - null !== nextProps && (init.pooledCacheLanes |= renderLanes), - (init = nextProps)), - (workInProgress.memoizedState = { - parent: elementType, - cache: init - }), - initializeUpdateQueue(workInProgress), - pushProvider(workInProgress, CacheContext, init)) - : (0 !== (current.lanes & renderLanes) && - (cloneUpdateQueue(current, workInProgress), - processUpdateQueue(workInProgress, null, null, renderLanes), - suspendIfUpdateReadFromEntangledAsyncAction()), - (init = current.memoizedState), - (nextProps = workInProgress.memoizedState), - init.parent !== elementType - ? ((init = { parent: elementType, cache: elementType }), - (workInProgress.memoizedState = init), - 0 === workInProgress.lanes && - (workInProgress.memoizedState = - workInProgress.updateQueue.baseState = - init), - pushProvider(workInProgress, CacheContext, elementType)) - : ((elementType = nextProps.cache), - pushProvider(workInProgress, CacheContext, elementType), - elementType !== init.cache && - propagateContextChange( - workInProgress, - CacheContext, - renderLanes - ))), - reconcileChildren( - current, - workInProgress, - workInProgress.pendingProps.children, - renderLanes - ), - workInProgress.child - ); - case 29: - throw workInProgress.pendingProps; } throw Error( "Unknown unit of work tag (" + @@ -6495,10 +5935,6 @@ function resetContextDependencies() { currentlyRenderingFiber = null; } -function pushProvider(providerFiber, context, nextValue) { - push(valueCursor, context._currentValue2); - context._currentValue2 = nextValue; -} function popProvider(context) { context._currentValue2 = valueCursor.current; pop(valueCursor); @@ -6516,74 +5952,6 @@ function scheduleContextWorkOnParentPath(parent, renderLanes, propagationRoot) { parent = parent.return; } } -function propagateContextChange(workInProgress, context, renderLanes) { - var fiber = workInProgress.child; - null !== fiber && (fiber.return = workInProgress); - for (; null !== fiber; ) { - var list = fiber.dependencies; - if (null !== list) { - var nextFiber = fiber.child; - for (var dependency = list.firstContext; null !== dependency; ) { - if (dependency.context === context) { - if (1 === fiber.tag) { - dependency = createUpdate(renderLanes & -renderLanes); - dependency.tag = 2; - var updateQueue = fiber.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; - } - } - fiber.lanes |= renderLanes; - dependency = fiber.alternate; - null !== dependency && (dependency.lanes |= renderLanes); - scheduleContextWorkOnParentPath( - fiber.return, - renderLanes, - workInProgress - ); - list.lanes |= renderLanes; - break; - } - dependency = dependency.next; - } - } else if (10 === fiber.tag) - nextFiber = fiber.type === workInProgress.type ? null : fiber.child; - else if (18 === fiber.tag) { - nextFiber = fiber.return; - if (null === nextFiber) - throw Error( - "We just came from a parent so we must have had a parent. This is a bug in React." - ); - nextFiber.lanes |= renderLanes; - list = nextFiber.alternate; - null !== list && (list.lanes |= renderLanes); - scheduleContextWorkOnParentPath(nextFiber, renderLanes, workInProgress); - nextFiber = fiber.sibling; - } else nextFiber = fiber.child; - if (null !== nextFiber) nextFiber.return = fiber; - else - for (nextFiber = fiber; null !== nextFiber; ) { - if (nextFiber === workInProgress) { - nextFiber = null; - break; - } - fiber = nextFiber.sibling; - if (null !== fiber) { - fiber.return = nextFiber.return; - nextFiber = fiber; - break; - } - nextFiber = nextFiber.return; - } - fiber = nextFiber; - } -} function prepareToReadContext(workInProgress, renderLanes) { currentlyRenderingFiber = workInProgress; lastFullyObservedContext = lastContextDependency = null; @@ -6617,80 +5985,13 @@ function readContextForConsumer(consumer, context) { } else lastContextDependency = lastContextDependency.next = context; return value; } -var AbortControllerLocal = - "undefined" !== typeof AbortController - ? AbortController - : function () { - var listeners = [], - signal = (this.signal = { - aborted: !1, - addEventListener: function (type, listener) { - listeners.push(listener); - } - }); - this.abort = function () { - signal.aborted = !0; - listeners.forEach(function (listener) { - return listener(); - }); - }; - }, - scheduleCallback$1 = Scheduler.unstable_scheduleCallback, - NormalPriority = Scheduler.unstable_NormalPriority, - CacheContext = { - $$typeof: REACT_CONTEXT_TYPE, - Consumer: null, - Provider: null, - _currentValue: null, - _currentValue2: null, - _threadCount: 0 - }; -function createCache() { - return { - controller: new AbortControllerLocal(), - data: new Map(), - refCount: 0 - }; -} -function releaseCache(cache) { - cache.refCount--; - 0 === cache.refCount && - scheduleCallback$1(NormalPriority, function () { - cache.controller.abort(); - }); -} -var prevOnStartTransitionFinish = ReactSharedInternals.S; -ReactSharedInternals.S = function (transition, returnValue) { - "object" === typeof returnValue && - null !== returnValue && - "function" === typeof returnValue.then && - entangleAsyncAction(transition, returnValue); - null !== prevOnStartTransitionFinish && - prevOnStartTransitionFinish(transition, returnValue); -}; -var resumedCache = createCursor(null); -function peekCacheFromPool() { - var cacheResumedFromPreviousRender = resumedCache.current; - return null !== cacheResumedFromPreviousRender - ? cacheResumedFromPreviousRender - : workInProgressRoot.pooledCache; -} -function pushTransition(offscreenWorkInProgress, prevCachePool) { - null === prevCachePool - ? push(resumedCache, resumedCache.current) - : push(resumedCache, prevCachePool.pool); -} -function getSuspendedCache() { - var cacheFromPool = peekCacheFromPool(); - return null === cacheFromPool - ? null - : { parent: CacheContext._currentValue2, pool: cacheFromPool }; -} +var ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig; +function handleAsyncAction() {} function doesRequireClone(current, completedWork) { if (null !== current && current.child === completedWork.child) return !1; if (0 !== (completedWork.flags & 16)) return !0; for (current = completedWork.child; null !== current; ) { - if (0 !== (current.flags & 13878) || 0 !== (current.subtreeFlags & 13878)) + if (0 !== (current.flags & 12854) || 0 !== (current.subtreeFlags & 12854)) return !0; current = current.sibling; } @@ -6811,14 +6112,14 @@ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { break; case "collapsed": lastTailNode = renderState.tail; - for (var lastTailNode$88 = null; null !== lastTailNode; ) - null !== lastTailNode.alternate && (lastTailNode$88 = lastTailNode), + for (var lastTailNode$61 = null; null !== lastTailNode; ) + null !== lastTailNode.alternate && (lastTailNode$61 = lastTailNode), (lastTailNode = lastTailNode.sibling); - null === lastTailNode$88 + null === lastTailNode$61 ? hasRenderedATailFallback || null === renderState.tail ? (renderState.tail = null) : (renderState.tail.sibling = null) - : (lastTailNode$88.sibling = null); + : (lastTailNode$61.sibling = null); } } function bubbleProperties(completedWork) { @@ -6828,19 +6129,19 @@ function bubbleProperties(completedWork) { newChildLanes = 0, subtreeFlags = 0; if (didBailout) - for (var child$89 = completedWork.child; null !== child$89; ) - (newChildLanes |= child$89.lanes | child$89.childLanes), - (subtreeFlags |= child$89.subtreeFlags & 31457280), - (subtreeFlags |= child$89.flags & 31457280), - (child$89.return = completedWork), - (child$89 = child$89.sibling); + for (var child$62 = completedWork.child; null !== child$62; ) + (newChildLanes |= child$62.lanes | child$62.childLanes), + (subtreeFlags |= child$62.subtreeFlags & 31457280), + (subtreeFlags |= child$62.flags & 31457280), + (child$62.return = completedWork), + (child$62 = child$62.sibling); else - for (child$89 = completedWork.child; null !== child$89; ) - (newChildLanes |= child$89.lanes | child$89.childLanes), - (subtreeFlags |= child$89.subtreeFlags), - (subtreeFlags |= child$89.flags), - (child$89.return = completedWork), - (child$89 = child$89.sibling); + for (child$62 = completedWork.child; null !== child$62; ) + (newChildLanes |= child$62.lanes | child$62.childLanes), + (subtreeFlags |= child$62.subtreeFlags), + (subtreeFlags |= child$62.flags), + (child$62.return = completedWork), + (child$62 = child$62.sibling); completedWork.subtreeFlags |= subtreeFlags; completedWork.childLanes = newChildLanes; return didBailout; @@ -6848,7 +6149,7 @@ function bubbleProperties(completedWork) { function completeWork(current, workInProgress, renderLanes) { var newProps = workInProgress.pendingProps; switch (workInProgress.tag) { - case 28: + case 2: case 16: case 15: case 0: @@ -6864,11 +6165,6 @@ function completeWork(current, workInProgress, renderLanes) { case 3: return ( (newProps = workInProgress.stateNode), - (renderLanes = null), - null !== current && (renderLanes = current.memoizedState.cache), - workInProgress.memoizedState.cache !== renderLanes && - (workInProgress.flags |= 2048), - popProvider(CacheContext), popHostContainer(), newProps.pendingContext && ((newProps.context = newProps.pendingContext), @@ -7034,20 +6330,9 @@ function completeWork(current, workInProgress, renderLanes) { if (0 !== (workInProgress.flags & 128)) return (workInProgress.lanes = renderLanes), workInProgress; newProps = null !== newProps; - current = null !== current && null !== current.memoizedState; - newProps && - ((renderLanes = workInProgress.child), - (oldProps = null), - null !== renderLanes.alternate && - null !== renderLanes.alternate.memoizedState && - null !== renderLanes.alternate.memoizedState.cachePool && - (oldProps = renderLanes.alternate.memoizedState.cachePool.pool), - (updatePayload = null), - null !== renderLanes.memoizedState && - null !== renderLanes.memoizedState.cachePool && - (updatePayload = renderLanes.memoizedState.cachePool.pool), - updatePayload !== oldProps && (renderLanes.flags |= 2048)); - newProps !== current && newProps && (workInProgress.child.flags |= 8192); + newProps !== (null !== current && null !== current.memoizedState) && + newProps && + (workInProgress.child.flags |= 8192); scheduleRetryEffect(workInProgress, workInProgress.updateQueue); bubbleProperties(workInProgress); return null; @@ -7060,7 +6345,9 @@ function completeWork(current, workInProgress, renderLanes) { ); case 10: return ( - popProvider(workInProgress.type), bubbleProperties(workInProgress), null + popProvider(workInProgress.type._context), + bubbleProperties(workInProgress), + null ); case 17: return bubbleProperties(workInProgress), null; @@ -7168,35 +6455,14 @@ function completeWork(current, workInProgress, renderLanes) { (bubbleProperties(workInProgress), workInProgress.subtreeFlags & 6 && (workInProgress.flags |= 8192)) : bubbleProperties(workInProgress), - (newProps = workInProgress.updateQueue), - null !== newProps && - scheduleRetryEffect(workInProgress, newProps.retryQueue), - (newProps = null), + (current = workInProgress.updateQueue), null !== current && - null !== current.memoizedState && - null !== current.memoizedState.cachePool && - (newProps = current.memoizedState.cachePool.pool), - (renderLanes = null), - null !== workInProgress.memoizedState && - null !== workInProgress.memoizedState.cachePool && - (renderLanes = workInProgress.memoizedState.cachePool.pool), - renderLanes !== newProps && (workInProgress.flags |= 2048), - null !== current && pop(resumedCache), + scheduleRetryEffect(workInProgress, current.retryQueue), null ); case 24: - return ( - (newProps = null), - null !== current && (newProps = current.memoizedState.cache), - workInProgress.memoizedState.cache !== newProps && - (workInProgress.flags |= 2048), - popProvider(CacheContext), - bubbleProperties(workInProgress), - null - ); - case 25: return null; - case 29: + case 25: return null; } throw Error( @@ -7216,7 +6482,6 @@ function unwindWork(current, workInProgress) { ); case 3: return ( - popProvider(CacheContext), popHostContainer(), (current = workInProgress.flags), 0 !== (current & 65536) && 0 === (current & 128) @@ -7247,20 +6512,19 @@ function unwindWork(current, workInProgress) { case 4: return popHostContainer(), null; case 10: - return popProvider(workInProgress.type), null; + return popProvider(workInProgress.type._context), null; case 22: case 23: return ( popSuspenseHandler(workInProgress), popHiddenContext(), - null !== current && pop(resumedCache), (current = workInProgress.flags), current & 65536 ? ((workInProgress.flags = (current & -65537) | 128), workInProgress) : null ); case 24: - return popProvider(CacheContext), null; + return null; case 25: return null; default: @@ -7270,7 +6534,6 @@ function unwindWork(current, workInProgress) { function unwindInterruptedWork(current, interruptedWork) { switch (interruptedWork.tag) { case 3: - popProvider(CacheContext); popHostContainer(); break; case 26: @@ -7288,30 +6551,17 @@ function unwindInterruptedWork(current, interruptedWork) { pop(suspenseStackCursor); break; case 10: - popProvider(interruptedWork.type); + popProvider(interruptedWork.type._context); break; case 22: case 23: - popSuspenseHandler(interruptedWork); - popHiddenContext(); - null !== current && pop(resumedCache); - break; - case 24: - popProvider(CacheContext); + popSuspenseHandler(interruptedWork), popHiddenContext(); } } var offscreenSubtreeIsHidden = !1, offscreenSubtreeWasHidden = !1, PossiblyWeakSet = "function" === typeof WeakSet ? WeakSet : Set, nextEffect = null; -function callComponentWillUnmountWithTimer(current, instance) { - instance.props = resolveClassComponentProps( - current.type, - current.memoizedProps - ); - instance.state = current.memoizedState; - instance.componentWillUnmount(); -} function safelyAttachRef(current, nearestMountedAncestor) { try { var ref = current.ref; @@ -7351,8 +6601,8 @@ function safelyDetachRef(current, nearestMountedAncestor) { else if ("function" === typeof ref) try { ref(null); - } catch (error$110) { - captureCommitPhaseError(current, nearestMountedAncestor, error$110); + } catch (error$76) { + captureCommitPhaseError(current, nearestMountedAncestor, error$76); } else ref.current = null; } @@ -7386,13 +6636,13 @@ function commitBeforeMutationEffects(root, firstChild) { break; case 1: if (0 !== (flags & 1024) && null !== current) { - var prevState = current.memoizedState, + var prevProps = current.memoizedProps, + prevState = current.memoizedState, instance = root.stateNode, snapshot = instance.getSnapshotBeforeUpdate( - resolveClassComponentProps( - root.type, - current.memoizedProps - ), + root.elementType === root.type + ? prevProps + : resolveDefaultProps(root.type, prevProps), prevState ); instance.__reactInternalSnapshotBeforeUpdate = snapshot; @@ -7456,10 +6706,10 @@ function commitHookEffectListMount(flags, finishedWork) { var effect = (finishedWork = finishedWork.next); do { if ((effect.tag & flags) === flags) { - var create$111 = effect.create, + var create$77 = effect.create, inst = effect.inst; - create$111 = create$111(); - inst.destroy = create$111; + create$77 = create$77(); + inst.destroy = create$77; } effect = effect.next; } while (effect !== finishedWork); @@ -7511,10 +6761,10 @@ function commitLayoutEffectOnFiber(finishedRoot, current, finishedWork) { captureCommitPhaseError(finishedWork, finishedWork.return, error); } else { - var prevProps = resolveClassComponentProps( - finishedWork.type, - current.memoizedProps - ); + var prevProps = + finishedWork.elementType === finishedWork.type + ? current.memoizedProps + : resolveDefaultProps(finishedWork.type, current.memoizedProps); current = current.memoizedState; try { finishedRoot.componentDidUpdate( @@ -7522,11 +6772,11 @@ function commitLayoutEffectOnFiber(finishedRoot, current, finishedWork) { current, finishedRoot.__reactInternalSnapshotBeforeUpdate ); - } catch (error$112) { + } catch (error$78) { captureCommitPhaseError( finishedWork, finishedWork.return, - error$112 + error$78 ); } } @@ -7705,7 +6955,9 @@ function commitDeletionEffectsOnFiber( "function" === typeof updateQueue.componentWillUnmount) ) try { - callComponentWillUnmountWithTimer(deletedFiber, updateQueue); + (updateQueue.props = deletedFiber.memoizedProps), + (updateQueue.state = deletedFiber.memoizedState), + updateQueue.componentWillUnmount(); } catch (error) { captureCommitPhaseError(deletedFiber, nearestMountedAncestor, error); } @@ -7794,7 +7046,7 @@ function recursivelyTraverseMutationEffects(root, parentFiber) { captureCommitPhaseError(childToDelete, parentFiber, error); } } - if (parentFiber.subtreeFlags & 13878) + if (parentFiber.subtreeFlags & 12854) for (parentFiber = parentFiber.child; null !== parentFiber; ) commitMutationEffectsOnFiber(parentFiber, root), (parentFiber = parentFiber.sibling); @@ -7818,8 +7070,8 @@ function commitMutationEffectsOnFiber(finishedWork, root) { } try { commitHookEffectListUnmount(5, finishedWork, finishedWork.return); - } catch (error$114) { - captureCommitPhaseError(finishedWork, finishedWork.return, error$114); + } catch (error$80) { + captureCommitPhaseError(finishedWork, finishedWork.return, error$80); } } break; @@ -7958,7 +7210,10 @@ function recursivelyTraverseDisappearLayoutEffects(parentFiber) { var current = finishedWork, nearestMountedAncestor = finishedWork.return; try { - callComponentWillUnmountWithTimer(current, instance); + var current$jscomp$0 = current; + instance.props = current$jscomp$0.memoizedProps; + instance.state = current$jscomp$0.memoizedState; + instance.componentWillUnmount(); } catch (error) { captureCommitPhaseError(current, nearestMountedAncestor, error); } @@ -8088,166 +7343,61 @@ function commitHookPassiveMountEffects(finishedWork, hookFlags) { captureCommitPhaseError(finishedWork, finishedWork.return, error); } } -function commitOffscreenPassiveMountEffects(current, finishedWork) { - var previousCache = null; - null !== current && - null !== current.memoizedState && - null !== current.memoizedState.cachePool && - (previousCache = current.memoizedState.cachePool.pool); - current = null; - null !== finishedWork.memoizedState && - null !== finishedWork.memoizedState.cachePool && - (current = finishedWork.memoizedState.cachePool.pool); - current !== previousCache && - (null != current && current.refCount++, - null != previousCache && releaseCache(previousCache)); -} -function commitCachePassiveMountEffect(current, finishedWork) { - current = null; - null !== finishedWork.alternate && - (current = finishedWork.alternate.memoizedState.cache); - finishedWork = finishedWork.memoizedState.cache; - finishedWork !== current && - (finishedWork.refCount++, null != current && releaseCache(current)); -} -function recursivelyTraversePassiveMountEffects( - root, - parentFiber, - committedLanes, - committedTransitions -) { +function recursivelyTraversePassiveMountEffects(root, parentFiber) { if (parentFiber.subtreeFlags & 10256) for (parentFiber = parentFiber.child; null !== parentFiber; ) - commitPassiveMountOnFiber( - root, - parentFiber, - committedLanes, - committedTransitions - ), + commitPassiveMountOnFiber(root, parentFiber), (parentFiber = parentFiber.sibling); } -function commitPassiveMountOnFiber( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions -) { +function commitPassiveMountOnFiber(finishedRoot, finishedWork) { var flags = finishedWork.flags; switch (finishedWork.tag) { case 0: case 11: case 15: - recursivelyTraversePassiveMountEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - ); + recursivelyTraversePassiveMountEffects(finishedRoot, finishedWork); flags & 2048 && commitHookPassiveMountEffects(finishedWork, 9); break; case 3: - recursivelyTraversePassiveMountEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - ); - flags & 2048 && - ((finishedRoot = null), - null !== finishedWork.alternate && - (finishedRoot = finishedWork.alternate.memoizedState.cache), - (finishedWork = finishedWork.memoizedState.cache), - finishedWork !== finishedRoot && - (finishedWork.refCount++, - null != finishedRoot && releaseCache(finishedRoot))); + recursivelyTraversePassiveMountEffects(finishedRoot, finishedWork); break; case 23: break; case 22: - var instance = finishedWork.stateNode; + flags = finishedWork.stateNode; null !== finishedWork.memoizedState - ? instance._visibility & 4 - ? recursivelyTraversePassiveMountEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - ) - : finishedWork.mode & 1 - ? recursivelyTraverseAtomicPassiveEffects(finishedRoot, finishedWork) - : ((instance._visibility |= 4), - recursivelyTraversePassiveMountEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - )) - : instance._visibility & 4 - ? recursivelyTraversePassiveMountEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - ) - : ((instance._visibility |= 4), + ? flags._visibility & 4 + ? recursivelyTraversePassiveMountEffects(finishedRoot, finishedWork) + : finishedWork.mode & 1 || + ((flags._visibility |= 4), + recursivelyTraversePassiveMountEffects(finishedRoot, finishedWork)) + : flags._visibility & 4 + ? recursivelyTraversePassiveMountEffects(finishedRoot, finishedWork) + : ((flags._visibility |= 4), recursivelyTraverseReconnectPassiveEffects( finishedRoot, - finishedWork, - committedLanes, - committedTransitions, - 0 !== (finishedWork.subtreeFlags & 10256) + finishedWork )); - flags & 2048 && - commitOffscreenPassiveMountEffects( - finishedWork.alternate, - finishedWork - ); break; case 24: - recursivelyTraversePassiveMountEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - ); - flags & 2048 && - commitCachePassiveMountEffect(finishedWork.alternate, finishedWork); + recursivelyTraversePassiveMountEffects(finishedRoot, finishedWork); break; default: - recursivelyTraversePassiveMountEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - ); + recursivelyTraversePassiveMountEffects(finishedRoot, finishedWork); } } function recursivelyTraverseReconnectPassiveEffects( finishedRoot$jscomp$0, - parentFiber, - committedLanes$jscomp$0, - committedTransitions$jscomp$0, - includeWorkInProgressEffects + parentFiber ) { - includeWorkInProgressEffects = - includeWorkInProgressEffects && 0 !== (parentFiber.subtreeFlags & 10256); for (parentFiber = parentFiber.child; null !== parentFiber; ) { var finishedRoot = finishedRoot$jscomp$0, - finishedWork = parentFiber, - committedLanes = committedLanes$jscomp$0, - committedTransitions = committedTransitions$jscomp$0, - flags = finishedWork.flags; + finishedWork = parentFiber; switch (finishedWork.tag) { case 0: case 11: case 15: - recursivelyTraverseReconnectPassiveEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions, - includeWorkInProgressEffects - ); + recursivelyTraverseReconnectPassiveEffects(finishedRoot, finishedWork); commitHookPassiveMountEffects(finishedWork, 8); break; case 23: @@ -8257,93 +7407,30 @@ function recursivelyTraverseReconnectPassiveEffects( null !== finishedWork.memoizedState ? instance._visibility & 4 ? recursivelyTraverseReconnectPassiveEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions, - includeWorkInProgressEffects - ) - : finishedWork.mode & 1 - ? recursivelyTraverseAtomicPassiveEffects( finishedRoot, finishedWork ) - : ((instance._visibility |= 4), + : finishedWork.mode & 1 || + ((instance._visibility |= 4), recursivelyTraverseReconnectPassiveEffects( finishedRoot, - finishedWork, - committedLanes, - committedTransitions, - includeWorkInProgressEffects + finishedWork )) : ((instance._visibility |= 4), recursivelyTraverseReconnectPassiveEffects( finishedRoot, - finishedWork, - committedLanes, - committedTransitions, - includeWorkInProgressEffects + finishedWork )); - includeWorkInProgressEffects && - flags & 2048 && - commitOffscreenPassiveMountEffects( - finishedWork.alternate, - finishedWork - ); break; case 24: - recursivelyTraverseReconnectPassiveEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions, - includeWorkInProgressEffects - ); - includeWorkInProgressEffects && - flags & 2048 && - commitCachePassiveMountEffect(finishedWork.alternate, finishedWork); + recursivelyTraverseReconnectPassiveEffects(finishedRoot, finishedWork); break; default: - recursivelyTraverseReconnectPassiveEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions, - includeWorkInProgressEffects - ); + recursivelyTraverseReconnectPassiveEffects(finishedRoot, finishedWork); } parentFiber = parentFiber.sibling; } } -function recursivelyTraverseAtomicPassiveEffects( - finishedRoot$jscomp$0, - parentFiber -) { - if (parentFiber.subtreeFlags & 10256) - for (parentFiber = parentFiber.child; null !== parentFiber; ) { - var finishedRoot = finishedRoot$jscomp$0, - finishedWork = parentFiber, - flags = finishedWork.flags; - switch (finishedWork.tag) { - case 22: - recursivelyTraverseAtomicPassiveEffects(finishedRoot, finishedWork); - flags & 2048 && - commitOffscreenPassiveMountEffects( - finishedWork.alternate, - finishedWork - ); - break; - case 24: - recursivelyTraverseAtomicPassiveEffects(finishedRoot, finishedWork); - flags & 2048 && - commitCachePassiveMountEffect(finishedWork.alternate, finishedWork); - break; - default: - recursivelyTraverseAtomicPassiveEffects(finishedRoot, finishedWork); - } - parentFiber = parentFiber.sibling; - } -} var suspenseyCommitFlag = 8192; function recursivelyAccumulateSuspenseyCommit(parentFiber) { if (parentFiber.subtreeFlags & suspenseyCommitFlag) @@ -8355,9 +7442,10 @@ function accumulateSuspenseyCommitOnFiber(fiber) { switch (fiber.tag) { case 26: recursivelyAccumulateSuspenseyCommit(fiber); - fiber.flags & suspenseyCommitFlag && - null !== fiber.memoizedState && - shim(); + if (fiber.flags & suspenseyCommitFlag && null !== fiber.memoizedState) + throw Error( + "The current renderer does not support Resources. This error is likely caused by a bug in React. Please file an issue." + ); break; case 5: recursivelyAccumulateSuspenseyCommit(fiber); @@ -8482,29 +7570,16 @@ function commitPassiveUnmountEffectsInsideOfDeletedTree_begin( case 11: case 15: commitHookEffectListUnmount(8, fiber, nearestMountedAncestor); - break; - case 23: - case 22: - if ( - null !== fiber.memoizedState && - null !== fiber.memoizedState.cachePool - ) { - var cache = fiber.memoizedState.cachePool.pool; - null != cache && cache.refCount++; - } - break; - case 24: - releaseCache(fiber.memoizedState.cache); } - cache = fiber.child; - if (null !== cache) (cache.return = fiber), (nextEffect = cache); + var child = fiber.child; + if (null !== child) (child.return = fiber), (nextEffect = child); else a: for (fiber = deletedSubtreeRoot; null !== nextEffect; ) { - cache = nextEffect; - var sibling = cache.sibling, - returnFiber = cache.return; - detachFiberAfterEffects(cache); - if (cache === fiber) { + child = nextEffect; + var sibling = child.sibling, + returnFiber = child.return; + detachFiberAfterEffects(child); + if (child === fiber) { nextEffect = null; break a; } @@ -8517,17 +7592,10 @@ function commitPassiveUnmountEffectsInsideOfDeletedTree_begin( } } } -var DefaultAsyncDispatcher = { - getCacheForType: function (resourceType) { - var cache = readContext(CacheContext), - cacheForType = cache.data.get(resourceType); - void 0 === cacheForType && - ((cacheForType = resourceType()), - cache.data.set(resourceType, cacheForType)); - return cacheForType; - } - }, - PossiblyWeakMap = "function" === typeof WeakMap ? WeakMap : Map, +var PossiblyWeakMap = "function" === typeof WeakMap ? WeakMap : Map, + ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, + ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner, + ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig, executionContext = 0, workInProgressRoot = null, workInProgress = null, @@ -8537,6 +7605,7 @@ var DefaultAsyncDispatcher = { workInProgressRootDidAttachPingListener = !1, entangledRenderLanes = 0, workInProgressRootExitStatus = 0, + workInProgressRootFatalError = null, workInProgressRootSkippedLanes = 0, workInProgressRootInterleavedUpdatedLanes = 0, workInProgressRootPingedLanes = 0, @@ -8544,27 +7613,44 @@ var DefaultAsyncDispatcher = { workInProgressRootConcurrentErrors = null, workInProgressRootRecoverableErrors = null, workInProgressRootDidIncludeRecursiveRenderUpdate = !1, - didIncludeCommitPhaseUpdate = !1, globalMostRecentFallbackTime = 0, workInProgressRootRenderTargetTime = Infinity, workInProgressTransitions = null, + hasUncaughtError = !1, + firstUncaughtError = null, legacyErrorBoundariesThatAlreadyFailed = null, rootDoesHavePassiveEffects = !1, rootWithPendingPassiveEffects = null, pendingPassiveEffectsLanes = 0, - pendingPassiveEffectsRemainingLanes = 0, - pendingPassiveTransitions = null, nestedUpdateCount = 0, rootWithNestedUpdates = null; function requestUpdateLane(fiber) { - return 0 === (fiber.mode & 1) - ? 2 - : 0 !== (executionContext & 2) && 0 !== workInProgressRootRenderLanes - ? workInProgressRootRenderLanes & -workInProgressRootRenderLanes - : null !== ReactSharedInternals.T - ? ((fiber = currentEntangledLane), - 0 !== fiber ? fiber : requestTransitionLane()) - : resolveUpdatePriority(); + if (0 === (fiber.mode & 1)) return 2; + if (0 !== (executionContext & 2) && 0 !== workInProgressRootRenderLanes) + return workInProgressRootRenderLanes & -workInProgressRootRenderLanes; + fiber = ReactCurrentBatchConfig$1.transition; + null !== fiber && fiber._callbacks.add(handleAsyncAction); + if (null !== fiber) + return ( + 0 === currentEventTransitionLane && + (currentEventTransitionLane = claimNextTransitionLane()), + currentEventTransitionLane + ); + fiber = currentUpdatePriority; + if (0 === fiber) + a: { + fiber = fabricGetCurrentEventPriority + ? fabricGetCurrentEventPriority() + : null; + if (null != fiber) + switch (fiber) { + case FabricDiscretePriority: + fiber = 2; + break a; + } + fiber = 32; + } + return fiber; } function requestDeferredLane() { 0 === workInProgressDeferredLane && @@ -8587,7 +7673,7 @@ function scheduleUpdateOnFiber(root, fiber, lane) { workInProgressRootRenderLanes, workInProgressDeferredLane ); - markRootUpdated(root, lane); + markRootUpdated$1(root, lane); if (0 === (executionContext & 2) || root !== workInProgressRoot) root === workInProgressRoot && (0 === (executionContext & 2) && @@ -8640,24 +7726,22 @@ function performConcurrentWorkOnRoot(root, didTimeout) { root, renderWasConcurrent ); - if ( - 0 !== errorRetryLanes && + 0 !== errorRetryLanes && ((lanes = errorRetryLanes), (exitStatus = recoverFromConcurrentError( root, renderWasConcurrent, errorRetryLanes - )), - (renderWasConcurrent = !1), - 2 !== exitStatus) - ) - continue; - } - if (1 === exitStatus) { - prepareFreshStack(root, 0); - markRootSuspended(root, lanes, 0); - break; + ))); } + if (1 === exitStatus) + throw ( + ((originalCallbackNode = workInProgressRootFatalError), + prepareFreshStack(root, 0), + markRootSuspended(root, lanes, 0), + ensureRootIsScheduled(root), + originalCallbackNode) + ); root.finishedWork = didTimeout; root.finishedLanes = lanes; a: { @@ -8677,8 +7761,6 @@ function performConcurrentWorkOnRoot(root, didTimeout) { } break; case 2: - workInProgressRootRecoverableErrors = null; - break; case 3: case 5: break; @@ -8739,10 +7821,13 @@ function recoverFromConcurrentError( originallyAttemptedLanes, errorRetryLanes ) { - var errorsFromFirstAttempt = workInProgressRootConcurrentErrors; + var errorsFromFirstAttempt = workInProgressRootConcurrentErrors, + JSCompiler_inline_result; + (JSCompiler_inline_result = root.current.memoizedState.isDehydrated) && + (prepareFreshStack(root, errorRetryLanes).flags |= 256); errorRetryLanes = renderRootSync(root, errorRetryLanes); if (2 !== errorRetryLanes) { - if (workInProgressRootDidAttachPingListener) + if (workInProgressRootDidAttachPingListener && !JSCompiler_inline_result) return ( (root.errorRecoveryDisabledLanes |= originallyAttemptedLanes), (workInProgressRootInterleavedUpdatedLanes |= originallyAttemptedLanes), @@ -8771,9 +7856,7 @@ function commitRootWhenReady( lanes, spawnedLane ) { - lanes = finishedWork.subtreeFlags; - (lanes & 8192 || 16785408 === (lanes & 16785408)) && - accumulateSuspenseyCommitOnFiber(finishedWork); + 0 === (lanes & 42) && accumulateSuspenseyCommitOnFiber(finishedWork); commitRoot( root, recoverableErrors, @@ -8816,15 +7899,6 @@ function isRenderConsistentWithExternalStores(finishedWork) { } return !0; } -function markRootUpdated(root, updatedLanes) { - root.pendingLanes |= updatedLanes; - 268435456 !== updatedLanes && - ((root.suspendedLanes = 0), (root.pingedLanes = 0)); - executionContext & 2 - ? (workInProgressRootDidIncludeRecursiveRenderUpdate = !0) - : executionContext & 4 && (didIncludeCommitPhaseUpdate = !0); - throwIfInfiniteUpdateLoopDetected(); -} function markRootSuspended(root, suspendedLanes, spawnedLane) { suspendedLanes &= ~workInProgressRootPingedLanes; suspendedLanes &= ~workInProgressRootInterleavedUpdatedLanes; @@ -8835,58 +7909,14 @@ function markRootSuspended(root, suspendedLanes, spawnedLane) { 0 < lanes; ) { - var index$8 = 31 - clz32(lanes), - lane = 1 << index$8; - expirationTimes[index$8] = -1; + var index$4 = 31 - clz32(lanes), + lane = 1 << index$4; + expirationTimes[index$4] = -1; lanes &= ~lane; } 0 !== spawnedLane && markSpawnedDeferredLane(root, spawnedLane, suspendedLanes); } -function performSyncWorkOnRoot(root, lanes) { - if (0 !== (executionContext & 6)) - throw Error("Should not already be working."); - if (flushPassiveEffects()) return ensureRootIsScheduled(root), null; - var exitStatus = renderRootSync(root, lanes); - if (0 !== root.tag && 2 === exitStatus) { - var originallyAttemptedLanes = lanes, - errorRetryLanes = getLanesToRetrySynchronouslyOnError( - root, - originallyAttemptedLanes - ); - 0 !== errorRetryLanes && - ((lanes = errorRetryLanes), - (exitStatus = recoverFromConcurrentError( - root, - originallyAttemptedLanes, - errorRetryLanes - ))); - } - if (1 === exitStatus) - return ( - prepareFreshStack(root, 0), - markRootSuspended(root, lanes, 0), - ensureRootIsScheduled(root), - null - ); - if (6 === exitStatus) - return ( - markRootSuspended(root, lanes, workInProgressDeferredLane), - ensureRootIsScheduled(root), - null - ); - root.finishedWork = root.current.alternate; - root.finishedLanes = lanes; - commitRoot( - root, - workInProgressRootRecoverableErrors, - workInProgressTransitions, - workInProgressRootDidIncludeRecursiveRenderUpdate, - workInProgressDeferredLane - ); - ensureRootIsScheduled(root); - return null; -} function resetWorkInProgressStack() { if (null !== workInProgress) { if (0 === workInProgressSuspendedReason) @@ -8920,11 +7950,12 @@ function prepareFreshStack(root, lanes) { workInProgressSuspendedReason = 0; workInProgressThrownValue = null; workInProgressRootDidAttachPingListener = !1; + workInProgressRootExitStatus = 0; + workInProgressRootFatalError = null; workInProgressDeferredLane = workInProgressRootPingedLanes = workInProgressRootInterleavedUpdatedLanes = workInProgressRootSkippedLanes = - workInProgressRootExitStatus = 0; workInProgressRootRecoverableErrors = workInProgressRootConcurrentErrors = null; @@ -8937,9 +7968,9 @@ function prepareFreshStack(root, lanes) { 0 < allEntangledLanes; ) { - var index$6 = 31 - clz32(allEntangledLanes), - lane = 1 << index$6; - lanes |= root[index$6]; + var index$2 = 31 - clz32(allEntangledLanes), + lane = 1 << index$2; + lanes |= root[index$2]; allEntangledLanes &= ~lane; } entangledRenderLanes = lanes; @@ -8948,53 +7979,45 @@ function prepareFreshStack(root, lanes) { } function handleThrow(root, thrownValue) { currentlyRenderingFiber$1 = null; - ReactSharedInternals.H = ContextOnlyDispatcher; - if (thrownValue === SuspenseException) { - thrownValue = getSuspendedThenable(); - var handler = suspenseHandlerStackCursor.current; - workInProgressSuspendedReason = - (null !== handler && - ((workInProgressRootRenderLanes & 4194176) === - workInProgressRootRenderLanes - ? null !== shellBoundary - : ((workInProgressRootRenderLanes & 62914560) !== - workInProgressRootRenderLanes && - 0 === (workInProgressRootRenderLanes & 536870912)) || - handler !== shellBoundary)) || - 0 !== (workInProgressRootSkippedLanes & 134217727) || - 0 !== (workInProgressRootInterleavedUpdatedLanes & 134217727) - ? 3 - : 2; - } else - thrownValue === SuspenseyCommitException - ? ((thrownValue = getSuspendedThenable()), - (workInProgressSuspendedReason = 4)) - : (workInProgressSuspendedReason = - thrownValue === SelectiveHydrationException - ? 8 - : null !== thrownValue && - "object" === typeof thrownValue && - "function" === typeof thrownValue.then - ? 6 - : 1); + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + ReactCurrentOwner.current = null; + thrownValue === SuspenseException + ? ((thrownValue = getSuspendedThenable()), + (root = suspenseHandlerStackCursor.current), + (workInProgressSuspendedReason = + (null !== root && + ((workInProgressRootRenderLanes & 4194176) === + workInProgressRootRenderLanes + ? null !== shellBoundary + : ((workInProgressRootRenderLanes & 62914560) !== + workInProgressRootRenderLanes && + 0 === (workInProgressRootRenderLanes & 536870912)) || + root !== shellBoundary)) || + 0 !== (workInProgressRootSkippedLanes & 134217727) || + 0 !== (workInProgressRootInterleavedUpdatedLanes & 134217727) + ? 3 + : 2)) + : thrownValue === SuspenseyCommitException + ? ((thrownValue = getSuspendedThenable()), + (workInProgressSuspendedReason = 4)) + : (workInProgressSuspendedReason = + thrownValue === SelectiveHydrationException + ? 8 + : null !== thrownValue && + "object" === typeof thrownValue && + "function" === typeof thrownValue.then + ? 6 + : 1); workInProgressThrownValue = thrownValue; null === workInProgress && ((workInProgressRootExitStatus = 1), - logUncaughtError( - root, - createCapturedValueAtFiber(thrownValue, root.current) - )); + (workInProgressRootFatalError = thrownValue)); } function pushDispatcher() { - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = ContextOnlyDispatcher; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = ContextOnlyDispatcher; return null === prevDispatcher ? ContextOnlyDispatcher : prevDispatcher; } -function pushAsyncDispatcher() { - var prevAsyncDispatcher = ReactSharedInternals.A; - ReactSharedInternals.A = DefaultAsyncDispatcher; - return prevAsyncDispatcher; -} function renderDidSuspendDelayIfPossible() { workInProgressRootExitStatus = 4; (0 === (workInProgressRootSkippedLanes & 134217727) && @@ -9009,8 +8032,7 @@ function renderDidSuspendDelayIfPossible() { function renderRootSync(root, lanes) { var prevExecutionContext = executionContext; executionContext |= 2; - var prevDispatcher = pushDispatcher(), - prevAsyncDispatcher = pushAsyncDispatcher(); + var prevDispatcher = pushDispatcher(); if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) (workInProgressTransitions = null), prepareFreshStack(root, lanes); lanes = !1; @@ -9037,15 +8059,14 @@ function renderRootSync(root, lanes) { } workLoopSync(); break; - } catch (thrownValue$126) { - handleThrow(root, thrownValue$126); + } catch (thrownValue$88) { + handleThrow(root, thrownValue$88); } while (1); lanes && root.shellSuspendCounter++; resetContextDependencies(); executionContext = prevExecutionContext; - ReactSharedInternals.H = prevDispatcher; - ReactSharedInternals.A = prevAsyncDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; if (null !== workInProgress) throw Error( "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." @@ -9061,8 +8082,7 @@ function workLoopSync() { function renderRootConcurrent(root, lanes) { var prevExecutionContext = executionContext; executionContext |= 2; - var prevDispatcher = pushDispatcher(), - prevAsyncDispatcher = pushAsyncDispatcher(); + var prevDispatcher = pushDispatcher(); if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) (workInProgressTransitions = null), (workInProgressRootRenderTargetTime = now() + 500), @@ -9109,27 +8129,23 @@ function renderRootConcurrent(root, lanes) { throwAndUnwindWorkLoop(root, lanes, thrownValue)); break; case 5: - var resource = null; switch (workInProgress.tag) { - case 26: - resource = workInProgress.memoizedState; case 5: + case 26: case 27: - var hostFiber = workInProgress; - if (resource ? shim(resource) : 1) { - workInProgressSuspendedReason = 0; - workInProgressThrownValue = null; - var sibling = hostFiber.sibling; - if (null !== sibling) workInProgress = sibling; - else { - var returnFiber = hostFiber.return; - null !== returnFiber - ? ((workInProgress = returnFiber), - completeUnitOfWork(returnFiber)) - : (workInProgress = null); - } - break b; + lanes = workInProgress; + workInProgressSuspendedReason = 0; + workInProgressThrownValue = null; + var sibling = lanes.sibling; + if (null !== sibling) workInProgress = sibling; + else { + var returnFiber = lanes.return; + null !== returnFiber + ? ((workInProgress = returnFiber), + completeUnitOfWork(returnFiber)) + : (workInProgress = null); } + break b; } workInProgressSuspendedReason = 0; workInProgressThrownValue = null; @@ -9150,13 +8166,12 @@ function renderRootConcurrent(root, lanes) { } workLoopConcurrent(); break; - } catch (thrownValue$128) { - handleThrow(root, thrownValue$128); + } catch (thrownValue$90) { + handleThrow(root, thrownValue$90); } while (1); resetContextDependencies(); - ReactSharedInternals.H = prevDispatcher; - ReactSharedInternals.A = prevAsyncDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; executionContext = prevExecutionContext; if (null !== workInProgress) return 0; workInProgressRoot = null; @@ -9172,42 +8187,59 @@ function performUnitOfWork(unitOfWork) { var next = beginWork(unitOfWork.alternate, unitOfWork, entangledRenderLanes); unitOfWork.memoizedProps = unitOfWork.pendingProps; null === next ? completeUnitOfWork(unitOfWork) : (workInProgress = next); + ReactCurrentOwner.current = null; } function replaySuspendedUnitOfWork(unitOfWork) { - var next = unitOfWork; - var current = next.alternate; - switch (next.tag) { + var current = unitOfWork.alternate; + switch (unitOfWork.tag) { + case 2: + unitOfWork.tag = 0; case 15: case 0: - next = replayFunctionComponent( + var Component = unitOfWork.type, + unresolvedProps = unitOfWork.pendingProps; + unresolvedProps = + unitOfWork.elementType === Component + ? unresolvedProps + : resolveDefaultProps(Component, unresolvedProps); + current = replayFunctionComponent( current, - next, - next.pendingProps, - next.type, + unitOfWork, + unresolvedProps, + Component, void 0, workInProgressRootRenderLanes ); break; case 11: - next = replayFunctionComponent( + Component = unitOfWork.type.render; + unresolvedProps = unitOfWork.pendingProps; + unresolvedProps = + unitOfWork.elementType === Component + ? unresolvedProps + : resolveDefaultProps(Component, unresolvedProps); + current = replayFunctionComponent( current, - next, - next.pendingProps, - next.type.render, - next.ref, + unitOfWork, + unresolvedProps, + Component, + unitOfWork.ref, workInProgressRootRenderLanes ); break; case 5: - resetHooksOnUnwind(next); + resetHooksOnUnwind(unitOfWork); default: - unwindInterruptedWork(current, next), - (next = workInProgress = - resetWorkInProgress(next, entangledRenderLanes)), - (next = beginWork(current, next, entangledRenderLanes)); + unwindInterruptedWork(current, unitOfWork), + (unitOfWork = workInProgress = + resetWorkInProgress(unitOfWork, entangledRenderLanes)), + (current = beginWork(current, unitOfWork, entangledRenderLanes)); } unitOfWork.memoizedProps = unitOfWork.pendingProps; - null === next ? completeUnitOfWork(unitOfWork) : (workInProgress = next); + null === current + ? completeUnitOfWork(unitOfWork) + : (workInProgress = current); + ReactCurrentOwner.current = null; } function throwAndUnwindWorkLoop(root, unitOfWork, thrownValue) { resetContextDependencies(); @@ -9226,20 +8258,14 @@ function throwAndUnwindWorkLoop(root, unitOfWork, thrownValue) { ) ) { workInProgressRootExitStatus = 1; - logUncaughtError( - root, - createCapturedValueAtFiber(thrownValue, root.current) - ); + workInProgressRootFatalError = thrownValue; workInProgress = null; return; } } catch (error) { if (null !== returnFiber) throw ((workInProgress = returnFiber), error); workInProgressRootExitStatus = 1; - logUncaughtError( - root, - createCapturedValueAtFiber(thrownValue, root.current) - ); + workInProgressRootFatalError = thrownValue; workInProgress = null; return; } @@ -9294,11 +8320,11 @@ function commitRoot( didIncludeRenderPhaseUpdate, spawnedLane ) { - var prevTransition = ReactSharedInternals.T, - previousUpdateLanePriority = currentUpdatePriority; + var previousUpdateLanePriority = currentUpdatePriority, + prevTransition = ReactCurrentBatchConfig.transition; try { - (currentUpdatePriority = 2), - (ReactSharedInternals.T = null), + (ReactCurrentBatchConfig.transition = null), + (currentUpdatePriority = 2), commitRootImpl( root, recoverableErrors, @@ -9308,7 +8334,7 @@ function commitRoot( spawnedLane ); } finally { - (ReactSharedInternals.T = prevTransition), + (ReactCurrentBatchConfig.transition = prevTransition), (currentUpdatePriority = previousUpdateLanePriority); } return null; @@ -9325,78 +8351,88 @@ function commitRootImpl( while (null !== rootWithPendingPassiveEffects); if (0 !== (executionContext & 6)) throw Error("Should not already be working."); - var finishedWork = root.finishedWork, - lanes = root.finishedLanes; - if (null === finishedWork) return null; + didIncludeRenderPhaseUpdate = root.finishedWork; + transitions = root.finishedLanes; + if (null === didIncludeRenderPhaseUpdate) return null; root.finishedWork = null; root.finishedLanes = 0; - if (finishedWork === root.current) + if (didIncludeRenderPhaseUpdate === root.current) throw Error( "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." ); root.callbackNode = null; root.callbackPriority = 0; root.cancelPendingCommit = null; - var remainingLanes = finishedWork.lanes | finishedWork.childLanes; + var remainingLanes = + didIncludeRenderPhaseUpdate.lanes | didIncludeRenderPhaseUpdate.childLanes; remainingLanes |= concurrentlyUpdatedLanes; markRootFinished(root, remainingLanes, spawnedLane); - didIncludeCommitPhaseUpdate = !1; root === workInProgressRoot && ((workInProgress = workInProgressRoot = null), (workInProgressRootRenderLanes = 0)); - (0 === (finishedWork.subtreeFlags & 10256) && - 0 === (finishedWork.flags & 10256)) || + (0 === (didIncludeRenderPhaseUpdate.subtreeFlags & 10256) && + 0 === (didIncludeRenderPhaseUpdate.flags & 10256)) || rootDoesHavePassiveEffects || ((rootDoesHavePassiveEffects = !0), - (pendingPassiveEffectsRemainingLanes = remainingLanes), - (pendingPassiveTransitions = transitions), - scheduleCallback(NormalPriority$1, function () { + scheduleCallback(NormalPriority, function () { flushPassiveEffects(); return null; })); - transitions = 0 !== (finishedWork.flags & 15990); - if (0 !== (finishedWork.subtreeFlags & 15990) || transitions) { - transitions = ReactSharedInternals.T; - ReactSharedInternals.T = null; - spawnedLane = currentUpdatePriority; + spawnedLane = 0 !== (didIncludeRenderPhaseUpdate.flags & 15990); + if (0 !== (didIncludeRenderPhaseUpdate.subtreeFlags & 15990) || spawnedLane) { + spawnedLane = ReactCurrentBatchConfig.transition; + ReactCurrentBatchConfig.transition = null; + remainingLanes = currentUpdatePriority; currentUpdatePriority = 2; var prevExecutionContext = executionContext; executionContext |= 4; - commitBeforeMutationEffects(root, finishedWork); - commitMutationEffectsOnFiber(finishedWork, root); - root.current = finishedWork; - commitLayoutEffectOnFiber(root, finishedWork.alternate, finishedWork); + ReactCurrentOwner.current = null; + commitBeforeMutationEffects(root, didIncludeRenderPhaseUpdate); + commitMutationEffectsOnFiber(didIncludeRenderPhaseUpdate, root); + root.current = didIncludeRenderPhaseUpdate; + commitLayoutEffectOnFiber( + root, + didIncludeRenderPhaseUpdate.alternate, + didIncludeRenderPhaseUpdate + ); requestPaint(); executionContext = prevExecutionContext; - currentUpdatePriority = spawnedLane; - ReactSharedInternals.T = transitions; - } else root.current = finishedWork; - rootDoesHavePassiveEffects - ? ((rootDoesHavePassiveEffects = !1), - (rootWithPendingPassiveEffects = root), - (pendingPassiveEffectsLanes = lanes)) - : releaseRootPooledCache(root, remainingLanes); + currentUpdatePriority = remainingLanes; + ReactCurrentBatchConfig.transition = spawnedLane; + } else root.current = didIncludeRenderPhaseUpdate; + rootDoesHavePassiveEffects && + ((rootDoesHavePassiveEffects = !1), + (rootWithPendingPassiveEffects = root), + (pendingPassiveEffectsLanes = transitions)); remainingLanes = root.pendingLanes; 0 === remainingLanes && (legacyErrorBoundariesThatAlreadyFailed = null); - onCommitRoot(finishedWork.stateNode, renderPriorityLevel); + onCommitRoot(didIncludeRenderPhaseUpdate.stateNode, renderPriorityLevel); ensureRootIsScheduled(root); if (null !== recoverableErrors) for ( - renderPriorityLevel = root.onRecoverableError, finishedWork = 0; - finishedWork < recoverableErrors.length; - finishedWork++ + renderPriorityLevel = root.onRecoverableError, + didIncludeRenderPhaseUpdate = 0; + didIncludeRenderPhaseUpdate < recoverableErrors.length; + didIncludeRenderPhaseUpdate++ ) - (remainingLanes = recoverableErrors[finishedWork]), - renderPriorityLevel(remainingLanes.value, { - componentStack: remainingLanes.stack - }); + (spawnedLane = recoverableErrors[didIncludeRenderPhaseUpdate]), + (remainingLanes = { + digest: spawnedLane.digest, + componentStack: spawnedLane.stack + }), + renderPriorityLevel(spawnedLane.value, remainingLanes); + if (hasUncaughtError) + throw ( + ((hasUncaughtError = !1), + (root = firstUncaughtError), + (firstUncaughtError = null), + root) + ); 0 !== (pendingPassiveEffectsLanes & 3) && 0 !== root.tag && flushPassiveEffects(); remainingLanes = root.pendingLanes; - didIncludeRenderPhaseUpdate || - didIncludeCommitPhaseUpdate || - (0 !== (lanes & 4194218) && 0 !== (remainingLanes & 42)) + 0 !== (transitions & 4194218) && 0 !== (remainingLanes & 42) ? root === rootWithNestedUpdates ? nestedUpdateCount++ : ((nestedUpdateCount = 0), (rootWithNestedUpdates = root)) @@ -9404,43 +8440,26 @@ function commitRootImpl( flushSyncWorkAcrossRoots_impl(!1); return null; } -function releaseRootPooledCache(root, remainingLanes) { - 0 === (root.pooledCacheLanes &= remainingLanes) && - ((remainingLanes = root.pooledCache), - null != remainingLanes && - ((root.pooledCache = null), releaseCache(remainingLanes))); -} function flushPassiveEffects() { if (null !== rootWithPendingPassiveEffects) { - var root = rootWithPendingPassiveEffects, - remainingLanes = pendingPassiveEffectsRemainingLanes; - pendingPassiveEffectsRemainingLanes = 0; var renderPriority = lanesToEventPriority(pendingPassiveEffectsLanes), - prevTransition = ReactSharedInternals.T, + prevTransition = ReactCurrentBatchConfig.transition, previousPriority = currentUpdatePriority; try { + ReactCurrentBatchConfig.transition = null; currentUpdatePriority = 32 > renderPriority ? 32 : renderPriority; - ReactSharedInternals.T = null; if (null === rootWithPendingPassiveEffects) var JSCompiler_inline_result = !1; else { - renderPriority = pendingPassiveTransitions; - pendingPassiveTransitions = null; - var root$jscomp$0 = rootWithPendingPassiveEffects, - lanes = pendingPassiveEffectsLanes; + renderPriority = rootWithPendingPassiveEffects; rootWithPendingPassiveEffects = null; pendingPassiveEffectsLanes = 0; if (0 !== (executionContext & 6)) throw Error("Cannot flush passive effects while already rendering."); var prevExecutionContext = executionContext; executionContext |= 4; - commitPassiveUnmountOnFiber(root$jscomp$0.current); - commitPassiveMountOnFiber( - root$jscomp$0, - root$jscomp$0.current, - lanes, - renderPriority - ); + commitPassiveUnmountOnFiber(renderPriority.current); + commitPassiveMountOnFiber(renderPriority, renderPriority.current); executionContext = prevExecutionContext; flushSyncWorkAcrossRoots_impl(!1); if ( @@ -9448,25 +8467,24 @@ function flushPassiveEffects() { "function" === typeof injectedHook.onPostCommitFiberRoot ) try { - injectedHook.onPostCommitFiberRoot(rendererID, root$jscomp$0); + injectedHook.onPostCommitFiberRoot(rendererID, renderPriority); } catch (err) {} JSCompiler_inline_result = !0; } return JSCompiler_inline_result; } finally { (currentUpdatePriority = previousPriority), - (ReactSharedInternals.T = prevTransition), - releaseRootPooledCache(root, remainingLanes); + (ReactCurrentBatchConfig.transition = prevTransition); } } return !1; } function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { sourceFiber = createCapturedValueAtFiber(error, sourceFiber); - sourceFiber = createRootErrorUpdate(rootFiber.stateNode, sourceFiber, 2); + sourceFiber = createRootErrorUpdate(rootFiber, sourceFiber, 2); rootFiber = enqueueUpdate(rootFiber, sourceFiber, 2); null !== rootFiber && - (markRootUpdated(rootFiber, 2), ensureRootIsScheduled(rootFiber)); + (markRootUpdated$1(rootFiber, 2), ensureRootIsScheduled(rootFiber)); } function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error) { if (3 === sourceFiber.tag) @@ -9490,17 +8508,19 @@ function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error) { !legacyErrorBoundariesThatAlreadyFailed.has(instance))) ) { sourceFiber = createCapturedValueAtFiber(error, sourceFiber); - error = createClassErrorUpdate(2); - instance = enqueueUpdate(nearestMountedAncestor, error, 2); - null !== instance && - (initializeClassErrorUpdate( - error, - instance, - nearestMountedAncestor, - sourceFiber - ), - markRootUpdated(instance, 2), - ensureRootIsScheduled(instance)); + sourceFiber = createClassErrorUpdate( + nearestMountedAncestor, + sourceFiber, + 2 + ); + nearestMountedAncestor = enqueueUpdate( + nearestMountedAncestor, + sourceFiber, + 2 + ); + null !== nearestMountedAncestor && + (markRootUpdated$1(nearestMountedAncestor, 2), + ensureRootIsScheduled(nearestMountedAncestor)); break; } } @@ -9527,10 +8547,6 @@ function pingSuspendedRoot(root, wakeable, pingedLanes) { var pingCache = root.pingCache; null !== pingCache && pingCache.delete(wakeable); root.pingedLanes |= root.suspendedLanes & pingedLanes; - executionContext & 2 - ? (workInProgressRootDidIncludeRecursiveRenderUpdate = !0) - : executionContext & 4 && (didIncludeCommitPhaseUpdate = !0); - throwIfInfiniteUpdateLoopDetected(); workInProgressRoot === root && (workInProgressRootRenderLanes & pingedLanes) === pingedLanes && (4 === workInProgressRootExitStatus || @@ -9547,7 +8563,7 @@ function retryTimedOutBoundary(boundaryFiber, retryLane) { (retryLane = 0 === (boundaryFiber.mode & 1) ? 2 : claimNextRetryLane()); boundaryFiber = enqueueConcurrentRenderForLane(boundaryFiber, retryLane); null !== boundaryFiber && - (markRootUpdated(boundaryFiber, retryLane), + (markRootUpdated$1(boundaryFiber, retryLane), ensureRootIsScheduled(boundaryFiber)); } function retryDehydratedSuspenseBoundary(boundaryFiber) { @@ -9578,22 +8594,8 @@ function resolveRetryWakeable(boundaryFiber, wakeable) { null !== retryCache && retryCache.delete(wakeable); retryTimedOutBoundary(boundaryFiber, retryLane); } -function throwIfInfiniteUpdateLoopDetected() { - if (50 < nestedUpdateCount) - throw ( - ((nestedUpdateCount = 0), - (rootWithNestedUpdates = null), - executionContext & 2 && - null !== workInProgressRoot && - (workInProgressRoot.errorRecoveryDisabledLanes |= - workInProgressRootRenderLanes), - Error( - "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." - )) - ); -} function scheduleCallback(priorityLevel, callback) { - return scheduleCallback$3(priorityLevel, callback); + return scheduleCallback$2(priorityLevel, callback); } function FiberNode(tag, pendingProps, key, mode) { this.tag = tag; @@ -9626,6 +8628,16 @@ function shouldConstruct(Component) { Component = Component.prototype; return !(!Component || !Component.isReactComponent); } +function resolveLazyComponentTag(Component) { + if ("function" === typeof Component) + return shouldConstruct(Component) ? 1 : 0; + if (void 0 !== Component && null !== Component) { + Component = Component.$$typeof; + if (Component === REACT_FORWARD_REF_TYPE) return 11; + if (Component === REACT_MEMO_TYPE) return 14; + } + return 2; +} function createWorkInProgress(current, pendingProps) { var workInProgress = current.alternate; null === workInProgress @@ -9703,7 +8715,7 @@ function createFiberFromTypeAndProps( mode, lanes ) { - var fiberTag = 0; + var fiberTag = 2; owner = type; if ("function" === typeof type) shouldConstruct(type) && (fiberTag = 1); else if ("string" === typeof type) fiberTag = 5; @@ -9743,12 +8755,12 @@ function createFiberFromTypeAndProps( if ("object" === typeof type && null !== type) switch (type.$$typeof) { case REACT_PROVIDER_TYPE: - case REACT_CONTEXT_TYPE: fiberTag = 10; break a; - case REACT_CONSUMER_TYPE: + case REACT_CONTEXT_TYPE: fiberTag = 9; break a; + case REACT_CONSUMER_TYPE: case REACT_FORWARD_REF_TYPE: fiberTag = 11; break a; @@ -9762,7 +8774,7 @@ function createFiberFromTypeAndProps( } throw Error( "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + - ((null === type ? "null" : typeof type) + ".") + ((null == type ? type : typeof type) + ".") ); } key = createFiber(fiberTag, pendingProps, key, mode); @@ -9842,8 +8854,6 @@ function FiberRootNode( tag, hydrate, identifierPrefix, - onUncaughtError, - onCaughtError, onRecoverableError, formState ) { @@ -9875,11 +8885,7 @@ function FiberRootNode( this.entanglements = createLaneMap(0); this.hiddenUpdates = createLaneMap(null); this.identifierPrefix = identifierPrefix; - this.onUncaughtError = onUncaughtError; - this.onCaughtError = onCaughtError; this.onRecoverableError = onRecoverableError; - this.pooledCache = null; - this.pooledCacheLanes = 0; this.formState = formState; this.incompleteTransitions = new Map(); } @@ -9952,30 +8958,8 @@ function findNodeHandle(componentOrHandle) { function getInspectorDataForInstance() { throw Error("getInspectorDataForInstance() is not available in production"); } -if ( - "function" !== - typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog -) - throw Error( - "Expected ReactFiberErrorDialog.showErrorDialog to be a function." - ); -function nativeOnUncaughtError(error, errorInfo) { - !1 !== - ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog({ - errorBoundary: null, - error: error, - componentStack: - null != errorInfo.componentStack ? errorInfo.componentStack : "" - }) && reportGlobalError(error); -} -function nativeOnCaughtError(error, errorInfo) { - !1 !== - ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog({ - errorBoundary: errorInfo.errorBoundary, - error: error, - componentStack: - null != errorInfo.componentStack ? errorInfo.componentStack : "" - }) && console.error(error); +function onRecoverableError(error) { + console.error(error); } batchedUpdatesImpl = function (fn, a) { var prevExecutionContext = executionContext; @@ -9990,10 +8974,10 @@ batchedUpdatesImpl = function (fn, a) { } }; var roots = new Map(), - devToolsConfig$jscomp$inline_1106 = { + devToolsConfig$jscomp$inline_1031 = { findFiberByHostInstance: getInstanceFromNode, bundleType: 0, - version: "19.0.0-rc-fb9a90fa48-20240614", + version: "18.3.0-canary-9372c6311-20240315", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForInstance: getInspectorDataForInstance, @@ -10009,11 +8993,11 @@ var roots = new Map(), }.bind(null, findNodeHandle) } }; -var internals$jscomp$inline_1340 = { - bundleType: devToolsConfig$jscomp$inline_1106.bundleType, - version: devToolsConfig$jscomp$inline_1106.version, - rendererPackageName: devToolsConfig$jscomp$inline_1106.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_1106.rendererConfig, +var internals$jscomp$inline_1259 = { + bundleType: devToolsConfig$jscomp$inline_1031.bundleType, + version: devToolsConfig$jscomp$inline_1031.version, + rendererPackageName: devToolsConfig$jscomp$inline_1031.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_1031.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -10023,32 +9007,32 @@ var internals$jscomp$inline_1340 = { setErrorHandler: null, setSuspenseHandler: null, scheduleUpdate: null, - currentDispatcherRef: ReactSharedInternals, + currentDispatcherRef: ReactSharedInternals.ReactCurrentDispatcher, findHostInstanceByFiber: function (fiber) { fiber = findCurrentHostFiber(fiber); return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_1106.findFiberByHostInstance || + devToolsConfig$jscomp$inline_1031.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "19.0.0-rc-fb9a90fa48-20240614" + reconcilerVersion: "18.3.0-canary-9372c6311-20240315" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_1341 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_1260 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_1341.isDisabled && - hook$jscomp$inline_1341.supportsFiber + !hook$jscomp$inline_1260.isDisabled && + hook$jscomp$inline_1260.supportsFiber ) try { - (rendererID = hook$jscomp$inline_1341.inject( - internals$jscomp$inline_1340 + (rendererID = hook$jscomp$inline_1260.inject( + internals$jscomp$inline_1259 )), - (injectedHook = hook$jscomp$inline_1341); + (injectedHook = hook$jscomp$inline_1260); } catch (err) {} } exports.createPortal = function (children, containerTag) { @@ -10110,54 +9094,25 @@ exports.getPublicInstanceFromInternalInstanceHandle = function ( exports.isChildPublicInstance = function () { throw Error("isChildPublicInstance() is not available in production."); }; -exports.render = function ( - element, - containerTag, - callback, - concurrentRoot, - options -) { +exports.render = function (element, containerTag, callback, concurrentRoot) { var root = roots.get(containerTag); - if (!root) { - root = nativeOnUncaughtError; - var onCaughtError = nativeOnCaughtError, - onRecoverableError = defaultOnRecoverableError; - options && - void 0 !== options.onUncaughtError && - (root = options.onUncaughtError); - options && - void 0 !== options.onCaughtError && - (onCaughtError = options.onCaughtError); - options && - void 0 !== options.onRecoverableError && - (onRecoverableError = options.onRecoverableError); - concurrentRoot = concurrentRoot ? 1 : 0; - options = new FiberRootNode( + root || + ((root = concurrentRoot ? 1 : 0), + (concurrentRoot = new FiberRootNode( containerTag, - concurrentRoot, + root, !1, "", - root, - onCaughtError, onRecoverableError, null - ); - concurrentRoot = createFiber(3, null, null, 1 === concurrentRoot ? 1 : 0); - options.current = concurrentRoot; - concurrentRoot.stateNode = options; - root = createCache(); - root.refCount++; - options.pooledCache = root; - root.refCount++; - concurrentRoot.memoizedState = { - element: null, - isDehydrated: !1, - cache: root - }; - initializeUpdateQueue(concurrentRoot); - root = options; - roots.set(containerTag, root); - } + )), + (root = createFiber(3, null, null, 1 === root ? 1 : 0)), + (concurrentRoot.current = root), + (root.stateNode = concurrentRoot), + (root.memoizedState = { element: null, isDehydrated: !1, cache: 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/packages/react-native/Libraries/Renderer/implementations/ReactFabric-profiling.js b/packages/react-native/Libraries/Renderer/implementations/ReactFabric-profiling.js index ce8b748c9d8b4d..0f5fab5c9e1422 100644 --- a/packages/react-native/Libraries/Renderer/implementations/ReactFabric-profiling.js +++ b/packages/react-native/Libraries/Renderer/implementations/ReactFabric-profiling.js @@ -6,10 +6,9 @@ * * @noflow * @nolint + * @providesModule ReactFabric-profiling * @preventMunge - * @generated SignedSource<> - * - * This file was sync'd from the facebook/react repository. + * @generated SignedSource<> */ "use strict"; @@ -22,219 +21,7 @@ var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/R Scheduler = require("scheduler"), React = require("react"), isArrayImpl = Array.isArray, - ReactSharedInternals = - React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, - REACT_LEGACY_ELEMENT_TYPE = Symbol.for("react.element"), - REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"), - REACT_PORTAL_TYPE = Symbol.for("react.portal"), - REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"), - REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"), - REACT_PROFILER_TYPE = Symbol.for("react.profiler"), - REACT_PROVIDER_TYPE = Symbol.for("react.provider"), - REACT_CONSUMER_TYPE = Symbol.for("react.consumer"), - REACT_CONTEXT_TYPE = Symbol.for("react.context"), - REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"), - REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"), - REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"), - REACT_MEMO_TYPE = Symbol.for("react.memo"), - REACT_LAZY_TYPE = Symbol.for("react.lazy"); -Symbol.for("react.scope"); -Symbol.for("react.debug_trace_mode"); -var REACT_OFFSCREEN_TYPE = Symbol.for("react.offscreen"); -Symbol.for("react.legacy_hidden"); -Symbol.for("react.tracing_marker"); -var REACT_MEMO_CACHE_SENTINEL = Symbol.for("react.memo_cache_sentinel"), - MAYBE_ITERATOR_SYMBOL = Symbol.iterator; -function getIteratorFn(maybeIterable) { - if (null === maybeIterable || "object" !== typeof maybeIterable) return null; - maybeIterable = - (MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL]) || - maybeIterable["@@iterator"]; - return "function" === typeof maybeIterable ? maybeIterable : null; -} -var assign = Object.assign, - prefix; -function describeBuiltInComponentFrame(name) { - if (void 0 === prefix) - try { - throw Error(); - } catch (x) { - var match = x.stack.trim().match(/\n( *(at )?)/); - prefix = (match && match[1]) || ""; - } - return "\n" + prefix + name; -} -var reentry = !1; -function describeNativeComponentFrame(fn, construct) { - if (!fn || reentry) return ""; - reentry = !0; - var previousPrepareStackTrace = Error.prepareStackTrace; - Error.prepareStackTrace = void 0; - var RunInRootFrame = { - DetermineComponentFrameRoot: function () { - try { - if (construct) { - var Fake = function () { - throw Error(); - }; - Object.defineProperty(Fake.prototype, "props", { - set: function () { - throw Error(); - } - }); - if ("object" === typeof Reflect && Reflect.construct) { - try { - Reflect.construct(Fake, []); - } catch (x) { - var control = x; - } - Reflect.construct(fn, [], Fake); - } else { - try { - Fake.call(); - } catch (x$0) { - control = x$0; - } - fn.call(Fake.prototype); - } - } else { - try { - throw Error(); - } catch (x$1) { - control = x$1; - } - (Fake = fn()) && - "function" === typeof Fake.catch && - Fake.catch(function () {}); - } - } catch (sample) { - if (sample && control && "string" === typeof sample.stack) - return [sample.stack, control.stack]; - } - return [null, null]; - } - }; - RunInRootFrame.DetermineComponentFrameRoot.displayName = - "DetermineComponentFrameRoot"; - var namePropDescriptor = Object.getOwnPropertyDescriptor( - RunInRootFrame.DetermineComponentFrameRoot, - "name" - ); - namePropDescriptor && - namePropDescriptor.configurable && - Object.defineProperty(RunInRootFrame.DetermineComponentFrameRoot, "name", { - value: "DetermineComponentFrameRoot" - }); - try { - var _RunInRootFrame$Deter = RunInRootFrame.DetermineComponentFrameRoot(), - sampleStack = _RunInRootFrame$Deter[0], - controlStack = _RunInRootFrame$Deter[1]; - if (sampleStack && controlStack) { - var sampleLines = sampleStack.split("\n"), - controlLines = controlStack.split("\n"); - for ( - namePropDescriptor = RunInRootFrame = 0; - RunInRootFrame < sampleLines.length && - !sampleLines[RunInRootFrame].includes("DetermineComponentFrameRoot"); - - ) - RunInRootFrame++; - for ( - ; - namePropDescriptor < controlLines.length && - !controlLines[namePropDescriptor].includes( - "DetermineComponentFrameRoot" - ); - - ) - namePropDescriptor++; - if ( - RunInRootFrame === sampleLines.length || - namePropDescriptor === controlLines.length - ) - for ( - RunInRootFrame = sampleLines.length - 1, - namePropDescriptor = controlLines.length - 1; - 1 <= RunInRootFrame && - 0 <= namePropDescriptor && - sampleLines[RunInRootFrame] !== controlLines[namePropDescriptor]; - - ) - namePropDescriptor--; - for ( - ; - 1 <= RunInRootFrame && 0 <= namePropDescriptor; - RunInRootFrame--, namePropDescriptor-- - ) - if (sampleLines[RunInRootFrame] !== controlLines[namePropDescriptor]) { - if (1 !== RunInRootFrame || 1 !== namePropDescriptor) { - do - if ( - (RunInRootFrame--, - namePropDescriptor--, - 0 > namePropDescriptor || - sampleLines[RunInRootFrame] !== - controlLines[namePropDescriptor]) - ) { - var frame = - "\n" + - sampleLines[RunInRootFrame].replace(" at new ", " at "); - fn.displayName && - frame.includes("") && - (frame = frame.replace("", fn.displayName)); - return frame; - } - while (1 <= RunInRootFrame && 0 <= namePropDescriptor); - } - break; - } - } - } finally { - (reentry = !1), (Error.prepareStackTrace = previousPrepareStackTrace); - } - return (previousPrepareStackTrace = fn ? fn.displayName || fn.name : "") - ? describeBuiltInComponentFrame(previousPrepareStackTrace) - : ""; -} -function describeFiber(fiber) { - switch (fiber.tag) { - case 26: - case 27: - case 5: - return describeBuiltInComponentFrame(fiber.type); - case 16: - return describeBuiltInComponentFrame("Lazy"); - case 13: - return describeBuiltInComponentFrame("Suspense"); - case 19: - return describeBuiltInComponentFrame("SuspenseList"); - case 0: - case 15: - return (fiber = describeNativeComponentFrame(fiber.type, !1)), fiber; - case 11: - return ( - (fiber = describeNativeComponentFrame(fiber.type.render, !1)), fiber - ); - case 1: - return (fiber = describeNativeComponentFrame(fiber.type, !0)), fiber; - default: - return ""; - } -} -function getStackByFiberInDevAndProd(workInProgress) { - try { - var info = ""; - do - (info += describeFiber(workInProgress)), - (workInProgress = workInProgress.return); - while (workInProgress); - return info; - } catch (x) { - return "\nError generating stack: " + x.message + "\n" + x.stack; - } -} -Symbol.for("react.client.reference"); -var hasError = !1, + hasError = !1, caughtError = null, getFiberCurrentPropsFromNode$1 = null, getInstanceFromNode$1 = null, @@ -261,6 +48,7 @@ function executeDirectDispatch(event) { event._dispatchInstances = null; return dispatchListener; } +var assign = Object.assign; function functionThatReturnsTrue() { return !0; } @@ -1109,7 +897,7 @@ eventPluginOrder = Array.prototype.slice.call([ "ReactNativeBridgeEventPlugin" ]); recomputePluginOrdering(); -var injectedNamesToPlugins$jscomp$inline_293 = { +var injectedNamesToPlugins$jscomp$inline_246 = { ResponderEventPlugin: ResponderEventPlugin, ReactNativeBridgeEventPlugin: { eventTypes: {}, @@ -1155,32 +943,32 @@ var injectedNamesToPlugins$jscomp$inline_293 = { } } }, - isOrderingDirty$jscomp$inline_294 = !1, - pluginName$jscomp$inline_295; -for (pluginName$jscomp$inline_295 in injectedNamesToPlugins$jscomp$inline_293) + isOrderingDirty$jscomp$inline_247 = !1, + pluginName$jscomp$inline_248; +for (pluginName$jscomp$inline_248 in injectedNamesToPlugins$jscomp$inline_246) if ( - injectedNamesToPlugins$jscomp$inline_293.hasOwnProperty( - pluginName$jscomp$inline_295 + injectedNamesToPlugins$jscomp$inline_246.hasOwnProperty( + pluginName$jscomp$inline_248 ) ) { - var pluginModule$jscomp$inline_296 = - injectedNamesToPlugins$jscomp$inline_293[pluginName$jscomp$inline_295]; + var pluginModule$jscomp$inline_249 = + injectedNamesToPlugins$jscomp$inline_246[pluginName$jscomp$inline_248]; if ( - !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_295) || - namesToPlugins[pluginName$jscomp$inline_295] !== - pluginModule$jscomp$inline_296 + !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_248) || + namesToPlugins[pluginName$jscomp$inline_248] !== + pluginModule$jscomp$inline_249 ) { - if (namesToPlugins[pluginName$jscomp$inline_295]) + if (namesToPlugins[pluginName$jscomp$inline_248]) throw Error( "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - (pluginName$jscomp$inline_295 + "`.") + (pluginName$jscomp$inline_248 + "`.") ); - namesToPlugins[pluginName$jscomp$inline_295] = - pluginModule$jscomp$inline_296; - isOrderingDirty$jscomp$inline_294 = !0; + namesToPlugins[pluginName$jscomp$inline_248] = + pluginModule$jscomp$inline_249; + isOrderingDirty$jscomp$inline_247 = !0; } } -isOrderingDirty$jscomp$inline_294 && recomputePluginOrdering(); +isOrderingDirty$jscomp$inline_247 && recomputePluginOrdering(); var emptyObject = {}, removedKeys = null, removedKeyCount = 0, @@ -1384,19 +1172,19 @@ function diffProperties(updatePayload, prevProps, nextProps, validAttributes) { ), (removedKeys = null)); } - for (var propKey$5 in prevProps) - void 0 === nextProps[propKey$5] && - (!(attributeConfig = validAttributes[propKey$5]) || - (updatePayload && void 0 !== updatePayload[propKey$5]) || - ((prevProp = prevProps[propKey$5]), + for (var propKey$1 in prevProps) + void 0 === nextProps[propKey$1] && + (!(attributeConfig = validAttributes[propKey$1]) || + (updatePayload && void 0 !== updatePayload[propKey$1]) || + ((prevProp = prevProps[propKey$1]), void 0 !== prevProp && ("object" !== typeof attributeConfig || "function" === typeof attributeConfig.diff || "function" === typeof attributeConfig.process - ? (((updatePayload || (updatePayload = {}))[propKey$5] = null), + ? (((updatePayload || (updatePayload = {}))[propKey$1] = null), removedKeys || (removedKeys = {}), - removedKeys[propKey$5] || - ((removedKeys[propKey$5] = !0), removedKeyCount++)) + removedKeys[propKey$1] || + ((removedKeys[propKey$1] = !0), removedKeyCount++)) : (updatePayload = clearNestedProperty( updatePayload, prevProp, @@ -1480,20 +1268,19 @@ function dispatchEvent(target, topLevelType, nativeEvent) { } }); } -var scheduleCallback$3 = Scheduler.unstable_scheduleCallback, +var scheduleCallback$2 = Scheduler.unstable_scheduleCallback, cancelCallback$1 = Scheduler.unstable_cancelCallback, shouldYield = Scheduler.unstable_shouldYield, requestPaint = Scheduler.unstable_requestPaint, now$1 = Scheduler.unstable_now, ImmediatePriority = Scheduler.unstable_ImmediatePriority, UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, - NormalPriority$1 = Scheduler.unstable_NormalPriority, + NormalPriority = Scheduler.unstable_NormalPriority, IdlePriority = Scheduler.unstable_IdlePriority, - log$1 = Scheduler.log, - unstable_setDisableYieldValue = Scheduler.unstable_setDisableYieldValue, + ReactSharedInternals = + React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED, rendererID = null, injectedHook = null, - injectedProfilingHooks = null, isDevToolsPresent = "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__; function onCommitRoot(root, eventPriority) { if (injectedHook && "function" === typeof injectedHook.onCommitFiberRoot) @@ -1507,13 +1294,13 @@ function onCommitRoot(root, eventPriority) { schedulerPriority = UserBlockingPriority; break; case 32: - schedulerPriority = NormalPriority$1; + schedulerPriority = NormalPriority; break; case 268435456: schedulerPriority = IdlePriority; break; default: - schedulerPriority = NormalPriority$1; + schedulerPriority = NormalPriority; } injectedHook.onCommitFiberRoot( rendererID, @@ -1523,66 +1310,6 @@ function onCommitRoot(root, eventPriority) { ); } catch (err) {} } -function setIsStrictModeForDevtools(newIsStrictMode) { - "function" === typeof log$1 && unstable_setDisableYieldValue(newIsStrictMode); - if (injectedHook && "function" === typeof injectedHook.setStrictMode) - try { - injectedHook.setStrictMode(rendererID, newIsStrictMode); - } catch (err) {} -} -function injectProfilingHooks(profilingHooks) { - injectedProfilingHooks = profilingHooks; -} -function getLaneLabelMap() { - for (var map = new Map(), lane = 1, index$6 = 0; 31 > index$6; index$6++) { - var label = getLabelForLane(lane); - map.set(lane, label); - lane *= 2; - } - return map; -} -function markCommitStopped() { - null !== injectedProfilingHooks && - "function" === typeof injectedProfilingHooks.markCommitStopped && - injectedProfilingHooks.markCommitStopped(); -} -function markComponentRenderStarted(fiber) { - null !== injectedProfilingHooks && - "function" === typeof injectedProfilingHooks.markComponentRenderStarted && - injectedProfilingHooks.markComponentRenderStarted(fiber); -} -function markComponentRenderStopped() { - null !== injectedProfilingHooks && - "function" === typeof injectedProfilingHooks.markComponentRenderStopped && - injectedProfilingHooks.markComponentRenderStopped(); -} -function markComponentLayoutEffectUnmountStarted(fiber) { - null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markComponentLayoutEffectUnmountStarted && - injectedProfilingHooks.markComponentLayoutEffectUnmountStarted(fiber); -} -function markComponentLayoutEffectUnmountStopped() { - null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markComponentLayoutEffectUnmountStopped && - injectedProfilingHooks.markComponentLayoutEffectUnmountStopped(); -} -function markRenderStarted(lanes) { - null !== injectedProfilingHooks && - "function" === typeof injectedProfilingHooks.markRenderStarted && - injectedProfilingHooks.markRenderStarted(lanes); -} -function markRenderStopped() { - null !== injectedProfilingHooks && - "function" === typeof injectedProfilingHooks.markRenderStopped && - injectedProfilingHooks.markRenderStopped(); -} -function markStateUpdateScheduled(fiber, lane) { - null !== injectedProfilingHooks && - "function" === typeof injectedProfilingHooks.markStateUpdateScheduled && - injectedProfilingHooks.markStateUpdateScheduled(fiber, lane); -} var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback, log = Math.log, LN2 = Math.LN2; @@ -1590,22 +1317,6 @@ function clz32Fallback(x) { x >>>= 0; return 0 === x ? 32 : (31 - ((log(x) / LN2) | 0)) | 0; } -function getLabelForLane(lane) { - if (lane & 1) return "SyncHydrationLane"; - if (lane & 2) return "Sync"; - if (lane & 4) return "InputContinuousHydration"; - if (lane & 8) return "InputContinuous"; - if (lane & 16) return "DefaultHydration"; - if (lane & 32) return "Default"; - if (lane & 64) return "TransitionHydration"; - if (lane & 4194176) return "Transition"; - if (lane & 62914560) return "Retry"; - if (lane & 67108864) return "SelectiveHydration"; - if (lane & 134217728) return "IdleHydration"; - if (lane & 268435456) return "Idle"; - if (lane & 536870912) return "Offscreen"; - if (lane & 1073741824) return "Deferred"; -} var nextTransitionLane = 128, nextRetryLane = 4194304; function getHighestPriorityLanes(lanes) { @@ -1752,6 +1463,11 @@ function createLaneMap(initial) { for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); return laneMap; } +function markRootUpdated$1(root, updateLane) { + root.pendingLanes |= updateLane; + 268435456 !== updateLane && + ((root.suspendedLanes = 0), (root.pingedLanes = 0)); +} function markRootFinished(root, remainingLanes, spawnedLane) { var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; root.pendingLanes = remainingLanes; @@ -1768,18 +1484,18 @@ function markRootFinished(root, remainingLanes, spawnedLane) { 0 < noLongerPendingLanes; ) { - var index$10 = 31 - clz32(noLongerPendingLanes), - lane = 1 << index$10; - remainingLanes[index$10] = 0; - expirationTimes[index$10] = -1; - var hiddenUpdatesForLane = hiddenUpdates[index$10]; + var index$5 = 31 - clz32(noLongerPendingLanes), + lane = 1 << index$5; + remainingLanes[index$5] = 0; + expirationTimes[index$5] = -1; + var hiddenUpdatesForLane = hiddenUpdates[index$5]; if (null !== hiddenUpdatesForLane) for ( - hiddenUpdates[index$10] = null, index$10 = 0; - index$10 < hiddenUpdatesForLane.length; - index$10++ + hiddenUpdates[index$5] = null, index$5 = 0; + index$5 < hiddenUpdatesForLane.length; + index$5++ ) { - var update = hiddenUpdatesForLane[index$10]; + var update = hiddenUpdatesForLane[index$5]; null !== update && (update.lane &= -536870913); } noLongerPendingLanes &= ~lane; @@ -1799,19 +1515,19 @@ function markSpawnedDeferredLane(root, spawnedLane, entangledLanes) { function markRootEntangled(root, entangledLanes) { var rootEntangledLanes = (root.entangledLanes |= entangledLanes); for (root = root.entanglements; rootEntangledLanes; ) { - var index$11 = 31 - clz32(rootEntangledLanes), - lane = 1 << index$11; - (lane & entangledLanes) | (root[index$11] & entangledLanes) && - (root[index$11] |= entangledLanes); + var index$6 = 31 - clz32(rootEntangledLanes), + lane = 1 << index$6; + (lane & entangledLanes) | (root[index$6] & entangledLanes) && + (root[index$6] |= entangledLanes); rootEntangledLanes &= ~lane; } } function addFiberToLanesMap(root, fiber, lanes) { if (isDevToolsPresent) for (root = root.pendingUpdatersLaneMap; 0 < lanes; ) { - var index$12 = 31 - clz32(lanes), - lane = 1 << index$12; - root[index$12].add(fiber); + var index$7 = 31 - clz32(lanes), + lane = 1 << index$7; + root[index$7].add(fiber); lanes &= ~lane; } } @@ -1823,19 +1539,20 @@ function movePendingFibersToMemoized(root, lanes) { 0 < lanes; ) { - var index$13 = 31 - clz32(lanes); - root = 1 << index$13; - index$13 = pendingUpdatersLaneMap[index$13]; - 0 < index$13.size && - (index$13.forEach(function (fiber) { + var index$8 = 31 - clz32(lanes); + root = 1 << index$8; + index$8 = pendingUpdatersLaneMap[index$8]; + 0 < index$8.size && + (index$8.forEach(function (fiber) { var alternate = fiber.alternate; (null !== alternate && memoizedUpdaters.has(alternate)) || memoizedUpdaters.add(fiber); }), - index$13.clear()); + index$8.clear()); lanes &= ~root; } } +var currentUpdatePriority = 0; function lanesToEventPriority(lanes) { lanes &= -lanes; return 2 < lanes @@ -1851,11 +1568,6 @@ function shim$1() { "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." ); } -function shim() { - throw Error( - "The current renderer does not support Resources. This error is likely caused by a bug in React. Please file an issue." - ); -} var _nativeFabricUIManage = nativeFabricUIManager, createNode = _nativeFabricUIManage.createNode, cloneNodeWithNewChildren = _nativeFabricUIManage.cloneNodeWithNewChildren, @@ -1874,7 +1586,6 @@ var _nativeFabricUIManage = nativeFabricUIManager, ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get, nextReactTag = 2; registerEventHandler && registerEventHandler(dispatchEvent); -var PROD_HOST_CONTEXT = { isInAParentText: !0 }; function createTextInstance( text, rootContainerInstance, @@ -1900,19 +1611,6 @@ function getPublicInstance(instance) { ? instance : null; } -var currentUpdatePriority = 0; -function resolveUpdatePriority() { - if (0 !== currentUpdatePriority) return currentUpdatePriority; - var currentEventPriority = fabricGetCurrentEventPriority - ? fabricGetCurrentEventPriority() - : null; - if (null != currentEventPriority) - switch (currentEventPriority) { - case FabricDiscretePriority: - return 2; - } - return 32; -} var scheduleTimeout = setTimeout, cancelTimeout = clearTimeout; function cloneHiddenInstance(instance) { @@ -1965,6 +1663,34 @@ ResponderEventPlugin.injection.injectGlobalResponderHandler({ ); } }); +var REACT_ELEMENT_TYPE = Symbol.for("react.element"), + REACT_PORTAL_TYPE = Symbol.for("react.portal"), + REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"), + REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"), + REACT_PROFILER_TYPE = Symbol.for("react.profiler"), + REACT_PROVIDER_TYPE = Symbol.for("react.provider"), + REACT_CONSUMER_TYPE = Symbol.for("react.consumer"), + REACT_CONTEXT_TYPE = Symbol.for("react.context"), + REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"), + REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"), + REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"), + REACT_MEMO_TYPE = Symbol.for("react.memo"), + REACT_LAZY_TYPE = Symbol.for("react.lazy"); +Symbol.for("react.scope"); +Symbol.for("react.debug_trace_mode"); +var REACT_OFFSCREEN_TYPE = Symbol.for("react.offscreen"); +Symbol.for("react.legacy_hidden"); +Symbol.for("react.cache"); +Symbol.for("react.tracing_marker"); +var MAYBE_ITERATOR_SYMBOL = Symbol.iterator; +function getIteratorFn(maybeIterable) { + if (null === maybeIterable || "object" !== typeof maybeIterable) return null; + maybeIterable = + (MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL]) || + maybeIterable["@@iterator"]; + return "function" === typeof maybeIterable ? maybeIterable : null; +} +Symbol.for("react.client.reference"); function getNearestMountedFiber(fiber) { var node = fiber, nearestMounted = fiber; @@ -2013,36 +1739,36 @@ function findCurrentFiberUsingSlowPath(fiber) { } if (a.return !== b.return) (a = parentA), (b = parentB); else { - for (var didFindChild = !1, child$14 = parentA.child; child$14; ) { - if (child$14 === a) { + for (var didFindChild = !1, child$9 = parentA.child; child$9; ) { + if (child$9 === a) { didFindChild = !0; a = parentA; b = parentB; break; } - if (child$14 === b) { + if (child$9 === b) { didFindChild = !0; b = parentA; a = parentB; break; } - child$14 = child$14.sibling; + child$9 = child$9.sibling; } if (!didFindChild) { - for (child$14 = parentB.child; child$14; ) { - if (child$14 === a) { + for (child$9 = parentB.child; child$9; ) { + if (child$9 === a) { didFindChild = !0; a = parentB; b = parentA; break; } - if (child$14 === b) { + if (child$9 === b) { didFindChild = !0; b = parentB; a = parentA; break; } - child$14 = child$14.sibling; + child$9 = child$9.sibling; } if (!didFindChild) throw Error( @@ -2092,34 +1818,15 @@ 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, - CapturedStacks = new WeakMap(); -function createCapturedValueAtFiber(value, source) { - if ("object" === typeof value && null !== value) { - var stack = CapturedStacks.get(value); - "string" !== typeof stack && - ((stack = getStackByFiberInDevAndProd(source)), - CapturedStacks.set(value, stack)); - } else stack = getStackByFiberInDevAndProd(source); - return { value: value, source: source, stack: stack }; -} -var contextStackCursor = createCursor(null), + contextStackCursor = createCursor(null), contextFiberStackCursor = createCursor(null), - rootInstanceStackCursor = createCursor(null), - hostTransitionProviderCursor = createCursor(null), - HostTransitionContext = { - $$typeof: REACT_CONTEXT_TYPE, - Provider: null, - Consumer: null, - _currentValue: null, - _currentValue2: null, - _threadCount: 0 - }; + rootInstanceStackCursor = createCursor(null); function pushHostContainer(fiber, nextRootInstance) { push(rootInstanceStackCursor, nextRootInstance); push(contextFiberStackCursor, fiber); push(contextStackCursor, null); pop(contextStackCursor); - push(contextStackCursor, PROD_HOST_CONTEXT); + push(contextStackCursor, { isInAParentText: !1 }); } function popHostContainer() { pop(contextStackCursor); @@ -2127,17 +1834,25 @@ function popHostContainer() { pop(rootInstanceStackCursor); } function pushHostContext(fiber) { - null !== fiber.memoizedState && push(hostTransitionProviderCursor, fiber); var context = contextStackCursor.current; - context !== context && - (push(contextFiberStackCursor, fiber), push(contextStackCursor, context)); + var JSCompiler_inline_result = fiber.type; + JSCompiler_inline_result = + "AndroidTextInput" === JSCompiler_inline_result || + "RCTMultilineTextInputView" === JSCompiler_inline_result || + "RCTSinglelineTextInputView" === JSCompiler_inline_result || + "RCTText" === JSCompiler_inline_result || + "RCTVirtualText" === JSCompiler_inline_result; + JSCompiler_inline_result = + context.isInAParentText !== JSCompiler_inline_result + ? { isInAParentText: JSCompiler_inline_result } + : context; + context !== JSCompiler_inline_result && + (push(contextFiberStackCursor, fiber), + push(contextStackCursor, JSCompiler_inline_result)); } function popHostContext(fiber) { contextFiberStackCursor.current === fiber && (pop(contextStackCursor), pop(contextFiberStackCursor)); - hostTransitionProviderCursor.current === fiber && - (pop(hostTransitionProviderCursor), - (HostTransitionContext._currentValue2 = null)); } var hydrationErrors = null, concurrentQueues = [], @@ -2178,10 +1893,6 @@ function enqueueUpdate$1(fiber, queue, update, lane) { fiber = fiber.alternate; null !== fiber && (fiber.lanes |= lane); } -function enqueueConcurrentHookUpdate(fiber, queue, update, lane) { - enqueueUpdate$1(fiber, queue, update, lane); - return getRootForUpdatedFiber(fiber); -} function enqueueConcurrentRenderForLane(fiber, lane) { enqueueUpdate$1(fiber, null, null, lane); return getRootForUpdatedFiber(fiber); @@ -2212,7 +1923,14 @@ function markUpdateLaneFromFiberToRoot(sourceFiber, update, lane) { (update.lane = lane | 536870912)); } function getRootForUpdatedFiber(sourceFiber) { - throwIfInfiniteUpdateLoopDetected(); + if (50 < nestedUpdateCount) + throw ( + ((nestedUpdateCount = 0), + (rootWithNestedUpdates = null), + Error( + "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." + )) + ); for (var parent = sourceFiber.return; null !== parent; ) (sourceFiber = parent), (parent = sourceFiber.return); return 3 === sourceFiber.tag ? sourceFiber.stateNode : null; @@ -2233,29 +1951,104 @@ function ensureRootIsScheduled(root) { didScheduleMicrotask || ((didScheduleMicrotask = !0), scheduleImmediateTask(processRootScheduleInMicrotask)); + scheduleTaskForRootDuringMicrotask(root, now$1()); } function flushSyncWorkAcrossRoots_impl(onlyLegacy) { if (!isFlushingWork && mightHavePendingSyncWork) { + var errors = null; isFlushingWork = !0; do { var didPerformSomeWork = !1; for (var root = firstScheduledRoot; null !== root; ) { if (!onlyLegacy || 0 === root.tag) { - var workInProgressRootRenderLanes$16 = workInProgressRootRenderLanes; - workInProgressRootRenderLanes$16 = getNextLanes( - root, - root === workInProgressRoot ? workInProgressRootRenderLanes$16 : 0 - ); - 0 !== (workInProgressRootRenderLanes$16 & 3) && - ((didPerformSomeWork = !0), - performSyncWorkOnRoot(root, workInProgressRootRenderLanes$16)); + var workInProgressRootRenderLanes$11 = workInProgressRootRenderLanes, + nextLanes = getNextLanes( + root, + root === workInProgressRoot ? workInProgressRootRenderLanes$11 : 0 + ); + if (0 !== (nextLanes & 3)) + try { + didPerformSomeWork = !0; + workInProgressRootRenderLanes$11 = root; + if (0 !== (executionContext & 6)) + throw Error("Should not already be working."); + if (!flushPassiveEffects()) { + currentUpdateIsNested = nestedUpdateScheduled; + nestedUpdateScheduled = !1; + var exitStatus = renderRootSync( + workInProgressRootRenderLanes$11, + nextLanes + ); + if ( + 0 !== workInProgressRootRenderLanes$11.tag && + 2 === exitStatus + ) { + var originallyAttemptedLanes = nextLanes, + errorRetryLanes = getLanesToRetrySynchronouslyOnError( + workInProgressRootRenderLanes$11, + originallyAttemptedLanes + ); + 0 !== errorRetryLanes && + ((nextLanes = errorRetryLanes), + (exitStatus = recoverFromConcurrentError( + workInProgressRootRenderLanes$11, + originallyAttemptedLanes, + errorRetryLanes + ))); + } + if (1 === exitStatus) + throw ( + ((originallyAttemptedLanes = workInProgressRootFatalError), + prepareFreshStack(workInProgressRootRenderLanes$11, 0), + markRootSuspended( + workInProgressRootRenderLanes$11, + nextLanes, + 0 + ), + ensureRootIsScheduled(workInProgressRootRenderLanes$11), + originallyAttemptedLanes) + ); + 6 === exitStatus + ? markRootSuspended( + workInProgressRootRenderLanes$11, + nextLanes, + workInProgressDeferredLane + ) + : ((workInProgressRootRenderLanes$11.finishedWork = + workInProgressRootRenderLanes$11.current.alternate), + (workInProgressRootRenderLanes$11.finishedLanes = + nextLanes), + commitRoot( + workInProgressRootRenderLanes$11, + workInProgressRootRecoverableErrors, + workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, + workInProgressDeferredLane + )); + } + ensureRootIsScheduled(workInProgressRootRenderLanes$11); + } catch (error) { + null === errors ? (errors = [error]) : errors.push(error); + } } root = root.next; } } while (didPerformSomeWork); isFlushingWork = !1; + if (null !== errors) { + if (1 < errors.length) { + if ("function" === typeof AggregateError) + throw new AggregateError(errors); + for (onlyLegacy = 1; onlyLegacy < errors.length; onlyLegacy++) + scheduleImmediateTask(throwError.bind(null, errors[onlyLegacy])); + } + throw errors[0]; + } } } +function throwError(error) { + throw error; +} function processRootScheduleInMicrotask() { mightHavePendingSyncWork = didScheduleMicrotask = !1; for ( @@ -2285,12 +2078,12 @@ function scheduleTaskForRootDuringMicrotask(root, currentTime) { 0 < lanes; ) { - var index$8 = 31 - clz32(lanes), - lane = 1 << index$8, - expirationTime = expirationTimes[index$8]; + var index$3 = 31 - clz32(lanes), + lane = 1 << index$3, + expirationTime = expirationTimes[index$3]; if (-1 === expirationTime) { if (0 === (lane & suspendedLanes) || 0 !== (lane & pingedLanes)) - expirationTimes[index$8] = computeExpirationTime(lane, currentTime); + expirationTimes[index$3] = computeExpirationTime(lane, currentTime); } else expirationTime <= currentTime && (root.expiredLanes |= lane); lanes &= ~lane; } @@ -2333,16 +2126,16 @@ function scheduleTaskForRootDuringMicrotask(root, currentTime) { suspendedLanes = UserBlockingPriority; break; case 32: - suspendedLanes = NormalPriority$1; + suspendedLanes = NormalPriority; break; case 268435456: suspendedLanes = IdlePriority; break; default: - suspendedLanes = NormalPriority$1; + suspendedLanes = NormalPriority; } pingedLanes = performConcurrentWorkOnRoot.bind(null, root); - suspendedLanes = scheduleCallback$3(suspendedLanes, pingedLanes); + suspendedLanes = scheduleCallback$2(suspendedLanes, pingedLanes); root.callbackPriority = currentTime; root.callbackNode = suspendedLanes; return currentTime; @@ -2351,75 +2144,10 @@ function scheduleImmediateTask(cb) { supportsMicrotasks ? scheduleMicrotask(function () { 0 !== (executionContext & 6) - ? scheduleCallback$3(ImmediatePriority, cb) + ? scheduleCallback$2(ImmediatePriority, cb) : cb(); }) - : scheduleCallback$3(ImmediatePriority, cb); -} -function requestTransitionLane() { - 0 === currentEventTransitionLane && - (currentEventTransitionLane = claimNextTransitionLane()); - return currentEventTransitionLane; -} -var currentEntangledListeners = null, - currentEntangledPendingCount = 0, - currentEntangledLane = 0, - currentEntangledActionThenable = null; -function entangleAsyncAction(transition, thenable) { - if (null === currentEntangledListeners) { - var entangledListeners = (currentEntangledListeners = []); - currentEntangledPendingCount = 0; - currentEntangledLane = requestTransitionLane(); - currentEntangledActionThenable = { - status: "pending", - value: void 0, - then: function (resolve) { - entangledListeners.push(resolve); - } - }; - } - currentEntangledPendingCount++; - thenable.then(pingEngtangledActionScope, pingEngtangledActionScope); - return thenable; -} -function pingEngtangledActionScope() { - if ( - null !== currentEntangledListeners && - 0 === --currentEntangledPendingCount - ) { - null !== currentEntangledActionThenable && - (currentEntangledActionThenable.status = "fulfilled"); - var listeners = currentEntangledListeners; - currentEntangledListeners = null; - currentEntangledLane = 0; - currentEntangledActionThenable = null; - for (var i = 0; i < listeners.length; i++) (0, listeners[i])(); - } -} -function chainThenableValue(thenable, result) { - var listeners = [], - thenableWithOverride = { - status: "pending", - value: null, - reason: null, - then: function (resolve) { - listeners.push(resolve); - } - }; - thenable.then( - function () { - thenableWithOverride.status = "fulfilled"; - thenableWithOverride.value = result; - for (var i = 0; i < listeners.length; i++) (0, listeners[i])(result); - }, - function (error) { - thenableWithOverride.status = "rejected"; - thenableWithOverride.reason = error; - for (error = 0; error < listeners.length; error++) - (0, listeners[error])(void 0); - } - ); - return thenableWithOverride; + : scheduleCallback$2(ImmediatePriority, cb); } var hasForceUpdate = !1; function initializeUpdateQueue(fiber) { @@ -2516,20 +2244,12 @@ function enqueueCapturedUpdate(workInProgress, capturedUpdate) { : (workInProgress.next = capturedUpdate); queue.lastBaseUpdate = capturedUpdate; } -var didReadFromEntangledAsyncAction = !1; -function suspendIfUpdateReadFromEntangledAsyncAction() { - if (didReadFromEntangledAsyncAction) { - var entangledActionThenable = currentEntangledActionThenable; - if (null !== entangledActionThenable) throw entangledActionThenable; - } -} function processUpdateQueue( workInProgress$jscomp$0, props, instance$jscomp$0, renderLanes ) { - didReadFromEntangledAsyncAction = !1; var queue = workInProgress$jscomp$0.updateQueue; hasForceUpdate = !1; var firstBaseUpdate = queue.firstBaseUpdate, @@ -2567,9 +2287,6 @@ function processUpdateQueue( ? (workInProgressRootRenderLanes & updateLane) === updateLane : (renderLanes & updateLane) === updateLane ) { - 0 !== updateLane && - updateLane === currentEntangledLane && - (didReadFromEntangledAsyncAction = !0); null !== current && (current = current.next = { @@ -2691,6 +2408,52 @@ function shallowEqual(objA, objB) { } return !0; } +function describeComponentFrame(name, ownerName) { + var sourceInfo = ""; + ownerName && (sourceInfo = " (created by " + ownerName + ")"); + return "\n in " + (name || "Unknown") + sourceInfo; +} +function describeFunctionComponentFrame(fn) { + return fn + ? describeComponentFrame(fn.displayName || fn.name || null, null) + : ""; +} +function describeFiber(fiber) { + switch (fiber.tag) { + case 26: + case 27: + case 5: + return describeComponentFrame(fiber.type, null); + case 16: + return describeComponentFrame("Lazy", null); + case 13: + return describeComponentFrame("Suspense", null); + case 19: + return describeComponentFrame("SuspenseList", null); + case 0: + case 2: + case 15: + return describeFunctionComponentFrame(fiber.type); + case 11: + return describeFunctionComponentFrame(fiber.type.render); + case 1: + return (fiber = describeFunctionComponentFrame(fiber.type)), fiber; + default: + return ""; + } +} +function getStackByFiberInDevAndProd(workInProgress) { + try { + var info = ""; + do + (info += describeFiber(workInProgress)), + (workInProgress = workInProgress.return); + while (workInProgress); + return info; + } catch (x) { + return "\nError generating stack: " + x.message + "\n" + x.stack; + } +} var SuspenseException = Error( "Suspense Exception: This is not a real error! It's an implementation detail of `use` to interrupt the current render. You must either rethrow it immediately, or move the `use` call outside of the `try/catch` block. Capturing without rethrowing will lead to unexpected behavior.\n\nTo handle async errors, wrap your component in an error boundary, or call the promise's `.catch` method and pass the result to `use`" ), @@ -2782,15 +2545,56 @@ function unwrapThenable(thenable) { null === thenableState$1 && (thenableState$1 = []); return trackUsedThenable(thenableState$1, thenable, index); } +function convertStringRefToCallbackRef( + returnFiber, + current, + element, + mixedRef +) { + function ref(value) { + var refs = inst.refs; + null === value ? delete refs[stringRef] : (refs[stringRef] = value); + } + var stringRef = "" + mixedRef; + returnFiber = element._owner; + if (!returnFiber) + throw Error( + "Element ref was specified as a string (" + + stringRef + + ") but no owner was set. This could happen for one of the following reasons:\n1. You may be adding a ref to a function component\n2. You may be adding a ref to a component that was not created inside a component's render method\n3. You have multiple copies of React loaded\nSee https://react.dev/link/refs-must-have-owner for more information." + ); + if (1 !== returnFiber.tag) + throw Error( + "Function components cannot have string refs. We recommend using useRef() instead. Learn more about using refs safely here: https://react.dev/link/strict-mode-string-ref" + ); + var inst = returnFiber.stateNode; + if (!inst) + throw Error( + "Missing owner for string ref " + + stringRef + + ". This error is likely caused by a bug in React. Please file an issue." + ); + if ( + null !== current && + null !== current.ref && + "function" === typeof current.ref && + current.ref._stringRef === stringRef + ) + return current.ref; + ref._stringRef = stringRef; + return ref; +} function coerceRef(returnFiber, current, workInProgress, element) { - returnFiber = element.props.ref; - workInProgress.ref = void 0 !== returnFiber ? returnFiber : null; + var mixedRef = element.ref; + returnFiber = + "string" === typeof mixedRef || + "number" === typeof mixedRef || + "boolean" === typeof mixedRef + ? convertStringRefToCallbackRef(returnFiber, current, element, mixedRef) + : mixedRef; + workInProgress.ref = returnFiber; } function throwOnInvalidObjectType(returnFiber, newChild) { - if (newChild.$$typeof === REACT_LEGACY_ELEMENT_TYPE) - throw Error( - 'A React Element from an older version of React was rendered. This is not supported. It can happen if:\n- Multiple copies of the "react" package is used.\n- A library pre-bundled an old copy of "react" or "react/jsx-runtime".\n- A compiler tries to "inline" JSX instead of using the runtime.' - ); returnFiber = Object.prototype.toString.call(newChild); throw Error( "Objects are not valid as a React child (found: " + @@ -2937,8 +2741,7 @@ function createChildReconciler(shouldTrackSideEffects) { function createChild(returnFiber, newChild, lanes) { if ( ("string" === typeof newChild && "" !== newChild) || - "number" === typeof newChild || - "bigint" === typeof newChild + "number" === typeof newChild ) return ( (newChild = createFiberFromText( @@ -2977,8 +2780,7 @@ function createChildReconciler(shouldTrackSideEffects) { ); case REACT_LAZY_TYPE: var init = newChild._init; - newChild = init(newChild._payload); - return createChild(returnFiber, newChild, lanes); + return createChild(returnFiber, init(newChild._payload), lanes); } if (isArrayImpl(newChild) || getIteratorFn(newChild)) return ( @@ -3007,8 +2809,7 @@ function createChildReconciler(shouldTrackSideEffects) { var key = null !== oldFiber ? oldFiber.key : null; if ( ("string" === typeof newChild && "" !== newChild) || - "number" === typeof newChild || - "bigint" === typeof newChild + "number" === typeof newChild ) return null !== key ? null @@ -3026,8 +2827,7 @@ function createChildReconciler(shouldTrackSideEffects) { case REACT_LAZY_TYPE: return ( (key = newChild._init), - (newChild = key(newChild._payload)), - updateSlot(returnFiber, oldFiber, newChild, lanes) + updateSlot(returnFiber, oldFiber, key(newChild._payload), lanes) ); } if (isArrayImpl(newChild) || getIteratorFn(newChild)) @@ -3061,8 +2861,7 @@ function createChildReconciler(shouldTrackSideEffects) { ) { if ( ("string" === typeof newChild && "" !== newChild) || - "number" === typeof newChild || - "bigint" === typeof newChild + "number" === typeof newChild ) return ( (existingChildren = existingChildren.get(newIdx) || null), @@ -3088,12 +2887,11 @@ function createChildReconciler(shouldTrackSideEffects) { ); case REACT_LAZY_TYPE: var init = newChild._init; - newChild = init(newChild._payload); return updateFromMap( existingChildren, returnFiber, newIdx, - newChild, + init(newChild._payload), lanes ); } @@ -3216,20 +3014,25 @@ function createChildReconciler(shouldTrackSideEffects) { function reconcileChildrenIterator( returnFiber, currentFirstChild, - newChildren, + newChildrenIterable, lanes ) { - if (null == newChildren) + var iteratorFn = getIteratorFn(newChildrenIterable); + if ("function" !== typeof iteratorFn) + throw Error( + "An object is not an iterable. This error is likely caused by a bug in React. Please file an issue." + ); + newChildrenIterable = iteratorFn.call(newChildrenIterable); + if (null == newChildrenIterable) throw Error("An iterable object provided no iterator."); for ( - var resultingFirstChild = null, - previousNewFiber = null, + var previousNewFiber = (iteratorFn = null), oldFiber = currentFirstChild, newIdx = (currentFirstChild = 0), nextOldFiber = null, - step = newChildren.next(); + step = newChildrenIterable.next(); null !== oldFiber && !step.done; - newIdx++, step = newChildren.next() + newIdx++, step = newChildrenIterable.next() ) { oldFiber.index > newIdx ? ((nextOldFiber = oldFiber), (oldFiber = null)) @@ -3245,30 +3048,28 @@ function createChildReconciler(shouldTrackSideEffects) { deleteChild(returnFiber, oldFiber); currentFirstChild = placeChild(newFiber, currentFirstChild, newIdx); null === previousNewFiber - ? (resultingFirstChild = newFiber) + ? (iteratorFn = newFiber) : (previousNewFiber.sibling = newFiber); previousNewFiber = newFiber; oldFiber = nextOldFiber; } if (step.done) - return ( - deleteRemainingChildren(returnFiber, oldFiber), resultingFirstChild - ); + return deleteRemainingChildren(returnFiber, oldFiber), iteratorFn; if (null === oldFiber) { - for (; !step.done; newIdx++, step = newChildren.next()) + for (; !step.done; newIdx++, step = newChildrenIterable.next()) (step = createChild(returnFiber, step.value, lanes)), null !== step && ((currentFirstChild = placeChild(step, currentFirstChild, newIdx)), null === previousNewFiber - ? (resultingFirstChild = step) + ? (iteratorFn = step) : (previousNewFiber.sibling = step), (previousNewFiber = step)); - return resultingFirstChild; + return iteratorFn; } for ( oldFiber = mapRemainingChildren(oldFiber); !step.done; - newIdx++, step = newChildren.next() + newIdx++, step = newChildrenIterable.next() ) (step = updateFromMap(oldFiber, returnFiber, newIdx, step.value, lanes)), null !== step && @@ -3277,14 +3078,14 @@ function createChildReconciler(shouldTrackSideEffects) { oldFiber.delete(null === step.key ? newIdx : step.key), (currentFirstChild = placeChild(step, currentFirstChild, newIdx)), null === previousNewFiber - ? (resultingFirstChild = step) + ? (iteratorFn = step) : (previousNewFiber.sibling = step), (previousNewFiber = step)); shouldTrackSideEffects && oldFiber.forEach(function (child) { return deleteChild(returnFiber, child); }); - return resultingFirstChild; + return iteratorFn; } function reconcileChildFibersImpl( returnFiber, @@ -3401,11 +3202,10 @@ function createChildReconciler(shouldTrackSideEffects) { case REACT_LAZY_TYPE: return ( (child = newChild._init), - (newChild = child(newChild._payload)), reconcileChildFibersImpl( returnFiber, currentFirstChild, - newChild, + child(newChild._payload), lanes ) ); @@ -3417,20 +3217,13 @@ function createChildReconciler(shouldTrackSideEffects) { newChild, lanes ); - if (getIteratorFn(newChild)) { - child = getIteratorFn(newChild); - if ("function" !== typeof child) - throw Error( - "An object is not an iterable. This error is likely caused by a bug in React. Please file an issue." - ); - newChild = child.call(newChild); + if (getIteratorFn(newChild)) return reconcileChildrenIterator( returnFiber, currentFirstChild, newChild, lanes ); - } if ("function" === typeof newChild.then) return reconcileChildFibersImpl( returnFiber, @@ -3448,8 +3241,7 @@ function createChildReconciler(shouldTrackSideEffects) { throwOnInvalidObjectType(returnFiber, newChild); } return ("string" === typeof newChild && "" !== newChild) || - "number" === typeof newChild || - "bigint" === typeof newChild + "number" === typeof newChild ? ((newChild = "" + newChild), null !== currentFirstChild && 6 === currentFirstChild.tag ? (deleteRemainingChildren(returnFiber, currentFirstChild.sibling), @@ -3468,31 +3260,15 @@ function createChildReconciler(shouldTrackSideEffects) { : deleteRemainingChildren(returnFiber, currentFirstChild); } return function (returnFiber, currentFirstChild, newChild, lanes) { - try { - thenableIndexCounter$1 = 0; - var firstChildFiber = reconcileChildFibersImpl( - returnFiber, - currentFirstChild, - newChild, - lanes - ); - thenableState$1 = null; - return firstChildFiber; - } catch (x) { - if ( - x === SuspenseException || - (0 === (returnFiber.mode & 1) && - "object" === typeof x && - null !== x && - "function" === typeof x.then) - ) - throw x; - var fiber = createFiber(29, x, null, returnFiber.mode); - fiber.lanes = lanes; - fiber.return = returnFiber; - return fiber; - } finally { - } + thenableIndexCounter$1 = 0; + returnFiber = reconcileChildFibersImpl( + returnFiber, + currentFirstChild, + newChild, + lanes + ); + thenableState$1 = null; + return returnFiber; }; } var reconcileChildFibers = createChildReconciler(!0), @@ -3572,7 +3348,9 @@ function findFirstSuspended(row) { } return null; } -var renderLanes = 0, +var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, + ReactCurrentBatchConfig$2 = ReactSharedInternals.ReactCurrentBatchConfig, + renderLanes = 0, currentlyRenderingFiber$1 = null, currentHook = null, workInProgressHook = null, @@ -3606,7 +3384,7 @@ function renderWithHooks( workInProgress.memoizedState = null; workInProgress.updateQueue = null; workInProgress.lanes = 0; - ReactSharedInternals.H = + ReactCurrentDispatcher$1.current = null === current || null === current.memoizedState ? HooksDispatcherOnMount : HooksDispatcherOnUpdate; @@ -3624,7 +3402,7 @@ function renderWithHooks( return current; } function finishRenderingHooks() { - ReactSharedInternals.H = ContextOnlyDispatcher; + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; var didRenderTooFewHooks = null !== currentHook && null !== currentHook.next; renderLanes = 0; workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; @@ -3650,23 +3428,11 @@ function renderWithHooksAgain(workInProgress, Component, props, secondArg) { numberOfReRenders += 1; workInProgressHook = currentHook = null; workInProgress.updateQueue = null; - ReactSharedInternals.H = HooksDispatcherOnRerender; + ReactCurrentDispatcher$1.current = HooksDispatcherOnRerender; var children = Component(props, secondArg); } while (didScheduleRenderPhaseUpdateDuringThisPass); return children; } -function TransitionAwareHostComponent() { - var dispatcher = ReactSharedInternals.H, - maybeThenable = dispatcher.useState()[0]; - maybeThenable = - "function" === typeof maybeThenable.then - ? useThenable(maybeThenable) - : maybeThenable; - dispatcher = dispatcher.useState()[0]; - (null !== currentHook ? currentHook.memoizedState : null) !== dispatcher && - (currentlyRenderingFiber$1.flags |= 1024); - return maybeThenable; -} function bailoutHooks(current, workInProgress, lanes) { workInProgress.updateQueue = current.updateQueue; workInProgress.flags &= -2053; @@ -3742,23 +3508,18 @@ function updateWorkInProgressHook() { } var createFunctionComponentUpdateQueue; createFunctionComponentUpdateQueue = function () { - return { lastEffect: null, events: null, stores: null, memoCache: null }; + return { lastEffect: null, events: null, stores: null }; }; function useThenable(thenable) { var index = thenableIndexCounter; thenableIndexCounter += 1; null === thenableState && (thenableState = []); thenable = trackUsedThenable(thenableState, thenable, index); - index = currentlyRenderingFiber$1; - null === + null === currentlyRenderingFiber$1.alternate && (null === workInProgressHook - ? index.memoizedState - : workInProgressHook.next) && - ((index = index.alternate), - (ReactSharedInternals.H = - null === index || null === index.memoizedState - ? HooksDispatcherOnMount - : HooksDispatcherOnUpdate)); + ? null === currentlyRenderingFiber$1.memoizedState + : null === workInProgressHook.next) && + (ReactCurrentDispatcher$1.current = HooksDispatcherOnMount); return thenable; } function use(usable) { @@ -3768,52 +3529,16 @@ function use(usable) { } throw Error("An unsupported type was passed to use(): " + String(usable)); } -function useMemoCache(size) { - var memoCache = null, - updateQueue = currentlyRenderingFiber$1.updateQueue; - null !== updateQueue && (memoCache = updateQueue.memoCache); - if (null == memoCache) { - var current = currentlyRenderingFiber$1.alternate; - null !== current && - ((current = current.updateQueue), - null !== current && - ((current = current.memoCache), - null != current && - (memoCache = { - data: current.data.map(function (array) { - return array.slice(); - }), - index: 0 - }))); - } - null == memoCache && (memoCache = { data: [], index: 0 }); - null === updateQueue && - ((updateQueue = createFunctionComponentUpdateQueue()), - (currentlyRenderingFiber$1.updateQueue = updateQueue)); - updateQueue.memoCache = memoCache; - updateQueue = memoCache.data[memoCache.index]; - if (void 0 === updateQueue) - for ( - updateQueue = memoCache.data[memoCache.index] = Array(size), current = 0; - current < size; - current++ - ) - updateQueue[current] = REACT_MEMO_CACHE_SENTINEL; - memoCache.index++; - return updateQueue; -} function basicStateReducer(state, action) { return "function" === typeof action ? action(state) : action; } function updateReducer(reducer) { - var hook = updateWorkInProgressHook(); - return updateReducerImpl(hook, currentHook, reducer); -} -function updateReducerImpl(hook, current, reducer) { - var queue = hook.queue; + var hook = updateWorkInProgressHook(), + current = currentHook, + queue = hook.queue; if (null === queue) throw Error( - "Should have a queue. You are likely calling Hooks conditionally, which is not allowed. (https://react.dev/link/invalid-hook-call)" + "Should have a queue. This is likely a bug in React. Please file an issue." ); queue.lastRenderedReducer = reducer; var baseQueue = hook.baseQueue, @@ -3833,82 +3558,52 @@ function updateReducerImpl(hook, current, reducer) { current = baseQueue.next; var newBaseQueueFirst = (baseFirst = null), newBaseQueueLast = null, - update = current, - didReadFromEntangledAsyncAction$46 = !1; + update = current; do { var updateLane = update.lane & -536870913; if ( updateLane !== update.lane ? (workInProgressRootRenderLanes & updateLane) === updateLane : (renderLanes & updateLane) === updateLane - ) { - var revertLane = update.revertLane; - if (0 === revertLane) - null !== newBaseQueueLast && - (newBaseQueueLast = newBaseQueueLast.next = - { - lane: 0, - revertLane: 0, - action: update.action, - hasEagerState: update.hasEagerState, - eagerState: update.eagerState, - next: null - }), - updateLane === currentEntangledLane && - (didReadFromEntangledAsyncAction$46 = !0); - else if ((renderLanes & revertLane) === revertLane) { - update = update.next; - revertLane === currentEntangledLane && - (didReadFromEntangledAsyncAction$46 = !0); - continue; - } else - (updateLane = { - lane: 0, - revertLane: update.revertLane, - action: update.action, - hasEagerState: update.hasEagerState, - eagerState: update.eagerState, - next: null - }), - null === newBaseQueueLast - ? ((newBaseQueueFirst = newBaseQueueLast = updateLane), - (baseFirst = pendingQueue)) - : (newBaseQueueLast = newBaseQueueLast.next = updateLane), - (currentlyRenderingFiber$1.lanes |= revertLane), - (workInProgressRootSkippedLanes |= revertLane); - updateLane = update.action; - shouldDoubleInvokeUserFnsInHooksDEV && - reducer(pendingQueue, updateLane); - pendingQueue = update.hasEagerState - ? update.eagerState - : reducer(pendingQueue, updateLane); - } else - (revertLane = { + ) + null !== newBaseQueueLast && + (newBaseQueueLast = newBaseQueueLast.next = + { + lane: 0, + revertLane: 0, + action: update.action, + hasEagerState: update.hasEagerState, + eagerState: update.eagerState, + next: null + }), + (updateLane = update.action), + shouldDoubleInvokeUserFnsInHooksDEV && + reducer(pendingQueue, updateLane), + (pendingQueue = update.hasEagerState + ? update.eagerState + : reducer(pendingQueue, updateLane)); + else { + var clone = { lane: updateLane, revertLane: update.revertLane, action: update.action, hasEagerState: update.hasEagerState, eagerState: update.eagerState, next: null - }), - null === newBaseQueueLast - ? ((newBaseQueueFirst = newBaseQueueLast = revertLane), - (baseFirst = pendingQueue)) - : (newBaseQueueLast = newBaseQueueLast.next = revertLane), - (currentlyRenderingFiber$1.lanes |= updateLane), - (workInProgressRootSkippedLanes |= updateLane); + }; + null === newBaseQueueLast + ? ((newBaseQueueFirst = newBaseQueueLast = clone), + (baseFirst = pendingQueue)) + : (newBaseQueueLast = newBaseQueueLast.next = clone); + currentlyRenderingFiber$1.lanes |= updateLane; + workInProgressRootSkippedLanes |= updateLane; + } update = update.next; } while (null !== update && update !== current); null === newBaseQueueLast ? (baseFirst = pendingQueue) : (newBaseQueueLast.next = newBaseQueueFirst); - if ( - !objectIs(pendingQueue, hook.memoizedState) && - ((didReceiveUpdate = !0), - didReadFromEntangledAsyncAction$46 && - ((reducer = currentEntangledActionThenable), null !== reducer)) - ) - throw reducer; + objectIs(pendingQueue, hook.memoizedState) || (didReceiveUpdate = !0); hook.memoizedState = pendingQueue; hook.baseState = baseFirst; hook.baseQueue = newBaseQueueLast; @@ -3922,7 +3617,7 @@ function rerenderReducer(reducer) { queue = hook.queue; if (null === queue) throw Error( - "Should have a queue. You are likely calling Hooks conditionally, which is not allowed. (https://react.dev/link/invalid-hook-call)" + "Should have a queue. This is likely a bug in React. Please file an issue." ); queue.lastRenderedReducer = reducer; var dispatch = queue.dispatch, @@ -4017,10 +3712,7 @@ function mountStateImpl(initialState) { if ("function" === typeof initialState) { var initialStateInitializer = initialState; initialState = initialStateInitializer(); - shouldDoubleInvokeUserFnsInHooksDEV && - (setIsStrictModeForDevtools(!0), - initialStateInitializer(), - setIsStrictModeForDevtools(!1)); + shouldDoubleInvokeUserFnsInHooksDEV && initialStateInitializer(); } hook.memoizedState = hook.baseState = initialState; hook.queue = { @@ -4032,214 +3724,6 @@ function mountStateImpl(initialState) { }; return hook; } -function updateOptimisticImpl(hook, current, passthrough, reducer) { - hook.baseState = passthrough; - return updateReducerImpl( - hook, - currentHook, - "function" === typeof reducer ? reducer : basicStateReducer - ); -} -function dispatchActionState( - fiber, - actionQueue, - setPendingState, - setState, - payload -) { - if (isRenderPhaseUpdate(fiber)) - throw Error("Cannot update form state while rendering."); - fiber = actionQueue.action; - if (null !== fiber) { - var actionNode = { - payload: payload, - action: fiber, - next: null, - isTransition: !0, - status: "pending", - value: null, - reason: null, - listeners: [], - then: function (listener) { - actionNode.listeners.push(listener); - } - }; - null !== ReactSharedInternals.T - ? setPendingState(!0) - : (actionNode.isTransition = !1); - setState(actionNode); - setPendingState = actionQueue.pending; - null === setPendingState - ? ((actionNode.next = actionQueue.pending = actionNode), - runActionStateAction(actionQueue, actionNode)) - : ((actionNode.next = setPendingState.next), - (actionQueue.pending = setPendingState.next = actionNode)); - } -} -function runActionStateAction(actionQueue, node) { - var action = node.action, - payload = node.payload, - prevState = actionQueue.state; - if (node.isTransition) { - var prevTransition = ReactSharedInternals.T, - currentTransition = {}; - ReactSharedInternals.T = currentTransition; - try { - var returnValue = action(prevState, payload), - onStartTransitionFinish = ReactSharedInternals.S; - null !== onStartTransitionFinish && - onStartTransitionFinish(currentTransition, returnValue); - handleActionReturnValue(actionQueue, node, returnValue); - } catch (error) { - onActionError(actionQueue, node, error); - } finally { - ReactSharedInternals.T = prevTransition; - } - } else - try { - (prevTransition = action(prevState, payload)), - handleActionReturnValue(actionQueue, node, prevTransition); - } catch (error$50) { - onActionError(actionQueue, node, error$50); - } -} -function handleActionReturnValue(actionQueue, node, returnValue) { - null !== returnValue && - "object" === typeof returnValue && - "function" === typeof returnValue.then - ? returnValue.then( - function (nextState) { - onActionSuccess(actionQueue, node, nextState); - }, - function (error) { - return onActionError(actionQueue, node, error); - } - ) - : onActionSuccess(actionQueue, node, returnValue); -} -function onActionSuccess(actionQueue, actionNode, nextState) { - actionNode.status = "fulfilled"; - actionNode.value = nextState; - notifyActionListeners(actionNode); - actionQueue.state = nextState; - actionNode = actionQueue.pending; - null !== actionNode && - ((nextState = actionNode.next), - nextState === actionNode - ? (actionQueue.pending = null) - : ((nextState = nextState.next), - (actionNode.next = nextState), - runActionStateAction(actionQueue, nextState))); -} -function onActionError(actionQueue, actionNode, error) { - var last = actionQueue.pending; - actionQueue.pending = null; - if (null !== last) { - last = last.next; - do - (actionNode.status = "rejected"), - (actionNode.reason = error), - notifyActionListeners(actionNode), - (actionNode = actionNode.next); - while (actionNode !== last); - } - actionQueue.action = null; -} -function notifyActionListeners(actionNode) { - actionNode = actionNode.listeners; - for (var i = 0; i < actionNode.length; i++) (0, actionNode[i])(); -} -function actionStateReducer(oldState, newState) { - return newState; -} -function mountActionState(action, initialStateProp) { - var stateHook = mountWorkInProgressHook(); - stateHook.memoizedState = stateHook.baseState = initialStateProp; - var stateQueue = { - pending: null, - lanes: 0, - dispatch: null, - lastRenderedReducer: actionStateReducer, - lastRenderedState: initialStateProp - }; - stateHook.queue = stateQueue; - stateHook = dispatchSetState.bind( - null, - currentlyRenderingFiber$1, - stateQueue - ); - stateQueue.dispatch = stateHook; - stateQueue = mountStateImpl(!1); - var setPendingState = dispatchOptimisticSetState.bind( - null, - currentlyRenderingFiber$1, - !1, - stateQueue.queue - ); - stateQueue = mountWorkInProgressHook(); - var actionQueue = { - state: initialStateProp, - dispatch: null, - action: action, - pending: null - }; - stateQueue.queue = actionQueue; - stateHook = dispatchActionState.bind( - null, - currentlyRenderingFiber$1, - actionQueue, - setPendingState, - stateHook - ); - actionQueue.dispatch = stateHook; - stateQueue.memoizedState = action; - return [initialStateProp, stateHook, !1]; -} -function updateActionState(action) { - var stateHook = updateWorkInProgressHook(); - return updateActionStateImpl(stateHook, currentHook, action); -} -function updateActionStateImpl(stateHook, currentStateHook, action) { - currentStateHook = updateReducerImpl( - stateHook, - currentStateHook, - actionStateReducer - )[0]; - stateHook = updateReducer(basicStateReducer)[0]; - currentStateHook = - "object" === typeof currentStateHook && - null !== currentStateHook && - "function" === typeof currentStateHook.then - ? useThenable(currentStateHook) - : currentStateHook; - var actionQueueHook = updateWorkInProgressHook(), - actionQueue = actionQueueHook.queue, - dispatch = actionQueue.dispatch; - action !== actionQueueHook.memoizedState && - ((currentlyRenderingFiber$1.flags |= 2048), - pushEffect( - 9, - actionStateActionEffect.bind(null, actionQueue, action), - { destroy: void 0 }, - null - )); - return [currentStateHook, dispatch, stateHook]; -} -function actionStateActionEffect(actionQueue, action) { - actionQueue.action = action; -} -function rerenderActionState(action) { - var stateHook = updateWorkInProgressHook(), - currentStateHook = currentHook; - if (null !== currentStateHook) - return updateActionStateImpl(stateHook, currentStateHook, action); - updateWorkInProgressHook(); - stateHook = stateHook.memoizedState; - currentStateHook = updateWorkInProgressHook(); - var dispatch = currentStateHook.queue.dispatch; - currentStateHook.memoizedState = action; - return [stateHook, dispatch, !1]; -} function pushEffect(tag, create, inst, deps) { tag = { tag: tag, create: create, inst: inst, deps: deps, next: null }; create = currentlyRenderingFiber$1.updateQueue; @@ -4293,13 +3777,14 @@ function updateLayoutEffect(create, deps) { return updateEffectImpl(4, 4, create, deps); } function imperativeHandleEffect(create, ref) { - if ("function" === typeof ref) { - create = create(); - var refCleanup = ref(create); - return function () { - "function" === typeof refCleanup ? refCleanup() : ref(null); - }; - } + if ("function" === typeof ref) + return ( + (create = create()), + ref(create), + function () { + ref(null); + } + ); if (null !== ref && void 0 !== ref) return ( (create = create()), @@ -4330,33 +3815,28 @@ function updateMemo(nextCreate, deps) { if (null !== deps && areHookInputsEqual(deps, prevState[1])) return prevState[0]; prevState = nextCreate(); - shouldDoubleInvokeUserFnsInHooksDEV && - (setIsStrictModeForDevtools(!0), - nextCreate(), - setIsStrictModeForDevtools(!1)); + shouldDoubleInvokeUserFnsInHooksDEV && nextCreate(); hook.memoizedState = [prevState, deps]; return prevState; } -function mountDeferredValueImpl(hook, value, initialValue) { - if (void 0 === initialValue || 0 !== (renderLanes & 1073741824)) - return (hook.memoizedState = value); - hook.memoizedState = initialValue; - hook = requestDeferredLane(); - currentlyRenderingFiber$1.lanes |= hook; - workInProgressRootSkippedLanes |= hook; - return initialValue; -} -function updateDeferredValueImpl(hook, prevValue, value, initialValue) { +function updateDeferredValueImpl(hook, prevValue, value) { if (objectIs(value, prevValue)) return value; if (null !== currentTreeHiddenStackCursor.current) return ( - (hook = mountDeferredValueImpl(hook, value, initialValue)), - objectIs(hook, prevValue) || (didReceiveUpdate = !0), - hook + (hook.memoizedState = value), + objectIs(value, prevValue) || (didReceiveUpdate = !0), + value ); if (0 === (renderLanes & 42)) return (didReceiveUpdate = !0), (hook.memoizedState = value); - hook = requestDeferredLane(); + 0 === workInProgressDeferredLane && + (workInProgressDeferredLane = + 0 !== (workInProgressRootRenderLanes & 536870912) + ? 536870912 + : claimNextTransitionLane()); + hook = suspenseHandlerStackCursor.current; + null !== hook && (hook.flags |= 32); + hook = workInProgressDeferredLane; currentlyRenderingFiber$1.lanes |= hook; workInProgressRootSkippedLanes |= hook; return prevValue; @@ -4365,65 +3845,23 @@ function startTransition(fiber, queue, pendingState, finishedState, callback) { var previousPriority = currentUpdatePriority; currentUpdatePriority = 0 !== previousPriority && 8 > previousPriority ? previousPriority : 8; - var prevTransition = ReactSharedInternals.T, - currentTransition = {}; - ReactSharedInternals.T = currentTransition; - dispatchOptimisticSetState(fiber, !1, queue, pendingState); + var prevTransition = ReactCurrentBatchConfig$2.transition, + currentTransition = { _callbacks: new Set() }; + ReactCurrentBatchConfig$2.transition = null; + dispatchSetState(fiber, queue, pendingState); + ReactCurrentBatchConfig$2.transition = currentTransition; try { - var returnValue = callback(), - onStartTransitionFinish = ReactSharedInternals.S; - null !== onStartTransitionFinish && - onStartTransitionFinish(currentTransition, returnValue); - if ( - null !== returnValue && - "object" === typeof returnValue && - "function" === typeof returnValue.then - ) { - var thenableForFinishedState = chainThenableValue( - returnValue, - finishedState - ); - dispatchSetState(fiber, queue, thenableForFinishedState); - } else dispatchSetState(fiber, queue, finishedState); + dispatchSetState(fiber, queue, finishedState), callback(); } catch (error) { - dispatchSetState(fiber, queue, { - then: function () {}, - status: "rejected", - reason: error - }); + throw error; } finally { (currentUpdatePriority = previousPriority), - (ReactSharedInternals.T = prevTransition); + (ReactCurrentBatchConfig$2.transition = prevTransition); } } -function useHostTransitionStatus() { - var status = readContext(HostTransitionContext); - return null !== status ? status : null; -} function updateId() { return updateWorkInProgressHook().memoizedState; } -function updateRefresh() { - return updateWorkInProgressHook().memoizedState; -} -function refreshCache(fiber) { - for (var provider = fiber.return; null !== provider; ) { - switch (provider.tag) { - case 24: - case 3: - var lane = requestUpdateLane(provider); - fiber = createUpdate(lane); - var root = enqueueUpdate(provider, fiber, lane); - null !== root && - (scheduleUpdateOnFiber(root, provider, lane), - entangleTransitions(root, provider, lane)); - provider = { cache: createCache() }; - fiber.payload = provider; - return; - } - provider = provider.return; - } -} function dispatchReducerAction(fiber, queue, action) { var lane = requestUpdateLane(fiber); action = { @@ -4436,11 +3874,11 @@ function dispatchReducerAction(fiber, queue, action) { }; isRenderPhaseUpdate(fiber) ? enqueueRenderPhaseUpdate(queue, action) - : ((action = enqueueConcurrentHookUpdate(fiber, queue, action, lane)), + : (enqueueUpdate$1(fiber, queue, action, lane), + (action = getRootForUpdatedFiber(fiber)), null !== action && (scheduleUpdateOnFiber(action, fiber, lane), entangleTransitionUpdate(action, queue, lane))); - markStateUpdateScheduled(fiber, lane); } function dispatchSetState(fiber, queue, action) { var lane = requestUpdateLane(fiber), @@ -4473,35 +3911,12 @@ function dispatchSetState(fiber, queue, action) { } catch (error) { } finally { } - action = enqueueConcurrentHookUpdate(fiber, queue, update, lane); + enqueueUpdate$1(fiber, queue, update, lane); + action = getRootForUpdatedFiber(fiber); null !== action && (scheduleUpdateOnFiber(action, fiber, lane), entangleTransitionUpdate(action, queue, lane)); } - markStateUpdateScheduled(fiber, lane); -} -function dispatchOptimisticSetState(fiber, throwIfDuringRender, queue, action) { - action = { - lane: 2, - revertLane: requestTransitionLane(), - action: action, - hasEagerState: !1, - eagerState: null, - next: null - }; - if (isRenderPhaseUpdate(fiber)) { - if (throwIfDuringRender) - throw Error("Cannot update optimistic state while rendering."); - } else - (throwIfDuringRender = enqueueConcurrentHookUpdate( - fiber, - queue, - action, - 2 - )), - null !== throwIfDuringRender && - scheduleUpdateOnFiber(throwIfDuringRender, fiber, 2); - markStateUpdateScheduled(fiber, 2); } function isRenderPhaseUpdate(fiber) { var alternate = fiber.alternate; @@ -4529,286 +3944,217 @@ function entangleTransitionUpdate(root, queue, lane) { } } var ContextOnlyDispatcher = { - readContext: readContext, - use: use, - useCallback: throwInvalidHookError, - useContext: throwInvalidHookError, - useEffect: throwInvalidHookError, - useImperativeHandle: throwInvalidHookError, - useLayoutEffect: throwInvalidHookError, - useInsertionEffect: throwInvalidHookError, - useMemo: throwInvalidHookError, - useReducer: throwInvalidHookError, - useRef: throwInvalidHookError, - useState: throwInvalidHookError, - useDebugValue: throwInvalidHookError, - useDeferredValue: throwInvalidHookError, - useTransition: throwInvalidHookError, - useSyncExternalStore: throwInvalidHookError, - useId: throwInvalidHookError -}; -ContextOnlyDispatcher.useCacheRefresh = throwInvalidHookError; -ContextOnlyDispatcher.useMemoCache = throwInvalidHookError; -ContextOnlyDispatcher.useHostTransitionStatus = throwInvalidHookError; -ContextOnlyDispatcher.useFormState = throwInvalidHookError; -ContextOnlyDispatcher.useActionState = throwInvalidHookError; -ContextOnlyDispatcher.useOptimistic = throwInvalidHookError; -var HooksDispatcherOnMount = { - readContext: readContext, - use: use, - useCallback: function (callback, deps) { - mountWorkInProgressHook().memoizedState = [ - callback, - void 0 === deps ? null : deps - ]; - return callback; - }, - useContext: readContext, - useEffect: mountEffect, - useImperativeHandle: function (ref, create, deps) { - deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; - mountEffectImpl( - 4194308, - 4, - imperativeHandleEffect.bind(null, create, ref), - deps - ); - }, - useLayoutEffect: function (create, deps) { - return mountEffectImpl(4194308, 4, create, deps); - }, - useInsertionEffect: function (create, deps) { - mountEffectImpl(4, 2, create, deps); - }, - useMemo: function (nextCreate, deps) { - var hook = mountWorkInProgressHook(); - deps = void 0 === deps ? null : deps; - var nextValue = nextCreate(); - shouldDoubleInvokeUserFnsInHooksDEV && - (setIsStrictModeForDevtools(!0), - nextCreate(), - setIsStrictModeForDevtools(!1)); - hook.memoizedState = [nextValue, deps]; - return nextValue; - }, - useReducer: function (reducer, initialArg, init) { - var hook = mountWorkInProgressHook(); - if (void 0 !== init) { - var initialState = init(initialArg); - shouldDoubleInvokeUserFnsInHooksDEV && - (setIsStrictModeForDevtools(!0), - init(initialArg), - setIsStrictModeForDevtools(!1)); - } else initialState = initialArg; - hook.memoizedState = hook.baseState = initialState; - reducer = { - pending: null, - lanes: 0, - dispatch: null, - lastRenderedReducer: reducer, - lastRenderedState: initialState - }; - hook.queue = reducer; - reducer = reducer.dispatch = dispatchReducerAction.bind( - null, - currentlyRenderingFiber$1, - reducer - ); - return [hook.memoizedState, reducer]; - }, - useRef: function (initialValue) { - var hook = mountWorkInProgressHook(); - initialValue = { current: initialValue }; - return (hook.memoizedState = initialValue); - }, - useState: function (initialState) { - initialState = mountStateImpl(initialState); - var queue = initialState.queue, - dispatch = dispatchSetState.bind(null, currentlyRenderingFiber$1, queue); - queue.dispatch = dispatch; - return [initialState.memoizedState, dispatch]; - }, - useDebugValue: mountDebugValue, - useDeferredValue: function (value, initialValue) { - var hook = mountWorkInProgressHook(); - return mountDeferredValueImpl(hook, value, initialValue); - }, - useTransition: function () { - var stateHook = mountStateImpl(!1); - stateHook = startTransition.bind( - null, - currentlyRenderingFiber$1, - stateHook.queue, - !0, - !1 - ); - mountWorkInProgressHook().memoizedState = stateHook; - return [!1, stateHook]; + readContext: readContext, + use: use, + useCallback: throwInvalidHookError, + useContext: throwInvalidHookError, + useEffect: throwInvalidHookError, + useImperativeHandle: throwInvalidHookError, + useInsertionEffect: throwInvalidHookError, + useLayoutEffect: throwInvalidHookError, + useMemo: throwInvalidHookError, + useReducer: throwInvalidHookError, + useRef: throwInvalidHookError, + useState: throwInvalidHookError, + useDebugValue: throwInvalidHookError, + useDeferredValue: throwInvalidHookError, + useTransition: throwInvalidHookError, + useSyncExternalStore: throwInvalidHookError, + useId: throwInvalidHookError }, - useSyncExternalStore: function (subscribe, getSnapshot) { - var fiber = currentlyRenderingFiber$1, - hook = mountWorkInProgressHook(); - var nextSnapshot = getSnapshot(); - if (null === workInProgressRoot) - throw Error( - "Expected a work-in-progress root. This is a bug in React. Please file an issue." + HooksDispatcherOnMount = { + readContext: readContext, + use: use, + useCallback: function (callback, deps) { + mountWorkInProgressHook().memoizedState = [ + callback, + void 0 === deps ? null : deps + ]; + return callback; + }, + useContext: readContext, + useEffect: mountEffect, + useImperativeHandle: function (ref, create, deps) { + deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; + mountEffectImpl( + 4194308, + 4, + imperativeHandleEffect.bind(null, create, ref), + deps ); - 0 !== (workInProgressRootRenderLanes & 60) || - pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot); - hook.memoizedState = nextSnapshot; - var inst = { value: nextSnapshot, getSnapshot: getSnapshot }; - hook.queue = inst; - mountEffect(subscribeToStore.bind(null, fiber, inst, subscribe), [ - subscribe - ]); - fiber.flags |= 2048; - pushEffect( - 9, - updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot), - { destroy: void 0 }, - null - ); - return nextSnapshot; - }, - useId: function () { - var hook = mountWorkInProgressHook(), - identifierPrefix = workInProgressRoot.identifierPrefix, - globalClientId = globalClientIdCounter++; - identifierPrefix = - ":" + identifierPrefix + "r" + globalClientId.toString(32) + ":"; - return (hook.memoizedState = identifierPrefix); - }, - useCacheRefresh: function () { - return (mountWorkInProgressHook().memoizedState = refreshCache.bind( - null, - currentlyRenderingFiber$1 - )); - } -}; -HooksDispatcherOnMount.useMemoCache = useMemoCache; -HooksDispatcherOnMount.useHostTransitionStatus = useHostTransitionStatus; -HooksDispatcherOnMount.useFormState = mountActionState; -HooksDispatcherOnMount.useActionState = mountActionState; -HooksDispatcherOnMount.useOptimistic = function (passthrough) { - var hook = mountWorkInProgressHook(); - hook.memoizedState = hook.baseState = passthrough; - var queue = { - pending: null, - lanes: 0, - dispatch: null, - lastRenderedReducer: null, - lastRenderedState: null - }; - hook.queue = queue; - hook = dispatchOptimisticSetState.bind( - null, - currentlyRenderingFiber$1, - !0, - queue - ); - queue.dispatch = hook; - return [passthrough, hook]; -}; -var HooksDispatcherOnUpdate = { - readContext: readContext, - use: use, - useCallback: updateCallback, - useContext: readContext, - useEffect: updateEffect, - useImperativeHandle: updateImperativeHandle, - useInsertionEffect: updateInsertionEffect, - useLayoutEffect: updateLayoutEffect, - useMemo: updateMemo, - useReducer: updateReducer, - useRef: updateRef, - useState: function () { - return updateReducer(basicStateReducer); - }, - useDebugValue: mountDebugValue, - useDeferredValue: function (value, initialValue) { - var hook = updateWorkInProgressHook(); - return updateDeferredValueImpl( - hook, - currentHook.memoizedState, - value, - initialValue - ); - }, - useTransition: function () { - var booleanOrThenable = updateReducer(basicStateReducer)[0], - start = updateWorkInProgressHook().memoizedState; - return [ - "boolean" === typeof booleanOrThenable - ? booleanOrThenable - : useThenable(booleanOrThenable), - start - ]; - }, - useSyncExternalStore: updateSyncExternalStore, - useId: updateId -}; -HooksDispatcherOnUpdate.useCacheRefresh = updateRefresh; -HooksDispatcherOnUpdate.useMemoCache = useMemoCache; -HooksDispatcherOnUpdate.useHostTransitionStatus = useHostTransitionStatus; -HooksDispatcherOnUpdate.useFormState = updateActionState; -HooksDispatcherOnUpdate.useActionState = updateActionState; -HooksDispatcherOnUpdate.useOptimistic = function (passthrough, reducer) { - var hook = updateWorkInProgressHook(); - return updateOptimisticImpl(hook, currentHook, passthrough, reducer); -}; -var HooksDispatcherOnRerender = { - readContext: readContext, - use: use, - useCallback: updateCallback, - useContext: readContext, - useEffect: updateEffect, - useImperativeHandle: updateImperativeHandle, - useInsertionEffect: updateInsertionEffect, - useLayoutEffect: updateLayoutEffect, - useMemo: updateMemo, - useReducer: rerenderReducer, - useRef: updateRef, - useState: function () { - return rerenderReducer(basicStateReducer); - }, - useDebugValue: mountDebugValue, - useDeferredValue: function (value, initialValue) { - var hook = updateWorkInProgressHook(); - return null === currentHook - ? mountDeferredValueImpl(hook, value, initialValue) - : updateDeferredValueImpl( - hook, - currentHook.memoizedState, - value, - initialValue + }, + useLayoutEffect: function (create, deps) { + return mountEffectImpl(4194308, 4, create, deps); + }, + useInsertionEffect: function (create, deps) { + mountEffectImpl(4, 2, create, deps); + }, + useMemo: function (nextCreate, deps) { + var hook = mountWorkInProgressHook(); + deps = void 0 === deps ? null : deps; + var nextValue = nextCreate(); + shouldDoubleInvokeUserFnsInHooksDEV && nextCreate(); + hook.memoizedState = [nextValue, deps]; + return nextValue; + }, + useReducer: function (reducer, initialArg, init) { + var hook = mountWorkInProgressHook(); + if (void 0 !== init) { + var initialState = init(initialArg); + shouldDoubleInvokeUserFnsInHooksDEV && init(initialArg); + } else initialState = initialArg; + hook.memoizedState = hook.baseState = initialState; + reducer = { + pending: null, + lanes: 0, + dispatch: null, + lastRenderedReducer: reducer, + lastRenderedState: initialState + }; + hook.queue = reducer; + reducer = reducer.dispatch = dispatchReducerAction.bind( + null, + currentlyRenderingFiber$1, + reducer + ); + return [hook.memoizedState, reducer]; + }, + useRef: function (initialValue) { + var hook = mountWorkInProgressHook(); + initialValue = { current: initialValue }; + return (hook.memoizedState = initialValue); + }, + useState: function (initialState) { + initialState = mountStateImpl(initialState); + var queue = initialState.queue, + dispatch = dispatchSetState.bind( + null, + currentlyRenderingFiber$1, + queue + ); + queue.dispatch = dispatch; + return [initialState.memoizedState, dispatch]; + }, + useDebugValue: mountDebugValue, + useDeferredValue: function (value) { + mountWorkInProgressHook().memoizedState = value; + return value; + }, + useTransition: function () { + var stateHook = mountStateImpl(!1); + stateHook = startTransition.bind( + null, + currentlyRenderingFiber$1, + stateHook.queue, + !0, + !1 + ); + mountWorkInProgressHook().memoizedState = stateHook; + return [!1, stateHook]; + }, + useSyncExternalStore: function (subscribe, getSnapshot) { + var fiber = currentlyRenderingFiber$1, + hook = mountWorkInProgressHook(); + var nextSnapshot = getSnapshot(); + if (null === workInProgressRoot) + throw Error( + "Expected a work-in-progress root. This is a bug in React. Please file an issue." ); + 0 !== (workInProgressRootRenderLanes & 60) || + pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot); + hook.memoizedState = nextSnapshot; + var inst = { value: nextSnapshot, getSnapshot: getSnapshot }; + hook.queue = inst; + mountEffect(subscribeToStore.bind(null, fiber, inst, subscribe), [ + subscribe + ]); + fiber.flags |= 2048; + pushEffect( + 9, + updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot), + { destroy: void 0 }, + null + ); + return nextSnapshot; + }, + useId: function () { + var hook = mountWorkInProgressHook(), + identifierPrefix = workInProgressRoot.identifierPrefix, + globalClientId = globalClientIdCounter++; + identifierPrefix = + ":" + identifierPrefix + "r" + globalClientId.toString(32) + ":"; + return (hook.memoizedState = identifierPrefix); + } }, - useTransition: function () { - var booleanOrThenable = rerenderReducer(basicStateReducer)[0], - start = updateWorkInProgressHook().memoizedState; - return [ - "boolean" === typeof booleanOrThenable - ? booleanOrThenable - : useThenable(booleanOrThenable), - start - ]; + HooksDispatcherOnUpdate = { + readContext: readContext, + use: use, + useCallback: updateCallback, + useContext: readContext, + useEffect: updateEffect, + useImperativeHandle: updateImperativeHandle, + useInsertionEffect: updateInsertionEffect, + useLayoutEffect: updateLayoutEffect, + useMemo: updateMemo, + useReducer: updateReducer, + useRef: updateRef, + useState: function () { + return updateReducer(basicStateReducer); + }, + useDebugValue: mountDebugValue, + useDeferredValue: function (value) { + var hook = updateWorkInProgressHook(); + return updateDeferredValueImpl(hook, currentHook.memoizedState, value); + }, + useTransition: function () { + var booleanOrThenable = updateReducer(basicStateReducer)[0], + start = updateWorkInProgressHook().memoizedState; + return [ + "boolean" === typeof booleanOrThenable + ? booleanOrThenable + : useThenable(booleanOrThenable), + start + ]; + }, + useSyncExternalStore: updateSyncExternalStore, + useId: updateId }, - useSyncExternalStore: updateSyncExternalStore, - useId: updateId -}; -HooksDispatcherOnRerender.useCacheRefresh = updateRefresh; -HooksDispatcherOnRerender.useMemoCache = useMemoCache; -HooksDispatcherOnRerender.useHostTransitionStatus = useHostTransitionStatus; -HooksDispatcherOnRerender.useFormState = rerenderActionState; -HooksDispatcherOnRerender.useActionState = rerenderActionState; -HooksDispatcherOnRerender.useOptimistic = function (passthrough, reducer) { - var hook = updateWorkInProgressHook(); - if (null !== currentHook) - return updateOptimisticImpl(hook, currentHook, passthrough, reducer); - hook.baseState = passthrough; - return [passthrough, hook.queue.dispatch]; -}; -var now = Scheduler.unstable_now, + HooksDispatcherOnRerender = { + readContext: readContext, + use: use, + useCallback: updateCallback, + useContext: readContext, + useEffect: updateEffect, + useImperativeHandle: updateImperativeHandle, + useInsertionEffect: updateInsertionEffect, + useLayoutEffect: updateLayoutEffect, + useMemo: updateMemo, + useReducer: rerenderReducer, + useRef: updateRef, + useState: function () { + return rerenderReducer(basicStateReducer); + }, + useDebugValue: mountDebugValue, + useDeferredValue: function (value) { + var hook = updateWorkInProgressHook(); + return null === currentHook + ? ((hook.memoizedState = value), value) + : updateDeferredValueImpl(hook, currentHook.memoizedState, value); + }, + useTransition: function () { + var booleanOrThenable = rerenderReducer(basicStateReducer)[0], + start = updateWorkInProgressHook().memoizedState; + return [ + "boolean" === typeof booleanOrThenable + ? booleanOrThenable + : useThenable(booleanOrThenable), + start + ]; + }, + useSyncExternalStore: updateSyncExternalStore, + useId: updateId + }, + now = Scheduler.unstable_now, commitTime = 0, layoutEffectStartTime = -1, profilerStartTime = -1, @@ -4870,6 +4216,17 @@ function transferActualDuration(fiber) { for (var child = fiber.child; child; ) (fiber.actualDuration += child.actualDuration), (child = child.sibling); } +function resolveDefaultProps(Component, baseProps) { + if (Component && Component.defaultProps) { + baseProps = assign({}, baseProps); + Component = Component.defaultProps; + for (var propName in Component) + void 0 === baseProps[propName] && + (baseProps[propName] = Component[propName]); + return baseProps; + } + return baseProps; +} function applyDerivedStateFromProps( workInProgress, ctor, @@ -4902,7 +4259,6 @@ var classComponentUpdater = { null !== payload && (scheduleUpdateOnFiber(payload, inst, lane), entangleTransitions(payload, inst, lane)); - markStateUpdateScheduled(inst, lane); }, enqueueReplaceState: function (inst, payload, callback) { inst = inst._reactInternals; @@ -4915,7 +4271,6 @@ var classComponentUpdater = { null !== payload && (scheduleUpdateOnFiber(payload, inst, lane), entangleTransitions(payload, inst, lane)); - markStateUpdateScheduled(inst, lane); }, enqueueForceUpdate: function (inst, callback) { inst = inst._reactInternals; @@ -4927,9 +4282,6 @@ var classComponentUpdater = { null !== callback && (scheduleUpdateOnFiber(callback, inst, lane), entangleTransitions(callback, inst, lane)); - null !== injectedProfilingHooks && - "function" === typeof injectedProfilingHooks.markForceUpdateScheduled && - injectedProfilingHooks.markForceUpdateScheduled(inst, lane); } }; function checkShouldComponentUpdate( @@ -5004,111 +4356,80 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { ctor !== instance.state && classComponentUpdater.enqueueReplaceState(instance, instance.state, null), processUpdateQueue(workInProgress, newProps, instance, renderLanes), - suspendIfUpdateReadFromEntangledAsyncAction(), (instance.state = workInProgress.memoizedState)); "function" === typeof instance.componentDidMount && (workInProgress.flags |= 4194308); } -function resolveClassComponentProps(Component, baseProps) { - var newProps = baseProps; - if ("ref" in baseProps) { - newProps = {}; - for (var propName in baseProps) - "ref" !== propName && (newProps[propName] = baseProps[propName]); - } - if ((Component = Component.defaultProps)) { - newProps === baseProps && (newProps = assign({}, newProps)); - for (var propName$52 in Component) - void 0 === newProps[propName$52] && - (newProps[propName$52] = Component[propName$52]); - } - return newProps; -} -var reportGlobalError = - "function" === typeof reportError - ? reportError - : function (error) { - if ( - "object" === typeof window && - "function" === typeof window.ErrorEvent - ) { - var event = new window.ErrorEvent("error", { - bubbles: !0, - cancelable: !0, - message: - "object" === typeof error && - null !== error && - "string" === typeof error.message - ? String(error.message) - : String(error), - error: error - }); - if (!window.dispatchEvent(event)) return; - } else if ( - "object" === typeof process && - "function" === typeof process.emit - ) { - process.emit("uncaughtException", error); - return; - } - console.error(error); - }; -function defaultOnRecoverableError(error) { - reportGlobalError(error); +var CapturedStacks = new WeakMap(); +function createCapturedValueAtFiber(value, source) { + if ("object" === typeof value && null !== value) { + var stack = CapturedStacks.get(value); + "string" !== typeof stack && + ((stack = getStackByFiberInDevAndProd(source)), + CapturedStacks.set(value, stack)); + } else stack = getStackByFiberInDevAndProd(source); + return { value: value, source: source, stack: stack, digest: null }; } -function logUncaughtError(root, errorInfo) { - try { - var onUncaughtError = root.onUncaughtError; - onUncaughtError(errorInfo.value, { componentStack: errorInfo.stack }); - } catch (e) { - setTimeout(function () { - throw e; - }); - } +function createCapturedValueFromError(value, digest, stack) { + "string" === typeof stack && CapturedStacks.set(value, stack); + return { + value: value, + source: null, + stack: null != stack ? stack : null, + digest: null != digest ? digest : null + }; } -function logCaughtError(root, boundary, errorInfo) { +if ( + "function" !== + typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog +) + throw Error( + "Expected ReactFiberErrorDialog.showErrorDialog to be a function." + ); +function logCapturedError(boundary, errorInfo) { try { - var onCaughtError = root.onCaughtError; - onCaughtError(errorInfo.value, { - componentStack: errorInfo.stack, - errorBoundary: 1 === boundary.tag ? boundary.stateNode : null - }); + !1 !== + ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog({ + componentStack: null !== errorInfo.stack ? errorInfo.stack : "", + error: errorInfo.value, + errorBoundary: + null !== boundary && 1 === boundary.tag ? boundary.stateNode : null + }) && console.error(errorInfo.value); } catch (e) { setTimeout(function () { throw e; }); } } -function createRootErrorUpdate(root, errorInfo, lane) { +function createRootErrorUpdate(fiber, errorInfo, lane) { lane = createUpdate(lane); lane.tag = 3; lane.payload = { element: null }; + var error = errorInfo.value; lane.callback = function () { - logUncaughtError(root, errorInfo); + hasUncaughtError || ((hasUncaughtError = !0), (firstUncaughtError = error)); + logCapturedError(fiber, errorInfo); }; return lane; } -function createClassErrorUpdate(lane) { +function createClassErrorUpdate(fiber, errorInfo, lane) { lane = createUpdate(lane); lane.tag = 3; - return lane; -} -function initializeClassErrorUpdate(update, root, fiber, errorInfo) { var getDerivedStateFromError = fiber.type.getDerivedStateFromError; if ("function" === typeof getDerivedStateFromError) { var error = errorInfo.value; - update.payload = function () { + lane.payload = function () { return getDerivedStateFromError(error); }; - update.callback = function () { - logCaughtError(root, fiber, errorInfo); + lane.callback = function () { + logCapturedError(fiber, errorInfo); }; } var inst = fiber.stateNode; null !== inst && "function" === typeof inst.componentDidCatch && - (update.callback = function () { - logCaughtError(root, fiber, errorInfo); + (lane.callback = function () { + logCapturedError(fiber, errorInfo); "function" !== typeof getDerivedStateFromError && (null === legacyErrorBoundariesThatAlreadyFailed ? (legacyErrorBoundariesThatAlreadyFailed = new Set([this])) @@ -5118,6 +4439,7 @@ function initializeClassErrorUpdate(update, root, fiber, errorInfo) { componentStack: null !== stack ? stack : "" }); }); + return lane; } function throwException( root, @@ -5160,15 +4482,12 @@ function throwException( : ((tag.flags |= 128), (sourceFiber.flags |= 131072), (sourceFiber.flags &= -52805), - 1 === sourceFiber.tag - ? null === sourceFiber.alternate + 1 === sourceFiber.tag && + (null === sourceFiber.alternate ? (sourceFiber.tag = 17) : ((returnFiber = createUpdate(2)), (returnFiber.tag = 2), - enqueueUpdate(sourceFiber, returnFiber, 2)) - : 0 === sourceFiber.tag && - null === sourceFiber.alternate && - (sourceFiber.tag = 28), + enqueueUpdate(sourceFiber, returnFiber, 2))), (sourceFiber.lanes |= 2)) : ((tag.flags |= 65536), (tag.lanes = rootRenderLanes)), value === noopSuspenseyCommitThenable @@ -5219,35 +4538,34 @@ function throwException( "A component suspended while responding to synchronous input. This will cause the UI to be replaced with a loading indicator. To fix, updates that suspend should be wrapped with startTransition." ); } - tag = createCapturedValueAtFiber( - Error( - "There was an error during concurrent rendering but React was able to recover by instead synchronously rendering the entire root.", - { cause: value } - ), - sourceFiber - ); - null === workInProgressRootConcurrentErrors - ? (workInProgressRootConcurrentErrors = [tag]) - : workInProgressRootConcurrentErrors.push(tag); + root = value = createCapturedValueAtFiber(value, sourceFiber); 4 !== workInProgressRootExitStatus && (workInProgressRootExitStatus = 2); + null === workInProgressRootConcurrentErrors + ? (workInProgressRootConcurrentErrors = [root]) + : workInProgressRootConcurrentErrors.push(root); if (null === returnFiber) return !0; - value = createCapturedValueAtFiber(value, sourceFiber); + root = returnFiber; do { - switch (returnFiber.tag) { + switch (root.tag) { case 3: return ( - (returnFiber.flags |= 65536), - (root = rootRenderLanes & -rootRenderLanes), - (returnFiber.lanes |= root), - (root = createRootErrorUpdate(returnFiber.stateNode, value, root)), - enqueueCapturedUpdate(returnFiber, root), + (root.flags |= 65536), + (rootRenderLanes &= -rootRenderLanes), + (root.lanes |= rootRenderLanes), + (rootRenderLanes = createRootErrorUpdate( + root, + value, + rootRenderLanes + )), + enqueueCapturedUpdate(root, rootRenderLanes), !1 ); case 1: if ( - ((sourceFiber = returnFiber.type), - (tag = returnFiber.stateNode), - 0 === (returnFiber.flags & 128) && + ((returnFiber = value), + (sourceFiber = root.type), + (tag = root.stateNode), + 0 === (root.flags & 128) && ("function" === typeof sourceFiber.getDerivedStateFromError || (null !== tag && "function" === typeof tag.componentDidCatch && @@ -5255,25 +4573,24 @@ function throwException( !legacyErrorBoundariesThatAlreadyFailed.has(tag))))) ) return ( - (returnFiber.flags |= 65536), + (root.flags |= 65536), (rootRenderLanes &= -rootRenderLanes), - (returnFiber.lanes |= rootRenderLanes), - (rootRenderLanes = createClassErrorUpdate(rootRenderLanes)), - initializeClassErrorUpdate( - rootRenderLanes, + (root.lanes |= rootRenderLanes), + (rootRenderLanes = createClassErrorUpdate( root, returnFiber, - value - ), - enqueueCapturedUpdate(returnFiber, rootRenderLanes), + rootRenderLanes + )), + enqueueCapturedUpdate(root, rootRenderLanes), !1 ); } - returnFiber = returnFiber.return; - } while (null !== returnFiber); + root = root.return; + } while (null !== root); return !1; } -var SelectiveHydrationException = Error( +var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner, + SelectiveHydrationException = Error( "This is not a real error. It's an implementation detail of React's selective hydration feature. If this leaks into userspace, it's a bug in React. Please file an issue." ), didReceiveUpdate = !1; @@ -5297,22 +4614,15 @@ function updateForwardRef( ) { Component = Component.render; var ref = workInProgress.ref; - if ("ref" in nextProps) { - var propsWithoutRef = {}; - for (var key in nextProps) - "ref" !== key && (propsWithoutRef[key] = nextProps[key]); - } else propsWithoutRef = nextProps; prepareToReadContext(workInProgress, renderLanes); - markComponentRenderStarted(workInProgress); nextProps = renderWithHooks( current, workInProgress, Component, - propsWithoutRef, + nextProps, ref, renderLanes ); - markComponentRenderStopped(); if (null !== current && !didReceiveUpdate) return ( bailoutHooks(current, workInProgress, renderLanes), @@ -5335,7 +4645,8 @@ function updateMemoComponent( "function" === typeof type && !shouldConstruct(type) && void 0 === type.defaultProps && - null === Component.compare + null === Component.compare && + void 0 === Component.defaultProps ) return ( (workInProgress.tag = 15), @@ -5433,16 +4744,10 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { } if (0 === (workInProgress.mode & 1)) (workInProgress.memoizedState = { baseLanes: 0, cachePool: null }), - null !== current && pushTransition(workInProgress, null), reuseHiddenContextOnStack(), pushOffscreenSuspenseHandler(workInProgress); else if (0 !== (renderLanes & 536870912)) (workInProgress.memoizedState = { baseLanes: 0, cachePool: null }), - null !== current && - pushTransition( - workInProgress, - null !== prevState ? prevState.cachePool : null - ), null !== prevState ? pushHiddenContext(workInProgress, prevState) : reuseHiddenContextOnStack(), @@ -5458,27 +4763,16 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { ); } else null !== prevState - ? (pushTransition(workInProgress, prevState.cachePool), - pushHiddenContext(workInProgress, prevState), + ? (pushHiddenContext(workInProgress, prevState), reuseSuspenseHandlerOnStack(workInProgress), (workInProgress.memoizedState = null)) - : (null !== current && pushTransition(workInProgress, null), - reuseHiddenContextOnStack(), + : (reuseHiddenContextOnStack(), reuseSuspenseHandlerOnStack(workInProgress)); reconcileChildren(current, workInProgress, nextChildren, renderLanes); return workInProgress.child; } function deferHiddenOffscreenComponent(current, workInProgress, nextBaseLanes) { - var JSCompiler_inline_result = peekCacheFromPool(); - JSCompiler_inline_result = - null === JSCompiler_inline_result - ? null - : { parent: CacheContext._currentValue2, pool: JSCompiler_inline_result }; - workInProgress.memoizedState = { - baseLanes: nextBaseLanes, - cachePool: JSCompiler_inline_result - }; - null !== current && pushTransition(workInProgress, null); + workInProgress.memoizedState = { baseLanes: nextBaseLanes, cachePool: null }; reuseHiddenContextOnStack(); pushOffscreenSuspenseHandler(workInProgress); return null; @@ -5506,7 +4800,6 @@ function updateFunctionComponent( renderLanes ) { prepareToReadContext(workInProgress, renderLanes); - markComponentRenderStarted(workInProgress); Component = renderWithHooks( current, workInProgress, @@ -5515,7 +4808,6 @@ function updateFunctionComponent( void 0, renderLanes ); - markComponentRenderStopped(); if (null !== current && !didReceiveUpdate) return ( bailoutHooks(current, workInProgress, renderLanes), @@ -5534,7 +4826,6 @@ function replayFunctionComponent( renderLanes ) { prepareToReadContext(workInProgress, renderLanes); - markComponentRenderStarted(workInProgress); nextProps = renderWithHooksAgain( workInProgress, Component, @@ -5542,7 +4833,6 @@ function replayFunctionComponent( secondArg ); finishRenderingHooks(); - markComponentRenderStopped(); if (null !== current && !didReceiveUpdate) return ( bailoutHooks(current, workInProgress, renderLanes), @@ -5567,8 +4857,7 @@ function updateClassComponent( (nextProps = !0); else if (null === current) { var instance = workInProgress.stateNode, - unresolvedOldProps = workInProgress.memoizedProps, - oldProps = resolveClassComponentProps(Component, unresolvedOldProps); + oldProps = workInProgress.memoizedProps; instance.props = oldProps; var oldContext = instance.context, contextType = Component.contextType, @@ -5577,14 +4866,12 @@ function updateClassComponent( null !== contextType && (nextContext = readContext(contextType)); var getDerivedStateFromProps = Component.getDerivedStateFromProps; - contextType = + (contextType = "function" === typeof getDerivedStateFromProps || - "function" === typeof instance.getSnapshotBeforeUpdate; - unresolvedOldProps = workInProgress.pendingProps !== unresolvedOldProps; - contextType || + "function" === typeof instance.getSnapshotBeforeUpdate) || ("function" !== typeof instance.UNSAFE_componentWillReceiveProps && "function" !== typeof instance.componentWillReceiveProps) || - ((unresolvedOldProps || oldContext !== nextContext) && + ((oldProps !== nextProps || oldContext !== nextContext) && callComponentWillReceiveProps( workInProgress, instance, @@ -5595,9 +4882,8 @@ function updateClassComponent( var oldState = workInProgress.memoizedState; instance.state = oldState; processUpdateQueue(workInProgress, nextProps, instance, renderLanes); - suspendIfUpdateReadFromEntangledAsyncAction(); oldContext = workInProgress.memoizedState; - unresolvedOldProps || oldState !== oldContext || hasForceUpdate + oldProps !== nextProps || oldState !== oldContext || hasForceUpdate ? ("function" === typeof getDerivedStateFromProps && (applyDerivedStateFromProps( workInProgress, @@ -5641,22 +4927,26 @@ function updateClassComponent( instance = workInProgress.stateNode; cloneUpdateQueue(current, workInProgress); nextContext = workInProgress.memoizedProps; - contextType = resolveClassComponentProps(Component, nextContext); + contextType = + workInProgress.type === workInProgress.elementType + ? nextContext + : resolveDefaultProps(workInProgress.type, nextContext); instance.props = contextType; getDerivedStateFromProps = workInProgress.pendingProps; - oldState = instance.context; + var oldContext$jscomp$0 = instance.context; oldContext = Component.contextType; oldProps = emptyContextObject; "object" === typeof oldContext && null !== oldContext && (oldProps = readContext(oldContext)); - unresolvedOldProps = Component.getDerivedStateFromProps; + oldState = Component.getDerivedStateFromProps; (oldContext = - "function" === typeof unresolvedOldProps || + "function" === typeof oldState || "function" === typeof instance.getSnapshotBeforeUpdate) || ("function" !== typeof instance.UNSAFE_componentWillReceiveProps && "function" !== typeof instance.componentWillReceiveProps) || - ((nextContext !== getDerivedStateFromProps || oldState !== oldProps) && + ((nextContext !== getDerivedStateFromProps || + oldContext$jscomp$0 !== oldProps) && callComponentWillReceiveProps( workInProgress, instance, @@ -5664,19 +4954,18 @@ function updateClassComponent( oldProps )); hasForceUpdate = !1; - oldState = workInProgress.memoizedState; - instance.state = oldState; + oldContext$jscomp$0 = workInProgress.memoizedState; + instance.state = oldContext$jscomp$0; processUpdateQueue(workInProgress, nextProps, instance, renderLanes); - suspendIfUpdateReadFromEntangledAsyncAction(); var newState = workInProgress.memoizedState; nextContext !== getDerivedStateFromProps || - oldState !== newState || + oldContext$jscomp$0 !== newState || hasForceUpdate - ? ("function" === typeof unresolvedOldProps && + ? ("function" === typeof oldState && (applyDerivedStateFromProps( workInProgress, Component, - unresolvedOldProps, + oldState, nextProps ), (newState = workInProgress.memoizedState)), @@ -5687,7 +4976,7 @@ function updateClassComponent( Component, contextType, nextProps, - oldState, + oldContext$jscomp$0, newState, oldProps ) || @@ -5709,11 +4998,11 @@ function updateClassComponent( (workInProgress.flags |= 1024)) : ("function" !== typeof instance.componentDidUpdate || (nextContext === current.memoizedProps && - oldState === current.memoizedState) || + oldContext$jscomp$0 === current.memoizedState) || (workInProgress.flags |= 4), "function" !== typeof instance.getSnapshotBeforeUpdate || (nextContext === current.memoizedProps && - oldState === current.memoizedState) || + oldContext$jscomp$0 === current.memoizedState) || (workInProgress.flags |= 1024), (workInProgress.memoizedProps = nextProps), (workInProgress.memoizedState = newState)), @@ -5723,11 +5012,11 @@ function updateClassComponent( (nextProps = contextType)) : ("function" !== typeof instance.componentDidUpdate || (nextContext === current.memoizedProps && - oldState === current.memoizedState) || + oldContext$jscomp$0 === current.memoizedState) || (workInProgress.flags |= 4), "function" !== typeof instance.getSnapshotBeforeUpdate || (nextContext === current.memoizedProps && - oldState === current.memoizedState) || + oldContext$jscomp$0 === current.memoizedState) || (workInProgress.flags |= 1024), (nextProps = !1)); } @@ -5753,11 +5042,10 @@ function finishClassComponent( if (!shouldUpdate && !hasContext) return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); shouldUpdate = workInProgress.stateNode; + ReactCurrentOwner$1.current = workInProgress; hasContext && "function" !== typeof Component.getDerivedStateFromError ? ((Component = null), (profilerStartTime = -1)) - : (markComponentRenderStarted(workInProgress), - (Component = shouldUpdate.render()), - markComponentRenderStopped()); + : (Component = shouldUpdate.render()); workInProgress.flags |= 1; null !== current && hasContext ? ((workInProgress.child = reconcileChildFibers( @@ -5778,7 +5066,7 @@ function finishClassComponent( } var SUSPENDED_MARKER = { dehydrated: null, treeContext: null, retryLane: 0 }; function mountSuspenseOffscreenState(renderLanes) { - return { baseLanes: renderLanes, cachePool: getSuspendedCache() }; + return { baseLanes: renderLanes, cachePool: null }; } function getRemainingWorkInPrimaryTree( current, @@ -5803,258 +5091,112 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { JSCompiler_temp = 0 !== (workInProgress.flags & 32); workInProgress.flags &= -33; if (null === current) { - var nextPrimaryChildren = nextProps.children; + didSuspend = nextProps.children; nextProps = nextProps.fallback; - if (showFallback) - return ( - reuseSuspenseHandlerOnStack(workInProgress), - (showFallback = workInProgress.mode), - (didSuspend = workInProgress.child), - (nextPrimaryChildren = { - mode: "hidden", - children: nextPrimaryChildren - }), - 0 === (showFallback & 1) && null !== didSuspend - ? ((didSuspend.childLanes = 0), - (didSuspend.pendingProps = nextPrimaryChildren), - workInProgress.mode & 2 && - ((didSuspend.actualDuration = 0), - (didSuspend.actualStartTime = -1), - (didSuspend.selfBaseDuration = 0), - (didSuspend.treeBaseDuration = 0))) - : (didSuspend = createFiberFromOffscreen( - nextPrimaryChildren, - showFallback, - 0, - null - )), - (nextProps = createFiberFromFragment( - nextProps, - showFallback, - renderLanes, - null - )), - (didSuspend.return = workInProgress), - (nextProps.return = workInProgress), - (didSuspend.sibling = nextProps), - (workInProgress.child = didSuspend), - (nextPrimaryChildren = workInProgress.child), - (nextPrimaryChildren.memoizedState = - mountSuspenseOffscreenState(renderLanes)), - (nextPrimaryChildren.childLanes = getRemainingWorkInPrimaryTree( - current, - JSCompiler_temp, - renderLanes - )), - (workInProgress.memoizedState = SUSPENDED_MARKER), - nextProps - ); - pushPrimaryTreeSuspenseHandler(workInProgress); - return mountSuspensePrimaryChildren(workInProgress, nextPrimaryChildren); - } - nextPrimaryChildren = current.memoizedState; - if (null !== nextPrimaryChildren && null !== nextPrimaryChildren.dehydrated) { - if (didSuspend) - workInProgress.flags & 256 - ? (pushPrimaryTreeSuspenseHandler(workInProgress), - (workInProgress.flags &= -257), - (workInProgress = retrySuspenseComponentWithoutHydrating( - current, - workInProgress, - renderLanes - ))) - : null !== workInProgress.memoizedState - ? (reuseSuspenseHandlerOnStack(workInProgress), - (workInProgress.child = current.child), - (workInProgress.flags |= 128), - (workInProgress = null)) - : (reuseSuspenseHandlerOnStack(workInProgress), - (nextPrimaryChildren = nextProps.fallback), - (showFallback = workInProgress.mode), - (nextProps = createFiberFromOffscreen( - { mode: "visible", children: nextProps.children }, + if (showFallback) { + reuseSuspenseHandlerOnStack(workInProgress); + showFallback = workInProgress.mode; + var progressedPrimaryFragment = workInProgress.child; + didSuspend = { mode: "hidden", children: didSuspend }; + 0 === (showFallback & 1) && null !== progressedPrimaryFragment + ? ((progressedPrimaryFragment.childLanes = 0), + (progressedPrimaryFragment.pendingProps = didSuspend), + workInProgress.mode & 2 && + ((progressedPrimaryFragment.actualDuration = 0), + (progressedPrimaryFragment.actualStartTime = -1), + (progressedPrimaryFragment.selfBaseDuration = 0), + (progressedPrimaryFragment.treeBaseDuration = 0))) + : (progressedPrimaryFragment = createFiberFromOffscreen( + didSuspend, showFallback, 0, null - )), - (nextPrimaryChildren = createFiberFromFragment( - nextPrimaryChildren, - showFallback, - renderLanes, - null - )), - (nextPrimaryChildren.flags |= 2), - (nextProps.return = workInProgress), - (nextPrimaryChildren.return = workInProgress), - (nextProps.sibling = nextPrimaryChildren), - (workInProgress.child = nextProps), - 0 !== (workInProgress.mode & 1) && - reconcileChildFibers( - workInProgress, - current.child, - null, - renderLanes - ), - (nextProps = workInProgress.child), - (nextProps.memoizedState = mountSuspenseOffscreenState(renderLanes)), - (nextProps.childLanes = getRemainingWorkInPrimaryTree( - current, - JSCompiler_temp, - renderLanes - )), - (workInProgress.memoizedState = SUSPENDED_MARKER), - (workInProgress = nextPrimaryChildren)); - else if ((pushPrimaryTreeSuspenseHandler(workInProgress), shim$1())) - (JSCompiler_temp = shim$1().digest), - (nextProps = Error( - "The server could not finish this Suspense boundary, likely due to an error during server rendering. Switched to client rendering." - )), - (nextProps.stack = ""), - (nextProps.digest = JSCompiler_temp), - (JSCompiler_temp = { value: nextProps, source: null, stack: null }), - null === hydrationErrors - ? (hydrationErrors = [JSCompiler_temp]) - : hydrationErrors.push(JSCompiler_temp), - (workInProgress = retrySuspenseComponentWithoutHydrating( - current, - workInProgress, - renderLanes - )); - else if ( - ((JSCompiler_temp = 0 !== (renderLanes & current.childLanes)), - didReceiveUpdate || JSCompiler_temp) - ) { - JSCompiler_temp = workInProgressRoot; - if (null !== JSCompiler_temp) { - nextProps = renderLanes & -renderLanes; - if (0 !== (nextProps & 42)) nextProps = 1; - else - switch (nextProps) { - case 2: - nextProps = 1; - break; - case 8: - nextProps = 4; - break; - case 32: - nextProps = 16; - break; - case 128: - case 256: - case 512: - case 1024: - case 2048: - case 4096: - case 8192: - case 16384: - case 32768: - case 65536: - case 131072: - case 262144: - case 524288: - case 1048576: - case 2097152: - case 4194304: - case 8388608: - case 16777216: - case 33554432: - nextProps = 64; - break; - case 268435456: - nextProps = 134217728; - break; - default: - nextProps = 0; - } - nextProps = - 0 !== (nextProps & (JSCompiler_temp.suspendedLanes | renderLanes)) - ? 0 - : nextProps; - if (0 !== nextProps && nextProps !== nextPrimaryChildren.retryLane) - throw ( - ((nextPrimaryChildren.retryLane = nextProps), - enqueueConcurrentRenderForLane(current, nextProps), - scheduleUpdateOnFiber(JSCompiler_temp, current, nextProps), - SelectiveHydrationException) - ); - } - shim$1() || renderDidSuspendDelayIfPossible(); - workInProgress = retrySuspenseComponentWithoutHydrating( + )); + nextProps = createFiberFromFragment( + nextProps, + showFallback, + renderLanes, + null + ); + progressedPrimaryFragment.return = workInProgress; + nextProps.return = workInProgress; + progressedPrimaryFragment.sibling = nextProps; + workInProgress.child = progressedPrimaryFragment; + showFallback = workInProgress.child; + showFallback.memoizedState = mountSuspenseOffscreenState(renderLanes); + showFallback.childLanes = getRemainingWorkInPrimaryTree( + current, + JSCompiler_temp, + renderLanes + ); + workInProgress.memoizedState = SUSPENDED_MARKER; + return nextProps; + } + pushPrimaryTreeSuspenseHandler(workInProgress); + return mountSuspensePrimaryChildren(workInProgress, didSuspend); + } + progressedPrimaryFragment = current.memoizedState; + if (null !== progressedPrimaryFragment) { + var dehydrated = progressedPrimaryFragment.dehydrated; + if (null !== dehydrated) + return updateDehydratedSuspenseComponent( current, workInProgress, + didSuspend, + JSCompiler_temp, + nextProps, + dehydrated, + progressedPrimaryFragment, renderLanes ); - } else - shim$1() - ? ((workInProgress.flags |= 128), - (workInProgress.child = current.child), - retryDehydratedSuspenseBoundary.bind(null, current), - shim$1(), - (workInProgress = null)) - : ((workInProgress = mountSuspensePrimaryChildren( - workInProgress, - nextProps.children - )), - (workInProgress.flags |= 4096)); - return workInProgress; } if (showFallback) { reuseSuspenseHandlerOnStack(workInProgress); - nextPrimaryChildren = nextProps.fallback; - showFallback = workInProgress.mode; - didSuspend = current.child; - var currentFallbackChildFragment = didSuspend.sibling, - primaryChildProps = { mode: "hidden", children: nextProps.children }; - 0 === (showFallback & 1) && workInProgress.child !== didSuspend + showFallback = nextProps.fallback; + didSuspend = workInProgress.mode; + progressedPrimaryFragment = current.child; + dehydrated = progressedPrimaryFragment.sibling; + var primaryChildProps = { mode: "hidden", children: nextProps.children }; + 0 === (didSuspend & 1) && workInProgress.child !== progressedPrimaryFragment ? ((nextProps = workInProgress.child), (nextProps.childLanes = 0), (nextProps.pendingProps = primaryChildProps), workInProgress.mode & 2 && ((nextProps.actualDuration = 0), (nextProps.actualStartTime = -1), - (nextProps.selfBaseDuration = didSuspend.selfBaseDuration), - (nextProps.treeBaseDuration = didSuspend.treeBaseDuration)), + (nextProps.selfBaseDuration = + progressedPrimaryFragment.selfBaseDuration), + (nextProps.treeBaseDuration = + progressedPrimaryFragment.treeBaseDuration)), (workInProgress.deletions = null)) - : ((nextProps = createWorkInProgress(didSuspend, primaryChildProps)), - (nextProps.subtreeFlags = didSuspend.subtreeFlags & 31457280)); - null !== currentFallbackChildFragment - ? (nextPrimaryChildren = createWorkInProgress( - currentFallbackChildFragment, - nextPrimaryChildren - )) - : ((nextPrimaryChildren = createFiberFromFragment( - nextPrimaryChildren, + : ((nextProps = createWorkInProgress( + progressedPrimaryFragment, + primaryChildProps + )), + (nextProps.subtreeFlags = + progressedPrimaryFragment.subtreeFlags & 31457280)); + null !== dehydrated + ? (showFallback = createWorkInProgress(dehydrated, showFallback)) + : ((showFallback = createFiberFromFragment( showFallback, + didSuspend, renderLanes, null )), - (nextPrimaryChildren.flags |= 2)); - nextPrimaryChildren.return = workInProgress; + (showFallback.flags |= 2)); + showFallback.return = workInProgress; nextProps.return = workInProgress; - nextProps.sibling = nextPrimaryChildren; + nextProps.sibling = showFallback; workInProgress.child = nextProps; - nextProps = nextPrimaryChildren; - nextPrimaryChildren = workInProgress.child; - showFallback = current.child.memoizedState; - null === showFallback - ? (showFallback = mountSuspenseOffscreenState(renderLanes)) - : ((didSuspend = showFallback.cachePool), - null !== didSuspend - ? ((currentFallbackChildFragment = CacheContext._currentValue2), - (didSuspend = - didSuspend.parent !== currentFallbackChildFragment - ? { - parent: currentFallbackChildFragment, - pool: currentFallbackChildFragment - } - : didSuspend)) - : (didSuspend = getSuspendedCache()), - (showFallback = { - baseLanes: showFallback.baseLanes | renderLanes, - cachePool: didSuspend - })); - nextPrimaryChildren.memoizedState = showFallback; - nextPrimaryChildren.childLanes = getRemainingWorkInPrimaryTree( + nextProps = showFallback; + showFallback = workInProgress.child; + didSuspend = current.child.memoizedState; + didSuspend = + null === didSuspend + ? mountSuspenseOffscreenState(renderLanes) + : { baseLanes: didSuspend.baseLanes | renderLanes, cachePool: null }; + showFallback.memoizedState = didSuspend; + showFallback.childLanes = getRemainingWorkInPrimaryTree( current, JSCompiler_temp, renderLanes @@ -6094,8 +5236,13 @@ function mountSuspensePrimaryChildren(workInProgress, primaryChildren) { function retrySuspenseComponentWithoutHydrating( current, workInProgress, - renderLanes + renderLanes, + recoverableError ) { + null !== recoverableError && + (null === hydrationErrors + ? (hydrationErrors = [recoverableError]) + : hydrationErrors.push(recoverableError)); reconcileChildFibers(workInProgress, current.child, null, renderLanes); current = mountSuspensePrimaryChildren( workInProgress, @@ -6105,6 +5252,176 @@ function retrySuspenseComponentWithoutHydrating( workInProgress.memoizedState = null; return current; } +function updateDehydratedSuspenseComponent( + current, + workInProgress, + didSuspend, + didPrimaryChildrenDefer, + nextProps, + suspenseInstance, + suspenseState, + renderLanes +) { + if (didSuspend) { + if (workInProgress.flags & 256) + return ( + pushPrimaryTreeSuspenseHandler(workInProgress), + (workInProgress.flags &= -257), + (didPrimaryChildrenDefer = createCapturedValueFromError( + Error( + "There was an error while hydrating this Suspense boundary. Switched to client rendering." + ) + )), + retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + didPrimaryChildrenDefer + ) + ); + if (null !== workInProgress.memoizedState) + return ( + reuseSuspenseHandlerOnStack(workInProgress), + (workInProgress.child = current.child), + (workInProgress.flags |= 128), + null + ); + reuseSuspenseHandlerOnStack(workInProgress); + suspenseState = nextProps.fallback; + didSuspend = workInProgress.mode; + nextProps = createFiberFromOffscreen( + { mode: "visible", children: nextProps.children }, + didSuspend, + 0, + null + ); + suspenseState = createFiberFromFragment( + suspenseState, + didSuspend, + renderLanes, + null + ); + suspenseState.flags |= 2; + nextProps.return = workInProgress; + suspenseState.return = workInProgress; + nextProps.sibling = suspenseState; + workInProgress.child = nextProps; + 0 !== (workInProgress.mode & 1) && + reconcileChildFibers(workInProgress, current.child, null, renderLanes); + nextProps = workInProgress.child; + nextProps.memoizedState = mountSuspenseOffscreenState(renderLanes); + nextProps.childLanes = getRemainingWorkInPrimaryTree( + current, + didPrimaryChildrenDefer, + renderLanes + ); + workInProgress.memoizedState = SUSPENDED_MARKER; + return suspenseState; + } + pushPrimaryTreeSuspenseHandler(workInProgress); + if (0 === (workInProgress.mode & 1)) + return retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + null + ); + if (shim$1()) + return ( + (didPrimaryChildrenDefer = shim$1().digest), + (suspenseState = Error( + "The server could not finish this Suspense boundary, likely due to an error during server rendering. Switched to client rendering." + )), + (suspenseState.digest = didPrimaryChildrenDefer), + (didPrimaryChildrenDefer = createCapturedValueFromError( + suspenseState, + didPrimaryChildrenDefer, + void 0 + )), + retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + didPrimaryChildrenDefer + ) + ); + didPrimaryChildrenDefer = 0 !== (renderLanes & current.childLanes); + if (didReceiveUpdate || didPrimaryChildrenDefer) { + didPrimaryChildrenDefer = workInProgressRoot; + if (null !== didPrimaryChildrenDefer) { + nextProps = renderLanes & -renderLanes; + if (0 !== (nextProps & 42)) nextProps = 1; + else + switch (nextProps) { + case 2: + nextProps = 1; + break; + case 8: + nextProps = 4; + break; + case 32: + nextProps = 16; + break; + case 128: + case 256: + case 512: + case 1024: + case 2048: + case 4096: + case 8192: + case 16384: + case 32768: + case 65536: + case 131072: + case 262144: + case 524288: + case 1048576: + case 2097152: + case 4194304: + case 8388608: + case 16777216: + case 33554432: + nextProps = 64; + break; + case 268435456: + nextProps = 134217728; + break; + default: + nextProps = 0; + } + nextProps = + 0 !== + (nextProps & (didPrimaryChildrenDefer.suspendedLanes | renderLanes)) + ? 0 + : nextProps; + if (0 !== nextProps && nextProps !== suspenseState.retryLane) + throw ( + ((suspenseState.retryLane = nextProps), + enqueueConcurrentRenderForLane(current, nextProps), + scheduleUpdateOnFiber(didPrimaryChildrenDefer, current, nextProps), + SelectiveHydrationException) + ); + } + shim$1() || renderDidSuspendDelayIfPossible(); + return retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + null + ); + } + if (shim$1()) + return ( + (workInProgress.flags |= 128), + (workInProgress.child = current.child), + retryDehydratedSuspenseBoundary.bind(null, current), + shim$1(), + null + ); + current = mountSuspensePrimaryChildren(workInProgress, nextProps.children); + current.flags |= 4096; + return current; +} function scheduleSuspenseWorkOnFiber(fiber, renderLanes, propagationRoot) { fiber.lanes |= renderLanes; var alternate = fiber.alternate; @@ -6257,7 +5574,6 @@ function attemptEarlyBailoutIfNoScheduledUpdate( switch (workInProgress.tag) { case 3: pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); - pushProvider(workInProgress, CacheContext, current.memoizedState.cache); break; case 27: case 5: @@ -6267,23 +5583,22 @@ function attemptEarlyBailoutIfNoScheduledUpdate( pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); break; case 10: - pushProvider( - workInProgress, - workInProgress.type, - workInProgress.memoizedProps.value - ); + var newValue = workInProgress.memoizedProps.value, + context = workInProgress.type._context; + push(valueCursor, context._currentValue2); + context._currentValue2 = newValue; break; case 12: 0 !== (renderLanes & workInProgress.childLanes) && (workInProgress.flags |= 4); - var stateNode = workInProgress.stateNode; - stateNode.effectDuration = 0; - stateNode.passiveEffectDuration = 0; + newValue = workInProgress.stateNode; + newValue.effectDuration = 0; + newValue.passiveEffectDuration = 0; break; case 13: - stateNode = workInProgress.memoizedState; - if (null !== stateNode) { - if (null !== stateNode.dehydrated) + newValue = workInProgress.memoizedState; + if (null !== newValue) { + if (null !== newValue.dehydrated) return ( pushPrimaryTreeSuspenseHandler(workInProgress), (workInProgress.flags |= 128), @@ -6302,9 +5617,9 @@ function attemptEarlyBailoutIfNoScheduledUpdate( pushPrimaryTreeSuspenseHandler(workInProgress); break; case 19: - stateNode = 0 !== (renderLanes & workInProgress.childLanes); + newValue = 0 !== (renderLanes & workInProgress.childLanes); if (0 !== (current.flags & 128)) { - if (stateNode) + if (newValue) return updateSuspenseListComponent( current, workInProgress, @@ -6312,13 +5627,13 @@ function attemptEarlyBailoutIfNoScheduledUpdate( ); workInProgress.flags |= 128; } - var renderState = workInProgress.memoizedState; - null !== renderState && - ((renderState.rendering = null), - (renderState.tail = null), - (renderState.lastEffect = null)); + context = workInProgress.memoizedState; + null !== context && + ((context.rendering = null), + (context.tail = null), + (context.lastEffect = null)); push(suspenseStackCursor, suspenseStackCursor.current); - if (stateNode) break; + if (newValue) break; else return null; case 22: case 23: @@ -6326,8 +5641,6 @@ function attemptEarlyBailoutIfNoScheduledUpdate( (workInProgress.lanes = 0), updateOffscreenComponent(current, workInProgress, renderLanes) ); - case 24: - pushProvider(workInProgress, CacheContext, current.memoizedState.cache); } return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); } @@ -6353,86 +5666,132 @@ function beginWork(current, workInProgress, renderLanes) { else didReceiveUpdate = !1; workInProgress.lanes = 0; switch (workInProgress.tag) { + case 2: + var Component = workInProgress.type; + resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress); + current = workInProgress.pendingProps; + prepareToReadContext(workInProgress, renderLanes); + var value = renderWithHooks( + null, + workInProgress, + Component, + current, + void 0, + renderLanes + ); + workInProgress.flags |= 1; + "object" === typeof value && + null !== value && + "function" === typeof value.render && + void 0 === value.$$typeof + ? ((workInProgress.tag = 1), + (workInProgress.memoizedState = null), + (workInProgress.updateQueue = null), + (workInProgress.memoizedState = + null !== value.state && void 0 !== value.state + ? value.state + : null), + initializeUpdateQueue(workInProgress), + (value.updater = classComponentUpdater), + (workInProgress.stateNode = value), + (value._reactInternals = workInProgress), + mountClassInstance(workInProgress, Component, current, renderLanes), + (workInProgress = finishClassComponent( + null, + workInProgress, + Component, + !0, + !1, + renderLanes + ))) + : ((workInProgress.tag = 0), + reconcileChildren(null, workInProgress, value, renderLanes), + (workInProgress = workInProgress.child)); + return workInProgress; case 16: - var elementType = workInProgress.elementType; + Component = workInProgress.elementType; a: { resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress); current = workInProgress.pendingProps; - var init = elementType._init; - elementType = init(elementType._payload); - workInProgress.type = elementType; - if ("function" === typeof elementType) - shouldConstruct(elementType) - ? ((current = resolveClassComponentProps(elementType, current)), - (workInProgress.tag = 1), - (workInProgress = updateClassComponent( - null, - workInProgress, - elementType, - current, - renderLanes - ))) - : ((workInProgress.tag = 0), - (workInProgress = updateFunctionComponent( - null, - workInProgress, - elementType, - current, - renderLanes - ))); - else { - if (void 0 !== elementType && null !== elementType) - if ( - ((init = elementType.$$typeof), init === REACT_FORWARD_REF_TYPE) - ) { - workInProgress.tag = 11; - workInProgress = updateForwardRef( - null, - workInProgress, - elementType, - current, - renderLanes - ); - break a; - } else if (init === REACT_MEMO_TYPE) { - workInProgress.tag = 14; - workInProgress = updateMemoComponent( - null, - workInProgress, - elementType, - current, - renderLanes - ); - break a; - } - throw Error( - "Element type is invalid. Received a promise that resolves to: " + - elementType + - ". Lazy element type must resolve to a class or function." - ); + value = Component._init; + Component = value(Component._payload); + workInProgress.type = Component; + value = workInProgress.tag = resolveLazyComponentTag(Component); + current = resolveDefaultProps(Component, current); + switch (value) { + case 0: + workInProgress = updateFunctionComponent( + null, + workInProgress, + Component, + current, + renderLanes + ); + break a; + case 1: + workInProgress = updateClassComponent( + null, + workInProgress, + Component, + current, + renderLanes + ); + break a; + case 11: + workInProgress = updateForwardRef( + null, + workInProgress, + Component, + current, + renderLanes + ); + break a; + case 14: + workInProgress = updateMemoComponent( + null, + workInProgress, + Component, + resolveDefaultProps(Component.type, current), + renderLanes + ); + break a; } + throw Error( + "Element type is invalid. Received a promise that resolves to: " + + Component + + ". Lazy element type must resolve to a class or function." + ); } return workInProgress; case 0: - return updateFunctionComponent( - current, - workInProgress, - workInProgress.type, - workInProgress.pendingProps, - renderLanes + return ( + (Component = workInProgress.type), + (value = workInProgress.pendingProps), + (value = + workInProgress.elementType === Component + ? value + : resolveDefaultProps(Component, value)), + updateFunctionComponent( + current, + workInProgress, + Component, + value, + renderLanes + ) ); case 1: return ( - (elementType = workInProgress.type), - (init = resolveClassComponentProps( - elementType, - workInProgress.pendingProps - )), + (Component = workInProgress.type), + (value = workInProgress.pendingProps), + (value = + workInProgress.elementType === Component + ? value + : resolveDefaultProps(Component, value)), updateClassComponent( current, workInProgress, - elementType, - init, + Component, + value, renderLanes ) ); @@ -6440,25 +5799,18 @@ function beginWork(current, workInProgress, renderLanes) { pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); if (null === current) throw Error("Should have a current fiber. This is a bug in React."); - var nextProps = workInProgress.pendingProps; - init = workInProgress.memoizedState; - elementType = init.element; + value = workInProgress.pendingProps; + Component = workInProgress.memoizedState.element; cloneUpdateQueue(current, workInProgress); - processUpdateQueue(workInProgress, nextProps, null, renderLanes); - nextProps = workInProgress.memoizedState; - var nextCache = nextProps.cache; - pushProvider(workInProgress, CacheContext, nextCache); - nextCache !== init.cache && - propagateContextChange(workInProgress, CacheContext, renderLanes); - suspendIfUpdateReadFromEntangledAsyncAction(); - init = nextProps.element; - init === elementType + processUpdateQueue(workInProgress, value, null, renderLanes); + value = workInProgress.memoizedState.element; + value === Component ? (workInProgress = bailoutOnAlreadyFinishedWork( current, workInProgress, renderLanes )) - : (reconcileChildren(current, workInProgress, init, renderLanes), + : (reconcileChildren(current, workInProgress, value, renderLanes), (workInProgress = workInProgress.child)); return workInProgress; case 26: @@ -6466,27 +5818,9 @@ function beginWork(current, workInProgress, renderLanes) { case 5: return ( pushHostContext(workInProgress), - (elementType = workInProgress.pendingProps.children), - null !== workInProgress.memoizedState && - ((init = renderWithHooks( - current, - workInProgress, - TransitionAwareHostComponent, - null, - null, - renderLanes - )), - (HostTransitionContext._currentValue2 = init), - didReceiveUpdate && - null !== current && - current.memoizedState.memoizedState !== init && - propagateContextChange( - workInProgress, - HostTransitionContext, - renderLanes - )), + (Component = workInProgress.pendingProps.children), markRef(current, workInProgress), - reconcileChildren(current, workInProgress, elementType, renderLanes), + reconcileChildren(current, workInProgress, Component, renderLanes), workInProgress.child ); case 6: @@ -6499,29 +5833,26 @@ function beginWork(current, workInProgress, renderLanes) { workInProgress, workInProgress.stateNode.containerInfo ), - (elementType = workInProgress.pendingProps), + (Component = workInProgress.pendingProps), null === current ? (workInProgress.child = reconcileChildFibers( workInProgress, null, - elementType, + Component, renderLanes )) - : reconcileChildren( - current, - workInProgress, - elementType, - renderLanes - ), + : reconcileChildren(current, workInProgress, Component, renderLanes), workInProgress.child ); case 11: - return updateForwardRef( - current, - workInProgress, - workInProgress.type, - workInProgress.pendingProps, - renderLanes + return ( + (Component = workInProgress.type), + (value = workInProgress.pendingProps), + (value = + workInProgress.elementType === Component + ? value + : resolveDefaultProps(Component, value)), + updateForwardRef(current, workInProgress, Component, value, renderLanes) ); case 7: return ( @@ -6546,9 +5877,9 @@ function beginWork(current, workInProgress, renderLanes) { case 12: return ( (workInProgress.flags |= 4), - (elementType = workInProgress.stateNode), - (elementType.effectDuration = 0), - (elementType.passiveEffectDuration = 0), + (Component = workInProgress.stateNode), + (Component.effectDuration = 0), + (Component.passiveEffectDuration = 0), reconcileChildren( current, workInProgress, @@ -6559,14 +5890,15 @@ function beginWork(current, workInProgress, renderLanes) { ); case 10: a: { - elementType = workInProgress.type; - init = workInProgress.pendingProps; - nextProps = workInProgress.memoizedProps; - nextCache = init.value; - pushProvider(workInProgress, elementType, nextCache); - if (null !== nextProps) - if (objectIs(nextProps.value, nextCache)) { - if (nextProps.children === init.children) { + Component = workInProgress.type._context; + value = workInProgress.pendingProps; + var oldProps = workInProgress.memoizedProps, + newValue = value.value; + push(valueCursor, Component._currentValue2); + Component._currentValue2 = newValue; + if (null !== oldProps) + if (objectIs(oldProps.value, newValue)) { + if (oldProps.children === value.children) { workInProgress = bailoutOnAlreadyFinishedWork( current, workInProgress, @@ -6575,31 +5907,111 @@ function beginWork(current, workInProgress, renderLanes) { break a; } } else - propagateContextChange(workInProgress, elementType, renderLanes); - reconcileChildren(current, workInProgress, init.children, renderLanes); + for ( + oldProps = workInProgress.child, + null !== oldProps && (oldProps.return = workInProgress); + null !== oldProps; + + ) { + var list = oldProps.dependencies; + if (null !== list) { + newValue = oldProps.child; + for ( + var dependency = list.firstContext; + null !== dependency; + + ) { + if (dependency.context === Component) { + if (1 === oldProps.tag) { + dependency = createUpdate(renderLanes & -renderLanes); + dependency.tag = 2; + var updateQueue = oldProps.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; + } + } + oldProps.lanes |= renderLanes; + dependency = oldProps.alternate; + null !== dependency && (dependency.lanes |= renderLanes); + scheduleContextWorkOnParentPath( + oldProps.return, + renderLanes, + workInProgress + ); + list.lanes |= renderLanes; + break; + } + dependency = dependency.next; + } + } else if (10 === oldProps.tag) + newValue = + oldProps.type === workInProgress.type ? null : oldProps.child; + else if (18 === oldProps.tag) { + newValue = oldProps.return; + if (null === newValue) + throw Error( + "We just came from a parent so we must have had a parent. This is a bug in React." + ); + newValue.lanes |= renderLanes; + list = newValue.alternate; + null !== list && (list.lanes |= renderLanes); + scheduleContextWorkOnParentPath( + newValue, + renderLanes, + workInProgress + ); + newValue = oldProps.sibling; + } else newValue = oldProps.child; + if (null !== newValue) newValue.return = oldProps; + else + for (newValue = oldProps; null !== newValue; ) { + if (newValue === workInProgress) { + newValue = null; + break; + } + oldProps = newValue.sibling; + if (null !== oldProps) { + oldProps.return = newValue.return; + newValue = oldProps; + break; + } + newValue = newValue.return; + } + oldProps = newValue; + } + reconcileChildren(current, workInProgress, value.children, renderLanes); workInProgress = workInProgress.child; } return workInProgress; case 9: return ( - (init = workInProgress.type._context), - (elementType = workInProgress.pendingProps.children), + (value = workInProgress.type), + (Component = workInProgress.pendingProps.children), prepareToReadContext(workInProgress, renderLanes), - (init = readContext(init)), - markComponentRenderStarted(workInProgress), - (elementType = elementType(init)), - markComponentRenderStopped(), + (value = readContext(value)), + (Component = Component(value)), (workInProgress.flags |= 1), - reconcileChildren(current, workInProgress, elementType, renderLanes), + reconcileChildren(current, workInProgress, Component, renderLanes), workInProgress.child ); case 14: - return updateMemoComponent( - current, - workInProgress, - workInProgress.type, - workInProgress.pendingProps, - renderLanes + return ( + (Component = workInProgress.type), + (value = resolveDefaultProps(Component, workInProgress.pendingProps)), + (value = resolveDefaultProps(Component.type, value)), + updateMemoComponent( + current, + workInProgress, + Component, + value, + renderLanes + ) ); case 15: return updateSimpleMemoComponent( @@ -6611,97 +6023,30 @@ function beginWork(current, workInProgress, renderLanes) { ); case 17: return ( - (elementType = workInProgress.type), - (init = resolveClassComponentProps( - elementType, - workInProgress.pendingProps - )), + (Component = workInProgress.type), + (value = workInProgress.pendingProps), + (value = + workInProgress.elementType === Component + ? value + : resolveDefaultProps(Component, value)), resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress), (workInProgress.tag = 1), prepareToReadContext(workInProgress, renderLanes), - constructClassInstance(workInProgress, elementType, init), - mountClassInstance(workInProgress, elementType, init, renderLanes), + constructClassInstance(workInProgress, Component, value), + mountClassInstance(workInProgress, Component, value, renderLanes), finishClassComponent( null, workInProgress, - elementType, + Component, !0, !1, renderLanes ) ); - case 28: - return ( - (elementType = workInProgress.type), - (init = resolveClassComponentProps( - elementType, - workInProgress.pendingProps - )), - resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress), - (workInProgress.tag = 0), - updateFunctionComponent( - null, - workInProgress, - elementType, - init, - renderLanes - ) - ); case 19: return updateSuspenseListComponent(current, workInProgress, renderLanes); case 22: return updateOffscreenComponent(current, workInProgress, renderLanes); - case 24: - return ( - prepareToReadContext(workInProgress, renderLanes), - (elementType = readContext(CacheContext)), - null === current - ? ((init = peekCacheFromPool()), - null === init && - ((init = workInProgressRoot), - (nextProps = createCache()), - (init.pooledCache = nextProps), - nextProps.refCount++, - null !== nextProps && (init.pooledCacheLanes |= renderLanes), - (init = nextProps)), - (workInProgress.memoizedState = { - parent: elementType, - cache: init - }), - initializeUpdateQueue(workInProgress), - pushProvider(workInProgress, CacheContext, init)) - : (0 !== (current.lanes & renderLanes) && - (cloneUpdateQueue(current, workInProgress), - processUpdateQueue(workInProgress, null, null, renderLanes), - suspendIfUpdateReadFromEntangledAsyncAction()), - (init = current.memoizedState), - (nextProps = workInProgress.memoizedState), - init.parent !== elementType - ? ((init = { parent: elementType, cache: elementType }), - (workInProgress.memoizedState = init), - 0 === workInProgress.lanes && - (workInProgress.memoizedState = - workInProgress.updateQueue.baseState = - init), - pushProvider(workInProgress, CacheContext, elementType)) - : ((elementType = nextProps.cache), - pushProvider(workInProgress, CacheContext, elementType), - elementType !== init.cache && - propagateContextChange( - workInProgress, - CacheContext, - renderLanes - ))), - reconcileChildren( - current, - workInProgress, - workInProgress.pendingProps.children, - renderLanes - ), - workInProgress.child - ); - case 29: - throw workInProgress.pendingProps; } throw Error( "Unknown unit of work tag (" + @@ -6719,10 +6064,6 @@ function resetContextDependencies() { currentlyRenderingFiber = null; } -function pushProvider(providerFiber, context, nextValue) { - push(valueCursor, context._currentValue2); - context._currentValue2 = nextValue; -} function popProvider(context) { context._currentValue2 = valueCursor.current; pop(valueCursor); @@ -6740,74 +6081,6 @@ function scheduleContextWorkOnParentPath(parent, renderLanes, propagationRoot) { parent = parent.return; } } -function propagateContextChange(workInProgress, context, renderLanes) { - var fiber = workInProgress.child; - null !== fiber && (fiber.return = workInProgress); - for (; null !== fiber; ) { - var list = fiber.dependencies; - if (null !== list) { - var nextFiber = fiber.child; - for (var dependency = list.firstContext; null !== dependency; ) { - if (dependency.context === context) { - if (1 === fiber.tag) { - dependency = createUpdate(renderLanes & -renderLanes); - dependency.tag = 2; - var updateQueue = fiber.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; - } - } - fiber.lanes |= renderLanes; - dependency = fiber.alternate; - null !== dependency && (dependency.lanes |= renderLanes); - scheduleContextWorkOnParentPath( - fiber.return, - renderLanes, - workInProgress - ); - list.lanes |= renderLanes; - break; - } - dependency = dependency.next; - } - } else if (10 === fiber.tag) - nextFiber = fiber.type === workInProgress.type ? null : fiber.child; - else if (18 === fiber.tag) { - nextFiber = fiber.return; - if (null === nextFiber) - throw Error( - "We just came from a parent so we must have had a parent. This is a bug in React." - ); - nextFiber.lanes |= renderLanes; - list = nextFiber.alternate; - null !== list && (list.lanes |= renderLanes); - scheduleContextWorkOnParentPath(nextFiber, renderLanes, workInProgress); - nextFiber = fiber.sibling; - } else nextFiber = fiber.child; - if (null !== nextFiber) nextFiber.return = fiber; - else - for (nextFiber = fiber; null !== nextFiber; ) { - if (nextFiber === workInProgress) { - nextFiber = null; - break; - } - fiber = nextFiber.sibling; - if (null !== fiber) { - fiber.return = nextFiber.return; - nextFiber = fiber; - break; - } - nextFiber = nextFiber.return; - } - fiber = nextFiber; - } -} function prepareToReadContext(workInProgress, renderLanes) { currentlyRenderingFiber = workInProgress; lastFullyObservedContext = lastContextDependency = null; @@ -6831,90 +6104,23 @@ function readContextForConsumer(consumer, context) { if ( ((context = { context: context, memoizedValue: value, next: null }), null === lastContextDependency) - ) { - if (null === consumer) - 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 = context; - consumer.dependencies = { lanes: 0, firstContext: context }; - } else lastContextDependency = lastContextDependency.next = context; - return value; -} -var AbortControllerLocal = - "undefined" !== typeof AbortController - ? AbortController - : function () { - var listeners = [], - signal = (this.signal = { - aborted: !1, - addEventListener: function (type, listener) { - listeners.push(listener); - } - }); - this.abort = function () { - signal.aborted = !0; - listeners.forEach(function (listener) { - return listener(); - }); - }; - }, - scheduleCallback$1 = Scheduler.unstable_scheduleCallback, - NormalPriority = Scheduler.unstable_NormalPriority, - CacheContext = { - $$typeof: REACT_CONTEXT_TYPE, - Consumer: null, - Provider: null, - _currentValue: null, - _currentValue2: null, - _threadCount: 0 - }; -function createCache() { - return { - controller: new AbortControllerLocal(), - data: new Map(), - refCount: 0 - }; -} -function releaseCache(cache) { - cache.refCount--; - 0 === cache.refCount && - scheduleCallback$1(NormalPriority, function () { - cache.controller.abort(); - }); -} -var prevOnStartTransitionFinish = ReactSharedInternals.S; -ReactSharedInternals.S = function (transition, returnValue) { - "object" === typeof returnValue && - null !== returnValue && - "function" === typeof returnValue.then && - entangleAsyncAction(transition, returnValue); - null !== prevOnStartTransitionFinish && - prevOnStartTransitionFinish(transition, returnValue); -}; -var resumedCache = createCursor(null); -function peekCacheFromPool() { - var cacheResumedFromPreviousRender = resumedCache.current; - return null !== cacheResumedFromPreviousRender - ? cacheResumedFromPreviousRender - : workInProgressRoot.pooledCache; -} -function pushTransition(offscreenWorkInProgress, prevCachePool) { - null === prevCachePool - ? push(resumedCache, resumedCache.current) - : push(resumedCache, prevCachePool.pool); -} -function getSuspendedCache() { - var cacheFromPool = peekCacheFromPool(); - return null === cacheFromPool - ? null - : { parent: CacheContext._currentValue2, pool: cacheFromPool }; + ) { + if (null === consumer) + 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 = context; + consumer.dependencies = { lanes: 0, firstContext: context }; + } else lastContextDependency = lastContextDependency.next = context; + return value; } +var ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig; +function handleAsyncAction() {} function doesRequireClone(current, completedWork) { if (null !== current && current.child === completedWork.child) return !1; if (0 !== (completedWork.flags & 16)) return !0; for (current = completedWork.child; null !== current; ) { - if (0 !== (current.flags & 13878) || 0 !== (current.subtreeFlags & 13878)) + if (0 !== (current.flags & 12854) || 0 !== (current.subtreeFlags & 12854)) return !0; current = current.sibling; } @@ -7035,14 +6241,14 @@ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { break; case "collapsed": lastTailNode = renderState.tail; - for (var lastTailNode$92 = null; null !== lastTailNode; ) - null !== lastTailNode.alternate && (lastTailNode$92 = lastTailNode), + for (var lastTailNode$64 = null; null !== lastTailNode; ) + null !== lastTailNode.alternate && (lastTailNode$64 = lastTailNode), (lastTailNode = lastTailNode.sibling); - null === lastTailNode$92 + null === lastTailNode$64 ? hasRenderedATailFallback || null === renderState.tail ? (renderState.tail = null) : (renderState.tail.sibling = null) - : (lastTailNode$92.sibling = null); + : (lastTailNode$64.sibling = null); } } function bubbleProperties(completedWork) { @@ -7054,53 +6260,53 @@ function bubbleProperties(completedWork) { if (didBailout) if (0 !== (completedWork.mode & 2)) { for ( - var treeBaseDuration$94 = completedWork.selfBaseDuration, - child$95 = completedWork.child; - null !== child$95; + var treeBaseDuration$66 = completedWork.selfBaseDuration, + child$67 = completedWork.child; + null !== child$67; ) - (newChildLanes |= child$95.lanes | child$95.childLanes), - (subtreeFlags |= child$95.subtreeFlags & 31457280), - (subtreeFlags |= child$95.flags & 31457280), - (treeBaseDuration$94 += child$95.treeBaseDuration), - (child$95 = child$95.sibling); - completedWork.treeBaseDuration = treeBaseDuration$94; + (newChildLanes |= child$67.lanes | child$67.childLanes), + (subtreeFlags |= child$67.subtreeFlags & 31457280), + (subtreeFlags |= child$67.flags & 31457280), + (treeBaseDuration$66 += child$67.treeBaseDuration), + (child$67 = child$67.sibling); + completedWork.treeBaseDuration = treeBaseDuration$66; } else for ( - treeBaseDuration$94 = completedWork.child; - null !== treeBaseDuration$94; + treeBaseDuration$66 = completedWork.child; + null !== treeBaseDuration$66; ) (newChildLanes |= - treeBaseDuration$94.lanes | treeBaseDuration$94.childLanes), - (subtreeFlags |= treeBaseDuration$94.subtreeFlags & 31457280), - (subtreeFlags |= treeBaseDuration$94.flags & 31457280), - (treeBaseDuration$94.return = completedWork), - (treeBaseDuration$94 = treeBaseDuration$94.sibling); + treeBaseDuration$66.lanes | treeBaseDuration$66.childLanes), + (subtreeFlags |= treeBaseDuration$66.subtreeFlags & 31457280), + (subtreeFlags |= treeBaseDuration$66.flags & 31457280), + (treeBaseDuration$66.return = completedWork), + (treeBaseDuration$66 = treeBaseDuration$66.sibling); else if (0 !== (completedWork.mode & 2)) { - treeBaseDuration$94 = completedWork.actualDuration; - child$95 = completedWork.selfBaseDuration; + treeBaseDuration$66 = completedWork.actualDuration; + child$67 = completedWork.selfBaseDuration; for (var child = completedWork.child; null !== child; ) (newChildLanes |= child.lanes | child.childLanes), (subtreeFlags |= child.subtreeFlags), (subtreeFlags |= child.flags), - (treeBaseDuration$94 += child.actualDuration), - (child$95 += child.treeBaseDuration), + (treeBaseDuration$66 += child.actualDuration), + (child$67 += child.treeBaseDuration), (child = child.sibling); - completedWork.actualDuration = treeBaseDuration$94; - completedWork.treeBaseDuration = child$95; + completedWork.actualDuration = treeBaseDuration$66; + completedWork.treeBaseDuration = child$67; } else for ( - treeBaseDuration$94 = completedWork.child; - null !== treeBaseDuration$94; + treeBaseDuration$66 = completedWork.child; + null !== treeBaseDuration$66; ) (newChildLanes |= - treeBaseDuration$94.lanes | treeBaseDuration$94.childLanes), - (subtreeFlags |= treeBaseDuration$94.subtreeFlags), - (subtreeFlags |= treeBaseDuration$94.flags), - (treeBaseDuration$94.return = completedWork), - (treeBaseDuration$94 = treeBaseDuration$94.sibling); + treeBaseDuration$66.lanes | treeBaseDuration$66.childLanes), + (subtreeFlags |= treeBaseDuration$66.subtreeFlags), + (subtreeFlags |= treeBaseDuration$66.flags), + (treeBaseDuration$66.return = completedWork), + (treeBaseDuration$66 = treeBaseDuration$66.sibling); completedWork.subtreeFlags |= subtreeFlags; completedWork.childLanes = newChildLanes; return didBailout; @@ -7108,7 +6314,7 @@ function bubbleProperties(completedWork) { function completeWork(current, workInProgress, renderLanes) { var newProps = workInProgress.pendingProps; switch (workInProgress.tag) { - case 28: + case 2: case 16: case 15: case 0: @@ -7124,11 +6330,6 @@ function completeWork(current, workInProgress, renderLanes) { case 3: return ( (renderLanes = workInProgress.stateNode), - (newProps = null), - null !== current && (newProps = current.memoizedState.cache), - workInProgress.memoizedState.cache !== newProps && - (workInProgress.flags |= 2048), - popProvider(CacheContext), popHostContainer(), renderLanes.pendingContext && ((renderLanes.context = renderLanes.pendingContext), @@ -7304,20 +6505,7 @@ function completeWork(current, workInProgress, renderLanes) { workInProgress ); renderLanes = null !== newProps; - current = null !== current && null !== current.memoizedState; - renderLanes && - ((newProps = workInProgress.child), - (oldProps = null), - null !== newProps.alternate && - null !== newProps.alternate.memoizedState && - null !== newProps.alternate.memoizedState.cachePool && - (oldProps = newProps.alternate.memoizedState.cachePool.pool), - (updatePayload = null), - null !== newProps.memoizedState && - null !== newProps.memoizedState.cachePool && - (updatePayload = newProps.memoizedState.cachePool.pool), - updatePayload !== oldProps && (newProps.flags |= 2048)); - renderLanes !== current && + renderLanes !== (null !== current && null !== current.memoizedState) && renderLanes && (workInProgress.child.flags |= 8192); scheduleRetryEffect(workInProgress, workInProgress.updateQueue); @@ -7337,7 +6525,9 @@ function completeWork(current, workInProgress, renderLanes) { ); case 10: return ( - popProvider(workInProgress.type), bubbleProperties(workInProgress), null + popProvider(workInProgress.type._context), + bubbleProperties(workInProgress), + null ); case 17: return bubbleProperties(workInProgress), null; @@ -7445,35 +6635,14 @@ function completeWork(current, workInProgress, renderLanes) { (bubbleProperties(workInProgress), workInProgress.subtreeFlags & 6 && (workInProgress.flags |= 8192)) : bubbleProperties(workInProgress), - (renderLanes = workInProgress.updateQueue), - null !== renderLanes && - scheduleRetryEffect(workInProgress, renderLanes.retryQueue), - (renderLanes = null), + (current = workInProgress.updateQueue), null !== current && - null !== current.memoizedState && - null !== current.memoizedState.cachePool && - (renderLanes = current.memoizedState.cachePool.pool), - (newProps = null), - null !== workInProgress.memoizedState && - null !== workInProgress.memoizedState.cachePool && - (newProps = workInProgress.memoizedState.cachePool.pool), - newProps !== renderLanes && (workInProgress.flags |= 2048), - null !== current && pop(resumedCache), + scheduleRetryEffect(workInProgress, current.retryQueue), null ); case 24: - return ( - (renderLanes = null), - null !== current && (renderLanes = current.memoizedState.cache), - workInProgress.memoizedState.cache !== renderLanes && - (workInProgress.flags |= 2048), - popProvider(CacheContext), - bubbleProperties(workInProgress), - null - ); - case 25: return null; - case 29: + case 25: return null; } throw Error( @@ -7496,7 +6665,6 @@ function unwindWork(current, workInProgress) { ); case 3: return ( - popProvider(CacheContext), popHostContainer(), (current = workInProgress.flags), 0 !== (current & 65536) && 0 === (current & 128) @@ -7530,13 +6698,12 @@ function unwindWork(current, workInProgress) { case 4: return popHostContainer(), null; case 10: - return popProvider(workInProgress.type), null; + return popProvider(workInProgress.type._context), null; case 22: case 23: return ( popSuspenseHandler(workInProgress), popHiddenContext(), - null !== current && pop(resumedCache), (current = workInProgress.flags), current & 65536 ? ((workInProgress.flags = (current & -65537) | 128), @@ -7546,7 +6713,7 @@ function unwindWork(current, workInProgress) { : null ); case 24: - return popProvider(CacheContext), null; + return null; case 25: return null; default: @@ -7556,7 +6723,6 @@ function unwindWork(current, workInProgress) { function unwindInterruptedWork(current, interruptedWork) { switch (interruptedWork.tag) { case 3: - popProvider(CacheContext); popHostContainer(); break; case 26: @@ -7574,16 +6740,11 @@ function unwindInterruptedWork(current, interruptedWork) { pop(suspenseStackCursor); break; case 10: - popProvider(interruptedWork.type); + popProvider(interruptedWork.type._context); break; case 22: case 23: - popSuspenseHandler(interruptedWork); - popHiddenContext(); - null !== current && pop(resumedCache); - break; - case 24: - popProvider(CacheContext); + popSuspenseHandler(interruptedWork), popHiddenContext(); } } var offscreenSubtreeIsHidden = !1, @@ -7596,10 +6757,7 @@ function shouldProfile(current) { return 0 !== (current.mode & 2) && 0 !== (executionContext & 4); } function callComponentWillUnmountWithTimer(current, instance) { - instance.props = resolveClassComponentProps( - current.type, - current.memoizedProps - ); + instance.props = current.memoizedProps; instance.state = current.memoizedState; if (shouldProfile(current)) try { @@ -7666,8 +6824,8 @@ function safelyDetachRef(current, nearestMountedAncestor) { recordLayoutEffectDuration(current); } else ref(null); - } catch (error$119) { - captureCommitPhaseError(current, nearestMountedAncestor, error$119); + } catch (error$84) { + captureCommitPhaseError(current, nearestMountedAncestor, error$84); } else ref.current = null; } @@ -7701,13 +6859,13 @@ function commitBeforeMutationEffects(root, firstChild) { break; case 1: if (0 !== (flags & 1024) && null !== current) { - var prevState = current.memoizedState, + var prevProps = current.memoizedProps, + prevState = current.memoizedState, instance = root.stateNode, snapshot = instance.getSnapshotBeforeUpdate( - resolveClassComponentProps( - root.type, - current.memoizedProps - ), + root.elementType === root.type + ? prevProps + : resolveDefaultProps(root.type, prevProps), prevState ); instance.__reactInternalSnapshotBeforeUpdate = snapshot; @@ -7758,65 +6916,26 @@ function commitHookEffectListUnmount( destroy = inst.destroy; void 0 !== destroy && ((inst.destroy = void 0), - 0 !== (flags & 8) - ? null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markComponentPassiveEffectUnmountStarted && - injectedProfilingHooks.markComponentPassiveEffectUnmountStarted( - finishedWork - ) - : 0 !== (flags & 4) && - markComponentLayoutEffectUnmountStarted(finishedWork), - safelyCallDestroy(finishedWork, nearestMountedAncestor, destroy), - 0 !== (flags & 8) - ? null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markComponentPassiveEffectUnmountStopped && - injectedProfilingHooks.markComponentPassiveEffectUnmountStopped() - : 0 !== (flags & 4) && markComponentLayoutEffectUnmountStopped()); + safelyCallDestroy(finishedWork, nearestMountedAncestor, destroy)); } effect = effect.next; } while (effect !== updateQueue); } } function commitHookEffectListMount(flags, finishedWork) { - var updateQueue = finishedWork.updateQueue; - updateQueue = null !== updateQueue ? updateQueue.lastEffect : null; - if (null !== updateQueue) { - var effect = (updateQueue = updateQueue.next); + finishedWork = finishedWork.updateQueue; + finishedWork = null !== finishedWork ? finishedWork.lastEffect : null; + if (null !== finishedWork) { + var effect = (finishedWork = finishedWork.next); do { if ((effect.tag & flags) === flags) { - 0 !== (flags & 8) - ? null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markComponentPassiveEffectMountStarted && - injectedProfilingHooks.markComponentPassiveEffectMountStarted( - finishedWork - ) - : 0 !== (flags & 4) && - null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markComponentLayoutEffectMountStarted && - injectedProfilingHooks.markComponentLayoutEffectMountStarted( - finishedWork - ); - var create$120 = effect.create, + var create$85 = effect.create, inst = effect.inst; - create$120 = create$120(); - inst.destroy = create$120; - 0 !== (flags & 8) - ? null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markComponentPassiveEffectMountStopped && - injectedProfilingHooks.markComponentPassiveEffectMountStopped() - : 0 !== (flags & 4) && - null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markComponentLayoutEffectMountStopped && - injectedProfilingHooks.markComponentLayoutEffectMountStopped(); + create$85 = create$85(); + inst.destroy = create$85; } effect = effect.next; - } while (effect !== updateQueue); + } while (effect !== finishedWork); } } function commitHookLayoutEffects(finishedWork, hookFlags) { @@ -7831,8 +6950,8 @@ function commitHookLayoutEffects(finishedWork, hookFlags) { } else try { commitHookEffectListMount(hookFlags, finishedWork); - } catch (error$122) { - captureCommitPhaseError(finishedWork, finishedWork.return, error$122); + } catch (error$87) { + captureCommitPhaseError(finishedWork, finishedWork.return, error$87); } } function commitClassCallbacks(finishedWork) { @@ -7921,18 +7040,18 @@ function commitLayoutEffectOnFiber(finishedRoot, current, finishedWork) { } else try { finishedRoot.componentDidMount(); - } catch (error$123) { + } catch (error$88) { captureCommitPhaseError( finishedWork, finishedWork.return, - error$123 + error$88 ); } else { - var prevProps = resolveClassComponentProps( - finishedWork.type, - current.memoizedProps - ); + var prevProps = + finishedWork.elementType === finishedWork.type + ? current.memoizedProps + : resolveDefaultProps(finishedWork.type, current.memoizedProps); current = current.memoizedState; if (shouldProfile(finishedWork)) { try { @@ -7942,11 +7061,11 @@ function commitLayoutEffectOnFiber(finishedRoot, current, finishedWork) { current, finishedRoot.__reactInternalSnapshotBeforeUpdate ); - } catch (error$124) { + } catch (error$89) { captureCommitPhaseError( finishedWork, finishedWork.return, - error$124 + error$89 ); } recordLayoutEffectDuration(finishedWork); @@ -7957,11 +7076,11 @@ function commitLayoutEffectOnFiber(finishedRoot, current, finishedWork) { current, finishedRoot.__reactInternalSnapshotBeforeUpdate ); - } catch (error$125) { + } catch (error$90) { captureCommitPhaseError( finishedWork, finishedWork.return, - error$125 + error$90 ); } } @@ -8117,8 +7236,7 @@ function commitDeletionEffectsOnFiber( destroy )) : 0 !== (tag & 4) && - (markComponentLayoutEffectUnmountStarted(deletedFiber), - shouldProfile(deletedFiber) + (shouldProfile(deletedFiber) ? (startLayoutEffectTimer(), (inst.destroy = void 0), safelyCallDestroy( @@ -8132,8 +7250,7 @@ function commitDeletionEffectsOnFiber( deletedFiber, nearestMountedAncestor, destroy - )), - markComponentLayoutEffectUnmountStopped())); + )))); effect = effect.next; } while (effect !== updateQueue); } @@ -8256,7 +7373,7 @@ function recursivelyTraverseMutationEffects(root, parentFiber) { captureCommitPhaseError(childToDelete, parentFiber, error); } } - if (parentFiber.subtreeFlags & 13878) + if (parentFiber.subtreeFlags & 12854) for (parentFiber = parentFiber.child; null !== parentFiber; ) commitMutationEffectsOnFiber(parentFiber, root), (parentFiber = parentFiber.sibling); @@ -8282,22 +7399,22 @@ function commitMutationEffectsOnFiber(finishedWork, root) { try { startLayoutEffectTimer(), commitHookEffectListUnmount(5, finishedWork, finishedWork.return); - } catch (error$128) { + } catch (error$93) { captureCommitPhaseError( finishedWork, finishedWork.return, - error$128 + error$93 ); } recordLayoutEffectDuration(finishedWork); } else try { commitHookEffectListUnmount(5, finishedWork, finishedWork.return); - } catch (error$129) { + } catch (error$94) { captureCommitPhaseError( finishedWork, finishedWork.return, - error$129 + error$94 ); } } @@ -8588,170 +7705,65 @@ function commitHookPassiveMountEffects(finishedWork, hookFlags) { } else try { commitHookEffectListMount(hookFlags, finishedWork); - } catch (error$137) { - captureCommitPhaseError(finishedWork, finishedWork.return, error$137); + } catch (error$102) { + captureCommitPhaseError(finishedWork, finishedWork.return, error$102); } } -function commitOffscreenPassiveMountEffects(current, finishedWork) { - var previousCache = null; - null !== current && - null !== current.memoizedState && - null !== current.memoizedState.cachePool && - (previousCache = current.memoizedState.cachePool.pool); - current = null; - null !== finishedWork.memoizedState && - null !== finishedWork.memoizedState.cachePool && - (current = finishedWork.memoizedState.cachePool.pool); - current !== previousCache && - (null != current && current.refCount++, - null != previousCache && releaseCache(previousCache)); -} -function commitCachePassiveMountEffect(current, finishedWork) { - current = null; - null !== finishedWork.alternate && - (current = finishedWork.alternate.memoizedState.cache); - finishedWork = finishedWork.memoizedState.cache; - finishedWork !== current && - (finishedWork.refCount++, null != current && releaseCache(current)); -} -function recursivelyTraversePassiveMountEffects( - root, - parentFiber, - committedLanes, - committedTransitions -) { +function recursivelyTraversePassiveMountEffects(root, parentFiber) { if (parentFiber.subtreeFlags & 10256) for (parentFiber = parentFiber.child; null !== parentFiber; ) - commitPassiveMountOnFiber( - root, - parentFiber, - committedLanes, - committedTransitions - ), + commitPassiveMountOnFiber(root, parentFiber), (parentFiber = parentFiber.sibling); } -function commitPassiveMountOnFiber( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions -) { +function commitPassiveMountOnFiber(finishedRoot, finishedWork) { var flags = finishedWork.flags; switch (finishedWork.tag) { case 0: case 11: case 15: - recursivelyTraversePassiveMountEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - ); + recursivelyTraversePassiveMountEffects(finishedRoot, finishedWork); flags & 2048 && commitHookPassiveMountEffects(finishedWork, 9); break; case 3: - recursivelyTraversePassiveMountEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - ); - flags & 2048 && - ((finishedRoot = null), - null !== finishedWork.alternate && - (finishedRoot = finishedWork.alternate.memoizedState.cache), - (finishedWork = finishedWork.memoizedState.cache), - finishedWork !== finishedRoot && - (finishedWork.refCount++, - null != finishedRoot && releaseCache(finishedRoot))); + recursivelyTraversePassiveMountEffects(finishedRoot, finishedWork); break; case 23: break; case 22: - var instance = finishedWork.stateNode; + flags = finishedWork.stateNode; null !== finishedWork.memoizedState - ? instance._visibility & 4 - ? recursivelyTraversePassiveMountEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - ) - : finishedWork.mode & 1 - ? recursivelyTraverseAtomicPassiveEffects(finishedRoot, finishedWork) - : ((instance._visibility |= 4), - recursivelyTraversePassiveMountEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - )) - : instance._visibility & 4 - ? recursivelyTraversePassiveMountEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - ) - : ((instance._visibility |= 4), + ? flags._visibility & 4 + ? recursivelyTraversePassiveMountEffects(finishedRoot, finishedWork) + : finishedWork.mode & 1 || + ((flags._visibility |= 4), + recursivelyTraversePassiveMountEffects(finishedRoot, finishedWork)) + : flags._visibility & 4 + ? recursivelyTraversePassiveMountEffects(finishedRoot, finishedWork) + : ((flags._visibility |= 4), recursivelyTraverseReconnectPassiveEffects( finishedRoot, - finishedWork, - committedLanes, - committedTransitions, - 0 !== (finishedWork.subtreeFlags & 10256) + finishedWork )); - flags & 2048 && - commitOffscreenPassiveMountEffects( - finishedWork.alternate, - finishedWork - ); break; case 24: - recursivelyTraversePassiveMountEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - ); - flags & 2048 && - commitCachePassiveMountEffect(finishedWork.alternate, finishedWork); + recursivelyTraversePassiveMountEffects(finishedRoot, finishedWork); break; default: - recursivelyTraversePassiveMountEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - ); + recursivelyTraversePassiveMountEffects(finishedRoot, finishedWork); } } function recursivelyTraverseReconnectPassiveEffects( finishedRoot$jscomp$0, - parentFiber, - committedLanes$jscomp$0, - committedTransitions$jscomp$0, - includeWorkInProgressEffects + parentFiber ) { - includeWorkInProgressEffects = - includeWorkInProgressEffects && 0 !== (parentFiber.subtreeFlags & 10256); for (parentFiber = parentFiber.child; null !== parentFiber; ) { var finishedRoot = finishedRoot$jscomp$0, - finishedWork = parentFiber, - committedLanes = committedLanes$jscomp$0, - committedTransitions = committedTransitions$jscomp$0, - flags = finishedWork.flags; + finishedWork = parentFiber; switch (finishedWork.tag) { case 0: case 11: case 15: - recursivelyTraverseReconnectPassiveEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions, - includeWorkInProgressEffects - ); + recursivelyTraverseReconnectPassiveEffects(finishedRoot, finishedWork); commitHookPassiveMountEffects(finishedWork, 8); break; case 23: @@ -8761,93 +7773,30 @@ function recursivelyTraverseReconnectPassiveEffects( null !== finishedWork.memoizedState ? instance._visibility & 4 ? recursivelyTraverseReconnectPassiveEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions, - includeWorkInProgressEffects - ) - : finishedWork.mode & 1 - ? recursivelyTraverseAtomicPassiveEffects( finishedRoot, finishedWork ) - : ((instance._visibility |= 4), + : finishedWork.mode & 1 || + ((instance._visibility |= 4), recursivelyTraverseReconnectPassiveEffects( finishedRoot, - finishedWork, - committedLanes, - committedTransitions, - includeWorkInProgressEffects + finishedWork )) : ((instance._visibility |= 4), recursivelyTraverseReconnectPassiveEffects( finishedRoot, - finishedWork, - committedLanes, - committedTransitions, - includeWorkInProgressEffects + finishedWork )); - includeWorkInProgressEffects && - flags & 2048 && - commitOffscreenPassiveMountEffects( - finishedWork.alternate, - finishedWork - ); break; case 24: - recursivelyTraverseReconnectPassiveEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions, - includeWorkInProgressEffects - ); - includeWorkInProgressEffects && - flags & 2048 && - commitCachePassiveMountEffect(finishedWork.alternate, finishedWork); + recursivelyTraverseReconnectPassiveEffects(finishedRoot, finishedWork); break; default: - recursivelyTraverseReconnectPassiveEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions, - includeWorkInProgressEffects - ); + recursivelyTraverseReconnectPassiveEffects(finishedRoot, finishedWork); } parentFiber = parentFiber.sibling; } } -function recursivelyTraverseAtomicPassiveEffects( - finishedRoot$jscomp$0, - parentFiber -) { - if (parentFiber.subtreeFlags & 10256) - for (parentFiber = parentFiber.child; null !== parentFiber; ) { - var finishedRoot = finishedRoot$jscomp$0, - finishedWork = parentFiber, - flags = finishedWork.flags; - switch (finishedWork.tag) { - case 22: - recursivelyTraverseAtomicPassiveEffects(finishedRoot, finishedWork); - flags & 2048 && - commitOffscreenPassiveMountEffects( - finishedWork.alternate, - finishedWork - ); - break; - case 24: - recursivelyTraverseAtomicPassiveEffects(finishedRoot, finishedWork); - flags & 2048 && - commitCachePassiveMountEffect(finishedWork.alternate, finishedWork); - break; - default: - recursivelyTraverseAtomicPassiveEffects(finishedRoot, finishedWork); - } - parentFiber = parentFiber.sibling; - } -} var suspenseyCommitFlag = 8192; function recursivelyAccumulateSuspenseyCommit(parentFiber) { if (parentFiber.subtreeFlags & suspenseyCommitFlag) @@ -8859,9 +7808,10 @@ function accumulateSuspenseyCommitOnFiber(fiber) { switch (fiber.tag) { case 26: recursivelyAccumulateSuspenseyCommit(fiber); - fiber.flags & suspenseyCommitFlag && - null !== fiber.memoizedState && - shim(); + if (fiber.flags & suspenseyCommitFlag && null !== fiber.memoizedState) + throw Error( + "The current renderer does not support Resources. This error is likely caused by a bug in React. Please file an issue." + ); break; case 5: recursivelyAccumulateSuspenseyCommit(fiber); @@ -9005,29 +7955,16 @@ function commitPassiveUnmountEffectsInsideOfDeletedTree_begin( case 11: case 15: commitHookPassiveUnmountEffects(fiber, nearestMountedAncestor, 8); - break; - case 23: - case 22: - if ( - null !== fiber.memoizedState && - null !== fiber.memoizedState.cachePool - ) { - var cache = fiber.memoizedState.cachePool.pool; - null != cache && cache.refCount++; - } - break; - case 24: - releaseCache(fiber.memoizedState.cache); } - cache = fiber.child; - if (null !== cache) (cache.return = fiber), (nextEffect = cache); + var child = fiber.child; + if (null !== child) (child.return = fiber), (nextEffect = child); else a: for (fiber = deletedSubtreeRoot; null !== nextEffect; ) { - cache = nextEffect; - var sibling = cache.sibling, - returnFiber = cache.return; - detachFiberAfterEffects(cache); - if (cache === fiber) { + child = nextEffect; + var sibling = child.sibling, + returnFiber = child.return; + detachFiberAfterEffects(child); + if (child === fiber) { nextEffect = null; break a; } @@ -9040,17 +7977,10 @@ function commitPassiveUnmountEffectsInsideOfDeletedTree_begin( } } } -var DefaultAsyncDispatcher = { - getCacheForType: function (resourceType) { - var cache = readContext(CacheContext), - cacheForType = cache.data.get(resourceType); - void 0 === cacheForType && - ((cacheForType = resourceType()), - cache.data.set(resourceType, cacheForType)); - return cacheForType; - } - }, - PossiblyWeakMap = "function" === typeof WeakMap ? WeakMap : Map, +var PossiblyWeakMap = "function" === typeof WeakMap ? WeakMap : Map, + ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, + ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner, + ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig, executionContext = 0, workInProgressRoot = null, workInProgress = null, @@ -9060,6 +7990,7 @@ var DefaultAsyncDispatcher = { workInProgressRootDidAttachPingListener = !1, entangledRenderLanes = 0, workInProgressRootExitStatus = 0, + workInProgressRootFatalError = null, workInProgressRootSkippedLanes = 0, workInProgressRootInterleavedUpdatedLanes = 0, workInProgressRootPingedLanes = 0, @@ -9067,38 +7998,45 @@ var DefaultAsyncDispatcher = { workInProgressRootConcurrentErrors = null, workInProgressRootRecoverableErrors = null, workInProgressRootDidIncludeRecursiveRenderUpdate = !1, - didIncludeCommitPhaseUpdate = !1, globalMostRecentFallbackTime = 0, workInProgressRootRenderTargetTime = Infinity, workInProgressTransitions = null, + hasUncaughtError = !1, + firstUncaughtError = null, legacyErrorBoundariesThatAlreadyFailed = null, rootDoesHavePassiveEffects = !1, rootWithPendingPassiveEffects = null, pendingPassiveEffectsLanes = 0, pendingPassiveProfilerEffects = [], - pendingPassiveEffectsRemainingLanes = 0, - pendingPassiveTransitions = null, nestedUpdateCount = 0, rootWithNestedUpdates = null; function requestUpdateLane(fiber) { - return 0 === (fiber.mode & 1) - ? 2 - : 0 !== (executionContext & 2) && 0 !== workInProgressRootRenderLanes - ? workInProgressRootRenderLanes & -workInProgressRootRenderLanes - : null !== ReactSharedInternals.T - ? ((fiber = currentEntangledLane), - 0 !== fiber ? fiber : requestTransitionLane()) - : resolveUpdatePriority(); -} -function requestDeferredLane() { - 0 === workInProgressDeferredLane && - (workInProgressDeferredLane = - 0 !== (workInProgressRootRenderLanes & 536870912) - ? 536870912 - : claimNextTransitionLane()); - var suspenseHandler = suspenseHandlerStackCursor.current; - null !== suspenseHandler && (suspenseHandler.flags |= 32); - return workInProgressDeferredLane; + if (0 === (fiber.mode & 1)) return 2; + if (0 !== (executionContext & 2) && 0 !== workInProgressRootRenderLanes) + return workInProgressRootRenderLanes & -workInProgressRootRenderLanes; + fiber = ReactCurrentBatchConfig$1.transition; + null !== fiber && fiber._callbacks.add(handleAsyncAction); + if (null !== fiber) + return ( + 0 === currentEventTransitionLane && + (currentEventTransitionLane = claimNextTransitionLane()), + currentEventTransitionLane + ); + fiber = currentUpdatePriority; + if (0 === fiber) + a: { + fiber = fabricGetCurrentEventPriority + ? fabricGetCurrentEventPriority() + : null; + if (null != fiber) + switch (fiber) { + case FabricDiscretePriority: + fiber = 2; + break a; + } + fiber = 32; + } + return fiber; } function scheduleUpdateOnFiber(root, fiber, lane) { if ( @@ -9111,7 +8049,7 @@ function scheduleUpdateOnFiber(root, fiber, lane) { workInProgressRootRenderLanes, workInProgressDeferredLane ); - markRootUpdated(root, lane); + markRootUpdated$1(root, lane); if (0 === (executionContext & 2) || root !== workInProgressRoot) isDevToolsPresent && addFiberToLanesMap(root, fiber, lane), root === workInProgressRoot && @@ -9166,24 +8104,22 @@ function performConcurrentWorkOnRoot(root, didTimeout) { root, renderWasConcurrent ); - if ( - 0 !== errorRetryLanes && + 0 !== errorRetryLanes && ((lanes = errorRetryLanes), (exitStatus = recoverFromConcurrentError( root, renderWasConcurrent, errorRetryLanes - )), - (renderWasConcurrent = !1), - 2 !== exitStatus) - ) - continue; - } - if (1 === exitStatus) { - prepareFreshStack(root, 0); - markRootSuspended(root, lanes, 0); - break; + ))); } + if (1 === exitStatus) + throw ( + ((originalCallbackNode = workInProgressRootFatalError), + prepareFreshStack(root, 0), + markRootSuspended(root, lanes, 0), + ensureRootIsScheduled(root), + originalCallbackNode) + ); root.finishedWork = didTimeout; root.finishedLanes = lanes; a: { @@ -9203,8 +8139,6 @@ function performConcurrentWorkOnRoot(root, didTimeout) { } break; case 2: - workInProgressRootRecoverableErrors = null; - break; case 3: case 5: break; @@ -9265,10 +8199,13 @@ function recoverFromConcurrentError( originallyAttemptedLanes, errorRetryLanes ) { - var errorsFromFirstAttempt = workInProgressRootConcurrentErrors; + var errorsFromFirstAttempt = workInProgressRootConcurrentErrors, + JSCompiler_inline_result; + (JSCompiler_inline_result = root.current.memoizedState.isDehydrated) && + (prepareFreshStack(root, errorRetryLanes).flags |= 256); errorRetryLanes = renderRootSync(root, errorRetryLanes); if (2 !== errorRetryLanes) { - if (workInProgressRootDidAttachPingListener) + if (workInProgressRootDidAttachPingListener && !JSCompiler_inline_result) return ( (root.errorRecoveryDisabledLanes |= originallyAttemptedLanes), (workInProgressRootInterleavedUpdatedLanes |= originallyAttemptedLanes), @@ -9297,9 +8234,7 @@ function commitRootWhenReady( lanes, spawnedLane ) { - lanes = finishedWork.subtreeFlags; - (lanes & 8192 || 16785408 === (lanes & 16785408)) && - accumulateSuspenseyCommitOnFiber(finishedWork); + 0 === (lanes & 42) && accumulateSuspenseyCommitOnFiber(finishedWork); commitRoot( root, recoverableErrors, @@ -9342,15 +8277,6 @@ function isRenderConsistentWithExternalStores(finishedWork) { } return !0; } -function markRootUpdated(root, updatedLanes) { - root.pendingLanes |= updatedLanes; - 268435456 !== updatedLanes && - ((root.suspendedLanes = 0), (root.pingedLanes = 0)); - executionContext & 2 - ? (workInProgressRootDidIncludeRecursiveRenderUpdate = !0) - : executionContext & 4 && (didIncludeCommitPhaseUpdate = !0); - throwIfInfiniteUpdateLoopDetected(); -} function markRootSuspended(root, suspendedLanes, spawnedLane) { suspendedLanes &= ~workInProgressRootPingedLanes; suspendedLanes &= ~workInProgressRootInterleavedUpdatedLanes; @@ -9361,60 +8287,14 @@ function markRootSuspended(root, suspendedLanes, spawnedLane) { 0 < lanes; ) { - var index$9 = 31 - clz32(lanes), - lane = 1 << index$9; - expirationTimes[index$9] = -1; + var index$4 = 31 - clz32(lanes), + lane = 1 << index$4; + expirationTimes[index$4] = -1; lanes &= ~lane; } 0 !== spawnedLane && markSpawnedDeferredLane(root, spawnedLane, suspendedLanes); } -function performSyncWorkOnRoot(root, lanes) { - if (0 !== (executionContext & 6)) - throw Error("Should not already be working."); - if (flushPassiveEffects()) return ensureRootIsScheduled(root), null; - currentUpdateIsNested = nestedUpdateScheduled; - nestedUpdateScheduled = !1; - var exitStatus = renderRootSync(root, lanes); - if (0 !== root.tag && 2 === exitStatus) { - var originallyAttemptedLanes = lanes, - errorRetryLanes = getLanesToRetrySynchronouslyOnError( - root, - originallyAttemptedLanes - ); - 0 !== errorRetryLanes && - ((lanes = errorRetryLanes), - (exitStatus = recoverFromConcurrentError( - root, - originallyAttemptedLanes, - errorRetryLanes - ))); - } - if (1 === exitStatus) - return ( - prepareFreshStack(root, 0), - markRootSuspended(root, lanes, 0), - ensureRootIsScheduled(root), - null - ); - if (6 === exitStatus) - return ( - markRootSuspended(root, lanes, workInProgressDeferredLane), - ensureRootIsScheduled(root), - null - ); - root.finishedWork = root.current.alternate; - root.finishedLanes = lanes; - commitRoot( - root, - workInProgressRootRecoverableErrors, - workInProgressTransitions, - workInProgressRootDidIncludeRecursiveRenderUpdate, - workInProgressDeferredLane - ); - ensureRootIsScheduled(root); - return null; -} function resetWorkInProgressStack() { if (null !== workInProgress) { if (0 === workInProgressSuspendedReason) @@ -9448,11 +8328,12 @@ function prepareFreshStack(root, lanes) { workInProgressSuspendedReason = 0; workInProgressThrownValue = null; workInProgressRootDidAttachPingListener = !1; + workInProgressRootExitStatus = 0; + workInProgressRootFatalError = null; workInProgressDeferredLane = workInProgressRootPingedLanes = workInProgressRootInterleavedUpdatedLanes = workInProgressRootSkippedLanes = - workInProgressRootExitStatus = 0; workInProgressRootRecoverableErrors = workInProgressRootConcurrentErrors = null; @@ -9465,9 +8346,9 @@ function prepareFreshStack(root, lanes) { 0 < allEntangledLanes; ) { - var index$7 = 31 - clz32(allEntangledLanes), - lane = 1 << index$7; - lanes |= root[index$7]; + var index$2 = 31 - clz32(allEntangledLanes), + lane = 1 << index$2; + lanes |= root[index$2]; allEntangledLanes &= ~lane; } entangledRenderLanes = lanes; @@ -9476,82 +8357,47 @@ function prepareFreshStack(root, lanes) { } function handleThrow(root, thrownValue) { currentlyRenderingFiber$1 = null; - ReactSharedInternals.H = ContextOnlyDispatcher; - if (thrownValue === SuspenseException) { - thrownValue = getSuspendedThenable(); - var handler = suspenseHandlerStackCursor.current; - workInProgressSuspendedReason = - (null !== handler && - ((workInProgressRootRenderLanes & 4194176) === - workInProgressRootRenderLanes - ? null !== shellBoundary - : ((workInProgressRootRenderLanes & 62914560) !== - workInProgressRootRenderLanes && - 0 === (workInProgressRootRenderLanes & 536870912)) || - handler !== shellBoundary)) || - 0 !== (workInProgressRootSkippedLanes & 134217727) || - 0 !== (workInProgressRootInterleavedUpdatedLanes & 134217727) - ? 3 - : 2; - } else - thrownValue === SuspenseyCommitException - ? ((thrownValue = getSuspendedThenable()), - (workInProgressSuspendedReason = 4)) - : (workInProgressSuspendedReason = - thrownValue === SelectiveHydrationException - ? 8 - : null !== thrownValue && - "object" === typeof thrownValue && - "function" === typeof thrownValue.then - ? 6 - : 1); + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + ReactCurrentOwner.current = null; + thrownValue === SuspenseException + ? ((thrownValue = getSuspendedThenable()), + (root = suspenseHandlerStackCursor.current), + (workInProgressSuspendedReason = + (null !== root && + ((workInProgressRootRenderLanes & 4194176) === + workInProgressRootRenderLanes + ? null !== shellBoundary + : ((workInProgressRootRenderLanes & 62914560) !== + workInProgressRootRenderLanes && + 0 === (workInProgressRootRenderLanes & 536870912)) || + root !== shellBoundary)) || + 0 !== (workInProgressRootSkippedLanes & 134217727) || + 0 !== (workInProgressRootInterleavedUpdatedLanes & 134217727) + ? 3 + : 2)) + : thrownValue === SuspenseyCommitException + ? ((thrownValue = getSuspendedThenable()), + (workInProgressSuspendedReason = 4)) + : (workInProgressSuspendedReason = + thrownValue === SelectiveHydrationException + ? 8 + : null !== thrownValue && + "object" === typeof thrownValue && + "function" === typeof thrownValue.then + ? 6 + : 1); workInProgressThrownValue = thrownValue; - handler = workInProgress; - if (null === handler) - (workInProgressRootExitStatus = 1), - logUncaughtError( - root, - createCapturedValueAtFiber(thrownValue, root.current) - ); - else - switch ( - (handler.mode & 2 && - stopProfilerTimerIfRunningAndRecordDelta(handler, !0), - markComponentRenderStopped(), - workInProgressSuspendedReason) - ) { - case 1: - null !== injectedProfilingHooks && - "function" === typeof injectedProfilingHooks.markComponentErrored && - injectedProfilingHooks.markComponentErrored( - handler, - thrownValue, - workInProgressRootRenderLanes - ); - break; - case 2: - case 3: - case 6: - case 7: - null !== injectedProfilingHooks && - "function" === typeof injectedProfilingHooks.markComponentSuspended && - injectedProfilingHooks.markComponentSuspended( - handler, - thrownValue, - workInProgressRootRenderLanes - ); - } + root = workInProgress; + null === root + ? ((workInProgressRootExitStatus = 1), + (workInProgressRootFatalError = thrownValue)) + : root.mode & 2 && stopProfilerTimerIfRunningAndRecordDelta(root, !0); } function pushDispatcher() { - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = ContextOnlyDispatcher; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = ContextOnlyDispatcher; return null === prevDispatcher ? ContextOnlyDispatcher : prevDispatcher; } -function pushAsyncDispatcher() { - var prevAsyncDispatcher = ReactSharedInternals.A; - ReactSharedInternals.A = DefaultAsyncDispatcher; - return prevAsyncDispatcher; -} function renderDidSuspendDelayIfPossible() { workInProgressRootExitStatus = 4; (0 === (workInProgressRootSkippedLanes & 134217727) && @@ -9566,8 +8412,7 @@ function renderDidSuspendDelayIfPossible() { function renderRootSync(root, lanes) { var prevExecutionContext = executionContext; executionContext |= 2; - var prevDispatcher = pushDispatcher(), - prevAsyncDispatcher = pushAsyncDispatcher(); + var prevDispatcher = pushDispatcher(); if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) { if (isDevToolsPresent) { var memoizedUpdaters = root.memoizedUpdaters; @@ -9579,7 +8424,6 @@ function renderRootSync(root, lanes) { workInProgressTransitions = null; prepareFreshStack(root, lanes); } - markRenderStarted(lanes); lanes = !1; a: do try { @@ -9604,20 +8448,18 @@ function renderRootSync(root, lanes) { } workLoopSync(); break; - } catch (thrownValue$142) { - handleThrow(root, thrownValue$142); + } catch (thrownValue$103) { + handleThrow(root, thrownValue$103); } while (1); lanes && root.shellSuspendCounter++; resetContextDependencies(); executionContext = prevExecutionContext; - ReactSharedInternals.H = prevDispatcher; - ReactSharedInternals.A = prevAsyncDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; if (null !== workInProgress) throw Error( "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." ); - markRenderStopped(); workInProgressRoot = null; workInProgressRootRenderLanes = 0; finishQueueingConcurrentUpdates(); @@ -9629,8 +8471,7 @@ function workLoopSync() { function renderRootConcurrent(root, lanes) { var prevExecutionContext = executionContext; executionContext |= 2; - var prevDispatcher = pushDispatcher(), - prevAsyncDispatcher = pushAsyncDispatcher(); + var prevDispatcher = pushDispatcher(); if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) { if (isDevToolsPresent) { var memoizedUpdaters = root.memoizedUpdaters; @@ -9643,7 +8484,6 @@ function renderRootConcurrent(root, lanes) { workInProgressRootRenderTargetTime = now$1() + 500; prepareFreshStack(root, lanes); } - markRenderStarted(lanes); a: do try { if (0 !== workInProgressSuspendedReason && null !== workInProgress) @@ -9688,27 +8528,23 @@ function renderRootConcurrent(root, lanes) { throwAndUnwindWorkLoop(root, lanes, memoizedUpdaters)); break; case 5: - var resource = null; switch (workInProgress.tag) { - case 26: - resource = workInProgress.memoizedState; case 5: + case 26: case 27: - var hostFiber = workInProgress; - if (resource ? shim(resource) : 1) { - workInProgressSuspendedReason = 0; - workInProgressThrownValue = null; - var sibling = hostFiber.sibling; - if (null !== sibling) workInProgress = sibling; - else { - var returnFiber = hostFiber.return; - null !== returnFiber - ? ((workInProgress = returnFiber), - completeUnitOfWork(returnFiber)) - : (workInProgress = null); - } - break b; + lanes = workInProgress; + workInProgressSuspendedReason = 0; + workInProgressThrownValue = null; + var sibling = lanes.sibling; + if (null !== sibling) workInProgress = sibling; + else { + var returnFiber = lanes.return; + null !== returnFiber + ? ((workInProgress = returnFiber), + completeUnitOfWork(returnFiber)) + : (workInProgress = null); } + break b; } workInProgressSuspendedReason = 0; workInProgressThrownValue = null; @@ -9728,22 +8564,14 @@ function renderRootConcurrent(root, lanes) { } workLoopConcurrent(); break; - } catch (thrownValue$144) { - handleThrow(root, thrownValue$144); + } catch (thrownValue$105) { + handleThrow(root, thrownValue$105); } while (1); resetContextDependencies(); - ReactSharedInternals.H = prevDispatcher; - ReactSharedInternals.A = prevAsyncDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; executionContext = prevExecutionContext; - if (null !== workInProgress) - return ( - null !== injectedProfilingHooks && - "function" === typeof injectedProfilingHooks.markRenderYielded && - injectedProfilingHooks.markRenderYielded(), - 0 - ); - markRenderStopped(); + if (null !== workInProgress) return 0; workInProgressRoot = null; workInProgressRootRenderLanes = 0; finishQueueingConcurrentUpdates(); @@ -9764,46 +8592,62 @@ function performUnitOfWork(unitOfWork) { null === current ? completeUnitOfWork(unitOfWork) : (workInProgress = current); + ReactCurrentOwner.current = null; } function replaySuspendedUnitOfWork(unitOfWork) { - var next = unitOfWork; - var current = next.alternate, - isProfilingMode = 0 !== (next.mode & 2); - isProfilingMode && startProfilerTimer(next); - switch (next.tag) { + var current = unitOfWork.alternate, + isProfilingMode = 0 !== (unitOfWork.mode & 2); + isProfilingMode && startProfilerTimer(unitOfWork); + switch (unitOfWork.tag) { + case 2: + unitOfWork.tag = 0; case 15: case 0: + var Component = unitOfWork.type, + unresolvedProps = unitOfWork.pendingProps; + unresolvedProps = + unitOfWork.elementType === Component + ? unresolvedProps + : resolveDefaultProps(Component, unresolvedProps); current = replayFunctionComponent( current, - next, - next.pendingProps, - next.type, + unitOfWork, + unresolvedProps, + Component, void 0, workInProgressRootRenderLanes ); break; case 11: + Component = unitOfWork.type.render; + unresolvedProps = unitOfWork.pendingProps; + unresolvedProps = + unitOfWork.elementType === Component + ? unresolvedProps + : resolveDefaultProps(Component, unresolvedProps); current = replayFunctionComponent( current, - next, - next.pendingProps, - next.type.render, - next.ref, + unitOfWork, + unresolvedProps, + Component, + unitOfWork.ref, workInProgressRootRenderLanes ); break; case 5: - resetHooksOnUnwind(next); + resetHooksOnUnwind(unitOfWork); default: - unwindInterruptedWork(current, next), - (next = workInProgress = - resetWorkInProgress(next, entangledRenderLanes)), - (current = beginWork(current, next, entangledRenderLanes)); + unwindInterruptedWork(current, unitOfWork), + (unitOfWork = workInProgress = + resetWorkInProgress(unitOfWork, entangledRenderLanes)), + (current = beginWork(current, unitOfWork, entangledRenderLanes)); } - isProfilingMode && stopProfilerTimerIfRunningAndRecordDelta(next, !0); - next = current; + isProfilingMode && stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, !0); unitOfWork.memoizedProps = unitOfWork.pendingProps; - null === next ? completeUnitOfWork(unitOfWork) : (workInProgress = next); + null === current + ? completeUnitOfWork(unitOfWork) + : (workInProgress = current); + ReactCurrentOwner.current = null; } function throwAndUnwindWorkLoop(root, unitOfWork, thrownValue) { resetContextDependencies(); @@ -9822,20 +8666,14 @@ function throwAndUnwindWorkLoop(root, unitOfWork, thrownValue) { ) ) { workInProgressRootExitStatus = 1; - logUncaughtError( - root, - createCapturedValueAtFiber(thrownValue, root.current) - ); + workInProgressRootFatalError = thrownValue; workInProgress = null; return; } } catch (error) { if (null !== returnFiber) throw ((workInProgress = returnFiber), error); workInProgressRootExitStatus = 1; - logUncaughtError( - root, - createCapturedValueAtFiber(thrownValue, root.current) - ); + workInProgressRootFatalError = thrownValue; workInProgress = null; return; } @@ -9899,11 +8737,11 @@ function commitRoot( didIncludeRenderPhaseUpdate, spawnedLane ) { - var prevTransition = ReactSharedInternals.T, - previousUpdateLanePriority = currentUpdatePriority; + var previousUpdateLanePriority = currentUpdatePriority, + prevTransition = ReactCurrentBatchConfig.transition; try { - (currentUpdatePriority = 2), - (ReactSharedInternals.T = null), + (ReactCurrentBatchConfig.transition = null), + (currentUpdatePriority = 2), commitRootImpl( root, recoverableErrors, @@ -9913,7 +8751,7 @@ function commitRoot( spawnedLane ); } finally { - (ReactSharedInternals.T = prevTransition), + (ReactCurrentBatchConfig.transition = prevTransition), (currentUpdatePriority = previousUpdateLanePriority); } return null; @@ -9930,143 +8768,118 @@ function commitRootImpl( while (null !== rootWithPendingPassiveEffects); if (0 !== (executionContext & 6)) throw Error("Should not already be working."); - var finishedWork = root.finishedWork, - lanes = root.finishedLanes; - null !== injectedProfilingHooks && - "function" === typeof injectedProfilingHooks.markCommitStarted && - injectedProfilingHooks.markCommitStarted(lanes); - if (null === finishedWork) return markCommitStopped(), null; + didIncludeRenderPhaseUpdate = root.finishedWork; + transitions = root.finishedLanes; + if (null === didIncludeRenderPhaseUpdate) return null; root.finishedWork = null; root.finishedLanes = 0; - if (finishedWork === root.current) + if (didIncludeRenderPhaseUpdate === root.current) throw Error( "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." ); root.callbackNode = null; root.callbackPriority = 0; root.cancelPendingCommit = null; - var remainingLanes = finishedWork.lanes | finishedWork.childLanes; + var remainingLanes = + didIncludeRenderPhaseUpdate.lanes | didIncludeRenderPhaseUpdate.childLanes; remainingLanes |= concurrentlyUpdatedLanes; markRootFinished(root, remainingLanes, spawnedLane); - didIncludeCommitPhaseUpdate = !1; root === workInProgressRoot && ((workInProgress = workInProgressRoot = null), (workInProgressRootRenderLanes = 0)); - (0 === (finishedWork.subtreeFlags & 10256) && - 0 === (finishedWork.flags & 10256)) || + (0 === (didIncludeRenderPhaseUpdate.subtreeFlags & 10256) && + 0 === (didIncludeRenderPhaseUpdate.flags & 10256)) || rootDoesHavePassiveEffects || ((rootDoesHavePassiveEffects = !0), - (pendingPassiveEffectsRemainingLanes = remainingLanes), - (pendingPassiveTransitions = transitions), - scheduleCallback(NormalPriority$1, function () { + scheduleCallback(NormalPriority, function () { flushPassiveEffects(); return null; })); - transitions = 0 !== (finishedWork.flags & 15990); - if (0 !== (finishedWork.subtreeFlags & 15990) || transitions) { - transitions = ReactSharedInternals.T; - ReactSharedInternals.T = null; - spawnedLane = currentUpdatePriority; + spawnedLane = 0 !== (didIncludeRenderPhaseUpdate.flags & 15990); + if (0 !== (didIncludeRenderPhaseUpdate.subtreeFlags & 15990) || spawnedLane) { + spawnedLane = ReactCurrentBatchConfig.transition; + ReactCurrentBatchConfig.transition = null; + remainingLanes = currentUpdatePriority; currentUpdatePriority = 2; var prevExecutionContext = executionContext; executionContext |= 4; - commitBeforeMutationEffects(root, finishedWork); + ReactCurrentOwner.current = null; + commitBeforeMutationEffects(root, didIncludeRenderPhaseUpdate); commitTime = now(); - commitMutationEffects(root, finishedWork, lanes); - root.current = finishedWork; - null !== injectedProfilingHooks && - "function" === typeof injectedProfilingHooks.markLayoutEffectsStarted && - injectedProfilingHooks.markLayoutEffectsStarted(lanes); - commitLayoutEffects(finishedWork, root, lanes); - null !== injectedProfilingHooks && - "function" === typeof injectedProfilingHooks.markLayoutEffectsStopped && - injectedProfilingHooks.markLayoutEffectsStopped(); + commitMutationEffects(root, didIncludeRenderPhaseUpdate, transitions); + root.current = didIncludeRenderPhaseUpdate; + commitLayoutEffects(didIncludeRenderPhaseUpdate, root, transitions); requestPaint(); executionContext = prevExecutionContext; - currentUpdatePriority = spawnedLane; - ReactSharedInternals.T = transitions; - } else (root.current = finishedWork), (commitTime = now()); - rootDoesHavePassiveEffects - ? ((rootDoesHavePassiveEffects = !1), - (rootWithPendingPassiveEffects = root), - (pendingPassiveEffectsLanes = lanes)) - : releaseRootPooledCache(root, remainingLanes); + currentUpdatePriority = remainingLanes; + ReactCurrentBatchConfig.transition = spawnedLane; + } else (root.current = didIncludeRenderPhaseUpdate), (commitTime = now()); + rootDoesHavePassiveEffects && + ((rootDoesHavePassiveEffects = !1), + (rootWithPendingPassiveEffects = root), + (pendingPassiveEffectsLanes = transitions)); remainingLanes = root.pendingLanes; 0 === remainingLanes && (legacyErrorBoundariesThatAlreadyFailed = null); - onCommitRoot(finishedWork.stateNode, renderPriorityLevel); + onCommitRoot(didIncludeRenderPhaseUpdate.stateNode, renderPriorityLevel); isDevToolsPresent && root.memoizedUpdaters.clear(); ensureRootIsScheduled(root); if (null !== recoverableErrors) for ( - renderPriorityLevel = root.onRecoverableError, finishedWork = 0; - finishedWork < recoverableErrors.length; - finishedWork++ + renderPriorityLevel = root.onRecoverableError, + didIncludeRenderPhaseUpdate = 0; + didIncludeRenderPhaseUpdate < recoverableErrors.length; + didIncludeRenderPhaseUpdate++ ) - (remainingLanes = recoverableErrors[finishedWork]), - renderPriorityLevel(remainingLanes.value, { - componentStack: remainingLanes.stack - }); + (spawnedLane = recoverableErrors[didIncludeRenderPhaseUpdate]), + (remainingLanes = { + digest: spawnedLane.digest, + componentStack: spawnedLane.stack + }), + renderPriorityLevel(spawnedLane.value, remainingLanes); + if (hasUncaughtError) + throw ( + ((hasUncaughtError = !1), + (root = firstUncaughtError), + (firstUncaughtError = null), + root) + ); 0 !== (pendingPassiveEffectsLanes & 3) && 0 !== root.tag && flushPassiveEffects(); remainingLanes = root.pendingLanes; - didIncludeRenderPhaseUpdate || - didIncludeCommitPhaseUpdate || - (0 !== (lanes & 4194218) && 0 !== (remainingLanes & 42)) + 0 !== (transitions & 4194218) && 0 !== (remainingLanes & 42) ? ((nestedUpdateScheduled = !0), root === rootWithNestedUpdates ? nestedUpdateCount++ : ((nestedUpdateCount = 0), (rootWithNestedUpdates = root))) : (nestedUpdateCount = 0); flushSyncWorkAcrossRoots_impl(!1); - markCommitStopped(); return null; } -function releaseRootPooledCache(root, remainingLanes) { - 0 === (root.pooledCacheLanes &= remainingLanes) && - ((remainingLanes = root.pooledCache), - null != remainingLanes && - ((root.pooledCache = null), releaseCache(remainingLanes))); -} function flushPassiveEffects() { if (null !== rootWithPendingPassiveEffects) { - var root = rootWithPendingPassiveEffects, - remainingLanes = pendingPassiveEffectsRemainingLanes; - pendingPassiveEffectsRemainingLanes = 0; var renderPriority = lanesToEventPriority(pendingPassiveEffectsLanes), - prevTransition = ReactSharedInternals.T, + prevTransition = ReactCurrentBatchConfig.transition, previousPriority = currentUpdatePriority; try { + ReactCurrentBatchConfig.transition = null; currentUpdatePriority = 32 > renderPriority ? 32 : renderPriority; - ReactSharedInternals.T = null; if (null === rootWithPendingPassiveEffects) var JSCompiler_inline_result = !1; else { - var transitions = pendingPassiveTransitions; - pendingPassiveTransitions = null; renderPriority = rootWithPendingPassiveEffects; - var lanes = pendingPassiveEffectsLanes; rootWithPendingPassiveEffects = null; pendingPassiveEffectsLanes = 0; if (0 !== (executionContext & 6)) throw Error("Cannot flush passive effects while already rendering."); - null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markPassiveEffectsStarted && - injectedProfilingHooks.markPassiveEffectsStarted(lanes); var prevExecutionContext = executionContext; executionContext |= 4; commitPassiveUnmountOnFiber(renderPriority.current); - commitPassiveMountOnFiber( - renderPriority, - renderPriority.current, - lanes, - transitions - ); - transitions = pendingPassiveProfilerEffects; + commitPassiveMountOnFiber(renderPriority, renderPriority.current); + var profilerEffects = pendingPassiveProfilerEffects; pendingPassiveProfilerEffects = []; - for (lanes = 0; lanes < transitions.length; lanes++) { - var finishedWork = transitions[lanes]; + for (var i = 0; i < profilerEffects.length; i++) { + var finishedWork = profilerEffects[i]; if (executionContext & 4 && 0 !== (finishedWork.flags & 4)) switch (finishedWork.tag) { case 12: @@ -10075,16 +8888,11 @@ function flushPassiveEffects() { _finishedWork$memoize = finishedWork.memoizedProps, id = _finishedWork$memoize.id, onPostCommit = _finishedWork$memoize.onPostCommit, - commitTime$121 = commitTime, + commitTime$86 = commitTime, phase = null === finishedWork.alternate ? "mount" : "update"; currentUpdateIsNested && (phase = "nested-update"); "function" === typeof onPostCommit && - onPostCommit( - id, - phase, - passiveEffectDuration, - commitTime$121 - ); + onPostCommit(id, phase, passiveEffectDuration, commitTime$86); var parentFiber = finishedWork.return; b: for (; null !== parentFiber; ) { switch (parentFiber.tag) { @@ -10101,10 +8909,6 @@ function flushPassiveEffects() { } } } - null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markPassiveEffectsStopped && - injectedProfilingHooks.markPassiveEffectsStopped(); executionContext = prevExecutionContext; flushSyncWorkAcrossRoots_impl(!1); if ( @@ -10122,8 +8926,7 @@ function flushPassiveEffects() { return JSCompiler_inline_result; } finally { (currentUpdatePriority = previousPriority), - (ReactSharedInternals.T = prevTransition), - releaseRootPooledCache(root, remainingLanes); + (ReactCurrentBatchConfig.transition = prevTransition); } } return !1; @@ -10132,17 +8935,17 @@ function enqueuePendingPassiveProfilerEffect(fiber) { pendingPassiveProfilerEffects.push(fiber); rootDoesHavePassiveEffects || ((rootDoesHavePassiveEffects = !0), - scheduleCallback(NormalPriority$1, function () { + scheduleCallback(NormalPriority, function () { flushPassiveEffects(); return null; })); } function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { sourceFiber = createCapturedValueAtFiber(error, sourceFiber); - sourceFiber = createRootErrorUpdate(rootFiber.stateNode, sourceFiber, 2); + sourceFiber = createRootErrorUpdate(rootFiber, sourceFiber, 2); rootFiber = enqueueUpdate(rootFiber, sourceFiber, 2); null !== rootFiber && - (markRootUpdated(rootFiber, 2), ensureRootIsScheduled(rootFiber)); + (markRootUpdated$1(rootFiber, 2), ensureRootIsScheduled(rootFiber)); } function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error) { if (3 === sourceFiber.tag) @@ -10166,17 +8969,19 @@ function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error) { !legacyErrorBoundariesThatAlreadyFailed.has(instance))) ) { sourceFiber = createCapturedValueAtFiber(error, sourceFiber); - error = createClassErrorUpdate(2); - instance = enqueueUpdate(nearestMountedAncestor, error, 2); - null !== instance && - (initializeClassErrorUpdate( - error, - instance, - nearestMountedAncestor, - sourceFiber - ), - markRootUpdated(instance, 2), - ensureRootIsScheduled(instance)); + sourceFiber = createClassErrorUpdate( + nearestMountedAncestor, + sourceFiber, + 2 + ); + nearestMountedAncestor = enqueueUpdate( + nearestMountedAncestor, + sourceFiber, + 2 + ); + null !== nearestMountedAncestor && + (markRootUpdated$1(nearestMountedAncestor, 2), + ensureRootIsScheduled(nearestMountedAncestor)); break; } } @@ -10204,10 +9009,6 @@ function pingSuspendedRoot(root, wakeable, pingedLanes) { var pingCache = root.pingCache; null !== pingCache && pingCache.delete(wakeable); root.pingedLanes |= root.suspendedLanes & pingedLanes; - executionContext & 2 - ? (workInProgressRootDidIncludeRecursiveRenderUpdate = !0) - : executionContext & 4 && (didIncludeCommitPhaseUpdate = !0); - throwIfInfiniteUpdateLoopDetected(); workInProgressRoot === root && (workInProgressRootRenderLanes & pingedLanes) === pingedLanes && (4 === workInProgressRootExitStatus || @@ -10224,7 +9025,7 @@ function retryTimedOutBoundary(boundaryFiber, retryLane) { (retryLane = 0 === (boundaryFiber.mode & 1) ? 2 : claimNextRetryLane()); boundaryFiber = enqueueConcurrentRenderForLane(boundaryFiber, retryLane); null !== boundaryFiber && - (markRootUpdated(boundaryFiber, retryLane), + (markRootUpdated$1(boundaryFiber, retryLane), ensureRootIsScheduled(boundaryFiber)); } function retryDehydratedSuspenseBoundary(boundaryFiber) { @@ -10255,20 +9056,6 @@ function resolveRetryWakeable(boundaryFiber, wakeable) { null !== retryCache && retryCache.delete(wakeable); retryTimedOutBoundary(boundaryFiber, retryLane); } -function throwIfInfiniteUpdateLoopDetected() { - if (50 < nestedUpdateCount) - throw ( - ((nestedUpdateCount = 0), - (rootWithNestedUpdates = null), - executionContext & 2 && - null !== workInProgressRoot && - (workInProgressRoot.errorRecoveryDisabledLanes |= - workInProgressRootRenderLanes), - Error( - "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." - )) - ); -} function restorePendingUpdaters(root, lanes) { isDevToolsPresent && root.memoizedUpdaters.forEach(function (schedulingFiber) { @@ -10276,7 +9063,7 @@ function restorePendingUpdaters(root, lanes) { }); } function scheduleCallback(priorityLevel, callback) { - return scheduleCallback$3(priorityLevel, callback); + return scheduleCallback$2(priorityLevel, callback); } function FiberNode(tag, pendingProps, key, mode) { this.tag = tag; @@ -10312,6 +9099,16 @@ function shouldConstruct(Component) { Component = Component.prototype; return !(!Component || !Component.isReactComponent); } +function resolveLazyComponentTag(Component) { + if ("function" === typeof Component) + return shouldConstruct(Component) ? 1 : 0; + if (void 0 !== Component && null !== Component) { + Component = Component.$$typeof; + if (Component === REACT_FORWARD_REF_TYPE) return 11; + if (Component === REACT_MEMO_TYPE) return 14; + } + return 2; +} function createWorkInProgress(current, pendingProps) { var workInProgress = current.alternate; null === workInProgress @@ -10397,7 +9194,7 @@ function createFiberFromTypeAndProps( mode, lanes ) { - var fiberTag = 0; + var fiberTag = 2; owner = type; if ("function" === typeof type) shouldConstruct(type) && (fiberTag = 1); else if ("string" === typeof type) fiberTag = 5; @@ -10438,12 +9235,12 @@ function createFiberFromTypeAndProps( if ("object" === typeof type && null !== type) switch (type.$$typeof) { case REACT_PROVIDER_TYPE: - case REACT_CONTEXT_TYPE: fiberTag = 10; break a; - case REACT_CONSUMER_TYPE: + case REACT_CONTEXT_TYPE: fiberTag = 9; break a; + case REACT_CONSUMER_TYPE: case REACT_FORWARD_REF_TYPE: fiberTag = 11; break a; @@ -10457,7 +9254,7 @@ function createFiberFromTypeAndProps( } throw Error( "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + - ((null === type ? "null" : typeof type) + ".") + ((null == type ? type : typeof type) + ".") ); } key = createFiber(fiberTag, pendingProps, key, mode); @@ -10537,8 +9334,6 @@ function FiberRootNode( tag, hydrate, identifierPrefix, - onUncaughtError, - onCaughtError, onRecoverableError, formState ) { @@ -10570,11 +9365,7 @@ function FiberRootNode( this.entanglements = createLaneMap(0); this.hiddenUpdates = createLaneMap(null); this.identifierPrefix = identifierPrefix; - this.onUncaughtError = onUncaughtError; - this.onCaughtError = onCaughtError; this.onRecoverableError = onRecoverableError; - this.pooledCache = null; - this.pooledCacheLanes = 0; this.formState = formState; this.incompleteTransitions = new Map(); this.passiveEffectDuration = this.effectDuration = 0; @@ -10609,9 +9400,6 @@ function findHostInstance(component) { function updateContainer(element, container, parentComponent, callback) { parentComponent = container.current; var lane = requestUpdateLane(parentComponent); - null !== injectedProfilingHooks && - "function" === typeof injectedProfilingHooks.markRenderScheduled && - injectedProfilingHooks.markRenderScheduled(lane); null === container.context ? (container.context = emptyContextObject) : (container.pendingContext = emptyContextObject); @@ -10654,30 +9442,8 @@ function findNodeHandle(componentOrHandle) { function getInspectorDataForInstance() { throw Error("getInspectorDataForInstance() is not available in production"); } -if ( - "function" !== - typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog -) - throw Error( - "Expected ReactFiberErrorDialog.showErrorDialog to be a function." - ); -function nativeOnUncaughtError(error, errorInfo) { - !1 !== - ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog({ - errorBoundary: null, - error: error, - componentStack: - null != errorInfo.componentStack ? errorInfo.componentStack : "" - }) && reportGlobalError(error); -} -function nativeOnCaughtError(error, errorInfo) { - !1 !== - ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog({ - errorBoundary: errorInfo.errorBoundary, - error: error, - componentStack: - null != errorInfo.componentStack ? errorInfo.componentStack : "" - }) && console.error(error); +function onRecoverableError(error) { + console.error(error); } batchedUpdatesImpl = function (fn, a) { var prevExecutionContext = executionContext; @@ -10692,10 +9458,10 @@ batchedUpdatesImpl = function (fn, a) { } }; var roots = new Map(), - devToolsConfig$jscomp$inline_1187 = { + devToolsConfig$jscomp$inline_1090 = { findFiberByHostInstance: getInstanceFromNode, bundleType: 0, - version: "19.0.0-rc-fb9a90fa48-20240614", + version: "18.3.0-canary-f2de0db5", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForInstance: getInspectorDataForInstance, @@ -10711,24 +9477,11 @@ var roots = new Map(), }.bind(null, findNodeHandle) } }; -(function (internals) { - if ("undefined" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) return !1; - var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; - if (hook.isDisabled || !hook.supportsFiber) return !0; - try { - (internals = assign({}, internals, { - getLaneLabelMap: getLaneLabelMap, - injectProfilingHooks: injectProfilingHooks - })), - (rendererID = hook.inject(internals)), - (injectedHook = hook); - } catch (err) {} - return hook.checkDCE ? !0 : !1; -})({ - bundleType: devToolsConfig$jscomp$inline_1187.bundleType, - version: devToolsConfig$jscomp$inline_1187.version, - rendererPackageName: devToolsConfig$jscomp$inline_1187.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_1187.rendererConfig, +var internals$jscomp$inline_1312 = { + bundleType: devToolsConfig$jscomp$inline_1090.bundleType, + version: devToolsConfig$jscomp$inline_1090.version, + rendererPackageName: devToolsConfig$jscomp$inline_1090.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_1090.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -10738,21 +9491,34 @@ var roots = new Map(), setErrorHandler: null, setSuspenseHandler: null, scheduleUpdate: null, - currentDispatcherRef: ReactSharedInternals, + currentDispatcherRef: ReactSharedInternals.ReactCurrentDispatcher, findHostInstanceByFiber: function (fiber) { fiber = findCurrentHostFiber(fiber); return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_1187.findFiberByHostInstance || + devToolsConfig$jscomp$inline_1090.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "19.0.0-rc-fb9a90fa48-20240614" -}); + reconcilerVersion: "18.3.0-canary-f2de0db5" +}; +if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { + var hook$jscomp$inline_1313 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + if ( + !hook$jscomp$inline_1313.isDisabled && + hook$jscomp$inline_1313.supportsFiber + ) + try { + (rendererID = hook$jscomp$inline_1313.inject( + internals$jscomp$inline_1312 + )), + (injectedHook = hook$jscomp$inline_1313); + } catch (err) {} +} exports.createPortal = function (children, containerTag) { return createPortal$1( children, @@ -10812,56 +9578,27 @@ exports.getPublicInstanceFromInternalInstanceHandle = function ( exports.isChildPublicInstance = function () { throw Error("isChildPublicInstance() is not available in production."); }; -exports.render = function ( - element, - containerTag, - callback, - concurrentRoot, - options -) { +exports.render = function (element, containerTag, callback, concurrentRoot) { var root = roots.get(containerTag); - if (!root) { - root = nativeOnUncaughtError; - var onCaughtError = nativeOnCaughtError, - onRecoverableError = defaultOnRecoverableError; - options && - void 0 !== options.onUncaughtError && - (root = options.onUncaughtError); - options && - void 0 !== options.onCaughtError && - (onCaughtError = options.onCaughtError); - options && - void 0 !== options.onRecoverableError && - (onRecoverableError = options.onRecoverableError); - concurrentRoot = concurrentRoot ? 1 : 0; - options = new FiberRootNode( + root || + ((root = concurrentRoot ? 1 : 0), + (concurrentRoot = new FiberRootNode( containerTag, - concurrentRoot, + root, !1, "", - root, - onCaughtError, onRecoverableError, null - ); - concurrentRoot = 1 === concurrentRoot ? 1 : 0; - isDevToolsPresent && (concurrentRoot |= 2); - concurrentRoot = createFiber(3, null, null, concurrentRoot); - options.current = concurrentRoot; - concurrentRoot.stateNode = options; - root = createCache(); - root.refCount++; - options.pooledCache = root; - root.refCount++; - concurrentRoot.memoizedState = { - element: null, - isDehydrated: !1, - cache: root - }; - initializeUpdateQueue(concurrentRoot); - root = options; - roots.set(containerTag, root); - } + )), + (root = 1 === root ? 1 : 0), + isDevToolsPresent && (root |= 2), + (root = createFiber(3, null, null, root)), + (concurrentRoot.current = root), + (root.stateNode = concurrentRoot), + (root.memoizedState = { element: null, isDehydrated: !1, cache: 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/packages/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js b/packages/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js index be827c36fb3126..2544f756e3aaa7 100644 --- a/packages/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js +++ b/packages/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js @@ -6,839 +6,605 @@ * * @noflow * @nolint + * @providesModule ReactNativeRenderer-dev * @preventMunge - * @generated SignedSource<> - * - * This file was sync'd from the facebook/react repository. + * @generated SignedSource<<4fbb60a6e6520f92ffc104738fdd5ce8>> */ "use strict"; -__DEV__ && + +if (__DEV__) { (function () { - function findHook(fiber, id) { - for (fiber = fiber.memoizedState; null !== fiber && 0 < id; ) - (fiber = fiber.next), id--; - return fiber; - } - function copyWithSetImpl(obj, path, index, value) { - if (index >= path.length) return value; - var key = path[index], - updated = isArrayImpl(obj) ? obj.slice() : assign({}, obj); - updated[key] = copyWithSetImpl(obj[key], path, index + 1, value); - return updated; - } - function copyWithRename(obj, oldPath, newPath) { - if (oldPath.length !== newPath.length) - warn("copyWithRename() expects paths of the same length"); - else { - for (var i = 0; i < newPath.length - 1; i++) - if (oldPath[i] !== newPath[i]) { - warn( - "copyWithRename() expects paths to be the same except for the deepest key" - ); - return; - } - return copyWithRenameImpl(obj, oldPath, newPath, 0); - } - } - function copyWithRenameImpl(obj, oldPath, newPath, index) { - var oldKey = oldPath[index], - updated = isArrayImpl(obj) ? obj.slice() : assign({}, obj); - index + 1 === oldPath.length - ? ((updated[newPath[index]] = updated[oldKey]), - isArrayImpl(updated) - ? updated.splice(oldKey, 1) - : delete updated[oldKey]) - : (updated[oldKey] = copyWithRenameImpl( - obj[oldKey], - oldPath, - newPath, - index + 1 - )); - return updated; - } - function copyWithDeleteImpl(obj, path, index) { - var key = path[index], - updated = isArrayImpl(obj) ? obj.slice() : assign({}, obj); - if (index + 1 === path.length) - return ( - isArrayImpl(updated) ? updated.splice(key, 1) : delete updated[key], - updated - ); - updated[key] = copyWithDeleteImpl(obj[key], path, index + 1); - return updated; - } - function shouldSuspendImpl() { - return !1; - } - function shouldErrorImpl() { - return null; - } - function findHostInstancesForRefresh(root, families) { - var hostInstances = new Set(); - families = new Set( - families.map(function (family) { - return family.current; - }) - ); - findHostInstancesForMatchingFibersRecursively( - root.current, - families, - hostInstances - ); - return hostInstances; - } - function scheduleRoot(root, element) { - root.context === emptyContextObject && - (0 === root.tag && flushPassiveEffects(), - updateContainerImpl(root.current, SyncLane, element, root, null, null), - flushSyncWork()); - } - function scheduleRefresh(root, update) { - if (null !== resolveFamily) { - var staleFamilies = update.staleFamilies; - update = update.updatedFamilies; - flushPassiveEffects(); - scheduleFibersWithFamiliesRecursively( - root.current, - update, - staleFamilies - ); - flushSyncWork(); - } - } - function setRefreshHandler(handler) { - resolveFamily = handler; - } - function warnInvalidHookAccess() { - error$jscomp$0( - "Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. You can only call Hooks at the top level of your React function. For more information, see https://react.dev/link/rules-of-hooks" - ); - } - function warnInvalidContextAccess() { - error$jscomp$0( - "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()." - ); - } - function warnForMissingKey() {} - function setToSortedString(set) { - var array = []; - set.forEach(function (value) { - array.push(value); - }); - return array.sort().join(", "); - } - function batchedUpdatesImpl(fn, bookkeeping) { - return fn(bookkeeping); - } - function warn(format) { - if (!suppressWarning) { - for ( - var _len = arguments.length, - args = Array(1 < _len ? _len - 1 : 0), - _key = 1; - _key < _len; - _key++ - ) - args[_key - 1] = arguments[_key]; - printWarning("warn", format, args, Error("react-stack-top-frame")); - } - } - function error$jscomp$0(format) { - if (!suppressWarning) { - for ( - var _len2 = arguments.length, - args = Array(1 < _len2 ? _len2 - 1 : 0), - _key2 = 1; - _key2 < _len2; - _key2++ - ) - args[_key2 - 1] = arguments[_key2]; - printWarning("error", format, args, Error("react-stack-top-frame")); - } - } - function printWarning(level, format, args, currentStack) { - !supportsCreateTask && - ReactSharedInternals.getCurrentStack && - ((currentStack = ReactSharedInternals.getCurrentStack(currentStack)), - "" !== currentStack && - ((format += "%s"), (args = args.concat([currentStack])))); - args.unshift(format); - Function.prototype.apply.call(console[level], console, args); - } - function getIteratorFn(maybeIterable) { - if (null === maybeIterable || "object" !== typeof maybeIterable) - return null; - maybeIterable = - (MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL]) || - maybeIterable["@@iterator"]; - return "function" === typeof maybeIterable ? maybeIterable : null; - } - function disabledLog() {} - function disableLogs() { - if (0 === disabledDepth) { - prevLog = console.log; - prevInfo = console.info; - prevWarn = console.warn; - prevError = console.error; - prevGroup = console.group; - prevGroupCollapsed = console.groupCollapsed; - prevGroupEnd = console.groupEnd; - var props = { - configurable: !0, - enumerable: !0, - value: disabledLog, - writable: !0 - }; - Object.defineProperties(console, { - info: props, - log: props, - warn: props, - error: props, - group: props, - groupCollapsed: props, - groupEnd: props - }); - } - disabledDepth++; - } - function reenableLogs() { - disabledDepth--; - if (0 === disabledDepth) { - var props = { configurable: !0, enumerable: !0, writable: !0 }; - Object.defineProperties(console, { - log: assign({}, props, { value: prevLog }), - info: assign({}, props, { value: prevInfo }), - warn: assign({}, props, { value: prevWarn }), - error: assign({}, props, { value: prevError }), - group: assign({}, props, { value: prevGroup }), - groupCollapsed: assign({}, props, { value: prevGroupCollapsed }), - groupEnd: assign({}, props, { value: prevGroupEnd }) - }); - } - 0 > disabledDepth && - error$jscomp$0( - "disabledDepth fell below zero. This is a bug in React. Please file an issue." - ); + "use strict"; + + /* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */ + if ( + typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined" && + typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart === + "function" + ) { + __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error()); } - function describeBuiltInComponentFrame(name) { - if (void 0 === prefix) - try { - throw Error(); - } catch (x) { - var match = x.stack.trim().match(/\n( *(at )?)/); - prefix = (match && match[1]) || ""; - } - return "\n" + prefix + name; - } - function describeNativeComponentFrame(fn, construct) { - if (!fn || reentry) return ""; - var frame = componentFrameCache.get(fn); - if (void 0 !== frame) return frame; - reentry = !0; - frame = Error.prepareStackTrace; - Error.prepareStackTrace = void 0; - var previousDispatcher = null; - previousDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = null; - disableLogs(); - var RunInRootFrame = { - DetermineComponentFrameRoot: function () { - try { - if (construct) { - var Fake = function () { - throw Error(); - }; - Object.defineProperty(Fake.prototype, "props", { - set: function () { - throw Error(); - } - }); - if ("object" === typeof Reflect && Reflect.construct) { - try { - Reflect.construct(Fake, []); - } catch (x) { - var control = x; - } - Reflect.construct(fn, [], Fake); - } else { - try { - Fake.call(); - } catch (x$0) { - control = x$0; - } - fn.call(Fake.prototype); - } - } else { - try { - throw Error(); - } catch (x$1) { - control = x$1; - } - (Fake = fn()) && - "function" === typeof Fake.catch && - Fake.catch(function () {}); - } - } catch (sample) { - if (sample && control && "string" === typeof sample.stack) - return [sample.stack, control.stack]; - } - return [null, null]; - } - }; - RunInRootFrame.DetermineComponentFrameRoot.displayName = - "DetermineComponentFrameRoot"; - var namePropDescriptor = Object.getOwnPropertyDescriptor( - RunInRootFrame.DetermineComponentFrameRoot, - "name" - ); - namePropDescriptor && - namePropDescriptor.configurable && - Object.defineProperty( - RunInRootFrame.DetermineComponentFrameRoot, - "name", - { value: "DetermineComponentFrameRoot" } - ); - try { - var _RunInRootFrame$Deter = - RunInRootFrame.DetermineComponentFrameRoot(), - sampleStack = _RunInRootFrame$Deter[0], - controlStack = _RunInRootFrame$Deter[1]; - if (sampleStack && controlStack) { - var sampleLines = sampleStack.split("\n"), - controlLines = controlStack.split("\n"); - for ( - sampleStack = _RunInRootFrame$Deter = 0; - _RunInRootFrame$Deter < sampleLines.length && - !sampleLines[_RunInRootFrame$Deter].includes( - "DetermineComponentFrameRoot" - ); + var React = require("react"); + require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); + var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"); + var Scheduler = require("scheduler"); - ) - _RunInRootFrame$Deter++; - for ( - ; - sampleStack < controlLines.length && - !controlLines[sampleStack].includes("DetermineComponentFrameRoot"); + var ReactSharedInternals = + React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; - ) - sampleStack++; - if ( - _RunInRootFrame$Deter === sampleLines.length || - sampleStack === controlLines.length - ) - for ( - _RunInRootFrame$Deter = sampleLines.length - 1, - sampleStack = controlLines.length - 1; - 1 <= _RunInRootFrame$Deter && - 0 <= sampleStack && - sampleLines[_RunInRootFrame$Deter] !== controlLines[sampleStack]; + // by calls to these methods by a Babel plugin. + // + // In PROD (or in packages without access to React internals), + // they are left as they are instead. - ) - sampleStack--; + function warn(format) { + { + { for ( - ; - 1 <= _RunInRootFrame$Deter && 0 <= sampleStack; - _RunInRootFrame$Deter--, sampleStack-- - ) - if ( - sampleLines[_RunInRootFrame$Deter] !== controlLines[sampleStack] - ) { - if (1 !== _RunInRootFrame$Deter || 1 !== sampleStack) { - do - if ( - (_RunInRootFrame$Deter--, - sampleStack--, - 0 > sampleStack || - sampleLines[_RunInRootFrame$Deter] !== - controlLines[sampleStack]) - ) { - var _frame = - "\n" + - sampleLines[_RunInRootFrame$Deter].replace( - " at new ", - " at " - ); - fn.displayName && - _frame.includes("") && - (_frame = _frame.replace("", fn.displayName)); - "function" === typeof fn && - componentFrameCache.set(fn, _frame); - return _frame; - } - while (1 <= _RunInRootFrame$Deter && 0 <= sampleStack); - } - break; - } + var _len = arguments.length, + args = new Array(_len > 1 ? _len - 1 : 0), + _key = 1; + _key < _len; + _key++ + ) { + args[_key - 1] = arguments[_key]; + } + + printWarning("warn", format, args); } - } finally { - (reentry = !1), - (ReactSharedInternals.H = previousDispatcher), - reenableLogs(), - (Error.prepareStackTrace = frame); - } - sampleLines = (sampleLines = fn ? fn.displayName || fn.name : "") - ? describeBuiltInComponentFrame(sampleLines) - : ""; - "function" === typeof fn && componentFrameCache.set(fn, sampleLines); - return sampleLines; - } - function callComponentInDEV(Component, props, secondArg) { - var wasRendering = isRendering; - isRendering = !0; - try { - return Component(props, secondArg); - } finally { - isRendering = wasRendering; } } - function callRenderInDEV(instance) { - var wasRendering = isRendering; - isRendering = !0; - try { - return instance.render(); - } finally { - isRendering = wasRendering; - } - } - function callLazyInitInDEV(lazy) { - var init = lazy._init; - return init(lazy._payload); - } - function isNotExternal(stackFrame) { - return !externalRegExp.test(stackFrame); - } - function filterDebugStack(error) { - error = error.stack; - error.startsWith("Error: react-stack-top-frame\n") && - (error = error.slice(29)); - error = error.split("\n").slice(1); - if (null === callComponentFrame) { - var stack = callComponentInDEV( - Error, - "react-stack-top-frame", - {} - ).stack, - startIdx = stack.startsWith("Error: react-stack-top-frame\n") - ? 29 - : 0, - endIdx = stack.indexOf("\n", startIdx); - callComponentFrame = - -1 === endIdx ? stack.slice(startIdx) : stack.slice(startIdx, endIdx); - } - stack = error.indexOf(callComponentFrame); - if ( - -1 === stack && - (null === callLazyInitFrame && - ((stack = callLazyInitInDEV({ - $$typeof: REACT_LAZY_TYPE, - _init: Error, - _payload: "react-stack-top-frame" - }).stack), - (startIdx = stack.startsWith("Error: react-stack-top-frame\n") - ? 29 - : 0), - (endIdx = stack.indexOf("\n", startIdx)), - (callLazyInitFrame = - -1 === endIdx - ? stack.slice(startIdx) - : stack.slice(startIdx, endIdx))), - (stack = error.indexOf(callLazyInitFrame)), - -1 === stack) - ) { - if (null === callIteratorFrame) - try { - callRenderInDEV({ render: null }), (callIteratorFrame = ""); - } catch (error$2) { - (stack = error$2.stack), - (startIdx = stack.startsWith("TypeError: ") - ? stack.indexOf("\n") + 1 - : 0), - (endIdx = stack.indexOf("\n", startIdx)), - (callIteratorFrame = - -1 === endIdx - ? stack.slice(startIdx) - : stack.slice(startIdx, endIdx)); - } - stack = error.indexOf(callIteratorFrame); - } - if (-1 !== stack) error.length = stack; - else return ""; - return error.filter(isNotExternal).join("\n"); - } - function describeFiber(fiber) { - switch (fiber.tag) { - case 26: - case 27: - case 5: - return describeBuiltInComponentFrame(fiber.type); - case 16: - return describeBuiltInComponentFrame("Lazy"); - case 13: - return describeBuiltInComponentFrame("Suspense"); - case 19: - return describeBuiltInComponentFrame("SuspenseList"); - case 0: - case 15: - return (fiber = describeNativeComponentFrame(fiber.type, !1)), fiber; - case 11: - return ( - (fiber = describeNativeComponentFrame(fiber.type.render, !1)), fiber - ); - case 1: - return (fiber = describeNativeComponentFrame(fiber.type, !0)), fiber; - default: - return ""; + function error(format) { + { + { + for ( + var _len2 = arguments.length, + args = new Array(_len2 > 1 ? _len2 - 1 : 0), + _key2 = 1; + _key2 < _len2; + _key2++ + ) { + args[_key2 - 1] = arguments[_key2]; + } + + printWarning("error", format, args); + } } } - function getStackByFiberInDevAndProd(workInProgress) { - try { - var info = ""; - do { - info += describeFiber(workInProgress); - var debugInfo = workInProgress._debugInfo; - if (debugInfo) - for (var i = debugInfo.length - 1; 0 <= i; i--) { - var entry = debugInfo[i]; - if ("string" === typeof entry.name) { - var JSCompiler_temp_const = info, - env = entry.env; - var JSCompiler_inline_result = describeBuiltInComponentFrame( - entry.name + (env ? " (" + env + ")" : "") - ); - info = JSCompiler_temp_const + JSCompiler_inline_result; - } - } - workInProgress = workInProgress.return; - } while (workInProgress); - return info; - } catch (x) { - return "\nError generating stack: " + x.message + "\n" + x.stack; + + function printWarning(level, format, args) { + // When changing this logic, you might want to also + // update consoleWithStackDev.www.js as well. + { + var ReactDebugCurrentFrame = + ReactSharedInternals.ReactDebugCurrentFrame; + var stack = ReactDebugCurrentFrame.getStackAddendum(); + + if (stack !== "") { + format += "%s"; + args = args.concat([stack]); + } // eslint-disable-next-line react-internal/safe-string-coercion + + var argsWithFormat = args.map(function (item) { + return String(item); + }); // Careful: RN currently depends on this prefix + + argsWithFormat.unshift("Warning: " + format); // We intentionally don't use spread (or .apply) directly because it + // breaks IE9: https://github.com/facebook/react/issues/13610 + // eslint-disable-next-line react-internal/no-production-logging + + Function.prototype.apply.call(console[level], console, argsWithFormat); } } - function describeFunctionComponentFrameWithoutLineNumber(fn) { - return (fn = fn ? fn.displayName || fn.name : "") - ? describeBuiltInComponentFrame(fn) - : ""; - } - function getComponentNameFromType(type) { - if (null == type) return null; - if ("function" === typeof type) - return type.$$typeof === REACT_CLIENT_REFERENCE - ? null - : type.displayName || type.name || null; - if ("string" === typeof type) return type; - switch (type) { - case REACT_FRAGMENT_TYPE: - return "Fragment"; - case REACT_PORTAL_TYPE: - return "Portal"; - case REACT_PROFILER_TYPE: - return "Profiler"; - case REACT_STRICT_MODE_TYPE: - return "StrictMode"; - case REACT_SUSPENSE_TYPE: - return "Suspense"; - case REACT_SUSPENSE_LIST_TYPE: - return "SuspenseList"; - } - if ("object" === typeof type) - switch ( - ("number" === typeof type.tag && - error$jscomp$0( - "Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue." - ), - type.$$typeof) - ) { - case REACT_CONTEXT_TYPE: - return (type.displayName || "Context") + ".Provider"; - case REACT_CONSUMER_TYPE: - return (type._context.displayName || "Context") + ".Consumer"; - case REACT_FORWARD_REF_TYPE: - var innerType = type.render; - type = type.displayName; - type || - ((type = innerType.displayName || innerType.name || ""), - (type = "" !== type ? "ForwardRef(" + type + ")" : "ForwardRef")); - return type; - case REACT_MEMO_TYPE: - return ( - (innerType = type.displayName || null), - null !== innerType - ? innerType - : getComponentNameFromType(type.type) || "Memo" - ); - case REACT_LAZY_TYPE: - innerType = type._payload; - type = type._init; - try { - return getComponentNameFromType(type(innerType)); - } catch (x) {} - } - return null; + + var isArrayImpl = Array.isArray; // eslint-disable-next-line no-redeclare + + function isArray(a) { + return isArrayImpl(a); } - function getComponentNameFromFiber(fiber) { - var type = fiber.type; - switch (fiber.tag) { - case 24: - return "Cache"; - case 9: - return (type._context.displayName || "Context") + ".Consumer"; - case 10: - return (type.displayName || "Context") + ".Provider"; - case 18: - return "DehydratedFragment"; - case 11: - return ( - (fiber = type.render), - (fiber = fiber.displayName || fiber.name || ""), - type.displayName || - ("" !== fiber ? "ForwardRef(" + fiber + ")" : "ForwardRef") + + var hasError = false; + var caughtError = null; + var getFiberCurrentPropsFromNode$1 = null; + var getInstanceFromNode = null; + var getNodeFromInstance = null; + function setComponentTree( + getFiberCurrentPropsFromNodeImpl, + getInstanceFromNodeImpl, + getNodeFromInstanceImpl + ) { + getFiberCurrentPropsFromNode$1 = getFiberCurrentPropsFromNodeImpl; + getInstanceFromNode = getInstanceFromNodeImpl; + getNodeFromInstance = getNodeFromInstanceImpl; + + { + if (!getNodeFromInstance || !getInstanceFromNode) { + error( + "Injected " + + "module is missing getNodeFromInstance or getInstanceFromNode." ); - case 7: - return "Fragment"; - case 26: - case 27: - case 5: - return type; - case 4: - return "Portal"; - case 3: - return "Root"; - case 6: - return "Text"; - case 16: - return getComponentNameFromType(type); - 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 25: - return "TracingMarker"; - case 17: - case 28: - case 1: - case 0: - case 14: - case 15: - if ("function" === typeof type) - return type.displayName || type.name || null; - if ("string" === typeof type) return type; - break; - case 29: - type = fiber._debugInfo; - if (null != type) - for (var i = type.length - 1; 0 <= i; i--) - if ("string" === typeof type[i].name) return type[i].name; - if (null !== fiber.return) - return getComponentNameFromFiber(fiber.return); - } - return null; - } - function getCurrentFiberStackInDev(stack) { - if (null === current) return ""; - var workInProgress = current; - try { - var info = ""; - if (stack) { - var formattedTopStack = filterDebugStack(stack); - "" !== formattedTopStack && (info += "\n" + formattedTopStack); } - 6 === workInProgress.tag && (workInProgress = workInProgress.return); - switch (workInProgress.tag) { - case 26: - case 27: - case 5: - info += describeBuiltInComponentFrame(workInProgress.type); - break; - case 13: - info += describeBuiltInComponentFrame("Suspense"); - break; - case 19: - info += describeBuiltInComponentFrame("SuspenseList"); - break; - case 0: - case 15: - case 1: - workInProgress._debugOwner || - "" !== info || - (info += describeFunctionComponentFrameWithoutLineNumber( - workInProgress.type - )); - break; - case 11: - workInProgress._debugOwner || - "" !== info || - (info += describeFunctionComponentFrameWithoutLineNumber( - workInProgress.type.render - )); - } - for (stack = workInProgress; stack; ) - if ("number" === typeof stack.tag) { - workInProgress = stack; - stack = workInProgress._debugOwner; - var debugStack = workInProgress._debugStack; - stack && - debugStack && - ("string" !== typeof debugStack && - (workInProgress._debugStack = debugStack = - filterDebugStack(debugStack)), - "" !== debugStack && (info += "\n" + debugStack)); - } else if ("string" === typeof stack.stack) - "" !== stack.stack && (info += "\n" + stack.stack), - (stack = stack.owner); - else break; - var JSCompiler_inline_result = info; - } catch (x) { - JSCompiler_inline_result = - "\nError generating stack: " + x.message + "\n" + x.stack; - } - return JSCompiler_inline_result; - } - function runWithFiberInDEV(fiber, callback, arg0, arg1, arg2, arg3, arg4) { - var previousFiber = current; - ReactSharedInternals.getCurrentStack = - null === fiber ? null : getCurrentFiberStackInDev; - isRendering = !1; - current = fiber; - try { - return null !== fiber && fiber._debugTask - ? fiber._debugTask.run( - callback.bind(null, arg0, arg1, arg2, arg3, arg4) - ) - : callback(arg0, arg1, arg2, arg3, arg4); - } finally { - current = previousFiber; } - throw Error( - "runWithFiberInDEV should never be called in production. This is a bug in React." - ); } + function validateEventDispatches(event) { - var dispatchListeners = event._dispatchListeners, - dispatchInstances = event._dispatchInstances; - dispatchListeners = (event = isArrayImpl(dispatchListeners)) - ? dispatchListeners.length - : dispatchListeners - ? 1 - : 0; - var instancesIsArr = isArrayImpl(dispatchInstances); - dispatchInstances = instancesIsArr - ? dispatchInstances.length - : dispatchInstances - ? 1 - : 0; - (instancesIsArr === event && dispatchInstances === dispatchListeners) || - error$jscomp$0("EventPluginUtils: Invalid `event`."); + { + var dispatchListeners = event._dispatchListeners; + var dispatchInstances = event._dispatchInstances; + var listenersIsArr = isArray(dispatchListeners); + var listenersLen = listenersIsArr + ? dispatchListeners.length + : dispatchListeners + ? 1 + : 0; + var instancesIsArr = isArray(dispatchInstances); + var instancesLen = instancesIsArr + ? dispatchInstances.length + : dispatchInstances + ? 1 + : 0; + + if ( + instancesIsArr !== listenersIsArr || + instancesLen !== listenersLen + ) { + error("EventPluginUtils: Invalid `event`."); + } + } } + /** + * Dispatch the event to the listener. + * @param {SyntheticEvent} event SyntheticEvent to handle + * @param {function} listener Application-level callback + * @param {*} inst Internal component instance + */ + function executeDispatch(event, listener, inst) { event.currentTarget = getNodeFromInstance(inst); + try { listener(event); - } catch (error$3) { - hasError || ((hasError = !0), (caughtError = error$3)); + } catch (error) { + if (!hasError) { + hasError = true; + caughtError = error; + } } + event.currentTarget = null; } - function executeDirectDispatch(event) { - validateEventDispatches(event); - var dispatchListener = event._dispatchListeners, - dispatchInstance = event._dispatchInstances; - if (isArrayImpl(dispatchListener)) throw Error("Invalid `event`."); - event.currentTarget = dispatchListener - ? getNodeFromInstance(dispatchInstance) - : null; - dispatchListener = dispatchListener ? dispatchListener(event) : null; - event.currentTarget = null; + /** + * Standard/simple iteration through an event's collected dispatches. + */ + + function executeDispatchesInOrder(event) { + var dispatchListeners = event._dispatchListeners; + var dispatchInstances = event._dispatchInstances; + + { + validateEventDispatches(event); + } + + if (isArray(dispatchListeners)) { + for (var i = 0; i < dispatchListeners.length; i++) { + if (event.isPropagationStopped()) { + break; + } // Listeners and Instances are two parallel arrays that are always in sync. + + executeDispatch(event, dispatchListeners[i], dispatchInstances[i]); + } + } else if (dispatchListeners) { + executeDispatch(event, dispatchListeners, dispatchInstances); + } + event._dispatchListeners = null; event._dispatchInstances = null; - return dispatchListener; - } - function functionThatReturnsTrue() { - return !0; } - function functionThatReturnsFalse() { - return !1; + /** + * Standard/simple iteration through an event's collected dispatches, but stops + * at the first dispatch execution returning true, and returns that id. + * + * @return {?string} id of the first dispatch execution who's listener returns + * true, or null if no listener returned true. + */ + + function executeDispatchesInOrderStopAtTrueImpl(event) { + var dispatchListeners = event._dispatchListeners; + var dispatchInstances = event._dispatchInstances; + + { + validateEventDispatches(event); + } + + if (isArray(dispatchListeners)) { + for (var i = 0; i < dispatchListeners.length; i++) { + if (event.isPropagationStopped()) { + break; + } // Listeners and Instances are two parallel arrays that are always in sync. + + if (dispatchListeners[i](event, dispatchInstances[i])) { + return dispatchInstances[i]; + } + } + } else if (dispatchListeners) { + if (dispatchListeners(event, dispatchInstances)) { + return dispatchInstances; + } + } + + return null; } - function SyntheticEvent( - dispatchConfig, + /** + * @see executeDispatchesInOrderStopAtTrueImpl + */ + + function executeDispatchesInOrderStopAtTrue(event) { + var ret = executeDispatchesInOrderStopAtTrueImpl(event); + event._dispatchInstances = null; + event._dispatchListeners = null; + return ret; + } + /** + * Execution of a "direct" dispatch - there must be at most one dispatch + * accumulated on the event or it is considered an error. It doesn't really make + * sense for an event with multiple dispatches (bubbled) to keep track of the + * return values at each dispatch execution, but it does tend to make sense when + * dealing with "direct" dispatches. + * + * @return {*} The return value of executing the single dispatch. + */ + + function executeDirectDispatch(event) { + { + validateEventDispatches(event); + } + + var dispatchListener = event._dispatchListeners; + var dispatchInstance = event._dispatchInstances; + + if (isArray(dispatchListener)) { + throw new Error("Invalid `event`."); + } + + event.currentTarget = dispatchListener + ? getNodeFromInstance(dispatchInstance) + : null; + var res = dispatchListener ? dispatchListener(event) : null; + event.currentTarget = null; + event._dispatchListeners = null; + event._dispatchInstances = null; + return res; + } + /** + * @param {SyntheticEvent} event + * @return {boolean} True iff number of dispatches accumulated is greater than 0. + */ + + function hasDispatches(event) { + return !!event._dispatchListeners; + } + function rethrowCaughtError() { + if (hasError) { + var error = caughtError; + hasError = false; + caughtError = null; + throw error; + } + } + + var assign = Object.assign; + + var EVENT_POOL_SIZE = 10; + /** + * @interface Event + * @see http://www.w3.org/TR/DOM-Level-3-Events/ + */ + + var EventInterface = { + type: null, + target: null, + // currentTarget is set when dispatching; no use in copying it here + currentTarget: function () { + return null; + }, + eventPhase: null, + bubbles: null, + cancelable: null, + timeStamp: function (event) { + return event.timeStamp || Date.now(); + }, + defaultPrevented: null, + isTrusted: null + }; + + function functionThatReturnsTrue() { + return true; + } + + function functionThatReturnsFalse() { + return false; + } + /** + * Synthetic events are dispatched by event plugins, typically in response to a + * top-level event delegation handler. + * + * These systems should generally use pooling to reduce the frequency of garbage + * collection. The system should check `isPersistent` to determine whether the + * event should be released into the pool after being dispatched. Users that + * need a persisted event should invoke `persist`. + * + * Synthetic events (and subclasses) implement the DOM Level 3 Events API by + * normalizing browser quirks. Subclasses do not necessarily have to implement a + * DOM interface; custom application-specific events can also subclass this. + * + * @param {object} dispatchConfig Configuration used to dispatch this event. + * @param {*} targetInst Marker identifying the event target. + * @param {object} nativeEvent Native browser event. + * @param {DOMEventTarget} nativeEventTarget Target node. + */ + + function SyntheticEvent( + dispatchConfig, targetInst, nativeEvent, nativeEventTarget ) { - delete this.nativeEvent; - delete this.preventDefault; - delete this.stopPropagation; - delete this.isDefaultPrevented; - delete this.isPropagationStopped; + { + // these have a getter/setter for warnings + delete this.nativeEvent; + delete this.preventDefault; + delete this.stopPropagation; + delete this.isDefaultPrevented; + delete this.isPropagationStopped; + } + this.dispatchConfig = dispatchConfig; this._targetInst = targetInst; this.nativeEvent = nativeEvent; - this._dispatchInstances = this._dispatchListeners = null; - dispatchConfig = this.constructor.Interface; - for (var propName in dispatchConfig) - dispatchConfig.hasOwnProperty(propName) && - (delete this[propName], - (targetInst = dispatchConfig[propName]) - ? (this[propName] = targetInst(nativeEvent)) - : "target" === propName - ? (this.target = nativeEventTarget) - : (this[propName] = nativeEvent[propName])); - this.isDefaultPrevented = ( - null != nativeEvent.defaultPrevented + this._dispatchListeners = null; + this._dispatchInstances = null; + var Interface = this.constructor.Interface; + + for (var propName in Interface) { + if (!Interface.hasOwnProperty(propName)) { + continue; + } + + { + delete this[propName]; // this has a getter/setter for warnings + } + + var normalize = Interface[propName]; + + if (normalize) { + this[propName] = normalize(nativeEvent); + } else { + if (propName === "target") { + this.target = nativeEventTarget; + } else { + this[propName] = nativeEvent[propName]; + } + } + } + + var defaultPrevented = + nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented - : !1 === nativeEvent.returnValue - ) - ? functionThatReturnsTrue - : functionThatReturnsFalse; + : nativeEvent.returnValue === false; + + if (defaultPrevented) { + this.isDefaultPrevented = functionThatReturnsTrue; + } else { + this.isDefaultPrevented = functionThatReturnsFalse; + } + this.isPropagationStopped = functionThatReturnsFalse; return this; } + + assign(SyntheticEvent.prototype, { + preventDefault: function () { + this.defaultPrevented = true; + var event = this.nativeEvent; + + if (!event) { + return; + } + + if (event.preventDefault) { + event.preventDefault(); + } else if (typeof event.returnValue !== "unknown") { + event.returnValue = false; + } + + this.isDefaultPrevented = functionThatReturnsTrue; + }, + stopPropagation: function () { + var event = this.nativeEvent; + + if (!event) { + return; + } + + if (event.stopPropagation) { + event.stopPropagation(); + } else if (typeof event.cancelBubble !== "unknown") { + // The ChangeEventPlugin registers a "propertychange" event for + // IE. This event does not support bubbling or cancelling, and + // any references to cancelBubble throw "Member not found". A + // typeof check of "unknown" circumvents this issue (and is also + // IE specific). + event.cancelBubble = true; + } + + this.isPropagationStopped = functionThatReturnsTrue; + }, + + /** + * We release all dispatched `SyntheticEvent`s after each event loop, adding + * them back into the pool. This allows a way to hold onto a reference that + * won't be added back into the pool. + */ + persist: function () { + this.isPersistent = functionThatReturnsTrue; + }, + + /** + * Checks if this event should be released back into the pool. + * + * @return {boolean} True if this should not be released, false otherwise. + */ + isPersistent: functionThatReturnsFalse, + + /** + * `PooledClass` looks for `destructor` on each instance it releases. + */ + destructor: function () { + var Interface = this.constructor.Interface; + + for (var propName in Interface) { + { + Object.defineProperty( + this, + propName, + getPooledWarningPropertyDefinition(propName, Interface[propName]) + ); + } + } + + this.dispatchConfig = null; + this._targetInst = null; + this.nativeEvent = null; + this.isDefaultPrevented = functionThatReturnsFalse; + this.isPropagationStopped = functionThatReturnsFalse; + this._dispatchListeners = null; + this._dispatchInstances = null; + + { + Object.defineProperty( + this, + "nativeEvent", + getPooledWarningPropertyDefinition("nativeEvent", null) + ); + Object.defineProperty( + this, + "isDefaultPrevented", + getPooledWarningPropertyDefinition( + "isDefaultPrevented", + functionThatReturnsFalse + ) + ); + Object.defineProperty( + this, + "isPropagationStopped", + getPooledWarningPropertyDefinition( + "isPropagationStopped", + functionThatReturnsFalse + ) + ); + Object.defineProperty( + this, + "preventDefault", + getPooledWarningPropertyDefinition("preventDefault", function () {}) + ); + Object.defineProperty( + this, + "stopPropagation", + getPooledWarningPropertyDefinition( + "stopPropagation", + function () {} + ) + ); + } + } + }); + SyntheticEvent.Interface = EventInterface; + /** + * Helper to reduce boilerplate when creating subclasses. + */ + + SyntheticEvent.extend = function (Interface) { + var Super = this; + + var E = function () {}; + + E.prototype = Super.prototype; + var prototype = new E(); + + function Class() { + return Super.apply(this, arguments); + } + + assign(prototype, Class.prototype); + Class.prototype = prototype; + Class.prototype.constructor = Class; + Class.Interface = assign({}, Super.Interface, Interface); + Class.extend = Super.extend; + addEventPoolingTo(Class); + return Class; + }; + + addEventPoolingTo(SyntheticEvent); + /** + * Helper to nullify syntheticEvent instance properties when destructing + * + * @param {String} propName + * @param {?object} getVal + * @return {object} defineProperty object + */ + function getPooledWarningPropertyDefinition(propName, getVal) { - function warn(action, result) { - error$jscomp$0( - "This synthetic event is reused for performance reasons. If you're seeing this, you're %s `%s` on a released/nullified synthetic event. %s. If you must keep the original synthetic event around, use event.persist(). See https://react.dev/link/event-pooling for more information.", - action, - propName, - result - ); + function set(val) { + var action = isFunction ? "setting the method" : "setting the property"; + warn(action, "This is effectively a no-op"); + return val; } - var isFunction = "function" === typeof getVal; - return { - configurable: !0, - set: function (val) { - warn( - isFunction ? "setting the method" : "setting the property", - "This is effectively a no-op" - ); - return val; - }, - get: function () { - warn( - isFunction ? "accessing the method" : "accessing the property", - isFunction ? "This is a no-op function" : "This is set to null" + + function get() { + var action = isFunction + ? "accessing the method" + : "accessing the property"; + var result = isFunction + ? "This is a no-op function" + : "This is set to null"; + warn(action, result); + return getVal; + } + + function warn(action, result) { + { + error( + "This synthetic event is reused for performance reasons. If you're seeing this, " + + "you're %s `%s` on a released/nullified synthetic event. %s. " + + "If you must keep the original synthetic event around, use event.persist(). " + + "See https://react.dev/link/event-pooling for more information.", + action, + propName, + result ); - return getVal; } + } + + var isFunction = typeof getVal === "function"; + return { + configurable: true, + set: set, + get: get }; } + function createOrGetPooledEvent( dispatchConfig, targetInst, nativeEvent, nativeInst ) { - if (this.eventPool.length) { - var instance = this.eventPool.pop(); - this.call( + var EventConstructor = this; + + if (EventConstructor.eventPool.length) { + var instance = EventConstructor.eventPool.pop(); + EventConstructor.call( instance, dispatchConfig, targetInst, @@ -847,104 +613,211 @@ __DEV__ && ); return instance; } - return new this(dispatchConfig, targetInst, nativeEvent, nativeInst); + + return new EventConstructor( + dispatchConfig, + targetInst, + nativeEvent, + nativeInst + ); } + function releasePooledEvent(event) { - if (!(event instanceof this)) - throw Error( + var EventConstructor = this; + + if (!(event instanceof EventConstructor)) { + throw new Error( "Trying to release an event instance into a pool of a different type." ); + } + event.destructor(); - 10 > this.eventPool.length && this.eventPool.push(event); + + if (EventConstructor.eventPool.length < EVENT_POOL_SIZE) { + EventConstructor.eventPool.push(event); + } } + function addEventPoolingTo(EventConstructor) { EventConstructor.getPooled = createOrGetPooledEvent; EventConstructor.eventPool = []; EventConstructor.release = releasePooledEvent; } + + /** + * `touchHistory` isn't actually on the native event, but putting it in the + * interface will ensure that it is cleaned up when pooled/destroyed. The + * `ResponderEventPlugin` will populate it appropriately. + */ + + var ResponderSyntheticEvent = SyntheticEvent.extend({ + touchHistory: function (nativeEvent) { + return null; // Actually doesn't even look at the native event. + } + }); + + var TOP_TOUCH_START = "topTouchStart"; + var TOP_TOUCH_MOVE = "topTouchMove"; + var TOP_TOUCH_END = "topTouchEnd"; + var TOP_TOUCH_CANCEL = "topTouchCancel"; + var TOP_SCROLL = "topScroll"; + var TOP_SELECTION_CHANGE = "topSelectionChange"; function isStartish(topLevelType) { - return "topTouchStart" === topLevelType; + return topLevelType === TOP_TOUCH_START; } function isMoveish(topLevelType) { - return "topTouchMove" === topLevelType; + return topLevelType === TOP_TOUCH_MOVE; + } + function isEndish(topLevelType) { + return ( + topLevelType === TOP_TOUCH_END || topLevelType === TOP_TOUCH_CANCEL + ); } + var startDependencies = [TOP_TOUCH_START]; + var moveDependencies = [TOP_TOUCH_MOVE]; + var endDependencies = [TOP_TOUCH_CANCEL, TOP_TOUCH_END]; + + /** + * Tracks the position and time of each active touch by `touch.identifier`. We + * should typically only see IDs in the range of 1-20 because IDs get recycled + * when touches end and start again. + */ + + var MAX_TOUCH_BANK = 20; + var touchBank = []; + var touchHistory = { + touchBank: touchBank, + numberActiveTouches: 0, + // If there is only one active touch, we remember its location. This prevents + // us having to loop through all of the touches all the time in the most + // common case. + indexOfSingleActiveTouch: -1, + mostRecentTimeStamp: 0 + }; + function timestampForTouch(touch) { + // The legacy internal implementation provides "timeStamp", which has been + // renamed to "timestamp". Let both work for now while we iron it out + // TODO (evv): rename timeStamp to timestamp in internal code return touch.timeStamp || touch.timestamp; } + /** + * TODO: Instead of making gestures recompute filtered velocity, we could + * include a built in velocity computation that can be reused globally. + */ + + function createTouchRecord(touch) { + return { + touchActive: true, + startPageX: touch.pageX, + startPageY: touch.pageY, + startTimeStamp: timestampForTouch(touch), + currentPageX: touch.pageX, + currentPageY: touch.pageY, + currentTimeStamp: timestampForTouch(touch), + previousPageX: touch.pageX, + previousPageY: touch.pageY, + previousTimeStamp: timestampForTouch(touch) + }; + } + + function resetTouchRecord(touchRecord, touch) { + touchRecord.touchActive = true; + touchRecord.startPageX = touch.pageX; + touchRecord.startPageY = touch.pageY; + touchRecord.startTimeStamp = timestampForTouch(touch); + touchRecord.currentPageX = touch.pageX; + touchRecord.currentPageY = touch.pageY; + touchRecord.currentTimeStamp = timestampForTouch(touch); + touchRecord.previousPageX = touch.pageX; + touchRecord.previousPageY = touch.pageY; + touchRecord.previousTimeStamp = timestampForTouch(touch); + } + function getTouchIdentifier(_ref) { - _ref = _ref.identifier; - if (null == _ref) throw Error("Touch object is missing identifier."); - 20 < _ref && - error$jscomp$0( - "Touch identifier %s is greater than maximum supported %s which causes performance issues backfilling array locations for all of the indices.", - _ref, - 20 - ); - return _ref; + var identifier = _ref.identifier; + + if (identifier == null) { + throw new Error("Touch object is missing identifier."); + } + + { + if (identifier > MAX_TOUCH_BANK) { + error( + "Touch identifier %s is greater than maximum supported %s which causes " + + "performance issues backfilling array locations for all of the indices.", + identifier, + MAX_TOUCH_BANK + ); + } + } + + return identifier; } + function recordTouchStart(touch) { - var identifier = getTouchIdentifier(touch), - touchRecord = touchBank[identifier]; - touchRecord - ? ((touchRecord.touchActive = !0), - (touchRecord.startPageX = touch.pageX), - (touchRecord.startPageY = touch.pageY), - (touchRecord.startTimeStamp = timestampForTouch(touch)), - (touchRecord.currentPageX = touch.pageX), - (touchRecord.currentPageY = touch.pageY), - (touchRecord.currentTimeStamp = timestampForTouch(touch)), - (touchRecord.previousPageX = touch.pageX), - (touchRecord.previousPageY = touch.pageY), - (touchRecord.previousTimeStamp = timestampForTouch(touch))) - : ((touchRecord = { - touchActive: !0, - startPageX: touch.pageX, - startPageY: touch.pageY, - startTimeStamp: timestampForTouch(touch), - currentPageX: touch.pageX, - currentPageY: touch.pageY, - currentTimeStamp: timestampForTouch(touch), - previousPageX: touch.pageX, - previousPageY: touch.pageY, - previousTimeStamp: timestampForTouch(touch) - }), - (touchBank[identifier] = touchRecord)); + var identifier = getTouchIdentifier(touch); + var touchRecord = touchBank[identifier]; + + if (touchRecord) { + resetTouchRecord(touchRecord, touch); + } else { + touchBank[identifier] = createTouchRecord(touch); + } + touchHistory.mostRecentTimeStamp = timestampForTouch(touch); } + function recordTouchMove(touch) { var touchRecord = touchBank[getTouchIdentifier(touch)]; - touchRecord - ? ((touchRecord.touchActive = !0), - (touchRecord.previousPageX = touchRecord.currentPageX), - (touchRecord.previousPageY = touchRecord.currentPageY), - (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), - (touchRecord.currentPageX = touch.pageX), - (touchRecord.currentPageY = touch.pageY), - (touchRecord.currentTimeStamp = timestampForTouch(touch)), - (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) - : warn( - "Cannot record touch move without a touch start.\nTouch Move: %s\nTouch Bank: %s", + + if (touchRecord) { + touchRecord.touchActive = true; + touchRecord.previousPageX = touchRecord.currentPageX; + touchRecord.previousPageY = touchRecord.currentPageY; + touchRecord.previousTimeStamp = touchRecord.currentTimeStamp; + touchRecord.currentPageX = touch.pageX; + touchRecord.currentPageY = touch.pageY; + touchRecord.currentTimeStamp = timestampForTouch(touch); + touchHistory.mostRecentTimeStamp = timestampForTouch(touch); + } else { + { + warn( + "Cannot record touch move without a touch start.\n" + + "Touch Move: %s\n" + + "Touch Bank: %s", printTouch(touch), printTouchBank() ); + } + } } + function recordTouchEnd(touch) { var touchRecord = touchBank[getTouchIdentifier(touch)]; - touchRecord - ? ((touchRecord.touchActive = !1), - (touchRecord.previousPageX = touchRecord.currentPageX), - (touchRecord.previousPageY = touchRecord.currentPageY), - (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), - (touchRecord.currentPageX = touch.pageX), - (touchRecord.currentPageY = touch.pageY), - (touchRecord.currentTimeStamp = timestampForTouch(touch)), - (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) - : warn( - "Cannot record touch end without a touch start.\nTouch End: %s\nTouch Bank: %s", + + if (touchRecord) { + touchRecord.touchActive = false; + touchRecord.previousPageX = touchRecord.currentPageX; + touchRecord.previousPageY = touchRecord.currentPageY; + touchRecord.previousTimeStamp = touchRecord.currentTimeStamp; + touchRecord.currentPageX = touch.pageX; + touchRecord.currentPageY = touch.pageY; + touchRecord.currentTimeStamp = timestampForTouch(touch); + touchHistory.mostRecentTimeStamp = timestampForTouch(touch); + } else { + { + warn( + "Cannot record touch end without a touch start.\n" + + "Touch End: %s\n" + + "Touch Bank: %s", printTouch(touch), printTouchBank() ); + } + } } + function printTouch(touch) { return JSON.stringify({ identifier: touch.identifier, @@ -953,15825 +826,26856 @@ __DEV__ && timestamp: timestampForTouch(touch) }); } + function printTouchBank() { - var printed = JSON.stringify(touchBank.slice(0, 20)); - 20 < touchBank.length && - (printed += " (original size: " + touchBank.length + ")"); + var printed = JSON.stringify(touchBank.slice(0, MAX_TOUCH_BANK)); + + if (touchBank.length > MAX_TOUCH_BANK) { + printed += " (original size: " + touchBank.length + ")"; + } + 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)) { + nativeEvent.changedTouches.forEach(recordTouchStart); + touchHistory.numberActiveTouches = nativeEvent.touches.length; + + if (touchHistory.numberActiveTouches === 1) { + touchHistory.indexOfSingleActiveTouch = + nativeEvent.touches[0].identifier; + } + } else if (isEndish(topLevelType)) { + nativeEvent.changedTouches.forEach(recordTouchEnd); + touchHistory.numberActiveTouches = nativeEvent.touches.length; + + if (touchHistory.numberActiveTouches === 1) { + for (var i = 0; i < touchBank.length; i++) { + var touchTrackToCheck = touchBank[i]; + + if (touchTrackToCheck != null && touchTrackToCheck.touchActive) { + touchHistory.indexOfSingleActiveTouch = i; + break; + } + } + + { + var activeRecord = + touchBank[touchHistory.indexOfSingleActiveTouch]; + + if (activeRecord == null || !activeRecord.touchActive) { + error("Cannot find single active touch."); + } + } + } + } + }, + touchHistory: touchHistory + }; + + /** + * Accumulates items that must not be null or undefined. + * + * This is used to conserve memory by avoiding array allocations. + * + * @return {*|array<*>} An accumulation of items. + */ + function accumulate(current, next) { - if (null == next) - throw Error("Accumulated items must not be null or undefined."); - return null == current - ? next - : isArrayImpl(current) - ? current.concat(next) - : isArrayImpl(next) - ? [current].concat(next) - : [current, next]; + if (next == null) { + throw new Error("Accumulated items must not be null or undefined."); + } + + if (current == null) { + return 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 (isArray(current)) { + /* $FlowFixMe[incompatible-return] if `current` is `T` and `T` an array, + * `isArray` might refine to the array element type of `T` */ + return current.concat(next); + } + + if (isArray(next)) { + /* $FlowFixMe[incompatible-return] unsound if `next` is `T` and `T` an array, + * `isArray` might refine to the array element type of `T` */ + return [current].concat(next); + } + + return [current, next]; } + + /** + * Accumulates items that must not be null or undefined into the first one. This + * is used to conserve memory by avoiding array allocations, and thus sacrifices + * API cleanness. Since `current` can be null before being passed in and not + * null after this function, make sure to assign it back to `current`: + * + * `a = accumulateInto(a, b);` + * + * This API should be sparingly used. Try `accumulate` for something cleaner. + * + * @return {*|array<*>} An accumulation of items. + */ + function accumulateInto(current, next) { - if (null == next) - throw Error("Accumulated items must not be null or undefined."); - if (null == current) return next; - if (isArrayImpl(current)) { - if (isArrayImpl(next)) - return current.push.apply(current, next), current; + if (next == null) { + throw new Error("Accumulated items must not be null or undefined."); + } + + if (current == null) { + return 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 (isArray(current)) { + if (isArray(next)) { + // $FlowFixMe[prop-missing] `isArray` does not ensure array is mutable + // $FlowFixMe[method-unbinding] + current.push.apply(current, next); + return current; + } // $FlowFixMe[prop-missing] `isArray` does not ensure array is mutable + current.push(next); return current; } - 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); + + if (isArray(next)) { + // A bit too dangerous to mutate `next`. + + /* $FlowFixMe[incompatible-return] unsound if `next` is `T` and `T` an array, + * `isArray` might refine to the array element type of `T` */ + return [current].concat(next); + } + + return [current, next]; + } + + /** + * @param {array} arr an "accumulation" of items which is either an Array or + * a single item. Useful when paired with the `accumulate` module. This is a + * simple utility that allows us to reason about a collection of items, but + * handling the case when there is exactly one item (and we do not need to + * allocate an array). + * @param {function} cb Callback invoked with each element or a collection. + * @param {?} [scope] Scope used as `this` in a callback. + */ + function forEachAccumulated(arr, cb, scope) { + if (Array.isArray(arr)) { + // $FlowFixMe[incompatible-call] if `T` is an array, `cb` cannot be called + arr.forEach(cb, scope); + } else if (arr) { + cb.call(scope, arr); + } } + + var FunctionComponent = 0; + var ClassComponent = 1; + var IndeterminateComponent = 2; // Before we know whether it is function or class + + var HostRoot = 3; // Root of a host tree. Could be nested inside another node. + + var HostPortal = 4; // A subtree. Could be an entry point to a different renderer. + + var HostComponent = 5; + var HostText = 6; + var Fragment = 7; + var Mode = 8; + var ContextConsumer = 9; + var ContextProvider = 10; + var ForwardRef = 11; + var Profiler = 12; + var SuspenseComponent = 13; + var MemoComponent = 14; + var SimpleMemoComponent = 15; + var LazyComponent = 16; + var IncompleteClassComponent = 17; + var DehydratedFragment = 18; + var SuspenseListComponent = 19; + var ScopeComponent = 21; + var OffscreenComponent = 22; + var LegacyHiddenComponent = 23; + var CacheComponent = 24; + var TracingMarkerComponent = 25; + var HostHoistable = 26; + var HostSingleton = 27; + + /** + * Instance of element that should respond to touch/move types of interactions, + * as indicated explicitly by relevant callbacks. + */ + + var responderInst = null; + /** + * Count of current touches. A textInput should become responder iff the + * selection changes while there is a touch on the screen. + */ + + var trackedTouchCount = 0; + function changeResponder(nextResponderInst, blockHostResponder) { var oldResponderInst = responderInst; responderInst = nextResponderInst; - if (null !== ResponderEventPlugin.GlobalResponderHandler) + + if (ResponderEventPlugin.GlobalResponderHandler !== null) { ResponderEventPlugin.GlobalResponderHandler.onChange( oldResponderInst, nextResponderInst, blockHostResponder ); + } } + + var eventTypes = { + /** + * On a `touchStart`/`mouseDown`, is it desired that this element become the + * responder? + */ + startShouldSetResponder: { + phasedRegistrationNames: { + bubbled: "onStartShouldSetResponder", + captured: "onStartShouldSetResponderCapture" + }, + dependencies: startDependencies + }, + + /** + * On a `scroll`, is it desired that this element become the responder? This + * is usually not needed, but should be used to retroactively infer that a + * `touchStart` had occurred during momentum scroll. During a momentum scroll, + * a touch start will be immediately followed by a scroll event if the view is + * currently scrolling. + * + * TODO: This shouldn't bubble. + */ + scrollShouldSetResponder: { + phasedRegistrationNames: { + bubbled: "onScrollShouldSetResponder", + captured: "onScrollShouldSetResponderCapture" + }, + dependencies: [TOP_SCROLL] + }, + + /** + * On text selection change, should this element become the responder? This + * is needed for text inputs or other views with native selection, so the + * JS view can claim the responder. + * + * TODO: This shouldn't bubble. + */ + selectionChangeShouldSetResponder: { + phasedRegistrationNames: { + bubbled: "onSelectionChangeShouldSetResponder", + captured: "onSelectionChangeShouldSetResponderCapture" + }, + dependencies: [TOP_SELECTION_CHANGE] + }, + + /** + * On a `touchMove`/`mouseMove`, is it desired that this element become the + * responder? + */ + moveShouldSetResponder: { + phasedRegistrationNames: { + bubbled: "onMoveShouldSetResponder", + captured: "onMoveShouldSetResponderCapture" + }, + dependencies: moveDependencies + }, + + /** + * Direct responder events dispatched directly to responder. Do not bubble. + */ + responderStart: { + registrationName: "onResponderStart", + dependencies: startDependencies + }, + responderMove: { + registrationName: "onResponderMove", + dependencies: moveDependencies + }, + responderEnd: { + registrationName: "onResponderEnd", + dependencies: endDependencies + }, + responderRelease: { + registrationName: "onResponderRelease", + dependencies: endDependencies + }, + responderTerminationRequest: { + registrationName: "onResponderTerminationRequest", + dependencies: [] + }, + responderGrant: { + registrationName: "onResponderGrant", + dependencies: [] + }, + responderReject: { + registrationName: "onResponderReject", + dependencies: [] + }, + responderTerminate: { + registrationName: "onResponderTerminate", + dependencies: [] + } + }; // Start of inline: the below functions were inlined from + // EventPropagator.js, as they deviated from ReactDOM's newer + // implementations. + function getParent$1(inst) { - do inst = inst.return; - while (inst && 5 !== inst.tag); - return inst ? inst : null; + do { + inst = inst.return; // TODO: If this is a HostRoot we might want to bail out. + // That is depending on if we want nested subtrees (layers) to bubble + // events to their parent. We could also go through parentNode on the + // host node but that wouldn't work for React Native and doesn't let us + // do the portal feature. + } while (inst && inst.tag !== HostComponent); + + if (inst) { + return inst; + } + + return null; + } + /** + * Return the lowest common ancestor of A and B, or null if they are in + * different trees. + */ + + function getLowestCommonAncestor(instA, instB) { + var depthA = 0; + + for (var tempA = instA; tempA; tempA = getParent$1(tempA)) { + depthA++; + } + + var depthB = 0; + + for (var tempB = instB; tempB; tempB = getParent$1(tempB)) { + depthB++; + } // If A is deeper, crawl up. + + while (depthA - depthB > 0) { + instA = getParent$1(instA); + depthA--; + } // If B is deeper, crawl up. + + while (depthB - depthA > 0) { + instB = getParent$1(instB); + depthB--; + } // Walk in lockstep until we find a match. + + var depth = depthA; + + while (depth--) { + if (instA === instB || instA === instB.alternate) { + return instA; + } + + instA = getParent$1(instA); + instB = getParent$1(instB); + } + + return null; + } + /** + * Return if A is an ancestor of B. + */ + + function isAncestor(instA, instB) { + while (instB) { + if (instA === instB || instA === instB.alternate) { + return true; + } + + instB = getParent$1(instB); + } + + return false; } + /** + * Simulates the traversal of a two-phase, capture/bubble event dispatch. + */ + function traverseTwoPhase$1(inst, fn, arg) { - for (var path = []; inst; ) path.push(inst), (inst = getParent$1(inst)); - for (inst = path.length; 0 < inst--; ) fn(path[inst], "captured", arg); - for (inst = 0; inst < path.length; inst++) fn(path[inst], "bubbled", arg); + var path = []; + + while (inst) { + path.push(inst); + inst = getParent$1(inst); + } + + var i; + + for (i = path.length; i-- > 0; ) { + fn(path[i], "captured", arg); + } + + for (i = 0; i < path.length; i++) { + fn(path[i], "bubbled", arg); + } } + function getListener$1(inst, registrationName) { - inst = inst.stateNode; - if (null === inst) return null; - inst = getFiberCurrentPropsFromNode$1(inst); - if (null === inst) return null; - if ((inst = inst[registrationName]) && "function" !== typeof inst) - throw Error( + var stateNode = inst.stateNode; + + if (stateNode === null) { + // Work in progress (ex: onload events in incremental mode). + return null; + } + + var props = getFiberCurrentPropsFromNode$1(stateNode); + + if (props === null) { + // Work in progress. + return null; + } + + var listener = props[registrationName]; + + if (listener && typeof listener !== "function") { + throw new Error( "Expected `" + registrationName + "` listener to be a function, instead got a value of `" + - typeof inst + + typeof listener + "` type." ); - return inst; + } + + return listener; } + + function listenerAtPhase$1(inst, event, propagationPhase) { + var registrationName = + event.dispatchConfig.phasedRegistrationNames[propagationPhase]; + return getListener$1(inst, registrationName); + } + function accumulateDirectionalDispatches$1(inst, phase, event) { - inst || error$jscomp$0("Dispatching inst must not be null"); - if ( - (phase = getListener$1( - inst, - event.dispatchConfig.phasedRegistrationNames[phase] - )) - ) - (event._dispatchListeners = accumulateInto( + { + if (!inst) { + error("Dispatching inst must not be null"); + } + } + + var listener = listenerAtPhase$1(inst, event, phase); + + if (listener) { + event._dispatchListeners = accumulateInto( event._dispatchListeners, - phase - )), - (event._dispatchInstances = accumulateInto( + listener + ); + event._dispatchInstances = accumulateInto( + event._dispatchInstances, + inst + ); + } + } + /** + * Accumulates without regard to direction, does not look for phased + * registration names. Same as `accumulateDirectDispatchesSingle` but without + * requiring that the `dispatchMarker` be the same as the dispatched ID. + */ + + function accumulateDispatches$1(inst, ignoredDirection, event) { + if (inst && event && event.dispatchConfig.registrationName) { + var registrationName = event.dispatchConfig.registrationName; + var listener = getListener$1(inst, registrationName); + + if (listener) { + event._dispatchListeners = accumulateInto( + event._dispatchListeners, + listener + ); + event._dispatchInstances = accumulateInto( event._dispatchInstances, inst - )); + ); + } + } } + /** + * Accumulates dispatches on an `SyntheticEvent`, but only for the + * `dispatchMarker`. + * @param {SyntheticEvent} event + */ + function accumulateDirectDispatchesSingle$1(event) { if (event && event.dispatchConfig.registrationName) { - var inst = event._targetInst; - if (inst && event && event.dispatchConfig.registrationName) { - var listener = getListener$1( - inst, - event.dispatchConfig.registrationName - ); - listener && - ((event._dispatchListeners = accumulateInto( - event._dispatchListeners, - listener - )), - (event._dispatchInstances = accumulateInto( - event._dispatchInstances, - inst - ))); - } + accumulateDispatches$1(event._targetInst, null, event); } } + + function accumulateDirectDispatches$1(events) { + forEachAccumulated(events, accumulateDirectDispatchesSingle$1); + } + function accumulateTwoPhaseDispatchesSingleSkipTarget(event) { if (event && event.dispatchConfig.phasedRegistrationNames) { var targetInst = event._targetInst; - targetInst = targetInst ? getParent$1(targetInst) : null; + var parentInst = targetInst ? getParent$1(targetInst) : null; traverseTwoPhase$1( - targetInst, + parentInst, accumulateDirectionalDispatches$1, event ); } } + + function accumulateTwoPhaseDispatchesSkipTarget(events) { + forEachAccumulated(events, accumulateTwoPhaseDispatchesSingleSkipTarget); + } + function accumulateTwoPhaseDispatchesSingle$1(event) { - event && - event.dispatchConfig.phasedRegistrationNames && + if (event && event.dispatchConfig.phasedRegistrationNames) { traverseTwoPhase$1( event._targetInst, accumulateDirectionalDispatches$1, event ); - } - function recomputePluginOrdering() { - if (eventPluginOrder) - for (var pluginName in namesToPlugins) { - var pluginModule = namesToPlugins[pluginName], - pluginIndex = eventPluginOrder.indexOf(pluginName); - if (-1 >= pluginIndex) - throw Error( - "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + - (pluginName + "`.") - ); - if (!plugins[pluginIndex]) { - if (!pluginModule.extractEvents) - throw Error( - "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + - (pluginName + "` does not.") - ); - plugins[pluginIndex] = pluginModule; - pluginIndex = pluginModule.eventTypes; - for (var eventName in pluginIndex) { - var JSCompiler_inline_result = void 0; - var dispatchConfig = pluginIndex[eventName], - pluginModule$jscomp$0 = pluginModule, - eventName$jscomp$0 = eventName; - if (eventNameDispatchConfigs.hasOwnProperty(eventName$jscomp$0)) - throw Error( - "EventPluginRegistry: More than one plugin attempted to publish the same event name, `" + - (eventName$jscomp$0 + "`.") - ); - eventNameDispatchConfigs[eventName$jscomp$0] = dispatchConfig; - if ( - (eventName$jscomp$0 = dispatchConfig.phasedRegistrationNames) - ) { - for (JSCompiler_inline_result in eventName$jscomp$0) - eventName$jscomp$0.hasOwnProperty(JSCompiler_inline_result) && - publishRegistrationName( - eventName$jscomp$0[JSCompiler_inline_result], - pluginModule$jscomp$0 - ); - JSCompiler_inline_result = !0; - } else - dispatchConfig.registrationName - ? (publishRegistrationName( - dispatchConfig.registrationName, - pluginModule$jscomp$0 - ), - (JSCompiler_inline_result = !0)) - : (JSCompiler_inline_result = !1); - if (!JSCompiler_inline_result) - throw Error( - "EventPluginRegistry: Failed to publish event `" + - eventName + - "` for plugin `" + - pluginName + - "`." - ); - } - } - } - } - function publishRegistrationName(registrationName, pluginModule) { - if (registrationNameModules[registrationName]) - throw Error( - "EventPluginRegistry: More than one plugin attempted to publish the same registration name, `" + - (registrationName + "`.") - ); - registrationNameModules[registrationName] = pluginModule; - registrationName.toLowerCase(); - } - function getListener(inst, registrationName) { - inst = inst.stateNode; - if (null === inst) return null; - inst = getFiberCurrentPropsFromNode$1(inst); - if (null === inst) return null; - if ((inst = inst[registrationName]) && "function" !== typeof inst) - throw Error( - "Expected `" + - registrationName + - "` listener to be a function, instead got a value of `" + - typeof inst + - "` type." - ); - return inst; - } - function accumulateDirectionalDispatches(inst, phase, event) { - inst || error$jscomp$0("Dispatching inst must not be null"); - if ( - (phase = getListener( - inst, - event.dispatchConfig.phasedRegistrationNames[phase] - )) - ) - (event._dispatchListeners = accumulateInto( - event._dispatchListeners, - phase - )), - (event._dispatchInstances = accumulateInto( - event._dispatchInstances, - inst - )); - } - function traverseTwoPhase(inst, fn, arg, skipBubbling) { - for (var path = []; inst; ) { - path.push(inst); - do inst = inst.return; - while (inst && 5 !== inst.tag); - inst = inst ? inst : null; } - for (inst = path.length; 0 < inst--; ) fn(path[inst], "captured", arg); - if (skipBubbling) fn(path[0], "bubbled", arg); - else - for (inst = 0; inst < path.length; inst++) - fn(path[inst], "bubbled", arg); } - function accumulateTwoPhaseDispatchesSingle(event) { - event && - event.dispatchConfig.phasedRegistrationNames && - traverseTwoPhase( - event._targetInst, - accumulateDirectionalDispatches, - event, - !1 + + function accumulateTwoPhaseDispatches$1(events) { + forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle$1); + } // End of inline + + /** + * + * Responder System: + * ---------------- + * + * - A global, solitary "interaction lock" on a view. + * - If a node becomes the responder, it should convey visual feedback + * immediately to indicate so, either by highlighting or moving accordingly. + * - To be the responder means, that touches are exclusively important to that + * responder view, and no other view. + * - While touches are still occurring, the responder lock can be transferred to + * a new view, but only to increasingly "higher" views (meaning ancestors of + * the current responder). + * + * Responder being granted: + * ------------------------ + * + * - Touch starts, moves, and scrolls can cause an ID to become the responder. + * - We capture/bubble `startShouldSetResponder`/`moveShouldSetResponder` to + * the "appropriate place". + * - If nothing is currently the responder, the "appropriate place" is the + * initiating event's `targetID`. + * - If something *is* already the responder, the "appropriate place" is the + * first common ancestor of the event target and the current `responderInst`. + * - Some negotiation happens: See the timing diagram below. + * - Scrolled views automatically become responder. The reasoning is that a + * platform scroll view that isn't built on top of the responder system has + * began scrolling, and the active responder must now be notified that the + * interaction is no longer locked to it - the system has taken over. + * + * - Responder being released: + * As soon as no more touches that *started* inside of descendants of the + * *current* responderInst, an `onResponderRelease` event is dispatched to the + * current responder, and the responder lock is released. + * + * TODO: + * - on "end", a callback hook for `onResponderEndShouldRemainResponder` that + * determines if the responder lock should remain. + * - If a view shouldn't "remain" the responder, any active touches should by + * default be considered "dead" and do not influence future negotiations or + * bubble paths. It should be as if those touches do not exist. + * -- For multitouch: Usually a translate-z will choose to "remain" responder + * after one out of many touches ended. For translate-y, usually the view + * doesn't wish to "remain" responder after one of many touches end. + * - Consider building this on top of a `stopPropagation` model similar to + * `W3C` events. + * - Ensure that `onResponderTerminate` is called on touch cancels, whether or + * not `onResponderTerminationRequest` returns `true` or `false`. + * + */ + + /* Negotiation Performed + +-----------------------+ + / \ +Process low level events to + Current Responder + wantsResponderID +determine who to perform negot-| (if any exists at all) | +iation/transition | Otherwise just pass through| +-------------------------------+----------------------------+------------------+ +Bubble to find first ID | | +to return true:wantsResponderID| | + | | + +-------------+ | | + | onTouchStart| | | + +------+------+ none | | + | return| | ++-----------v-------------+true| +------------------------+ | +|onStartShouldSetResponder|----->|onResponderStart (cur) |<-----------+ ++-----------+-------------+ | +------------------------+ | | + | | | +--------+-------+ + | returned true for| false:REJECT +-------->|onResponderReject + | wantsResponderID | | | +----------------+ + | (now attempt | +------------------+-----+ | + | handoff) | | onResponder | | + +------------------->| TerminationRequest| | + | +------------------+-----+ | + | | | +----------------+ + | true:GRANT +-------->|onResponderGrant| + | | +--------+-------+ + | +------------------------+ | | + | | onResponderTerminate |<-----------+ + | +------------------+-----+ | + | | | +----------------+ + | +-------->|onResponderStart| + | | +----------------+ +Bubble to find first ID | | +to return true:wantsResponderID| | + | | + +-------------+ | | + | onTouchMove | | | + +------+------+ none | | + | return| | ++-----------v-------------+true| +------------------------+ | +|onMoveShouldSetResponder |----->|onResponderMove (cur) |<-----------+ ++-----------+-------------+ | +------------------------+ | | + | | | +--------+-------+ + | returned true for| false:REJECT +-------->|onResponderRejec| + | wantsResponderID | | | +----------------+ + | (now attempt | +------------------+-----+ | + | handoff) | | onResponder | | + +------------------->| TerminationRequest| | + | +------------------+-----+ | + | | | +----------------+ + | true:GRANT +-------->|onResponderGrant| + | | +--------+-------+ + | +------------------------+ | | + | | onResponderTerminate |<-----------+ + | +------------------+-----+ | + | | | +----------------+ + | +-------->|onResponderMove | + | | +----------------+ + | | + | | + Some active touch started| | + inside current responder | +------------------------+ | + +------------------------->| onResponderEnd | | + | | +------------------------+ | + +---+---------+ | | + | onTouchEnd | | | + +---+---------+ | | + | | +------------------------+ | + +------------------------->| onResponderEnd | | + No active touches started| +-----------+------------+ | + inside current responder | | | + | v | + | +------------------------+ | + | | onResponderRelease | | + | +------------------------+ | + | | + + + */ + + /** + * A note about event ordering in the `EventPluginRegistry`. + * + * Suppose plugins are injected in the following order: + * + * `[R, S, C]` + * + * To help illustrate the example, assume `S` is `SimpleEventPlugin` (for + * `onClick` etc) and `R` is `ResponderEventPlugin`. + * + * "Deferred-Dispatched Events": + * + * - The current event plugin system will traverse the list of injected plugins, + * in order, and extract events by collecting the plugin's return value of + * `extractEvents()`. + * - These events that are returned from `extractEvents` are "deferred + * dispatched events". + * - When returned from `extractEvents`, deferred-dispatched events contain an + * "accumulation" of deferred dispatches. + * - These deferred dispatches are accumulated/collected before they are + * returned, but processed at a later time by the `EventPluginRegistry` (hence the + * name deferred). + * + * In the process of returning their deferred-dispatched events, event plugins + * themselves can dispatch events on-demand without returning them from + * `extractEvents`. Plugins might want to do this, so that they can use event + * dispatching as a tool that helps them decide which events should be extracted + * in the first place. + * + * "On-Demand-Dispatched Events": + * + * - On-demand-dispatched events are not returned from `extractEvents`. + * - On-demand-dispatched events are dispatched during the process of returning + * the deferred-dispatched events. + * - They should not have side effects. + * - They should be avoided, and/or eventually be replaced with another + * abstraction that allows event plugins to perform multiple "rounds" of event + * extraction. + * + * Therefore, the sequence of event dispatches becomes: + * + * - `R`s on-demand events (if any) (dispatched by `R` on-demand) + * - `S`s on-demand events (if any) (dispatched by `S` on-demand) + * - `C`s on-demand events (if any) (dispatched by `C` on-demand) + * - `R`s extracted events (if any) (dispatched by `EventPluginRegistry`) + * - `S`s extracted events (if any) (dispatched by `EventPluginRegistry`) + * - `C`s extracted events (if any) (dispatched by `EventPluginRegistry`) + * + * In the case of `ResponderEventPlugin`: If the `startShouldSetResponder` + * on-demand dispatch returns `true` (and some other details are satisfied) the + * `onResponderGrant` deferred dispatched event is returned from + * `extractEvents`. The sequence of dispatch executions in this case + * will appear as follows: + * + * - `startShouldSetResponder` (`ResponderEventPlugin` dispatches on-demand) + * - `touchStartCapture` (`EventPluginRegistry` dispatches as usual) + * - `touchStart` (`EventPluginRegistry` dispatches as usual) + * - `responderGrant/Reject` (`EventPluginRegistry` dispatches as usual) + */ + + function setResponderAndExtractTransfer( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget + ) { + var shouldSetEventType = isStartish(topLevelType) + ? eventTypes.startShouldSetResponder + : isMoveish(topLevelType) + ? eventTypes.moveShouldSetResponder + : topLevelType === TOP_SELECTION_CHANGE + ? eventTypes.selectionChangeShouldSetResponder + : eventTypes.scrollShouldSetResponder; // TODO: stop one short of the current responder. + + var bubbleShouldSetFrom = !responderInst + ? targetInst + : getLowestCommonAncestor(responderInst, targetInst); // When capturing/bubbling the "shouldSet" event, we want to skip the target + // (deepest ID) if it happens to be the current responder. The reasoning: + // It's strange to get an `onMoveShouldSetResponder` when you're *already* + // the responder. + + var skipOverBubbleShouldSetFrom = bubbleShouldSetFrom === responderInst; + var shouldSetEvent = ResponderSyntheticEvent.getPooled( + shouldSetEventType, + bubbleShouldSetFrom, + nativeEvent, + nativeEventTarget + ); + shouldSetEvent.touchHistory = ResponderTouchHistoryStore.touchHistory; + + if (skipOverBubbleShouldSetFrom) { + accumulateTwoPhaseDispatchesSkipTarget(shouldSetEvent); + } else { + accumulateTwoPhaseDispatches$1(shouldSetEvent); + } + + var wantsResponderInst = + executeDispatchesInOrderStopAtTrue(shouldSetEvent); + + if (!shouldSetEvent.isPersistent()) { + shouldSetEvent.constructor.release(shouldSetEvent); + } + + if (!wantsResponderInst || wantsResponderInst === responderInst) { + return null; + } + + var extracted; + var grantEvent = ResponderSyntheticEvent.getPooled( + eventTypes.responderGrant, + wantsResponderInst, + nativeEvent, + nativeEventTarget + ); + grantEvent.touchHistory = ResponderTouchHistoryStore.touchHistory; + accumulateDirectDispatches$1(grantEvent); + var blockHostResponder = executeDirectDispatch(grantEvent) === true; + + if (responderInst) { + var terminationRequestEvent = ResponderSyntheticEvent.getPooled( + eventTypes.responderTerminationRequest, + responderInst, + nativeEvent, + nativeEventTarget ); - } - function accumulateDirectDispatchesSingle(event) { - if (event && event.dispatchConfig.registrationName) { - var inst = event._targetInst; - if (inst && event && event.dispatchConfig.registrationName) { - var listener = getListener( - inst, - event.dispatchConfig.registrationName + terminationRequestEvent.touchHistory = + ResponderTouchHistoryStore.touchHistory; + accumulateDirectDispatches$1(terminationRequestEvent); + var shouldSwitch = + !hasDispatches(terminationRequestEvent) || + executeDirectDispatch(terminationRequestEvent); + + if (!terminationRequestEvent.isPersistent()) { + terminationRequestEvent.constructor.release(terminationRequestEvent); + } + + if (shouldSwitch) { + var terminateEvent = ResponderSyntheticEvent.getPooled( + eventTypes.responderTerminate, + responderInst, + nativeEvent, + nativeEventTarget + ); + terminateEvent.touchHistory = ResponderTouchHistoryStore.touchHistory; + accumulateDirectDispatches$1(terminateEvent); + extracted = accumulate(extracted, [grantEvent, terminateEvent]); + changeResponder(wantsResponderInst, blockHostResponder); + } else { + var rejectEvent = ResponderSyntheticEvent.getPooled( + eventTypes.responderReject, + wantsResponderInst, + nativeEvent, + nativeEventTarget ); - listener && - ((event._dispatchListeners = accumulateInto( - event._dispatchListeners, - listener - )), - (event._dispatchInstances = accumulateInto( - event._dispatchInstances, - inst - ))); + rejectEvent.touchHistory = ResponderTouchHistoryStore.touchHistory; + accumulateDirectDispatches$1(rejectEvent); + extracted = accumulate(extracted, rejectEvent); } + } else { + extracted = accumulate(extracted, grantEvent); + changeResponder(wantsResponderInst, blockHostResponder); } + + return extracted; + } + /** + * A transfer is a negotiation between a currently set responder and the next + * element to claim responder status. Any start event could trigger a transfer + * of responderInst. Any move event could trigger a transfer. + * + * @param {string} topLevelType Record from `BrowserEventConstants`. + * @return {boolean} True if a transfer of responder could possibly occur. + */ + + function canTriggerTransfer(topLevelType, topLevelInst, nativeEvent) { + return ( + topLevelInst && // responderIgnoreScroll: We are trying to migrate away from specifically + // tracking native scroll events here and responderIgnoreScroll indicates we + // will send topTouchCancel to handle canceling touch events instead + ((topLevelType === TOP_SCROLL && !nativeEvent.responderIgnoreScroll) || + (trackedTouchCount > 0 && topLevelType === TOP_SELECTION_CHANGE) || + isStartish(topLevelType) || + isMoveish(topLevelType)) + ); } - function getInstanceFromTag(tag) { - return instanceCache.get(tag) || null; - } - function batchedUpdates$1(fn, bookkeeping) { - if (isInsideEventHandler) return fn(bookkeeping); - isInsideEventHandler = !0; - try { - return batchedUpdatesImpl(fn, bookkeeping); - } finally { - isInsideEventHandler = !1; + /** + * Returns whether or not this touch end event makes it such that there are no + * longer any touches that started inside of the current `responderInst`. + * + * @param {NativeEvent} nativeEvent Native touch end event. + * @return {boolean} Whether or not this touch end event ends the responder. + */ + + function noResponderTouches(nativeEvent) { + var touches = nativeEvent.touches; + + if (!touches || touches.length === 0) { + return true; } - } - function executeDispatchesAndReleaseTopLevel(e) { - if (e) { - var dispatchListeners = e._dispatchListeners, - dispatchInstances = e._dispatchInstances; - validateEventDispatches(e); - if (isArrayImpl(dispatchListeners)) - for ( - var i = 0; - i < dispatchListeners.length && !e.isPropagationStopped(); - i++ - ) { - var listener = dispatchListeners[i], - instance = dispatchInstances[i]; - null !== instance - ? runWithFiberInDEV( - instance, - executeDispatch, - e, - listener, - instance - ) - : executeDispatch(e, listener, instance); - } - else - dispatchListeners && - (null !== dispatchInstances - ? runWithFiberInDEV( - dispatchInstances, - executeDispatch, - e, - dispatchListeners, - dispatchInstances - ) - : executeDispatch(e, dispatchListeners, dispatchInstances)); - e._dispatchListeners = null; - e._dispatchInstances = null; - e.isPersistent() || e.constructor.release(e); + + for (var i = 0; i < touches.length; i++) { + var activeTouch = touches[i]; + var target = activeTouch.target; + + if (target !== null && target !== undefined && target !== 0) { + // Is the original touch location inside of the current responder? + var targetInst = getInstanceFromNode(target); + + if (isAncestor(responderInst, targetInst)) { + return false; + } + } } + + return true; } - function _receiveRootNodeIDEvent( - rootNodeID, - topLevelType, - nativeEventParam - ) { - var nativeEvent = nativeEventParam || EMPTY_NATIVE_EVENT, - inst = getInstanceFromTag(rootNodeID), - target = null; - null != inst && (target = inst.stateNode); - batchedUpdates$1(function () { - var events = target; - for ( - var events$jscomp$0 = null, legacyPlugins = plugins, i = 0; - i < legacyPlugins.length; - i++ - ) { - var possiblePlugin = legacyPlugins[i]; - possiblePlugin && - (possiblePlugin = possiblePlugin.extractEvents( + + var ResponderEventPlugin = { + /* For unit testing only */ + _getResponder: function () { + return responderInst; + }, + eventTypes: eventTypes, + + /** + * We must be resilient to `targetInst` being `null` on `touchMove` or + * `touchEnd`. On certain platforms, this means that a native scroll has + * assumed control and the original touch targets are destroyed. + */ + extractEvents: function ( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget, + eventSystemFlags + ) { + if (isStartish(topLevelType)) { + trackedTouchCount += 1; + } else if (isEndish(topLevelType)) { + if (trackedTouchCount >= 0) { + trackedTouchCount -= 1; + } else { + { + warn( + "Ended a touch event which was not counted in `trackedTouchCount`." + ); + } + + return null; + } + } + + ResponderTouchHistoryStore.recordTouchTrack(topLevelType, nativeEvent); + var extracted = canTriggerTransfer( + topLevelType, + targetInst, + nativeEvent + ) + ? setResponderAndExtractTransfer( topLevelType, - inst, + targetInst, nativeEvent, - events - )) && - (events$jscomp$0 = accumulateInto(events$jscomp$0, possiblePlugin)); - } - events = events$jscomp$0; - null !== events && (eventQueue = accumulateInto(eventQueue, events)); - events = eventQueue; - eventQueue = null; - if (events) { - forEachAccumulated(events, executeDispatchesAndReleaseTopLevel); - if (eventQueue) - throw Error( - "processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented." - ); - if (hasError) - throw ( - ((events = caughtError), - (hasError = !1), - (caughtError = null), - events) - ); + nativeEventTarget + ) + : null; // Responder may or may not have transferred on a new touch start/move. + // Regardless, whoever is the responder after any potential transfer, we + // direct all touch start/move/ends to them in the form of + // `onResponderMove/Start/End`. These will be called for *every* additional + // finger that move/start/end, dispatched directly to whoever is the + // current responder at that moment, until the responder is "released". + // + // These multiple individual change touch events are are always bookended + // by `onResponderGrant`, and one of + // (`onResponderRelease/onResponderTerminate`). + + var isResponderTouchStart = responderInst && isStartish(topLevelType); + var isResponderTouchMove = responderInst && isMoveish(topLevelType); + var isResponderTouchEnd = responderInst && isEndish(topLevelType); + var incrementalTouch = isResponderTouchStart + ? eventTypes.responderStart + : isResponderTouchMove + ? eventTypes.responderMove + : isResponderTouchEnd + ? eventTypes.responderEnd + : null; + + if (incrementalTouch) { + var gesture = ResponderSyntheticEvent.getPooled( + incrementalTouch, + responderInst, + nativeEvent, + nativeEventTarget + ); + gesture.touchHistory = ResponderTouchHistoryStore.touchHistory; + accumulateDirectDispatches$1(gesture); + extracted = accumulate(extracted, gesture); + } + + var isResponderTerminate = + responderInst && topLevelType === TOP_TOUCH_CANCEL; + var isResponderRelease = + responderInst && + !isResponderTerminate && + isEndish(topLevelType) && + noResponderTouches(nativeEvent); + var finalTouch = isResponderTerminate + ? eventTypes.responderTerminate + : isResponderRelease + ? eventTypes.responderRelease + : null; + + if (finalTouch) { + var finalEvent = ResponderSyntheticEvent.getPooled( + finalTouch, + responderInst, + nativeEvent, + nativeEventTarget + ); + finalEvent.touchHistory = ResponderTouchHistoryStore.touchHistory; + accumulateDirectDispatches$1(finalEvent); + extracted = accumulate(extracted, finalEvent); + changeResponder(null); + } + + return extracted; + }, + GlobalResponderHandler: null, + injection: { + /** + * @param {{onChange: (ReactID, ReactID) => void} GlobalResponderHandler + * Object that handles any change in responder. Use this to inject + * integration with an existing touch handling system etc. + */ + injectGlobalResponderHandler: function (GlobalResponderHandler) { + ResponderEventPlugin.GlobalResponderHandler = GlobalResponderHandler; } - }); - } - function getNearestMountedFiber(fiber) { - var node = fiber, - nearestMounted = fiber; - if (fiber.alternate) for (; node.return; ) node = node.return; - else { - fiber = node; - do - (node = fiber), - 0 !== (node.flags & 4098) && (nearestMounted = node.return), - (fiber = node.return); - while (fiber); } - return 3 === node.tag ? nearestMounted : null; - } - function assertIsMounted(fiber) { - if (getNearestMountedFiber(fiber) !== fiber) - throw Error("Unable to find node on an unmounted component."); - } - function findCurrentFiberUsingSlowPath(fiber) { - var alternate = fiber.alternate; - if (!alternate) { - alternate = getNearestMountedFiber(fiber); - if (null === alternate) - throw Error("Unable to find node on an unmounted component."); - return alternate !== fiber ? null : fiber; + }; + + /** + * Injectable ordering of event plugins. + */ + var eventPluginOrder = null; + /** + * Injectable mapping from names to event plugin modules. + */ + + var namesToPlugins = {}; + /** + * Recomputes the plugin list using the injected plugins and plugin ordering. + * + * @private + */ + + function recomputePluginOrdering() { + if (!eventPluginOrder) { + // Wait until an `eventPluginOrder` is injected. + return; } - for (var a = fiber, b = alternate; ; ) { - var parentA = a.return; - if (null === parentA) break; - var parentB = parentA.alternate; - if (null === parentB) { - b = parentA.return; - if (null !== b) { - a = b; - continue; - } - break; + + for (var pluginName in namesToPlugins) { + var pluginModule = namesToPlugins[pluginName]; // $FlowFixMe[incompatible-use] found when upgrading Flow + + var pluginIndex = eventPluginOrder.indexOf(pluginName); + + if (pluginIndex <= -1) { + throw new Error( + "EventPluginRegistry: Cannot inject event plugins that do not exist in " + + ("the plugin ordering, `" + pluginName + "`.") + ); } - if (parentA.child === parentB.child) { - for (parentB = parentA.child; parentB; ) { - if (parentB === a) return assertIsMounted(parentA), fiber; - if (parentB === b) return assertIsMounted(parentA), alternate; - parentB = parentB.sibling; - } - throw Error("Unable to find node on an unmounted component."); + + if (plugins[pluginIndex]) { + continue; } - if (a.return !== b.return) (a = parentA), (b = parentB); - else { - for (var didFindChild = !1, _child = parentA.child; _child; ) { - if (_child === a) { - didFindChild = !0; - a = parentA; - b = parentB; - break; - } - if (_child === b) { - didFindChild = !0; - b = parentA; - a = parentB; - break; - } - _child = _child.sibling; - } - if (!didFindChild) { - for (_child = parentB.child; _child; ) { - if (_child === a) { - didFindChild = !0; - a = parentB; - b = parentA; - break; - } - if (_child === b) { - didFindChild = !0; - b = parentB; - a = parentA; - break; - } - _child = _child.sibling; - } - if (!didFindChild) - throw Error( - "Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue." - ); + + if (!pluginModule.extractEvents) { + throw new Error( + "EventPluginRegistry: Event plugins must implement an `extractEvents` " + + ("method, but `" + pluginName + "` does not.") + ); + } + + plugins[pluginIndex] = pluginModule; + var publishedEvents = pluginModule.eventTypes; + + for (var eventName in publishedEvents) { + if ( + !publishEventForPlugin( + publishedEvents[eventName], + pluginModule, + eventName + ) + ) { + throw new Error( + "EventPluginRegistry: Failed to publish event `" + + eventName + + "` for plugin `" + + pluginName + + "`." + ); } } - if (a.alternate !== b) - throw Error( - "Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue." - ); } - if (3 !== a.tag) - throw Error("Unable to find node on an unmounted component."); - return a.stateNode.current === a ? fiber : alternate; - } - function findCurrentHostFiber(parent) { - parent = findCurrentFiberUsingSlowPath(parent); - return null !== parent ? findCurrentHostFiberImpl(parent) : null; } - function findCurrentHostFiberImpl(node) { - var tag = node.tag; - if (5 === tag || 26 === tag || 27 === tag || 6 === tag) return node; - for (node = node.child; null !== node; ) { - tag = findCurrentHostFiberImpl(node); - if (null !== tag) return tag; - node = node.sibling; + /** + * Publishes an event so that it can be dispatched by the supplied plugin. + * + * @param {object} dispatchConfig Dispatch configuration for the event. + * @param {object} PluginModule Plugin publishing the event. + * @return {boolean} True if the event was successfully published. + * @private + */ + + function publishEventForPlugin(dispatchConfig, pluginModule, eventName) { + if (eventNameDispatchConfigs.hasOwnProperty(eventName)) { + throw new Error( + "EventPluginRegistry: More than one plugin attempted to publish the same " + + ("event name, `" + eventName + "`.") + ); } - return null; - } - function doesFiberContain(parentFiber, childFiber) { - for ( - var parentFiberAlternate = parentFiber.alternate; - null !== childFiber; - ) { - if (childFiber === parentFiber || childFiber === parentFiberAlternate) - return !0; - childFiber = childFiber.return; + eventNameDispatchConfigs[eventName] = dispatchConfig; + var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; + + if (phasedRegistrationNames) { + for (var phaseName in phasedRegistrationNames) { + if (phasedRegistrationNames.hasOwnProperty(phaseName)) { + var phasedRegistrationName = phasedRegistrationNames[phaseName]; + publishRegistrationName(phasedRegistrationName, pluginModule); + } + } + + return true; + } else if (dispatchConfig.registrationName) { + publishRegistrationName(dispatchConfig.registrationName, pluginModule); + return true; } - return !1; - } - function defaultDiffer(prevProp, nextProp) { - return "object" !== typeof nextProp || null === nextProp - ? !0 - : ReactNativePrivateInterface.deepDiffer( - prevProp, - nextProp, - deepDifferOptions - ); - } - function restoreDeletedValuesInNestedArray( - updatePayload, - node, - validAttributes + + return false; + } + /** + * Publishes a registration name that is used to identify dispatched events. + * + * @param {string} registrationName Registration name to add. + * @param {object} PluginModule Plugin publishing the event. + * @private + */ + + function publishRegistrationName( + registrationName, + pluginModule, + eventName ) { - if (isArrayImpl(node)) - for (var i = node.length; i-- && 0 < removedKeyCount; ) - restoreDeletedValuesInNestedArray( - updatePayload, - node[i], - validAttributes - ); - else if (node && 0 < removedKeyCount) - for (i in removedKeys) - if (removedKeys[i]) { - var nextProp = node[i]; - if (void 0 !== nextProp) { - var attributeConfig = validAttributes[i]; - if (attributeConfig) { - "function" === typeof nextProp && (nextProp = !0); - "undefined" === typeof nextProp && (nextProp = null); - if ("object" !== typeof attributeConfig) - updatePayload[i] = nextProp; - else if ( - "function" === typeof attributeConfig.diff || - "function" === typeof attributeConfig.process - ) - (nextProp = - "function" === typeof attributeConfig.process - ? attributeConfig.process(nextProp) - : nextProp), - (updatePayload[i] = nextProp); - removedKeys[i] = !1; - removedKeyCount--; - } - } + if (registrationNameModules[registrationName]) { + throw new Error( + "EventPluginRegistry: More than one plugin attempted to publish the same " + + ("registration name, `" + registrationName + "`.") + ); + } + + registrationNameModules[registrationName] = pluginModule; + + { + registrationName.toLowerCase(); + } + } + /** + * Registers plugins so that they can extract and dispatch events. + */ + + /** + * Ordered list of injected plugins. + */ + + var plugins = []; + /** + * Mapping from event name to dispatch config + */ + + var eventNameDispatchConfigs = {}; + /** + * Mapping from registration name to plugin module + */ + + var registrationNameModules = {}; + + /** + * Injects an ordering of plugins (by plugin name). This allows the ordering + * to be decoupled from injection of the actual plugins so that ordering is + * always deterministic regardless of packaging, on-the-fly injection, etc. + * + * @param {array} InjectedEventPluginOrder + * @internal + */ + + function injectEventPluginOrder(injectedEventPluginOrder) { + if (eventPluginOrder) { + throw new Error( + "EventPluginRegistry: Cannot inject event plugin ordering more than " + + "once. You are likely trying to load more than one copy of React." + ); + } // Clone the ordering so it cannot be dynamically mutated. + // $FlowFixMe[method-unbinding] found when upgrading Flow + + eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder); + recomputePluginOrdering(); + } + /** + * Injects plugins to be used by plugin event system. The plugin names must be + * in the ordering injected by `injectEventPluginOrder`. + * + * Plugins can be injected as part of page initialization or on-the-fly. + * + * @param {object} injectedNamesToPlugins Map from names to plugin modules. + * @internal + */ + + function injectEventPluginsByName(injectedNamesToPlugins) { + var isOrderingDirty = false; + + for (var pluginName in injectedNamesToPlugins) { + if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) { + continue; + } + + var pluginModule = injectedNamesToPlugins[pluginName]; + + if ( + !namesToPlugins.hasOwnProperty(pluginName) || + namesToPlugins[pluginName] !== pluginModule + ) { + if (namesToPlugins[pluginName]) { + throw new Error( + "EventPluginRegistry: Cannot inject two different event plugins " + + ("using the same name, `" + pluginName + "`.") + ); } + + namesToPlugins[pluginName] = pluginModule; + isOrderingDirty = true; + } + } + + if (isOrderingDirty) { + recomputePluginOrdering(); + } } - function diffNestedProperty( - updatePayload, - prevProp, - nextProp, - validAttributes - ) { - if (!updatePayload && prevProp === nextProp) return updatePayload; - if (!prevProp || !nextProp) - return nextProp - ? addNestedProperty(updatePayload, nextProp, validAttributes) - : prevProp - ? clearNestedProperty(updatePayload, prevProp, validAttributes) - : updatePayload; - if (!isArrayImpl(prevProp) && !isArrayImpl(nextProp)) - return diffProperties( - updatePayload, - prevProp, - nextProp, - validAttributes + + function getListener(inst, registrationName) { + var stateNode = inst.stateNode; + + if (stateNode === null) { + // Work in progress (ex: onload events in incremental mode). + return null; + } + + var props = getFiberCurrentPropsFromNode$1(stateNode); + + if (props === null) { + // Work in progress. + return null; + } + + var listener = props[registrationName]; + + if (listener && typeof listener !== "function") { + throw new Error( + "Expected `" + + registrationName + + "` listener to be a function, instead got a value of `" + + typeof listener + + "` type." ); - if (isArrayImpl(prevProp) && isArrayImpl(nextProp)) { - var minLength = - prevProp.length < nextProp.length - ? prevProp.length - : nextProp.length, - i; - for (i = 0; i < minLength; i++) - updatePayload = diffNestedProperty( - updatePayload, - prevProp[i], - nextProp[i], - validAttributes - ); - for (; i < prevProp.length; i++) - updatePayload = clearNestedProperty( - updatePayload, - prevProp[i], - validAttributes - ); - for (; i < nextProp.length; i++) - updatePayload = addNestedProperty( - updatePayload, - nextProp[i], - validAttributes - ); - return updatePayload; } - return isArrayImpl(prevProp) - ? diffProperties( - updatePayload, - ReactNativePrivateInterface.flattenStyle(prevProp), - nextProp, - validAttributes - ) - : diffProperties( - updatePayload, - prevProp, - ReactNativePrivateInterface.flattenStyle(nextProp), - validAttributes - ); + + return listener; } - function addNestedProperty(updatePayload, nextProp, validAttributes) { - if (!nextProp) return updatePayload; - if (!isArrayImpl(nextProp)) - return diffProperties( - updatePayload, - emptyObject$1, - nextProp, - validAttributes + + var customBubblingEventTypes = + ReactNativePrivateInterface.ReactNativeViewConfigRegistry + .customBubblingEventTypes, + customDirectEventTypes = + ReactNativePrivateInterface.ReactNativeViewConfigRegistry + .customDirectEventTypes; // Start of inline: the below functions were inlined from + // EventPropagator.js, as they deviated from ReactDOM's newer + // implementations. + // $FlowFixMe[missing-local-annot] + + function listenerAtPhase(inst, event, propagationPhase) { + var registrationName = + event.dispatchConfig.phasedRegistrationNames[propagationPhase]; + return getListener(inst, registrationName); + } // $FlowFixMe[missing-local-annot] + + function accumulateDirectionalDispatches(inst, phase, event) { + { + if (!inst) { + error("Dispatching inst must not be null"); + } + } + + var listener = listenerAtPhase(inst, event, phase); + + if (listener) { + event._dispatchListeners = accumulateInto( + event._dispatchListeners, + listener ); - for (var i = 0; i < nextProp.length; i++) - updatePayload = addNestedProperty( - updatePayload, - nextProp[i], - validAttributes + event._dispatchInstances = accumulateInto( + event._dispatchInstances, + inst ); - return updatePayload; + } + } // $FlowFixMe[missing-local-annot] + + function getParent(inst) { + do { + inst = inst.return; // TODO: If this is a HostRoot we might want to bail out. + // That is depending on if we want nested subtrees (layers) to bubble + // events to their parent. We could also go through parentNode on the + // host node but that wouldn't work for React Native and doesn't let us + // do the portal feature. + } while (inst && inst.tag !== HostComponent); + + if (inst) { + return inst; + } + + return null; } - function clearNestedProperty(updatePayload, prevProp, validAttributes) { - if (!prevProp) return updatePayload; - if (!isArrayImpl(prevProp)) - return diffProperties( - updatePayload, - prevProp, - emptyObject$1, - validAttributes + /** + * Simulates the traversal of a two-phase, capture/bubble event dispatch. + */ + + function traverseTwoPhase(inst, fn, arg, skipBubbling) { + var path = []; + + while (inst) { + path.push(inst); + inst = getParent(inst); + } + + var i; + + for (i = path.length; i-- > 0; ) { + fn(path[i], "captured", arg); + } + + if (skipBubbling) { + // Dispatch on target only + fn(path[0], "bubbled", arg); + } else { + for (i = 0; i < path.length; i++) { + fn(path[i], "bubbled", arg); + } + } + } // $FlowFixMe[missing-local-annot] + + function accumulateTwoPhaseDispatchesSingle(event) { + if (event && event.dispatchConfig.phasedRegistrationNames) { + traverseTwoPhase( + event._targetInst, + accumulateDirectionalDispatches, + event, + false ); - for (var i = 0; i < prevProp.length; i++) - updatePayload = clearNestedProperty( - updatePayload, - prevProp[i], - validAttributes + } + } // $FlowFixMe[missing-local-annot] + + function accumulateTwoPhaseDispatches(events) { + forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle); + } // $FlowFixMe[missing-local-annot] + + function accumulateCapturePhaseDispatches(event) { + if (event && event.dispatchConfig.phasedRegistrationNames) { + traverseTwoPhase( + event._targetInst, + accumulateDirectionalDispatches, + event, + true ); - return updatePayload; + } } - function diffProperties( - updatePayload, - prevProps, - nextProps, - validAttributes - ) { - var attributeConfig, propKey; - for (propKey in nextProps) - if ((attributeConfig = validAttributes[propKey])) { - var prevProp = prevProps[propKey]; - var nextProp = nextProps[propKey]; - "function" === typeof nextProp && - ((nextProp = !0), - "function" === typeof prevProp && (prevProp = !0)); - "undefined" === typeof nextProp && - ((nextProp = null), - "undefined" === typeof prevProp && (prevProp = null)); - removedKeys && (removedKeys[propKey] = !1); - if (updatePayload && void 0 !== updatePayload[propKey]) - if ("object" !== typeof attributeConfig) - updatePayload[propKey] = nextProp; - else { - if ( - "function" === typeof attributeConfig.diff || - "function" === typeof attributeConfig.process - ) - (attributeConfig = - "function" === typeof attributeConfig.process - ? attributeConfig.process(nextProp) - : nextProp), - (updatePayload[propKey] = attributeConfig); - } - else if (prevProp !== nextProp) - if ("object" !== typeof attributeConfig) - defaultDiffer(prevProp, nextProp) && - ((updatePayload || (updatePayload = {}))[propKey] = nextProp); - else if ( - "function" === typeof attributeConfig.diff || - "function" === typeof attributeConfig.process - ) { - if ( - void 0 === prevProp || - ("function" === typeof attributeConfig.diff - ? attributeConfig.diff(prevProp, nextProp) - : defaultDiffer(prevProp, nextProp)) - ) - (attributeConfig = - "function" === typeof attributeConfig.process - ? attributeConfig.process(nextProp) - : nextProp), - ((updatePayload || (updatePayload = {}))[propKey] = - attributeConfig); - } else - (removedKeys = null), - (removedKeyCount = 0), - (updatePayload = diffNestedProperty( - updatePayload, - prevProp, - nextProp, - attributeConfig - )), - 0 < removedKeyCount && - updatePayload && - (restoreDeletedValuesInNestedArray( - updatePayload, - nextProp, - attributeConfig - ), - (removedKeys = null)); - } - for (var _propKey in prevProps) - void 0 === nextProps[_propKey] && - (!(attributeConfig = validAttributes[_propKey]) || - (updatePayload && void 0 !== updatePayload[_propKey]) || - ((prevProp = prevProps[_propKey]), - void 0 !== prevProp && - ("object" !== typeof attributeConfig || - "function" === typeof attributeConfig.diff || - "function" === typeof attributeConfig.process - ? (((updatePayload || (updatePayload = {}))[_propKey] = null), - removedKeys || (removedKeys = {}), - removedKeys[_propKey] || - ((removedKeys[_propKey] = !0), removedKeyCount++)) - : (updatePayload = clearNestedProperty( - updatePayload, - prevProp, - attributeConfig - ))))); - return updatePayload; - } - function mountSafeCallback_NOT_REALLY_SAFE(context, callback) { - return function () { - if ( - callback && - ("boolean" !== typeof context.__isMounted || context.__isMounted) - ) - return callback.apply(context, arguments); - }; + /** + * Accumulates without regard to direction, does not look for phased + * registration names. Same as `accumulateDirectDispatchesSingle` but without + * requiring that the `dispatchMarker` be the same as the dispatched ID. + */ + + function accumulateDispatches(inst, ignoredDirection, event) { + if (inst && event && event.dispatchConfig.registrationName) { + var registrationName = event.dispatchConfig.registrationName; + var listener = getListener(inst, registrationName); + + if (listener) { + event._dispatchListeners = accumulateInto( + event._dispatchListeners, + listener + ); + event._dispatchInstances = accumulateInto( + event._dispatchInstances, + inst + ); + } + } } - function injectInternals(internals) { - if ("undefined" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) return !1; - var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; - if (hook.isDisabled) return !0; - if (!hook.supportsFiber) - return ( - error$jscomp$0( - "The installed version of React DevTools is too old and will not work with the current version of React. Please update React DevTools. https://react.dev/link/react-devtools" - ), - !0 - ); - try { - (internals = assign({}, internals, { - getLaneLabelMap: getLaneLabelMap, - injectProfilingHooks: injectProfilingHooks - })), - (rendererID = hook.inject(internals)), - (injectedHook = hook); - } catch (err) { - error$jscomp$0("React instrumentation encountered an error: %s.", err); + /** + * Accumulates dispatches on an `SyntheticEvent`, but only for the + * `dispatchMarker`. + * @param {SyntheticEvent} event + */ + + function accumulateDirectDispatchesSingle(event) { + if (event && event.dispatchConfig.registrationName) { + accumulateDispatches(event._targetInst, null, event); } - return hook.checkDCE ? !0 : !1; } - function onCommitRoot(root, eventPriority) { - if (injectedHook && "function" === typeof injectedHook.onCommitFiberRoot) - try { - var didError = 128 === (root.current.flags & 128); - switch (eventPriority) { - case DiscreteEventPriority: - var schedulerPriority = ImmediatePriority; - break; - case ContinuousEventPriority: - schedulerPriority = UserBlockingPriority; - break; - case DefaultEventPriority: - schedulerPriority = NormalPriority$1; - break; - case IdleEventPriority: - schedulerPriority = IdlePriority; - break; - default: - schedulerPriority = NormalPriority$1; - } - injectedHook.onCommitFiberRoot( - rendererID, - root, - schedulerPriority, - didError + + function accumulateDirectDispatches(events) { + forEachAccumulated(events, accumulateDirectDispatchesSingle); + } // End of inline + + var ReactNativeBridgeEventPlugin = { + eventTypes: {}, + extractEvents: function ( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget + ) { + if (targetInst == null) { + // Probably a node belonging to another renderer's tree. + return null; + } + + var bubbleDispatchConfig = customBubblingEventTypes[topLevelType]; + var directDispatchConfig = customDirectEventTypes[topLevelType]; + + if (!bubbleDispatchConfig && !directDispatchConfig) { + throw new Error( // $FlowFixMe[incompatible-type] - Flow doesn't like this string coercion because DOMTopLevelEventType is opaque + 'Unsupported top level event type "' + topLevelType + '" dispatched' ); - } catch (err) { - hasLoggedError || - ((hasLoggedError = !0), - error$jscomp$0( - "React instrumentation encountered an error: %s", - err - )); } - } - function setIsStrictModeForDevtools(newIsStrictMode) { - "function" === typeof log$1 && - (unstable_setDisableYieldValue(newIsStrictMode), - (suppressWarning = newIsStrictMode)); - if (injectedHook && "function" === typeof injectedHook.setStrictMode) - try { - injectedHook.setStrictMode(rendererID, newIsStrictMode); - } catch (err) { - hasLoggedError || - ((hasLoggedError = !0), - error$jscomp$0( - "React instrumentation encountered an error: %s", - err - )); + + var event = SyntheticEvent.getPooled( + bubbleDispatchConfig || directDispatchConfig, + targetInst, + nativeEvent, + nativeEventTarget + ); + + if (bubbleDispatchConfig) { + var skipBubbling = + event != null && + event.dispatchConfig.phasedRegistrationNames != null && + event.dispatchConfig.phasedRegistrationNames.skipBubbling; + + if (skipBubbling) { + accumulateCapturePhaseDispatches(event); + } else { + accumulateTwoPhaseDispatches(event); + } + } else if (directDispatchConfig) { + accumulateDirectDispatches(event); + } else { + return null; } + + return event; + } + }; + + var ReactNativeEventPluginOrder = [ + "ResponderEventPlugin", + "ReactNativeBridgeEventPlugin" + ]; + + /** + * Make sure essential globals are available and are patched correctly. Please don't remove this + * line. Bundles created by react-packager `require` it before executing any application code. This + * ensures it exists in the dependency graph and can be `require`d. + * TODO: require this in packager, not in React #10932517 + */ + /** + * Inject module for resolving DOM hierarchy and plugin ordering. + */ + + injectEventPluginOrder(ReactNativeEventPluginOrder); + /** + * Some important event plugins included by default (without having to require + * them). + */ + + injectEventPluginsByName({ + ResponderEventPlugin: ResponderEventPlugin, + ReactNativeBridgeEventPlugin: ReactNativeBridgeEventPlugin + }); + + var instanceCache = new Map(); + var instanceProps = new Map(); + function precacheFiberNode(hostInst, tag) { + instanceCache.set(tag, hostInst); } - function injectProfilingHooks(profilingHooks) { - injectedProfilingHooks = profilingHooks; - } - function getLaneLabelMap() { - for ( - var map = new Map(), lane = 1, index = 0; - index < TotalLanes; - index++ - ) { - var label = getLabelForLane(lane); - map.set(lane, label); - lane *= 2; - } - return map; - } - function markCommitStopped() { - null !== injectedProfilingHooks && - "function" === typeof injectedProfilingHooks.markCommitStopped && - injectedProfilingHooks.markCommitStopped(); - } - function markComponentRenderStarted(fiber) { - null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markComponentRenderStarted && - injectedProfilingHooks.markComponentRenderStarted(fiber); - } - function markComponentRenderStopped() { - null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markComponentRenderStopped && - injectedProfilingHooks.markComponentRenderStopped(); - } - function markComponentLayoutEffectUnmountStarted(fiber) { - null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markComponentLayoutEffectUnmountStarted && - injectedProfilingHooks.markComponentLayoutEffectUnmountStarted(fiber); - } - function markComponentLayoutEffectUnmountStopped() { - null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markComponentLayoutEffectUnmountStopped && - injectedProfilingHooks.markComponentLayoutEffectUnmountStopped(); - } - function markRenderStarted(lanes) { - null !== injectedProfilingHooks && - "function" === typeof injectedProfilingHooks.markRenderStarted && - injectedProfilingHooks.markRenderStarted(lanes); - } - function markRenderStopped() { - null !== injectedProfilingHooks && - "function" === typeof injectedProfilingHooks.markRenderStopped && - injectedProfilingHooks.markRenderStopped(); - } - function markStateUpdateScheduled(fiber, lane) { - null !== injectedProfilingHooks && - "function" === typeof injectedProfilingHooks.markStateUpdateScheduled && - injectedProfilingHooks.markStateUpdateScheduled(fiber, lane); + function uncacheFiberNode(tag) { + instanceCache.delete(tag); + instanceProps.delete(tag); } - function clz32Fallback(x) { - x >>>= 0; - return 0 === x ? 32 : (31 - ((log(x) / LN2) | 0)) | 0; - } - function getLabelForLane(lane) { - if (lane & SyncHydrationLane) return "SyncHydrationLane"; - if (lane & SyncLane) return "Sync"; - if (lane & InputContinuousHydrationLane) - return "InputContinuousHydration"; - if (lane & InputContinuousLane) return "InputContinuous"; - if (lane & DefaultHydrationLane) return "DefaultHydration"; - if (lane & DefaultLane) return "Default"; - if (lane & TransitionHydrationLane) return "TransitionHydration"; - if (lane & TransitionLanes) return "Transition"; - if (lane & RetryLanes) return "Retry"; - if (lane & SelectiveHydrationLane) return "SelectiveHydration"; - if (lane & IdleHydrationLane) return "IdleHydration"; - if (lane & IdleLane) return "Idle"; - if (lane & OffscreenLane) return "Offscreen"; - if (lane & DeferredLane) return "Deferred"; + + function getInstanceFromTag(tag) { + return instanceCache.get(tag) || null; } - function getHighestPriorityLanes(lanes) { - var pendingSyncLanes = lanes & SyncUpdateLanes; - if (0 !== pendingSyncLanes) return pendingSyncLanes; - switch (lanes & -lanes) { - case SyncHydrationLane: - return SyncHydrationLane; - case SyncLane: - return SyncLane; - case InputContinuousHydrationLane: - return InputContinuousHydrationLane; - case InputContinuousLane: - return InputContinuousLane; - case DefaultHydrationLane: - return DefaultHydrationLane; - case DefaultLane: - return DefaultLane; - case TransitionHydrationLane: - return TransitionHydrationLane; - 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 & TransitionLanes; - case 4194304: - case 8388608: - case 16777216: - case 33554432: - return lanes & RetryLanes; - case SelectiveHydrationLane: - return SelectiveHydrationLane; - case IdleHydrationLane: - return IdleHydrationLane; - case IdleLane: - return IdleLane; - case OffscreenLane: - return OffscreenLane; - case DeferredLane: - return 0; - default: - return ( - error$jscomp$0( - "Should have found matching lanes. This is a bug in React." - ), - lanes - ); + + function getTagFromInstance(inst) { + var nativeInstance = inst.stateNode; + var tag = nativeInstance._nativeTag; + + if (tag === undefined && nativeInstance.canonical != null) { + // For compatibility with Fabric + tag = nativeInstance.canonical.nativeTag; + nativeInstance = nativeInstance.canonical.publicInstance; } - } - function getNextLanes(root, wipLanes) { - var pendingLanes = root.pendingLanes; - if (0 === pendingLanes) return 0; - var nextLanes = 0, - suspendedLanes = root.suspendedLanes; - root = root.pingedLanes; - var nonIdlePendingLanes = pendingLanes & 134217727; - 0 !== nonIdlePendingLanes - ? ((pendingLanes = nonIdlePendingLanes & ~suspendedLanes), - 0 !== pendingLanes - ? (nextLanes = getHighestPriorityLanes(pendingLanes)) - : ((root &= nonIdlePendingLanes), - 0 !== root && (nextLanes = getHighestPriorityLanes(root)))) - : ((pendingLanes &= ~suspendedLanes), - 0 !== pendingLanes - ? (nextLanes = getHighestPriorityLanes(pendingLanes)) - : 0 !== root && (nextLanes = getHighestPriorityLanes(root))); - return 0 === nextLanes - ? 0 - : 0 !== wipLanes && - wipLanes !== nextLanes && - 0 === (wipLanes & suspendedLanes) && - ((suspendedLanes = nextLanes & -nextLanes), - (root = wipLanes & -wipLanes), - suspendedLanes >= root || - (suspendedLanes === DefaultLane && 0 !== (root & TransitionLanes))) - ? wipLanes - : nextLanes; - } - function computeExpirationTime(lane, currentTime) { - switch (lane) { - case SyncHydrationLane: - case SyncLane: - case InputContinuousHydrationLane: - case InputContinuousLane: - return currentTime + 250; - case DefaultHydrationLane: - case DefaultLane: - case TransitionHydrationLane: - 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: - return -1; - case SelectiveHydrationLane: - case IdleHydrationLane: - case IdleLane: - case OffscreenLane: - case DeferredLane: - return -1; - default: - return ( - error$jscomp$0( - "Should have found matching lanes. This is a bug in React." - ), - -1 - ); + + if (!tag) { + throw new Error("All native instances should have a tag."); } + + return nativeInstance; } - function getLanesToRetrySynchronouslyOnError( - root, - originallyAttemptedLanes - ) { - if (root.errorRecoveryDisabledLanes & originallyAttemptedLanes) return 0; - root = root.pendingLanes & ~OffscreenLane; - return 0 !== root ? root : root & OffscreenLane ? OffscreenLane : 0; - } - function claimNextTransitionLane() { - var lane = nextTransitionLane; - nextTransitionLane <<= 1; - 0 === (nextTransitionLane & TransitionLanes) && - (nextTransitionLane = 128); - return lane; - } - function claimNextRetryLane() { - var lane = nextRetryLane; - nextRetryLane <<= 1; - 0 === (nextRetryLane & RetryLanes) && (nextRetryLane = 4194304); - return lane; + function getFiberCurrentPropsFromNode(stateNode) { + return instanceProps.get(stateNode._nativeTag) || null; } - function createLaneMap(initial) { - for (var laneMap = [], i = 0; i < TotalLanes; i++) laneMap.push(initial); - return laneMap; + function updateFiberProps(tag, props) { + instanceProps.set(tag, props); } - function markRootFinished(root, remainingLanes, spawnedLane) { - var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; - root.pendingLanes = remainingLanes; - root.suspendedLanes = 0; - root.pingedLanes = 0; - root.expiredLanes &= remainingLanes; - root.entangledLanes &= remainingLanes; - root.errorRecoveryDisabledLanes &= remainingLanes; - root.shellSuspendCounter = 0; - remainingLanes = root.entanglements; - for ( - var expirationTimes = root.expirationTimes, - hiddenUpdates = root.hiddenUpdates; - 0 < noLongerPendingLanes; - ) { - var index = 31 - clz32(noLongerPendingLanes), - lane = 1 << index; - remainingLanes[index] = 0; - expirationTimes[index] = -1; - var hiddenUpdatesForLane = hiddenUpdates[index]; - if (null !== hiddenUpdatesForLane) - for ( - hiddenUpdates[index] = null, index = 0; - index < hiddenUpdatesForLane.length; - index++ - ) { - var update = hiddenUpdatesForLane[index]; - null !== update && (update.lane &= ~OffscreenLane); - } - noLongerPendingLanes &= ~lane; + // Used as a way to call batchedUpdates when we don't have a reference to + // the renderer. Such as when we're dispatching events or if third party + // libraries need to call batchedUpdates. Eventually, this API will go away when + // everything is batched by default. We'll then have a similar API to opt-out of + // scheduled work and instead do synchronous work. + // Defaults + var batchedUpdatesImpl = function (fn, bookkeeping) { + return fn(bookkeeping); + }; + + var isInsideEventHandler = false; + function batchedUpdates$1(fn, bookkeeping) { + if (isInsideEventHandler) { + // If we are currently inside another batch, we need to wait until it + // fully completes before restoring state. + return fn(bookkeeping); } - 0 !== spawnedLane && markSpawnedDeferredLane(root, spawnedLane, 0); - } - function markSpawnedDeferredLane(root, spawnedLane, entangledLanes) { - root.pendingLanes |= spawnedLane; - root.suspendedLanes &= ~spawnedLane; - var spawnedLaneIndex = 31 - clz32(spawnedLane); - root.entangledLanes |= spawnedLane; - root.entanglements[spawnedLaneIndex] = - root.entanglements[spawnedLaneIndex] | - DeferredLane | - (entangledLanes & UpdateLanes); - } - function markRootEntangled(root, entangledLanes) { - var rootEntangledLanes = (root.entangledLanes |= entangledLanes); - for (root = root.entanglements; rootEntangledLanes; ) { - var index = 31 - clz32(rootEntangledLanes), - lane = 1 << index; - (lane & entangledLanes) | (root[index] & entangledLanes) && - (root[index] |= entangledLanes); - rootEntangledLanes &= ~lane; + + isInsideEventHandler = true; + + try { + return batchedUpdatesImpl(fn, bookkeeping); + } finally { + isInsideEventHandler = false; } } - function addFiberToLanesMap(root, fiber, lanes) { - if (isDevToolsPresent) - for (root = root.pendingUpdatersLaneMap; 0 < lanes; ) { - var index = 31 - clz32(lanes), - lane = 1 << index; - root[index].add(fiber); - lanes &= ~lane; - } + function setBatchingImplementation( + _batchedUpdatesImpl, + _discreteUpdatesImpl + ) { + batchedUpdatesImpl = _batchedUpdatesImpl; } - function movePendingFibersToMemoized(root, lanes) { - if (isDevToolsPresent) - for ( - var pendingUpdatersLaneMap = root.pendingUpdatersLaneMap, - memoizedUpdaters = root.memoizedUpdaters; - 0 < lanes; - ) { - var index = 31 - clz32(lanes); - root = 1 << index; - index = pendingUpdatersLaneMap[index]; - 0 < index.size && - (index.forEach(function (fiber) { - var alternate = fiber.alternate; - (null !== alternate && memoizedUpdaters.has(alternate)) || - memoizedUpdaters.add(fiber); - }), - index.clear()); - lanes &= ~root; + /** + * Internal queue of events that have accumulated their dispatches and are + * waiting to have their dispatches executed. + */ + + var eventQueue = null; + /** + * Dispatches an event and releases it back into the pool, unless persistent. + * + * @param {?object} event Synthetic event to be dispatched. + * @private + */ + + function executeDispatchesAndRelease(event) { + if (event) { + executeDispatchesInOrder(event); + + if (!event.isPersistent()) { + event.constructor.release(event); } - } - function lanesToEventPriority(lanes) { - lanes &= -lanes; - return 0 !== DiscreteEventPriority && DiscreteEventPriority < lanes - ? 0 !== ContinuousEventPriority && ContinuousEventPriority < lanes - ? 0 !== (lanes & 134217727) - ? DefaultEventPriority - : IdleEventPriority - : ContinuousEventPriority - : DiscreteEventPriority; - } - 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." - ); - } - function shim() { - throw Error( - "The current renderer does not support Resources. This error is likely caused by a bug in React. Please file an issue." - ); - } - function allocateTag() { - var tag = nextReactTag; - 1 === tag % 10 && (tag += 2); - nextReactTag = tag + 2; - return tag; - } - function recursivelyUncacheFiberNode(node) { - if ("number" === typeof node) - instanceCache.delete(node), instanceProps.delete(node); - else { - var tag = node._nativeTag; - instanceCache.delete(tag); - instanceProps.delete(tag); - node._children.forEach(recursivelyUncacheFiberNode); } + } // $FlowFixMe[missing-local-annot] + + function executeDispatchesAndReleaseTopLevel(e) { + return executeDispatchesAndRelease(e); } - function finalizeInitialChildren(parentInstance) { - if (0 === parentInstance._children.length) return !1; - var nativeTags = parentInstance._children.map(function (child) { - return "number" === typeof child ? child : child._nativeTag; - }); - ReactNativePrivateInterface.UIManager.setChildren( - parentInstance._nativeTag, - nativeTags + + function runEventsInBatch(events) { + if (events !== null) { + eventQueue = accumulateInto(eventQueue, events); + } // Set `eventQueue` to null before processing it so that we can tell if more + // events get enqueued while processing. + + var processingEventQueue = eventQueue; + eventQueue = null; + + if (!processingEventQueue) { + return; + } + + forEachAccumulated( + processingEventQueue, + executeDispatchesAndReleaseTopLevel ); - return !1; - } - function getPublicInstance(instance) { - return null != instance.canonical && - null != instance.canonical.publicInstance - ? instance.canonical.publicInstance - : instance; - } - function createCursor(defaultValue) { - return { current: defaultValue }; - } - function pop(cursor, fiber) { - 0 > index$jscomp$0 - ? error$jscomp$0("Unexpected pop.") - : (fiber !== fiberStack[index$jscomp$0] && - error$jscomp$0("Unexpected Fiber popped."), - (cursor.current = valueStack[index$jscomp$0]), - (valueStack[index$jscomp$0] = null), - (fiberStack[index$jscomp$0] = null), - index$jscomp$0--); - } - function push(cursor, value, fiber) { - index$jscomp$0++; - valueStack[index$jscomp$0] = cursor.current; - fiberStack[index$jscomp$0] = fiber; - cursor.current = value; - } - function is(x, y) { - return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y); - } - function createCapturedValueAtFiber(value, source) { - if ("object" === typeof value && null !== value) { - var stack = CapturedStacks.get(value); - "string" !== typeof stack && - ((stack = getStackByFiberInDevAndProd(source)), - CapturedStacks.set(value, stack)); - } else stack = getStackByFiberInDevAndProd(source); - return { value: value, source: source, stack: stack }; - } - function requiredContext(c) { - null === c && - error$jscomp$0( - "Expected host context to exist. This error is likely caused by a bug in React. Please file an issue." + + if (eventQueue) { + throw new Error( + "processEventQueue(): Additional events were enqueued while processing " + + "an event queue. Support for this has not yet been implemented." ); - return c; - } - function pushHostContainer(fiber, nextRootInstance) { - push(rootInstanceStackCursor, nextRootInstance, fiber); - push(contextFiberStackCursor, fiber, fiber); - push(contextStackCursor, null, fiber); - pop(contextStackCursor, fiber); - push(contextStackCursor, { isInAParentText: !1 }, fiber); - } - function popHostContainer(fiber) { - pop(contextStackCursor, fiber); - pop(contextFiberStackCursor, fiber); - pop(rootInstanceStackCursor, fiber); - } - function pushHostContext(fiber) { - null !== fiber.memoizedState && - push(hostTransitionProviderCursor, fiber, fiber); - var context = requiredContext(contextStackCursor.current); - var nextContext = fiber.type; - nextContext = - "AndroidTextInput" === nextContext || - "RCTMultilineTextInputView" === nextContext || - "RCTSinglelineTextInputView" === nextContext || - "RCTText" === nextContext || - "RCTVirtualText" === nextContext; - nextContext = - context.isInAParentText !== nextContext - ? { isInAParentText: nextContext } - : context; - context !== nextContext && - (push(contextFiberStackCursor, fiber, fiber), - push(contextStackCursor, nextContext, fiber)); + } // This would be a good time to rethrow if any of the event handlers threw. + + rethrowCaughtError(); } - function popHostContext(fiber) { - contextFiberStackCursor.current === fiber && - (pop(contextStackCursor, fiber), pop(contextFiberStackCursor, fiber)); - hostTransitionProviderCursor.current === fiber && - (pop(hostTransitionProviderCursor, fiber), - (HostTransitionContext._currentValue = null)); - } - function findNotableNode(node, indent) { - return void 0 === node.serverProps && - 0 === node.serverTail.length && - 1 === node.children.length && - 3 < node.distanceFromLeaf && - node.distanceFromLeaf > 15 - indent - ? findNotableNode(node.children[0], indent) - : node; - } - function indentation(indent) { - return " " + " ".repeat(indent); - } - function added(indent) { - return "+ " + " ".repeat(indent); - } - function removed(indent) { - return "- " + " ".repeat(indent); - } - function describeFiberType(fiber) { - switch (fiber.tag) { - case 26: - case 27: - case 5: - return fiber.type; - case 16: - return "Lazy"; - case 13: - return "Suspense"; - case 19: - return "SuspenseList"; - case 0: - case 15: - return (fiber = fiber.type), fiber.displayName || fiber.name || null; - case 11: - return ( - (fiber = fiber.type.render), fiber.displayName || fiber.name || null - ); - case 1: - return (fiber = fiber.type), fiber.displayName || fiber.name || null; - default: - return null; + + /** + * Version of `ReactBrowserEventEmitter` that works on the receiving side of a + * serialized worker boundary. + */ + // Shared default empty native event - conserve memory. + + var EMPTY_NATIVE_EVENT = {}; + /** + * Selects a subsequence of `Touch`es, without destroying `touches`. + * + * @param {Array} touches Deserialized touch objects. + * @param {Array} indices Indices by which to pull subsequence. + * @return {Array} Subsequence of touch objects. + */ + // $FlowFixMe[missing-local-annot] + + function touchSubsequence(touches, indices) { + var ret = []; + + for (var i = 0; i < indices.length; i++) { + ret.push(touches[indices[i]]); } - } - function describeTextNode(content, maxLength) { - return needsEscaping.test(content) - ? ((content = JSON.stringify(content)), - content.length > maxLength - 2 - ? 8 > maxLength - ? '{"..."}' - : "{" + content.slice(0, maxLength - 7) + '..."}' - : "{" + content + "}") - : content.length > maxLength - ? 5 > maxLength - ? '{"..."}' - : content.slice(0, maxLength - 3) + "..." - : content; - } - function describeTextDiff(clientText, serverProps, indent) { - var maxLength = 120 - 2 * indent; - if (null === serverProps) - return added(indent) + describeTextNode(clientText, maxLength) + "\n"; - if ("string" === typeof serverProps) { - for ( - var firstDiff = 0; - firstDiff < serverProps.length && - firstDiff < clientText.length && - serverProps.charCodeAt(firstDiff) === - clientText.charCodeAt(firstDiff); - firstDiff++ - ); - firstDiff > maxLength - 8 && - 10 < firstDiff && - ((clientText = "..." + clientText.slice(firstDiff - 8)), - (serverProps = "..." + serverProps.slice(firstDiff - 8))); - return ( - added(indent) + - describeTextNode(clientText, maxLength) + - "\n" + - removed(indent) + - describeTextNode(serverProps, maxLength) + - "\n" - ); + + return ret; + } + /** + * TODO: Pool all of this. + * + * Destroys `touches` by removing touch objects at indices `indices`. This is + * to maintain compatibility with W3C touch "end" events, where the active + * touches don't include the set that has just been "ended". + * + * @param {Array} touches Deserialized touch objects. + * @param {Array} indices Indices to remove from `touches`. + * @return {Array} Subsequence of removed touch objects. + */ + + function removeTouchesAtIndices(touches, indices) { + var rippedOut = []; // use an unsafe downcast to alias to nullable elements, + // so we can delete and then compact. + + var temp = touches; + + for (var i = 0; i < indices.length; i++) { + var index = indices[i]; + rippedOut.push(touches[index]); + temp[index] = null; } - return ( - indentation(indent) + describeTextNode(clientText, maxLength) + "\n" - ); - } - function objectName(object) { - return Object.prototype.toString - .call(object) - .replace(/^\[object (.*)\]$/, function (m, p0) { - return p0; - }); - } - function describeValue(value, maxLength) { - switch (typeof value) { - case "string": - return ( - (value = JSON.stringify(value)), - value.length > maxLength - ? 5 > maxLength - ? '"..."' - : value.slice(0, maxLength - 4) + '..."' - : value - ); - case "object": - if (null === value) return "null"; - if (isArrayImpl(value)) return "[...]"; - if (value.$$typeof === REACT_ELEMENT_TYPE) - return (maxLength = getComponentNameFromType(value.type)) - ? "<" + maxLength + ">" - : "<...>"; - var name = objectName(value); - if ("Object" === name) { - name = ""; - maxLength -= 2; - for (var propName in value) - if (value.hasOwnProperty(propName)) { - var jsonPropName = JSON.stringify(propName); - jsonPropName !== '"' + propName + '"' && - (propName = jsonPropName); - maxLength -= propName.length - 2; - jsonPropName = describeValue( - value[propName], - 15 > maxLength ? maxLength : 15 - ); - maxLength -= jsonPropName.length; - if (0 > maxLength) { - name += "" === name ? "..." : ", ..."; - break; - } - name += - ("" === name ? "" : ",") + propName + ":" + jsonPropName; - } - return "{" + name + "}"; - } - return name; - case "function": - return (maxLength = value.displayName || value.name) - ? "function " + maxLength - : "function"; - default: - return String(value); - } - } - function describePropValue(value, maxLength) { - return "string" !== typeof value || needsEscaping.test(value) - ? "{" + describeValue(value, maxLength - 2) + "}" - : value.length > maxLength - 2 - ? 5 > maxLength - ? '"..."' - : '"' + value.slice(0, maxLength - 5) + '..."' - : '"' + value + '"'; - } - function describeExpandedElement(type, props, rowPrefix) { - var remainingRowLength = 120 - rowPrefix.length - type.length, - properties = [], - propName; - for (propName in props) - if (props.hasOwnProperty(propName) && "children" !== propName) { - var propValue = describePropValue( - props[propName], - 120 - rowPrefix.length - propName.length - 1 - ); - remainingRowLength -= propName.length + propValue.length + 2; - properties.push(propName + "=" + propValue); - } - return 0 === properties.length - ? rowPrefix + "<" + type + ">\n" - : 0 < remainingRowLength - ? rowPrefix + "<" + type + " " + properties.join(" ") + ">\n" - : rowPrefix + - "<" + - type + - "\n" + - rowPrefix + - " " + - properties.join("\n" + rowPrefix + " ") + - "\n" + - rowPrefix + - ">\n"; - } - function describePropertiesDiff(clientObject, serverObject, indent) { - var properties = "", - remainingServerProperties = assign({}, serverObject), - propName; - for (propName in clientObject) - if (clientObject.hasOwnProperty(propName)) { - delete remainingServerProperties[propName]; - var maxLength = 120 - 2 * indent - propName.length - 2, - clientPropValue = describeValue(clientObject[propName], maxLength); - serverObject.hasOwnProperty(propName) - ? ((maxLength = describeValue(serverObject[propName], maxLength)), - (properties += - added(indent) + propName + ": " + clientPropValue + "\n"), - (properties += - removed(indent) + propName + ": " + maxLength + "\n")) - : (properties += - added(indent) + propName + ": " + clientPropValue + "\n"); - } - for (var _propName in remainingServerProperties) - remainingServerProperties.hasOwnProperty(_propName) && - ((clientObject = describeValue( - remainingServerProperties[_propName], - 120 - 2 * indent - _propName.length - 2 - )), - (properties += - removed(indent) + _propName + ": " + clientObject + "\n")); - return properties; - } - function describeElementDiff(type, clientProps, serverProps, indent) { - var content = "", - serverPropNames = new Map(); - for (propName$jscomp$0 in serverProps) - serverProps.hasOwnProperty(propName$jscomp$0) && - serverPropNames.set( - propName$jscomp$0.toLowerCase(), - propName$jscomp$0 - ); - if (1 === serverPropNames.size && serverPropNames.has("children")) - content += describeExpandedElement( - type, - clientProps, - indentation(indent) - ); - else { - for (var _propName2 in clientProps) - if ( - clientProps.hasOwnProperty(_propName2) && - "children" !== _propName2 - ) { - var maxLength$jscomp$0 = - 120 - 2 * (indent + 1) - _propName2.length - 1, - serverPropName = serverPropNames.get(_propName2.toLowerCase()); - if (void 0 !== serverPropName) { - serverPropNames.delete(_propName2.toLowerCase()); - var propName$jscomp$0 = clientProps[_propName2]; - serverPropName = serverProps[serverPropName]; - var clientPropValue = describePropValue( - propName$jscomp$0, - maxLength$jscomp$0 - ); - maxLength$jscomp$0 = describePropValue( - serverPropName, - maxLength$jscomp$0 - ); - "object" === typeof propName$jscomp$0 && - null !== propName$jscomp$0 && - "object" === typeof serverPropName && - null !== serverPropName && - "Object" === objectName(propName$jscomp$0) && - "Object" === objectName(serverPropName) && - (2 < Object.keys(propName$jscomp$0).length || - 2 < Object.keys(serverPropName).length || - -1 < clientPropValue.indexOf("...") || - -1 < maxLength$jscomp$0.indexOf("...")) - ? (content += - indentation(indent + 1) + - _propName2 + - "={{\n" + - describePropertiesDiff( - propName$jscomp$0, - serverPropName, - indent + 2 - ) + - indentation(indent + 1) + - "}}\n") - : ((content += - added(indent + 1) + - _propName2 + - "=" + - clientPropValue + - "\n"), - (content += - removed(indent + 1) + - _propName2 + - "=" + - maxLength$jscomp$0 + - "\n")); - } else - content += - indentation(indent + 1) + - _propName2 + - "=" + - describePropValue(clientProps[_propName2], maxLength$jscomp$0) + - "\n"; - } - serverPropNames.forEach(function (propName) { - if ("children" !== propName) { - var maxLength = 120 - 2 * (indent + 1) - propName.length - 1; - content += - removed(indent + 1) + - propName + - "=" + - describePropValue(serverProps[propName], maxLength) + - "\n"; - } - }); - content = - "" === content - ? indentation(indent) + "<" + type + ">\n" - : indentation(indent) + - "<" + - type + - "\n" + - content + - indentation(indent) + - ">\n"; - } - type = serverProps.children; - clientProps = clientProps.children; - if ( - "string" === typeof type || - "number" === typeof type || - "bigint" === typeof type - ) { - serverPropNames = ""; - if ( - "string" === typeof clientProps || - "number" === typeof clientProps || - "bigint" === typeof clientProps - ) - serverPropNames = "" + clientProps; - content += describeTextDiff(serverPropNames, "" + type, indent + 1); - } else if ( - "string" === typeof clientProps || - "number" === typeof clientProps || - "bigint" === typeof clientProps - ) - content += describeTextDiff("" + clientProps, void 0, indent + 1); - return content; - } - function describeSiblingFiber(fiber, indent) { - var type = describeFiberType(fiber); - if (null === type) { - type = ""; - for (fiber = fiber.child; fiber; ) - (type += describeSiblingFiber(fiber, indent)), - (fiber = fiber.sibling); - return type; + + var fillAt = 0; + + for (var j = 0; j < temp.length; j++) { + var cur = temp[j]; + + if (cur !== null) { + temp[fillAt++] = cur; + } } - return indentation(indent) + "<" + type + ">\n"; - } - function describeNode(node, indent) { - var skipToNode = findNotableNode(node, indent); - if ( - skipToNode !== node && - (1 !== node.children.length || node.children[0] !== skipToNode) - ) - return ( - indentation(indent) + "...\n" + describeNode(skipToNode, indent + 1) + + temp.length = fillAt; + return rippedOut; + } + /** + * Internal version of `receiveEvent` in terms of normalized (non-tag) + * `rootNodeID`. + * + * @see receiveEvent. + * + * @param {rootNodeID} rootNodeID React root node ID that event occurred on. + * @param {TopLevelType} topLevelType Top level type of event. + * @param {?object} nativeEventParam Object passed from native. + */ + + function _receiveRootNodeIDEvent( + rootNodeID, + topLevelType, + nativeEventParam + ) { + var nativeEvent = nativeEventParam || EMPTY_NATIVE_EVENT; + var inst = getInstanceFromTag(rootNodeID); + var target = null; + + if (inst != null) { + target = inst.stateNode; + } + + batchedUpdates$1(function () { + runExtractedPluginEventsInBatch( + topLevelType, + inst, + nativeEvent, + target ); - skipToNode = ""; - var debugInfo = node.fiber._debugInfo; - if (debugInfo) - for (var i = 0; i < debugInfo.length; i++) { - var serverComponentName = debugInfo[i].name; - "string" === typeof serverComponentName && - ((skipToNode += - indentation(indent) + "<" + serverComponentName + ">\n"), - indent++); - } - debugInfo = ""; - i = node.fiber.pendingProps; - if (6 === node.fiber.tag) - debugInfo = describeTextDiff(i, node.serverProps, indent); - else if ( - ((serverComponentName = describeFiberType(node.fiber)), - null !== serverComponentName) - ) - if (void 0 === node.serverProps) { - debugInfo = indent; - var maxLength = 120 - 2 * debugInfo - serverComponentName.length - 2, - content = ""; - for (propName in i) - if (i.hasOwnProperty(propName) && "children" !== propName) { - var propValue = describePropValue(i[propName], 15); - maxLength -= propName.length + propValue.length + 2; - if (0 > maxLength) { - content += " ..."; - break; - } - content += " " + propName + "=" + propValue; - } - debugInfo = - indentation(debugInfo) + - "<" + - serverComponentName + - content + - ">\n"; - indent++; - } else - null === node.serverProps - ? (debugInfo = describeExpandedElement( - serverComponentName, - i, - added(indent) - )) - : "string" === typeof node.serverProps - ? error$jscomp$0( - "Should not have matched a non HostText fiber to a Text node. This is a bug in React." - ) - : ((debugInfo = describeElementDiff( - serverComponentName, - i, - node.serverProps, - indent - )), - indent++); - var propName = ""; - i = node.fiber.child; - for ( - serverComponentName = 0; - i && serverComponentName < node.children.length; - - ) - (maxLength = node.children[serverComponentName]), - maxLength.fiber === i - ? ((propName += describeNode(maxLength, indent)), - serverComponentName++) - : (propName += describeSiblingFiber(i, indent)), - (i = i.sibling); - i && - 0 < node.children.length && - (propName += indentation(indent) + "...\n"); - node = node.serverTail; - for (i = 0; i < node.length; i++) - (serverComponentName = node[i]), - (propName = - "string" === typeof serverComponentName - ? propName + - (removed(indent) + - describeTextNode(serverComponentName, 120 - 2 * indent) + - "\n") - : propName + - describeExpandedElement( - serverComponentName.type, - serverComponentName.props, - removed(indent) - )); - return skipToNode + debugInfo + propName; - } - function finishQueueingConcurrentUpdates() { - for ( - var endIndex = concurrentQueuesIndex, - i = (concurrentlyUpdatedLanes = concurrentQueuesIndex = 0); - i < endIndex; + }); // React Native doesn't use ReactControlledComponent but if it did, here's + // where it would do it. + } + /** + * Allows registered plugins an opportunity to extract events from top-level + * native browser events. + * + * @return {*} An accumulation of synthetic events. + * @internal + */ - ) { - var fiber = concurrentQueues[i]; - concurrentQueues[i++] = null; - var queue = concurrentQueues[i]; - concurrentQueues[i++] = null; - var update = concurrentQueues[i]; - concurrentQueues[i++] = null; - var lane = concurrentQueues[i]; - concurrentQueues[i++] = null; - if (null !== queue && null !== update) { - var pending = queue.pending; - null === pending - ? (update.next = update) - : ((update.next = pending.next), (pending.next = update)); - queue.pending = update; + function extractPluginEvents( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget + ) { + var events = null; + var legacyPlugins = plugins; + + for (var i = 0; i < legacyPlugins.length; i++) { + // Not every plugin in the ordering may be loaded at runtime. + var possiblePlugin = legacyPlugins[i]; + + if (possiblePlugin) { + var extractedEvents = possiblePlugin.extractEvents( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget + ); + + if (extractedEvents) { + events = accumulateInto(events, extractedEvents); + } } - 0 !== lane && markUpdateLaneFromFiberToRoot(fiber, update, lane); } + + return events; } - function enqueueUpdate$1(fiber, queue, update, lane) { - concurrentQueues[concurrentQueuesIndex++] = fiber; - concurrentQueues[concurrentQueuesIndex++] = queue; - concurrentQueues[concurrentQueuesIndex++] = update; - concurrentQueues[concurrentQueuesIndex++] = lane; - concurrentlyUpdatedLanes |= lane; - fiber.lanes |= lane; - fiber = fiber.alternate; - null !== fiber && (fiber.lanes |= lane); - } - function enqueueConcurrentHookUpdate(fiber, queue, update, lane) { - enqueueUpdate$1(fiber, queue, update, lane); - return getRootForUpdatedFiber(fiber); - } - function enqueueConcurrentRenderForLane(fiber, lane) { - enqueueUpdate$1(fiber, null, null, lane); - return getRootForUpdatedFiber(fiber); - } - function markUpdateLaneFromFiberToRoot(sourceFiber, update, lane) { - sourceFiber.lanes |= lane; - var alternate = sourceFiber.alternate; - null !== alternate && (alternate.lanes |= lane); - for (var isHidden = !1, parent = sourceFiber.return; null !== parent; ) - (parent.childLanes |= lane), - (alternate = parent.alternate), - null !== alternate && (alternate.childLanes |= lane), - 22 === parent.tag && - ((sourceFiber = parent.stateNode), - null === sourceFiber || - sourceFiber._visibility & 1 || - (isHidden = !0)), - (sourceFiber = parent), - (parent = parent.return); - isHidden && - null !== update && - 3 === sourceFiber.tag && - ((parent = sourceFiber.stateNode), - (isHidden = 31 - clz32(lane)), - (parent = parent.hiddenUpdates), - (sourceFiber = parent[isHidden]), - null === sourceFiber - ? (parent[isHidden] = [update]) - : sourceFiber.push(update), - (update.lane = lane | OffscreenLane)); - } - function getRootForUpdatedFiber(sourceFiber) { - throwIfInfiniteUpdateLoopDetected(); - null === sourceFiber.alternate && - 0 !== (sourceFiber.flags & 4098) && - warnAboutUpdateOnNotYetMountedFiberInDEV(sourceFiber); - for (var node = sourceFiber, parent = node.return; null !== parent; ) - null === node.alternate && - 0 !== (node.flags & 4098) && - warnAboutUpdateOnNotYetMountedFiberInDEV(sourceFiber), - (node = parent), - (parent = node.return); - return 3 === node.tag ? node.stateNode : null; - } - function ensureRootIsScheduled(root) { - root !== lastScheduledRoot && - null === root.next && - (null === lastScheduledRoot - ? (firstScheduledRoot = lastScheduledRoot = root) - : (lastScheduledRoot = lastScheduledRoot.next = root)); - mightHavePendingSyncWork = !0; - null !== ReactSharedInternals.actQueue - ? didScheduleMicrotask_act || - ((didScheduleMicrotask_act = !0), - scheduleImmediateTask(processRootScheduleInMicrotask)) - : didScheduleMicrotask || - ((didScheduleMicrotask = !0), - scheduleImmediateTask(processRootScheduleInMicrotask)); - ReactSharedInternals.isBatchingLegacy && - 0 === root.tag && - (ReactSharedInternals.didScheduleLegacyUpdate = !0); - } - function flushSyncWorkAcrossRoots_impl(onlyLegacy) { - if (!isFlushingWork && mightHavePendingSyncWork) { - isFlushingWork = !0; - do { - var didPerformSomeWork = !1; - for (var root = firstScheduledRoot; null !== root; ) { - if (!onlyLegacy || 0 === root.tag) { - var workInProgressRootRenderLanes$jscomp$0 = - workInProgressRootRenderLanes; - workInProgressRootRenderLanes$jscomp$0 = getNextLanes( - root, - root === workInProgressRoot - ? workInProgressRootRenderLanes$jscomp$0 - : 0 - ); - 0 !== - (workInProgressRootRenderLanes$jscomp$0 & - (SyncLane | SyncHydrationLane)) && - ((didPerformSomeWork = !0), - performSyncWorkOnRoot( - root, - workInProgressRootRenderLanes$jscomp$0 - )); + + function runExtractedPluginEventsInBatch( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget + ) { + var events = extractPluginEvents( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget + ); + runEventsInBatch(events); + } + /** + * Publicly exposed method on module for native objc to invoke when a top + * level event is extracted. + * @param {rootNodeID} rootNodeID React root node ID that event occurred on. + * @param {TopLevelType} topLevelType Top level type of event. + * @param {object} nativeEventParam Object passed from native. + */ + + function receiveEvent(rootNodeID, topLevelType, nativeEventParam) { + _receiveRootNodeIDEvent(rootNodeID, topLevelType, nativeEventParam); + } + /** + * Simple multi-wrapper around `receiveEvent` that is intended to receive an + * efficient representation of `Touch` objects, and other information that + * can be used to construct W3C compliant `Event` and `Touch` lists. + * + * This may create dispatch behavior that differs than web touch handling. We + * loop through each of the changed touches and receive it as a single event. + * So two `touchStart`/`touchMove`s that occur simultaneously are received as + * two separate touch event dispatches - when they arguably should be one. + * + * This implementation reuses the `Touch` objects themselves as the `Event`s + * since we dispatch an event for each touch (though that might not be spec + * compliant). The main purpose of reusing them is to save allocations. + * + * TODO: Dispatch multiple changed touches in one event. The bubble path + * could be the first common ancestor of all the `changedTouches`. + * + * One difference between this behavior and W3C spec: cancelled touches will + * not appear in `.touches`, or in any future `.touches`, though they may + * still be "actively touching the surface". + * + * Web desktop polyfills only need to construct a fake touch event with + * identifier 0, also abandoning traditional click handlers. + */ + + function receiveTouches(eventTopLevelType, touches, changedIndices) { + var changedTouches = + eventTopLevelType === "topTouchEnd" || + eventTopLevelType === "topTouchCancel" + ? removeTouchesAtIndices(touches, changedIndices) + : touchSubsequence(touches, changedIndices); + + for (var jj = 0; jj < changedTouches.length; jj++) { + var touch = changedTouches[jj]; // Touch objects can fulfill the role of `DOM` `Event` objects if we set + // the `changedTouches`/`touches`. This saves allocations. + + touch.changedTouches = changedTouches; + touch.touches = touches; + var nativeEvent = touch; + var rootNodeID = null; + var target = nativeEvent.target; + + if (target !== null && target !== undefined) { + if (target < 1) { + { + error("A view is reporting that a touch occurred on tag zero."); } - root = root.next; + } else { + rootNodeID = target; } - } while (didPerformSomeWork); - isFlushingWork = !1; + } // $FlowFixMe[incompatible-call] Shouldn't we *not* call it if rootNodeID is null? + + _receiveRootNodeIDEvent(rootNodeID, eventTopLevelType, nativeEvent); } } - function processRootScheduleInMicrotask() { - mightHavePendingSyncWork = - didScheduleMicrotask_act = - didScheduleMicrotask = - !1; - for ( - var currentTime = now$1(), prev = null, root = firstScheduledRoot; - null !== root; - ) { - var next = root.next, - nextLanes = scheduleTaskForRootDuringMicrotask(root, currentTime); - 0 === nextLanes - ? ((root.next = null), - null === prev ? (firstScheduledRoot = next) : (prev.next = next), - null === next && (lastScheduledRoot = prev)) - : ((prev = root), - 0 !== (nextLanes & (SyncLane | SyncHydrationLane)) && - (mightHavePendingSyncWork = !0)); - root = next; + // Module provided by RN: + var ReactNativeGlobalResponderHandler = { + onChange: function (from, to, blockNativeResponder) { + if (to !== null) { + var tag = to.stateNode._nativeTag; + ReactNativePrivateInterface.UIManager.setJSResponder( + tag, + blockNativeResponder + ); + } else { + ReactNativePrivateInterface.UIManager.clearJSResponder(); + } } - currentEventTransitionLane = 0; - flushSyncWorkAcrossRoots_impl(!1); + }; + + /** + * Register the event emitter with the native bridge + */ + + ReactNativePrivateInterface.RCTEventEmitter.register({ + receiveEvent: receiveEvent, + receiveTouches: receiveTouches + }); + setComponentTree( + getFiberCurrentPropsFromNode, + getInstanceFromTag, + getTagFromInstance + ); + ResponderEventPlugin.injection.injectGlobalResponderHandler( + ReactNativeGlobalResponderHandler + ); + + /** + * `ReactInstanceMap` maintains a mapping from a public facing stateful + * instance (key) and the internal representation (value). This allows public + * methods to accept the user facing instance as an argument and map them back + * to internal methods. + * + * Note that this module is currently shared and assumed to be stateless. + * If this becomes an actual Map, that will break. + */ + function get(key) { + return key._reactInternals; + } + function set(key, value) { + key._reactInternals = value; } - function scheduleTaskForRootDuringMicrotask(root, currentTime) { - for ( - var suspendedLanes = root.suspendedLanes, - pingedLanes = root.pingedLanes, - expirationTimes = root.expirationTimes, - lanes = root.pendingLanes & ~RetryLanes; - 0 < lanes; - ) { - var index = 31 - clz32(lanes), - lane = 1 << index, - expirationTime = expirationTimes[index]; - if (-1 === expirationTime) { - if (0 === (lane & suspendedLanes) || 0 !== (lane & pingedLanes)) - expirationTimes[index] = computeExpirationTime(lane, currentTime); - } else expirationTime <= currentTime && (root.expiredLanes |= lane); - lanes &= ~lane; + // ----------------------------------------------------------------------------- + var enableSchedulingProfiler = false; + var enableProfilerTimer = true; + var enableProfilerCommitHooks = true; + var enableProfilerNestedUpdatePhase = true; + var syncLaneExpirationMs = 250; + var transitionLaneExpirationMs = 5000; + var enableLazyContextPropagation = false; + var enableLegacyHidden = false; + var enableAsyncActions = false; + var enableBigIntSupport = false; + + // ATTENTION + // When adding new symbols to this file, + // Please consider also adding to 'react-devtools-shared/src/backend/ReactSymbols' + // The Symbol used to tag the ReactElement-like types. + var REACT_ELEMENT_TYPE = Symbol.for("react.element"); + var REACT_PORTAL_TYPE = Symbol.for("react.portal"); + var REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"); + var REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"); + var REACT_PROFILER_TYPE = Symbol.for("react.profiler"); + var REACT_PROVIDER_TYPE = Symbol.for("react.provider"); // TODO: Delete with enableRenderableContext + + var REACT_CONSUMER_TYPE = Symbol.for("react.consumer"); + var REACT_CONTEXT_TYPE = Symbol.for("react.context"); + var REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"); + var REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"); + var REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"); + var REACT_MEMO_TYPE = Symbol.for("react.memo"); + var REACT_LAZY_TYPE = Symbol.for("react.lazy"); + var REACT_SCOPE_TYPE = Symbol.for("react.scope"); + var REACT_DEBUG_TRACING_MODE_TYPE = Symbol.for("react.debug_trace_mode"); + var REACT_OFFSCREEN_TYPE = Symbol.for("react.offscreen"); + var REACT_LEGACY_HIDDEN_TYPE = Symbol.for("react.legacy_hidden"); + var REACT_CACHE_TYPE = Symbol.for("react.cache"); + var REACT_TRACING_MARKER_TYPE = Symbol.for("react.tracing_marker"); + var MAYBE_ITERATOR_SYMBOL = Symbol.iterator; + var FAUX_ITERATOR_SYMBOL = "@@iterator"; + function getIteratorFn(maybeIterable) { + if (maybeIterable === null || typeof maybeIterable !== "object") { + return null; } - currentTime = workInProgressRoot; - suspendedLanes = workInProgressRootRenderLanes; - suspendedLanes = getNextLanes( - root, - root === currentTime ? suspendedLanes : 0 - ); - pingedLanes = root.callbackNode; - if ( - 0 === suspendedLanes || - (root === currentTime && - workInProgressSuspendedReason === SuspendedOnData) || - null !== root.cancelPendingCommit - ) - return ( - null !== pingedLanes && cancelCallback(pingedLanes), - (root.callbackNode = null), - (root.callbackPriority = 0) - ); - if (0 !== (suspendedLanes & (SyncLane | SyncHydrationLane))) - return ( - null !== pingedLanes && cancelCallback(pingedLanes), - (root.callbackPriority = SyncLane), - (root.callbackNode = null), - SyncLane - ); - currentTime = suspendedLanes & -suspendedLanes; - if ( - currentTime !== root.callbackPriority || - (null !== ReactSharedInternals.actQueue && - pingedLanes !== fakeActCallbackNode$1) - ) - cancelCallback(pingedLanes); - else return currentTime; - switch (lanesToEventPriority(suspendedLanes)) { - case DiscreteEventPriority: - suspendedLanes = ImmediatePriority; - break; - case ContinuousEventPriority: - suspendedLanes = UserBlockingPriority; - break; - case DefaultEventPriority: - suspendedLanes = NormalPriority$1; - break; - case IdleEventPriority: - suspendedLanes = IdlePriority; - break; - default: - suspendedLanes = NormalPriority$1; + + var maybeIterator = + (MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL]) || + maybeIterable[FAUX_ITERATOR_SYMBOL]; + + if (typeof maybeIterator === "function") { + return maybeIterator; } - pingedLanes = performConcurrentWorkOnRoot.bind(null, root); - null !== ReactSharedInternals.actQueue - ? (ReactSharedInternals.actQueue.push(pingedLanes), - (suspendedLanes = fakeActCallbackNode$1)) - : (suspendedLanes = scheduleCallback$3(suspendedLanes, pingedLanes)); - root.callbackPriority = currentTime; - root.callbackNode = suspendedLanes; - return currentTime; - } - function cancelCallback(callbackNode) { - callbackNode !== fakeActCallbackNode$1 && - null !== callbackNode && - cancelCallback$1(callbackNode); - } - function scheduleImmediateTask(cb) { - null !== ReactSharedInternals.actQueue && - ReactSharedInternals.actQueue.push(function () { - cb(); - return null; - }); - scheduleCallback$3(ImmediatePriority, cb); - } - function requestTransitionLane() { - 0 === currentEventTransitionLane && - (currentEventTransitionLane = claimNextTransitionLane()); - return currentEventTransitionLane; + + return null; } - function entangleAsyncAction(transition, thenable) { - if (null === currentEntangledListeners) { - var entangledListeners = (currentEntangledListeners = []); - currentEntangledPendingCount = 0; - currentEntangledLane = requestTransitionLane(); - currentEntangledActionThenable = { - status: "pending", - value: void 0, - then: function (resolve) { - entangledListeners.push(resolve); - } - }; + + function getWrappedName$1(outerType, innerType, wrapperName) { + var displayName = outerType.displayName; + + if (displayName) { + return displayName; } - currentEntangledPendingCount++; - thenable.then(pingEngtangledActionScope, pingEngtangledActionScope); - return thenable; + + var functionName = innerType.displayName || innerType.name || ""; + return functionName !== "" + ? wrapperName + "(" + functionName + ")" + : wrapperName; + } // Keep in sync with react-reconciler/getComponentNameFromFiber + + function getContextName$1(type) { + return type.displayName || "Context"; } - function pingEngtangledActionScope() { - if ( - null !== currentEntangledListeners && - 0 === --currentEntangledPendingCount - ) { - null !== currentEntangledActionThenable && - (currentEntangledActionThenable.status = "fulfilled"); - var listeners = currentEntangledListeners; - currentEntangledListeners = null; - currentEntangledLane = 0; - currentEntangledActionThenable = null; - for (var i = 0; i < listeners.length; i++) (0, listeners[i])(); + + var REACT_CLIENT_REFERENCE = Symbol.for("react.client.reference"); // Note that the reconciler package should generally prefer to use getComponentNameFromFiber() instead. + + function getComponentNameFromType(type) { + if (type == null) { + // Host root, text node or just invalid type. + return null; } - } - function chainThenableValue(thenable, result) { - var listeners = [], - thenableWithOverride = { - status: "pending", - value: null, - reason: null, - then: function (resolve) { - listeners.push(resolve); - } - }; - thenable.then( - function () { - thenableWithOverride.status = "fulfilled"; - thenableWithOverride.value = result; - for (var i = 0; i < listeners.length; i++) (0, listeners[i])(result); - }, - function (error) { - thenableWithOverride.status = "rejected"; - thenableWithOverride.reason = error; - for (error = 0; error < listeners.length; error++) - (0, listeners[error])(void 0); + + if (typeof type === "function") { + if (type.$$typeof === REACT_CLIENT_REFERENCE) { + // TODO: Create a convention for naming client references with debug info. + return null; } - ); - return thenableWithOverride; - } - function initializeUpdateQueue(fiber) { - fiber.updateQueue = { - baseState: fiber.memoizedState, - firstBaseUpdate: null, - lastBaseUpdate: null, - shared: { pending: null, lanes: 0, hiddenCallbacks: null }, - callbacks: null - }; - } - function cloneUpdateQueue(current, workInProgress) { - current = current.updateQueue; - workInProgress.updateQueue === current && - (workInProgress.updateQueue = { - baseState: current.baseState, - firstBaseUpdate: current.firstBaseUpdate, - lastBaseUpdate: current.lastBaseUpdate, - shared: current.shared, - callbacks: null - }); - } - function createUpdate(lane) { - return { - lane: lane, - tag: UpdateState, - payload: null, - callback: null, - next: null - }; - } - function enqueueUpdate(fiber, update, lane) { - var updateQueue = fiber.updateQueue; - if (null === updateQueue) return null; - updateQueue = updateQueue.shared; - if ( - currentlyProcessingQueue === updateQueue && - !didWarnUpdateInsideUpdate - ) { - var componentName = getComponentNameFromFiber(fiber); - error$jscomp$0( - "An update (setState, replaceState, or forceUpdate) was scheduled from inside an update function. Update functions should be pure, with zero side-effects. Consider using componentDidUpdate or a callback.\n\nPlease update the following component: %s", - componentName - ); - didWarnUpdateInsideUpdate = !0; - } - if ((executionContext & RenderContext) !== NoContext) - return ( - (componentName = updateQueue.pending), - null === componentName - ? (update.next = update) - : ((update.next = componentName.next), - (componentName.next = update)), - (updateQueue.pending = update), - (update = getRootForUpdatedFiber(fiber)), - markUpdateLaneFromFiberToRoot(fiber, null, lane), - update - ); - enqueueUpdate$1(fiber, updateQueue, update, lane); - return getRootForUpdatedFiber(fiber); - } - function entangleTransitions(root, fiber, lane) { - fiber = fiber.updateQueue; - if ( - null !== fiber && - ((fiber = fiber.shared), 0 !== (lane & TransitionLanes)) - ) { - var queueLanes = fiber.lanes; - queueLanes &= root.pendingLanes; - lane |= queueLanes; - fiber.lanes = lane; - markRootEntangled(root, lane); + + return type.displayName || type.name || null; } - } - function enqueueCapturedUpdate(workInProgress, capturedUpdate) { - var queue = workInProgress.updateQueue, - current = workInProgress.alternate; - if ( - null !== current && - ((current = current.updateQueue), queue === current) - ) { - var newFirst = null, - newLast = null; - queue = queue.firstBaseUpdate; - if (null !== queue) { - do { - var clone = { - lane: queue.lane, - tag: queue.tag, - payload: queue.payload, - callback: null, - next: null - }; - null === newLast - ? (newFirst = newLast = clone) - : (newLast = newLast.next = clone); - queue = queue.next; - } while (null !== queue); - null === newLast - ? (newFirst = newLast = capturedUpdate) - : (newLast = newLast.next = capturedUpdate); - } else newFirst = newLast = capturedUpdate; - queue = { - baseState: current.baseState, - firstBaseUpdate: newFirst, - lastBaseUpdate: newLast, - shared: current.shared, - callbacks: current.callbacks - }; - workInProgress.updateQueue = queue; - return; + + if (typeof type === "string") { + return type; } - workInProgress = queue.lastBaseUpdate; - null === workInProgress - ? (queue.firstBaseUpdate = capturedUpdate) - : (workInProgress.next = capturedUpdate); - queue.lastBaseUpdate = capturedUpdate; - } - function suspendIfUpdateReadFromEntangledAsyncAction() { - if (didReadFromEntangledAsyncAction) { - var entangledActionThenable = currentEntangledActionThenable; - if (null !== entangledActionThenable) throw entangledActionThenable; + + switch (type) { + case REACT_FRAGMENT_TYPE: + return "Fragment"; + + case REACT_PORTAL_TYPE: + return "Portal"; + + case REACT_PROFILER_TYPE: + return "Profiler"; + + case REACT_STRICT_MODE_TYPE: + return "StrictMode"; + + case REACT_SUSPENSE_TYPE: + return "Suspense"; + + case REACT_SUSPENSE_LIST_TYPE: + return "SuspenseList"; } - } - function processUpdateQueue( - workInProgress, - props, - instance$jscomp$0, - renderLanes - ) { - didReadFromEntangledAsyncAction = !1; - var queue = workInProgress.updateQueue; - hasForceUpdate = !1; - currentlyProcessingQueue = queue.shared; - var firstBaseUpdate = queue.firstBaseUpdate, - lastBaseUpdate = queue.lastBaseUpdate, - pendingQueue = queue.shared.pending; - if (null !== pendingQueue) { - queue.shared.pending = null; - var lastPendingUpdate = pendingQueue, - firstPendingUpdate = lastPendingUpdate.next; - lastPendingUpdate.next = null; - null === lastBaseUpdate - ? (firstBaseUpdate = firstPendingUpdate) - : (lastBaseUpdate.next = firstPendingUpdate); - lastBaseUpdate = lastPendingUpdate; - var current = workInProgress.alternate; - null !== current && - ((current = current.updateQueue), - (pendingQueue = current.lastBaseUpdate), - pendingQueue !== lastBaseUpdate && - (null === pendingQueue - ? (current.firstBaseUpdate = firstPendingUpdate) - : (pendingQueue.next = firstPendingUpdate), - (current.lastBaseUpdate = lastPendingUpdate))); - } - if (null !== firstBaseUpdate) { - var newState = queue.baseState; - lastBaseUpdate = 0; - current = firstPendingUpdate = lastPendingUpdate = null; - pendingQueue = firstBaseUpdate; - do { - var updateLane = pendingQueue.lane & ~OffscreenLane, - isHiddenUpdate = updateLane !== pendingQueue.lane; - if ( - isHiddenUpdate - ? (workInProgressRootRenderLanes & updateLane) === updateLane - : (renderLanes & updateLane) === updateLane - ) { - 0 !== updateLane && - updateLane === currentEntangledLane && - (didReadFromEntangledAsyncAction = !0); - null !== current && - (current = current.next = - { - lane: 0, - tag: pendingQueue.tag, - payload: pendingQueue.payload, - callback: null, - next: null - }); - a: { - updateLane = workInProgress; - var partialState = pendingQueue; - var nextProps = props, - instance = instance$jscomp$0; - switch (partialState.tag) { - case ReplaceState: - partialState = partialState.payload; - if ("function" === typeof partialState) { - isDisallowedContextReadInDEV = !0; - var nextState = partialState.call( - instance, - newState, - nextProps - ); - if (updateLane.mode & 8) { - setIsStrictModeForDevtools(!0); - try { - partialState.call(instance, newState, nextProps); - } finally { - setIsStrictModeForDevtools(!1); - } - } - isDisallowedContextReadInDEV = !1; - newState = nextState; - break a; - } - newState = partialState; - break a; - case CaptureUpdate: - updateLane.flags = (updateLane.flags & -65537) | 128; - case UpdateState: - nextState = partialState.payload; - if ("function" === typeof nextState) { - isDisallowedContextReadInDEV = !0; - partialState = nextState.call( - instance, - newState, - nextProps - ); - if (updateLane.mode & 8) { - setIsStrictModeForDevtools(!0); - try { - nextState.call(instance, newState, nextProps); - } finally { - setIsStrictModeForDevtools(!1); - } - } - isDisallowedContextReadInDEV = !1; - } else partialState = nextState; - if (null === partialState || void 0 === partialState) break a; - newState = assign({}, newState, partialState); - break a; - case ForceUpdate: - hasForceUpdate = !0; - } + + if (typeof type === "object") { + { + if (typeof type.tag === "number") { + error( + "Received an unexpected object in getComponentNameFromType(). " + + "This is likely a bug in React. Please file an issue." + ); + } + } + + switch (type.$$typeof) { + case REACT_PROVIDER_TYPE: { + var provider = type; + return getContextName$1(provider._context) + ".Provider"; + } + + case REACT_CONTEXT_TYPE: + var context = type; + + { + return getContextName$1(context) + ".Consumer"; } - updateLane = pendingQueue.callback; - null !== updateLane && - ((workInProgress.flags |= 64), - isHiddenUpdate && (workInProgress.flags |= 8192), - (isHiddenUpdate = queue.callbacks), - null === isHiddenUpdate - ? (queue.callbacks = [updateLane]) - : isHiddenUpdate.push(updateLane)); - } else - (isHiddenUpdate = { - lane: updateLane, - tag: pendingQueue.tag, - payload: pendingQueue.payload, - callback: pendingQueue.callback, - next: null - }), - null === current - ? ((firstPendingUpdate = current = isHiddenUpdate), - (lastPendingUpdate = newState)) - : (current = current.next = isHiddenUpdate), - (lastBaseUpdate |= updateLane); - pendingQueue = pendingQueue.next; - if (null === pendingQueue) - if (((pendingQueue = queue.shared.pending), null === pendingQueue)) - break; - else - (isHiddenUpdate = pendingQueue), - (pendingQueue = isHiddenUpdate.next), - (isHiddenUpdate.next = null), - (queue.lastBaseUpdate = isHiddenUpdate), - (queue.shared.pending = null); - } while (1); - null === current && (lastPendingUpdate = newState); - queue.baseState = lastPendingUpdate; - queue.firstBaseUpdate = firstPendingUpdate; - queue.lastBaseUpdate = current; - null === firstBaseUpdate && (queue.shared.lanes = 0); - workInProgressRootSkippedLanes |= lastBaseUpdate; - workInProgress.lanes = lastBaseUpdate; - workInProgress.memoizedState = newState; - } - currentlyProcessingQueue = null; - } - function callCallback(callback, context) { - if ("function" !== typeof callback) - throw Error( - "Invalid argument passed as callback. Expected a function. Instead received: " + - callback - ); - callback.call(context); - } - function commitCallbacks(updateQueue, context) { - var callbacks = updateQueue.callbacks; - if (null !== callbacks) - for ( - updateQueue.callbacks = null, updateQueue = 0; - updateQueue < callbacks.length; - updateQueue++ - ) - callCallback(callbacks[updateQueue], context); - } - 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++) { - var currentKey = keysA[keysB]; - if ( - !hasOwnProperty.call(objB, currentKey) || - !objectIs(objA[currentKey], objB[currentKey]) - ) - return !1; + + case REACT_CONSUMER_TYPE: { + return null; + } + + case REACT_FORWARD_REF_TYPE: + return getWrappedName$1(type, type.render, "ForwardRef"); + + case REACT_MEMO_TYPE: + var outerName = type.displayName || null; + + if (outerName !== null) { + return outerName; + } + + return getComponentNameFromType(type.type) || "Memo"; + + case REACT_LAZY_TYPE: { + var lazyComponent = type; + var payload = lazyComponent._payload; + var init = lazyComponent._init; + + try { + return getComponentNameFromType(init(payload)); + } catch (x) { + return null; + } + } + } } - return !0; - } - function createThenableState() { - return { didWarnAboutUncachedPromise: !1, thenables: [] }; + + return null; } - function isThenableResolved(thenable) { - thenable = thenable.status; - return "fulfilled" === thenable || "rejected" === thenable; + + function getWrappedName(outerType, innerType, wrapperName) { + var functionName = innerType.displayName || innerType.name || ""; + return ( + outerType.displayName || + (functionName !== "" + ? wrapperName + "(" + functionName + ")" + : wrapperName) + ); + } // Keep in sync with shared/getComponentNameFromType + + function getContextName(type) { + return type.displayName || "Context"; } - function noop() {} - function trackUsedThenable(thenableState, thenable, index) { - null !== ReactSharedInternals.actQueue && - (ReactSharedInternals.didUsePromise = !0); - var trackedThenables = thenableState.thenables; - index = trackedThenables[index]; - void 0 === index - ? trackedThenables.push(thenable) - : index !== thenable && - (thenableState.didWarnAboutUncachedPromise || - ((thenableState.didWarnAboutUncachedPromise = !0), - error$jscomp$0( - "A component was suspended by an uncached promise. Creating promises inside a Client Component or hook is not yet supported, except via a Suspense-compatible library or framework." - )), - thenable.then(noop, noop), - (thenable = index)); - switch (thenable.status) { - case "fulfilled": - return thenable.value; - case "rejected": - throw ( - ((thenableState = thenable.reason), - checkIfUseWrappedInAsyncCatch(thenableState), - thenableState) - ); - default: - if ("string" === typeof thenable.status) thenable.then(noop, noop); - else { - thenableState = workInProgressRoot; - if ( - null !== thenableState && - 100 < thenableState.shellSuspendCounter - ) - throw Error( - "async/await is not yet supported in Client Components, only Server Components. This error is often caused by accidentally adding `'use client'` to a module that was originally written for the server." - ); - thenableState = thenable; - thenableState.status = "pending"; - thenableState.then( - function (fulfilledValue) { - if ("pending" === thenable.status) { - var fulfilledThenable = thenable; - fulfilledThenable.status = "fulfilled"; - fulfilledThenable.value = fulfilledValue; - } - }, - function (error) { - if ("pending" === thenable.status) { - var rejectedThenable = thenable; - rejectedThenable.status = "rejected"; - rejectedThenable.reason = error; - } - } - ); + + function getComponentNameFromFiber(fiber) { + var tag = fiber.tag, + type = fiber.type; + + switch (tag) { + case CacheComponent: + return "Cache"; + + case ContextConsumer: { + var context = type; + return getContextName(context) + ".Consumer"; + } + + case ContextProvider: { + var provider = type; + return getContextName(provider._context) + ".Provider"; + } + + case DehydratedFragment: + return "DehydratedFragment"; + + case ForwardRef: + return getWrappedName(type, type.render, "ForwardRef"); + + case Fragment: + return "Fragment"; + + case HostHoistable: + case HostSingleton: + 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 Mode: + if (type === REACT_STRICT_MODE_TYPE) { + // Don't be less specific than shared/getComponentNameFromType + return "StrictMode"; } - switch (thenable.status) { - case "fulfilled": - return thenable.value; - case "rejected": - throw ( - ((thenableState = thenable.reason), - checkIfUseWrappedInAsyncCatch(thenableState), - thenableState) - ); + + return "Mode"; + + case OffscreenComponent: + return "Offscreen"; + + case Profiler: + return "Profiler"; + + case ScopeComponent: + return "Scope"; + + case SuspenseComponent: + return "Suspense"; + + case SuspenseListComponent: + return "SuspenseList"; + + case TracingMarkerComponent: + return "TracingMarker"; + // 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; } - suspendedThenable = thenable; - needsToResetSuspendedThenableDEV = !0; - throw SuspenseException; + + if (typeof type === "string") { + return type; + } + + break; } + + return null; } - function getSuspendedThenable() { - if (null === suspendedThenable) - throw Error( - "Expected a suspended thenable. This is a bug in React. Please file an issue." - ); - var thenable = suspendedThenable; - suspendedThenable = null; - needsToResetSuspendedThenableDEV = !1; - return thenable; - } - function checkIfUseWrappedInAsyncCatch(rejectedReason) { - if (rejectedReason === SuspenseException) - throw Error( - "Hooks are not supported inside an async component. This error is often caused by accidentally adding `'use client'` to a module that was originally written for the server." - ); - } - function pushDebugInfo(debugInfo) { - var previousDebugInfo = currentDebugInfo; - null != debugInfo && - (currentDebugInfo = - null === previousDebugInfo - ? debugInfo - : previousDebugInfo.concat(debugInfo)); - return previousDebugInfo; - } - function validateFragmentProps(element, fiber, returnFiber) { - for (var keys = Object.keys(element.props), i = 0; i < keys.length; i++) { - var key = keys[i]; - if ("children" !== key && "key" !== key) { - null === fiber && - ((fiber = createFiberFromElement(element, returnFiber.mode, 0)), - (fiber.return = returnFiber)); - runWithFiberInDEV( - fiber, - function (erroredKey) { - error$jscomp$0( - "Invalid prop `%s` supplied to `React.Fragment`. React.Fragment can only have `key` and `children` props.", - erroredKey - ); - }, - key - ); - break; + + var NoFlags$1 = + /* */ + 0; + var PerformedWork = + /* */ + 1; + var Placement = + /* */ + 2; + var DidCapture = + /* */ + 128; + var Hydrating = + /* */ + 4096; // You can change the rest (and add more). + + var Update = + /* */ + 4; + /* Skipped value: 0b0000000000000000000000001000; */ + + var ChildDeletion = + /* */ + 16; + var ContentReset = + /* */ + 32; + var Callback = + /* */ + 64; + /* Used by DidCapture: 0b0000000000000000000010000000; */ + + var ForceClientRender = + /* */ + 256; + var Ref = + /* */ + 512; + var Snapshot = + /* */ + 1024; + var Passive$1 = + /* */ + 2048; + /* Used by Hydrating: 0b0000000000000001000000000000; */ + + var Visibility = + /* */ + 8192; + var StoreConsistency = + /* */ + 16384; // It's OK to reuse these bits because these flags are mutually exclusive for + // different fiber types. We should really be doing this for as many flags as + // possible, because we're about to run out of bits. + + var ScheduleRetry = StoreConsistency; + var ShouldSuspendCommit = Visibility; + var DidDefer = ContentReset; + var LifecycleEffectMask = + Passive$1 | Update | Callback | Ref | Snapshot | StoreConsistency; // Union of all commit flags (flags with the lifetime of a particular commit) + + var HostEffectMask = + /* */ + 32767; // These are not really side effects, but we still reuse this field. + + var Incomplete = + /* */ + 32768; + var ShouldCapture = + /* */ + 65536; + var ForceUpdateForLegacySuspense = + /* */ + 131072; + var Forked = + /* */ + 1048576; // Static tags describe aspects of a fiber that are not specific to a render, + // e.g. a fiber uses a passive effect (even if there are no updates on this particular render). + // This enables us to defer more work in the unmount case, + // since we can defer traversing the tree during layout to look for Passive effects, + // and instead rely on the static flag as a signal that there may be cleanup work. + + var RefStatic = + /* */ + 2097152; + var LayoutStatic = + /* */ + 4194304; + var PassiveStatic = + /* */ + 8388608; + var MaySuspendCommit = + /* */ + 16777216; // Flag used to identify newly inserted fibers. It isn't reset after commit unlike `Placement`. + + var PlacementDEV = + /* */ + 33554432; + var MountLayoutDev = + /* */ + 67108864; + var MountPassiveDev = + /* */ + 134217728; // 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 Visibility + // flag logic (see #20043) + Update | Snapshot | 0; + var MutationMask = + Placement | + Update | + ChildDeletion | + ContentReset | + Ref | + Hydrating | + Visibility; + var LayoutMask = Update | Callback | Ref | Visibility; // TODO: Split into PassiveMountMask and PassiveUnmountMask + + var PassiveMask = Passive$1 | Visibility | ChildDeletion; // Union of tags that don't get reset on clones. + // This allows certain concepts to persist without recalculating them, + // e.g. whether a subtree contains passive effects or portals. + + var StaticMask = + LayoutStatic | PassiveStatic | RefStatic | MaySuspendCommit; + + var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner; + function getNearestMountedFiber(fiber) { + var node = fiber; + var nearestMounted = fiber; + + if (!fiber.alternate) { + // If there is no alternate, this might be a new tree that isn't inserted + // yet. If it is, then it will have a pending insertion effect on it. + var nextNode = node; + + do { + node = nextNode; + + if ((node.flags & (Placement | Hydrating)) !== NoFlags$1) { + // This is an insertion or in-progress hydration. The nearest possible + // mounted fiber is the parent but we need to continue to figure out + // if that one is still mounted. + nearestMounted = node.return; + } // $FlowFixMe[incompatible-type] we bail out when we get a null + + nextNode = node.return; + } while (nextNode); + } else { + while (node.return) { + node = node.return; } } + + if (node.tag === HostRoot) { + // TODO: Check if this was a nested HostRoot when used with + // renderContainerIntoSubtree. + return nearestMounted; + } // If we didn't hit the root, that means that we're in an disconnected tree + // that has been unmounted. + + return null; } - function unwrapThenable(thenable) { - var index = thenableIndexCounter$1; - thenableIndexCounter$1 += 1; - null === thenableState$1 && (thenableState$1 = createThenableState()); - return trackUsedThenable(thenableState$1, thenable, index); - } - function coerceRef(returnFiber, current, workInProgress, element) { - returnFiber = element.props.ref; - workInProgress.ref = void 0 !== returnFiber ? returnFiber : null; - } - function throwOnInvalidObjectType(returnFiber, newChild) { - if (newChild.$$typeof === REACT_LEGACY_ELEMENT_TYPE) - throw Error( - 'A React Element from an older version of React was rendered. This is not supported. It can happen if:\n- Multiple copies of the "react" package is used.\n- A library pre-bundled an old copy of "react" or "react/jsx-runtime".\n- A compiler tries to "inline" JSX instead of using the runtime.' - ); - 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 warnOnFunctionType(returnFiber, invalidChild) { - var parentName = getComponentNameFromFiber(returnFiber) || "Component"; - ownerHasFunctionTypeWarning[parentName] || - ((ownerHasFunctionTypeWarning[parentName] = !0), - (invalidChild = - invalidChild.displayName || invalidChild.name || "Component"), - 3 === returnFiber.tag - ? error$jscomp$0( - "Functions are not valid as a React child. This may happen if you return %s instead of <%s /> from render. Or maybe you meant to call this function rather than return it.\n root.render(%s)", - invalidChild, - invalidChild, - invalidChild - ) - : error$jscomp$0( - "Functions are not valid as a React child. This may happen if you return %s instead of <%s /> from render. Or maybe you meant to call this function rather than return it.\n <%s>{%s}", - invalidChild, - invalidChild, - parentName, - invalidChild, - parentName - )); - } - function warnOnSymbolType(returnFiber, invalidChild) { - var parentName = getComponentNameFromFiber(returnFiber) || "Component"; - ownerHasSymbolTypeWarning[parentName] || - ((ownerHasSymbolTypeWarning[parentName] = !0), - (invalidChild = String(invalidChild)), - 3 === returnFiber.tag - ? error$jscomp$0( - "Symbols are not valid as a React child.\n root.render(%s)", - invalidChild - ) - : error$jscomp$0( - "Symbols are not valid as a React child.\n <%s>%s", - parentName, - invalidChild, - parentName - )); - } - function createChildReconciler(shouldTrackSideEffects) { - function deleteChild(returnFiber, childToDelete) { - if (shouldTrackSideEffects) { - var deletions = returnFiber.deletions; - null === deletions - ? ((returnFiber.deletions = [childToDelete]), - (returnFiber.flags |= 16)) - : deletions.push(childToDelete); + function isMounted(component) { + { + var owner = ReactCurrentOwner$3.current; + + if (owner !== null && owner.tag === ClassComponent) { + var ownerFiber = owner; + var instance = ownerFiber.stateNode; + + if (!instance._warnedAboutRefsInRender) { + error( + "%s is accessing isMounted inside its render() function. " + + "render() should be a pure function of props and state. It should " + + "never access something that requires stale data from the previous " + + "render, such as refs. Move this logic to componentDidMount and " + + "componentDidUpdate instead.", + getComponentNameFromFiber(ownerFiber) || "A component" + ); + } + + instance._warnedAboutRefsInRender = true; } } - function deleteRemainingChildren(returnFiber, currentFirstChild) { - if (!shouldTrackSideEffects) return null; - for (; null !== currentFirstChild; ) - deleteChild(returnFiber, currentFirstChild), - (currentFirstChild = currentFirstChild.sibling); - return null; - } - function mapRemainingChildren(currentFirstChild) { - for (var existingChildren = new Map(); null !== currentFirstChild; ) - null !== currentFirstChild.key - ? existingChildren.set(currentFirstChild.key, currentFirstChild) - : existingChildren.set(currentFirstChild.index, currentFirstChild), - (currentFirstChild = currentFirstChild.sibling); - return existingChildren; - } - function useFiber(fiber, pendingProps) { - fiber = createWorkInProgress(fiber, pendingProps); - fiber.index = 0; - fiber.sibling = null; - return fiber; + + var fiber = get(component); + + if (!fiber) { + return false; } - function placeChild(newFiber, lastPlacedIndex, newIndex) { - newFiber.index = newIndex; - if (!shouldTrackSideEffects) - return (newFiber.flags |= 1048576), lastPlacedIndex; - newIndex = newFiber.alternate; - if (null !== newIndex) - return ( - (newIndex = newIndex.index), - newIndex < lastPlacedIndex - ? ((newFiber.flags |= 33554434), lastPlacedIndex) - : newIndex - ); - newFiber.flags |= 33554434; - return lastPlacedIndex; + + return getNearestMountedFiber(fiber) === fiber; + } + + function assertIsMounted(fiber) { + if (getNearestMountedFiber(fiber) !== fiber) { + throw new Error("Unable to find node on an unmounted component."); } - function placeSingleChild(newFiber) { - shouldTrackSideEffects && - null === newFiber.alternate && - (newFiber.flags |= 33554434); - return newFiber; - } - function updateTextNode(returnFiber, current, textContent, lanes) { - if (null === current || 6 !== current.tag) - return ( - (current = createFiberFromText( - textContent, - returnFiber.mode, - lanes - )), - (current.return = returnFiber), - (current._debugInfo = currentDebugInfo), - current - ); - current = useFiber(current, textContent); - current.return = returnFiber; - current._debugInfo = currentDebugInfo; - return current; - } - function updateElement(returnFiber, current, element, lanes) { - var elementType = element.type; - if (elementType === REACT_FRAGMENT_TYPE) - return ( - (current = updateFragment( - returnFiber, - current, - element.props.children, - lanes, - element.key - )), - validateFragmentProps(element, current, returnFiber), - current - ); - if ( - null !== current && - (current.elementType === elementType || - isCompatibleFamilyForHotReloading(current, element) || - ("object" === typeof elementType && - null !== elementType && - elementType.$$typeof === REACT_LAZY_TYPE && - callLazyInitInDEV(elementType) === current.type)) - ) - return ( - (lanes = useFiber(current, element.props)), - coerceRef(returnFiber, current, lanes, element), - (lanes.return = returnFiber), - (lanes._debugOwner = element._owner), - (lanes._debugInfo = currentDebugInfo), - lanes - ); - lanes = createFiberFromElement(element, returnFiber.mode, lanes); - coerceRef(returnFiber, current, lanes, element); - lanes.return = returnFiber; - lanes._debugInfo = currentDebugInfo; - return lanes; - } - function updatePortal(returnFiber, current, portal, lanes) { - if ( - null === current || - 4 !== current.tag || - current.stateNode.containerInfo !== portal.containerInfo || - current.stateNode.implementation !== portal.implementation - ) - return ( - (current = createFiberFromPortal(portal, returnFiber.mode, lanes)), - (current.return = returnFiber), - (current._debugInfo = currentDebugInfo), - current - ); - current = useFiber(current, portal.children || []); - current.return = returnFiber; - current._debugInfo = currentDebugInfo; - return current; - } - function updateFragment(returnFiber, current, fragment, lanes, key) { - if (null === current || 7 !== current.tag) - return ( - (current = createFiberFromFragment( - fragment, - returnFiber.mode, - lanes, - key - )), - (current.return = returnFiber), - (current._debugInfo = currentDebugInfo), - current - ); - current = useFiber(current, fragment); - current.return = returnFiber; - current._debugInfo = currentDebugInfo; - return current; - } - function createChild(returnFiber, newChild, lanes) { - if ( - ("string" === typeof newChild && "" !== newChild) || - "number" === typeof newChild || - "bigint" === typeof newChild - ) - return ( - (newChild = createFiberFromText( - "" + newChild, - returnFiber.mode, - lanes - )), - (newChild.return = returnFiber), - (newChild._debugInfo = currentDebugInfo), - newChild - ); - if ("object" === typeof newChild && null !== newChild) { - switch (newChild.$$typeof) { - case REACT_ELEMENT_TYPE: - return ( - (lanes = createFiberFromElement( - newChild, - returnFiber.mode, - lanes - )), - coerceRef(returnFiber, null, lanes, newChild), - (lanes.return = returnFiber), - (returnFiber = pushDebugInfo(newChild._debugInfo)), - (lanes._debugInfo = currentDebugInfo), - (currentDebugInfo = returnFiber), - lanes - ); - case REACT_PORTAL_TYPE: - return ( - (newChild = createFiberFromPortal( - newChild, - returnFiber.mode, - lanes - )), - (newChild.return = returnFiber), - (newChild._debugInfo = currentDebugInfo), - newChild - ); - case REACT_LAZY_TYPE: - var _prevDebugInfo = pushDebugInfo(newChild._debugInfo); - newChild = callLazyInitInDEV(newChild); - returnFiber = createChild(returnFiber, newChild, lanes); - currentDebugInfo = _prevDebugInfo; - return returnFiber; - } - if (isArrayImpl(newChild) || getIteratorFn(newChild)) - return ( - (lanes = createFiberFromFragment( - newChild, - returnFiber.mode, - lanes, - null - )), - (lanes.return = returnFiber), - (returnFiber = pushDebugInfo(newChild._debugInfo)), - (lanes._debugInfo = currentDebugInfo), - (currentDebugInfo = returnFiber), - lanes - ); - if ("function" === typeof newChild.then) - return ( - (_prevDebugInfo = pushDebugInfo(newChild._debugInfo)), - (returnFiber = createChild( - returnFiber, - unwrapThenable(newChild), - lanes - )), - (currentDebugInfo = _prevDebugInfo), - returnFiber - ); - if (newChild.$$typeof === REACT_CONTEXT_TYPE) - return createChild( - returnFiber, - readContextDuringReconciliation(returnFiber, newChild, lanes), - lanes - ); - throwOnInvalidObjectType(returnFiber, newChild); + } + + function findCurrentFiberUsingSlowPath(fiber) { + var alternate = fiber.alternate; + + if (!alternate) { + // If there is no alternate, then we only need to check if it is mounted. + var nearestMounted = getNearestMountedFiber(fiber); + + if (nearestMounted === null) { + throw new Error("Unable to find node on an unmounted component."); } - "function" === typeof newChild && - warnOnFunctionType(returnFiber, newChild); - "symbol" === typeof newChild && warnOnSymbolType(returnFiber, newChild); - return null; - } - function updateSlot(returnFiber, oldFiber, newChild, lanes) { - var key = null !== oldFiber ? oldFiber.key : null; - if ( - ("string" === typeof newChild && "" !== newChild) || - "number" === typeof newChild || - "bigint" === typeof newChild - ) - return null !== key - ? null - : updateTextNode(returnFiber, oldFiber, "" + newChild, lanes); - if ("object" === typeof newChild && null !== newChild) { - switch (newChild.$$typeof) { - case REACT_ELEMENT_TYPE: - return newChild.key === key - ? ((key = pushDebugInfo(newChild._debugInfo)), - (returnFiber = updateElement( - returnFiber, - oldFiber, - newChild, - lanes - )), - (currentDebugInfo = key), - returnFiber) - : null; - case REACT_PORTAL_TYPE: - return newChild.key === key - ? updatePortal(returnFiber, oldFiber, newChild, lanes) - : null; - case REACT_LAZY_TYPE: - return ( - (key = pushDebugInfo(newChild._debugInfo)), - (newChild = callLazyInitInDEV(newChild)), - (returnFiber = updateSlot( - returnFiber, - oldFiber, - newChild, - lanes - )), - (currentDebugInfo = key), - returnFiber - ); - } - if (isArrayImpl(newChild) || getIteratorFn(newChild)) { - if (null !== key) return null; - key = pushDebugInfo(newChild._debugInfo); - returnFiber = updateFragment( - returnFiber, - oldFiber, - newChild, - lanes, - null - ); - currentDebugInfo = key; - return returnFiber; - } - if ("function" === typeof newChild.then) - return ( - (key = pushDebugInfo(newChild._debugInfo)), - (returnFiber = updateSlot( - returnFiber, - oldFiber, - unwrapThenable(newChild), - lanes - )), - (currentDebugInfo = key), - returnFiber - ); - if (newChild.$$typeof === REACT_CONTEXT_TYPE) - return updateSlot( - returnFiber, - oldFiber, - readContextDuringReconciliation(returnFiber, newChild, lanes), - lanes - ); - throwOnInvalidObjectType(returnFiber, newChild); + + if (nearestMounted !== fiber) { + return null; } - "function" === typeof newChild && - warnOnFunctionType(returnFiber, newChild); - "symbol" === typeof newChild && warnOnSymbolType(returnFiber, newChild); - return null; - } - function updateFromMap( - existingChildren, - returnFiber, - newIdx, - newChild, - lanes - ) { - if ( - ("string" === typeof newChild && "" !== newChild) || - "number" === typeof newChild || - "bigint" === typeof newChild - ) - return ( - (existingChildren = existingChildren.get(newIdx) || null), - updateTextNode(returnFiber, existingChildren, "" + newChild, lanes) - ); - if ("object" === typeof newChild && null !== newChild) { - switch (newChild.$$typeof) { - case REACT_ELEMENT_TYPE: - return ( - (newIdx = - existingChildren.get( - null === newChild.key ? newIdx : newChild.key - ) || null), - (existingChildren = pushDebugInfo(newChild._debugInfo)), - (returnFiber = updateElement( - returnFiber, - newIdx, - newChild, - lanes - )), - (currentDebugInfo = existingChildren), - returnFiber - ); - case REACT_PORTAL_TYPE: - return ( - (existingChildren = - existingChildren.get( - null === newChild.key ? newIdx : newChild.key - ) || null), - updatePortal(returnFiber, existingChildren, newChild, lanes) - ); - case REACT_LAZY_TYPE: - var _prevDebugInfo7 = pushDebugInfo(newChild._debugInfo); - newChild = callLazyInitInDEV(newChild); - returnFiber = updateFromMap( - existingChildren, - returnFiber, - newIdx, - newChild, - lanes - ); - currentDebugInfo = _prevDebugInfo7; - return returnFiber; - } - if (isArrayImpl(newChild) || getIteratorFn(newChild)) - return ( - (newIdx = existingChildren.get(newIdx) || null), - (existingChildren = pushDebugInfo(newChild._debugInfo)), - (returnFiber = updateFragment( - returnFiber, - newIdx, - newChild, - lanes, - null - )), - (currentDebugInfo = existingChildren), - returnFiber - ); - if ("function" === typeof newChild.then) - return ( - (_prevDebugInfo7 = pushDebugInfo(newChild._debugInfo)), - (returnFiber = updateFromMap( - existingChildren, - returnFiber, - newIdx, - unwrapThenable(newChild), - lanes - )), - (currentDebugInfo = _prevDebugInfo7), - returnFiber - ); - if (newChild.$$typeof === REACT_CONTEXT_TYPE) - return updateFromMap( - existingChildren, - returnFiber, - newIdx, - readContextDuringReconciliation(returnFiber, newChild, lanes), - lanes - ); - throwOnInvalidObjectType(returnFiber, newChild); + + return fiber; + } // If we have two possible branches, we'll walk backwards up to the root + // to see what path the root points to. On the way we may hit one of the + // special cases and we'll deal with them. + + var a = fiber; + var b = alternate; + + while (true) { + var parentA = a.return; + + if (parentA === null) { + // We're at the root. + break; } - "function" === typeof newChild && - warnOnFunctionType(returnFiber, newChild); - "symbol" === typeof newChild && warnOnSymbolType(returnFiber, newChild); - return null; - } - function warnOnInvalidKey(returnFiber, workInProgress, child, knownKeys) { - if ("object" !== typeof child || null === child) return knownKeys; - switch (child.$$typeof) { - case REACT_ELEMENT_TYPE: - case REACT_PORTAL_TYPE: - warnForMissingKey(returnFiber, workInProgress, child); - var key = child.key; - if ("string" !== typeof key) break; - if (null === knownKeys) { - knownKeys = new Set(); - knownKeys.add(key); + + var parentB = parentA.alternate; + + if (parentB === null) { + // There is no alternate. This is an unusual case. Currently, it only + // happens when a Suspense component is hidden. An extra fragment fiber + // is inserted in between the Suspense fiber and its children. Skip + // over this extra fragment fiber and proceed to the next parent. + var nextParent = parentA.return; + + if (nextParent !== null) { + a = b = nextParent; + continue; + } // If there's no parent, we're at the root. + + break; + } // If both copies of the parent fiber point to the same child, we can + // assume that the child is current. This happens when we bailout on low + // priority: the bailed out fiber's child reuses the current child. + + if (parentA.child === parentB.child) { + var child = parentA.child; + + while (child) { + if (child === a) { + // We've determined that A is the current branch. + assertIsMounted(parentA); + return fiber; + } + + if (child === b) { + // We've determined that B is the current branch. + assertIsMounted(parentA); + return alternate; + } + + child = child.sibling; + } // We should never have an alternate for any mounting node. So the only + // way this could possibly happen is if this was unmounted, if at all. + + throw new Error("Unable to find node on an unmounted component."); + } + + if (a.return !== b.return) { + // The return pointer of A and the return pointer of B point to different + // fibers. We assume that return pointers never criss-cross, so A must + // belong to the child set of A.return, and B must belong to the child + // set of B.return. + a = parentA; + b = parentB; + } else { + // The return pointers point to the same fiber. We'll have to use the + // default, slow path: scan the child sets of each parent alternate to see + // which child belongs to which set. + // + // Search parent A's child set + var didFindChild = false; + var _child = parentA.child; + + while (_child) { + if (_child === a) { + didFindChild = true; + a = parentA; + b = parentB; break; } - if (!knownKeys.has(key)) { - knownKeys.add(key); + + if (_child === b) { + didFindChild = true; + b = parentA; + a = parentB; break; } - runWithFiberInDEV(workInProgress, function () { - error$jscomp$0( - "Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted \u2014 the behavior is unsupported and could change in a future version.", - key + + _child = _child.sibling; + } + + if (!didFindChild) { + // Search parent B's child set + _child = parentB.child; + + while (_child) { + if (_child === a) { + didFindChild = true; + a = parentB; + b = parentA; + break; + } + + if (_child === b) { + didFindChild = true; + b = parentB; + a = parentA; + break; + } + + _child = _child.sibling; + } + + if (!didFindChild) { + throw new Error( + "Child was not found in either parent set. This indicates a bug " + + "in React related to the return pointer. Please file an issue." ); - }); - break; - case REACT_LAZY_TYPE: - (child = callLazyInitInDEV(child)), - warnOnInvalidKey(returnFiber, workInProgress, child, knownKeys); - } - return knownKeys; - } - function reconcileChildrenArray( - returnFiber, - currentFirstChild, - newChildren, - lanes - ) { - for ( - var knownKeys = null, - resultingFirstChild = null, - previousNewFiber = null, - oldFiber = currentFirstChild, - newIdx = (currentFirstChild = 0), - nextOldFiber = null; - null !== oldFiber && newIdx < newChildren.length; - newIdx++ - ) { - oldFiber.index > newIdx - ? ((nextOldFiber = oldFiber), (oldFiber = null)) - : (nextOldFiber = oldFiber.sibling); - var newFiber = updateSlot( - returnFiber, - oldFiber, - newChildren[newIdx], - lanes - ); - if (null === newFiber) { - null === oldFiber && (oldFiber = nextOldFiber); - break; + } } - knownKeys = warnOnInvalidKey( - returnFiber, - newFiber, - newChildren[newIdx], - knownKeys - ); - shouldTrackSideEffects && - oldFiber && - null === newFiber.alternate && - deleteChild(returnFiber, oldFiber); - currentFirstChild = placeChild(newFiber, currentFirstChild, newIdx); - null === previousNewFiber - ? (resultingFirstChild = newFiber) - : (previousNewFiber.sibling = newFiber); - previousNewFiber = newFiber; - oldFiber = nextOldFiber; } - if (newIdx === newChildren.length) - return ( - deleteRemainingChildren(returnFiber, oldFiber), resultingFirstChild + + if (a.alternate !== b) { + throw new Error( + "Return fibers should always be each others' alternates. " + + "This error is likely caused by a bug in React. Please file an issue." ); - if (null === oldFiber) { - for (; newIdx < newChildren.length; newIdx++) - (oldFiber = createChild(returnFiber, newChildren[newIdx], lanes)), - null !== oldFiber && - ((knownKeys = warnOnInvalidKey( - returnFiber, - oldFiber, - newChildren[newIdx], - knownKeys - )), - (currentFirstChild = placeChild( - oldFiber, - currentFirstChild, - newIdx - )), - null === previousNewFiber - ? (resultingFirstChild = oldFiber) - : (previousNewFiber.sibling = oldFiber), - (previousNewFiber = oldFiber)); - return resultingFirstChild; } - for ( - oldFiber = mapRemainingChildren(oldFiber); - newIdx < newChildren.length; - newIdx++ - ) - (nextOldFiber = updateFromMap( - oldFiber, - returnFiber, - newIdx, - newChildren[newIdx], - lanes - )), - null !== nextOldFiber && - ((knownKeys = warnOnInvalidKey( - returnFiber, - nextOldFiber, - newChildren[newIdx], - knownKeys - )), - shouldTrackSideEffects && - null !== nextOldFiber.alternate && - oldFiber.delete( - null === nextOldFiber.key ? newIdx : nextOldFiber.key - ), - (currentFirstChild = placeChild( - nextOldFiber, - currentFirstChild, - newIdx - )), - null === previousNewFiber - ? (resultingFirstChild = nextOldFiber) - : (previousNewFiber.sibling = nextOldFiber), - (previousNewFiber = nextOldFiber)); - shouldTrackSideEffects && - oldFiber.forEach(function (child) { - return deleteChild(returnFiber, child); - }); - return resultingFirstChild; + } // If the root is not a host container, we're in a disconnected tree. I.e. + // unmounted. + + if (a.tag !== HostRoot) { + throw new Error("Unable to find node on an unmounted component."); } - function reconcileChildrenIterator( - returnFiber, - currentFirstChild, - newChildren, - lanes - ) { - if (null == newChildren) - throw Error("An iterable object provided no iterator."); - for ( - var resultingFirstChild = null, - previousNewFiber = null, - oldFiber = currentFirstChild, - newIdx = (currentFirstChild = 0), - nextOldFiber = null, - knownKeys = null, - step = newChildren.next(); - null !== oldFiber && !step.done; - newIdx++, step = newChildren.next() - ) { - oldFiber.index > newIdx - ? ((nextOldFiber = oldFiber), (oldFiber = null)) - : (nextOldFiber = oldFiber.sibling); - var newFiber = updateSlot(returnFiber, oldFiber, step.value, lanes); - if (null === newFiber) { - null === oldFiber && (oldFiber = nextOldFiber); - break; - } - knownKeys = warnOnInvalidKey( - returnFiber, - newFiber, - step.value, - knownKeys - ); - shouldTrackSideEffects && - oldFiber && - null === newFiber.alternate && - deleteChild(returnFiber, oldFiber); - currentFirstChild = placeChild(newFiber, currentFirstChild, newIdx); - null === previousNewFiber - ? (resultingFirstChild = newFiber) - : (previousNewFiber.sibling = newFiber); - previousNewFiber = newFiber; - oldFiber = nextOldFiber; - } - if (step.done) - return ( - deleteRemainingChildren(returnFiber, oldFiber), resultingFirstChild - ); - if (null === oldFiber) { - for (; !step.done; newIdx++, step = newChildren.next()) - (oldFiber = createChild(returnFiber, step.value, lanes)), - null !== oldFiber && - ((knownKeys = warnOnInvalidKey( - returnFiber, - oldFiber, - step.value, - knownKeys - )), - (currentFirstChild = placeChild( - oldFiber, - currentFirstChild, - newIdx - )), - null === previousNewFiber - ? (resultingFirstChild = oldFiber) - : (previousNewFiber.sibling = oldFiber), - (previousNewFiber = oldFiber)); - return resultingFirstChild; - } - for ( - oldFiber = mapRemainingChildren(oldFiber); - !step.done; - newIdx++, step = newChildren.next() - ) - (nextOldFiber = updateFromMap( - oldFiber, - returnFiber, - newIdx, - step.value, - lanes - )), - null !== nextOldFiber && - ((knownKeys = warnOnInvalidKey( - returnFiber, - nextOldFiber, - step.value, - knownKeys - )), - shouldTrackSideEffects && - null !== nextOldFiber.alternate && - oldFiber.delete( - null === nextOldFiber.key ? newIdx : nextOldFiber.key - ), - (currentFirstChild = placeChild( - nextOldFiber, - currentFirstChild, - newIdx - )), - null === previousNewFiber - ? (resultingFirstChild = nextOldFiber) - : (previousNewFiber.sibling = nextOldFiber), - (previousNewFiber = nextOldFiber)); - shouldTrackSideEffects && - oldFiber.forEach(function (child) { - return deleteChild(returnFiber, child); - }); - return resultingFirstChild; - } - function reconcileChildFibersImpl( - returnFiber, - currentFirstChild, - newChild, - lanes - ) { - "object" === typeof newChild && - null !== newChild && - newChild.type === REACT_FRAGMENT_TYPE && - null === newChild.key && - (validateFragmentProps(newChild, null, returnFiber), - (newChild = newChild.props.children)); - if ("object" === typeof newChild && null !== newChild) { - switch (newChild.$$typeof) { - case REACT_ELEMENT_TYPE: - var prevDebugInfo = pushDebugInfo(newChild._debugInfo); - a: { - for ( - var key = newChild.key, child = currentFirstChild; - null !== child; - ) { - if (child.key === key) { - key = newChild.type; - if (key === REACT_FRAGMENT_TYPE) { - if (7 === child.tag) { - deleteRemainingChildren(returnFiber, child.sibling); - currentFirstChild = useFiber( - child, - newChild.props.children - ); - currentFirstChild.return = returnFiber; - currentFirstChild._debugOwner = newChild._owner; - currentFirstChild._debugInfo = currentDebugInfo; - validateFragmentProps( - newChild, - currentFirstChild, - returnFiber - ); - returnFiber = currentFirstChild; - break a; - } - } else if ( - child.elementType === key || - isCompatibleFamilyForHotReloading(child, newChild) || - ("object" === typeof key && - null !== key && - key.$$typeof === REACT_LAZY_TYPE && - callLazyInitInDEV(key) === child.type) - ) { - deleteRemainingChildren(returnFiber, child.sibling); - currentFirstChild = useFiber(child, newChild.props); - coerceRef( - returnFiber, - child, - currentFirstChild, - newChild - ); - currentFirstChild.return = returnFiber; - currentFirstChild._debugOwner = newChild._owner; - currentFirstChild._debugInfo = currentDebugInfo; - returnFiber = currentFirstChild; - break a; - } - deleteRemainingChildren(returnFiber, child); - break; - } else deleteChild(returnFiber, child); - child = child.sibling; - } - newChild.type === REACT_FRAGMENT_TYPE - ? ((currentFirstChild = createFiberFromFragment( - newChild.props.children, - returnFiber.mode, - lanes, - newChild.key - )), - (currentFirstChild.return = returnFiber), - (currentFirstChild._debugInfo = currentDebugInfo), - validateFragmentProps( - newChild, - currentFirstChild, - returnFiber - ), - (returnFiber = currentFirstChild)) - : ((lanes = createFiberFromElement( - newChild, - returnFiber.mode, - lanes - )), - coerceRef(returnFiber, currentFirstChild, lanes, newChild), - (lanes.return = returnFiber), - (lanes._debugInfo = currentDebugInfo), - (returnFiber = lanes)); - } - returnFiber = placeSingleChild(returnFiber); - currentDebugInfo = prevDebugInfo; - return returnFiber; - case REACT_PORTAL_TYPE: - a: { - prevDebugInfo = newChild; - for ( - newChild = prevDebugInfo.key; - null !== currentFirstChild; + if (a.stateNode.current === a) { + // We've determined that A is the current branch. + return fiber; + } // Otherwise B has to be current branch. - ) { - if (currentFirstChild.key === newChild) - if ( - 4 === currentFirstChild.tag && - currentFirstChild.stateNode.containerInfo === - prevDebugInfo.containerInfo && - currentFirstChild.stateNode.implementation === - prevDebugInfo.implementation - ) { - deleteRemainingChildren( - returnFiber, - currentFirstChild.sibling - ); - currentFirstChild = useFiber( - currentFirstChild, - prevDebugInfo.children || [] - ); - currentFirstChild.return = returnFiber; - returnFiber = currentFirstChild; - break a; - } else { - deleteRemainingChildren(returnFiber, currentFirstChild); - break; - } - else deleteChild(returnFiber, currentFirstChild); - currentFirstChild = currentFirstChild.sibling; - } - currentFirstChild = createFiberFromPortal( - prevDebugInfo, - returnFiber.mode, - lanes - ); - currentFirstChild.return = returnFiber; - returnFiber = currentFirstChild; - } - return placeSingleChild(returnFiber); - case REACT_LAZY_TYPE: - return ( - (prevDebugInfo = pushDebugInfo(newChild._debugInfo)), - (newChild = callLazyInitInDEV(newChild)), - (returnFiber = reconcileChildFibersImpl( - returnFiber, - currentFirstChild, - newChild, - lanes - )), - (currentDebugInfo = prevDebugInfo), - returnFiber - ); - } - if (isArrayImpl(newChild)) - return ( - (prevDebugInfo = pushDebugInfo(newChild._debugInfo)), - (returnFiber = reconcileChildrenArray( - returnFiber, - currentFirstChild, - newChild, - lanes - )), - (currentDebugInfo = prevDebugInfo), - returnFiber - ); - if (getIteratorFn(newChild)) { - prevDebugInfo = pushDebugInfo(newChild._debugInfo); - child = getIteratorFn(newChild); - if ("function" !== typeof child) - throw Error( - "An object is not an iterable. This error is likely caused by a bug in React. Please file an issue." - ); - key = child.call(newChild); - if (key === newChild) { - if ( - 0 !== returnFiber.tag || - "[object GeneratorFunction]" !== - Object.prototype.toString.call(returnFiber.type) || - "[object Generator]" !== Object.prototype.toString.call(key) - ) - didWarnAboutGenerators || - error$jscomp$0( - "Using Iterators as children is unsupported and will likely yield unexpected results because enumerating a generator mutates it. You may convert it to an array with `Array.from()` or the `[...spread]` operator before rendering. You can also use an Iterable that can iterate multiple times over the same items." - ), - (didWarnAboutGenerators = !0); - } else - newChild.entries !== child || - didWarnAboutMaps || - (error$jscomp$0( - "Using Maps as children is not supported. Use an array of keyed ReactElements instead." - ), - (didWarnAboutMaps = !0)); - returnFiber = reconcileChildrenIterator( - returnFiber, - currentFirstChild, - key, - lanes - ); - currentDebugInfo = prevDebugInfo; - return returnFiber; - } - if ("function" === typeof newChild.then) - return ( - (prevDebugInfo = pushDebugInfo(newChild._debugInfo)), - (returnFiber = reconcileChildFibersImpl( - returnFiber, - currentFirstChild, - unwrapThenable(newChild), - lanes - )), - (currentDebugInfo = prevDebugInfo), - returnFiber - ); - if (newChild.$$typeof === REACT_CONTEXT_TYPE) - return reconcileChildFibersImpl( - returnFiber, - currentFirstChild, - readContextDuringReconciliation(returnFiber, newChild, lanes), - lanes - ); - throwOnInvalidObjectType(returnFiber, newChild); - } - if ( - ("string" === typeof newChild && "" !== newChild) || - "number" === typeof newChild || - "bigint" === typeof newChild - ) - return ( - (prevDebugInfo = "" + newChild), - null !== currentFirstChild && 6 === currentFirstChild.tag - ? (deleteRemainingChildren( - returnFiber, - currentFirstChild.sibling - ), - (currentFirstChild = useFiber( - currentFirstChild, - prevDebugInfo - )), - (currentFirstChild.return = returnFiber), - (returnFiber = currentFirstChild)) - : (deleteRemainingChildren(returnFiber, currentFirstChild), - (currentFirstChild = createFiberFromText( - prevDebugInfo, - returnFiber.mode, - lanes - )), - (currentFirstChild.return = returnFiber), - (returnFiber = currentFirstChild)), - placeSingleChild(returnFiber) - ); - "function" === typeof newChild && - warnOnFunctionType(returnFiber, newChild); - "symbol" === typeof newChild && warnOnSymbolType(returnFiber, newChild); - return deleteRemainingChildren(returnFiber, currentFirstChild); - } - return function (returnFiber, currentFirstChild, newChild, lanes) { - var prevDebugInfo = currentDebugInfo; - currentDebugInfo = null; - try { - thenableIndexCounter$1 = 0; - var firstChildFiber = reconcileChildFibersImpl( - returnFiber, - currentFirstChild, - newChild, - lanes - ); - thenableState$1 = null; - return firstChildFiber; - } catch (x) { - if ( - x === SuspenseException || - (0 === (returnFiber.mode & 1) && - "object" === typeof x && - null !== x && - "function" === typeof x.then) - ) - throw x; - var fiber = createFiber(29, x, null, returnFiber.mode); - fiber.lanes = lanes; - fiber.return = returnFiber; - var debugInfo = (fiber._debugInfo = currentDebugInfo); - fiber._debugOwner = returnFiber._debugOwner; - fiber._debugTask = returnFiber._debugTask; - if (null != debugInfo) - for (var i = debugInfo.length - 1; 0 <= i; i--) - if ("string" === typeof debugInfo[i].stack) { - fiber._debugOwner = debugInfo[i]; - fiber._debugTask = debugInfo[i].task; - break; - } - return fiber; - } finally { - currentDebugInfo = prevDebugInfo; - } - }; - } - function pushHiddenContext(fiber, context) { - var prevEntangledRenderLanes = entangledRenderLanes; - push(prevEntangledRenderLanesCursor, prevEntangledRenderLanes, fiber); - push(currentTreeHiddenStackCursor, context, fiber); - entangledRenderLanes = prevEntangledRenderLanes | context.baseLanes; - } - function reuseHiddenContextOnStack(fiber) { - push(prevEntangledRenderLanesCursor, entangledRenderLanes, fiber); - push( - currentTreeHiddenStackCursor, - currentTreeHiddenStackCursor.current, - fiber - ); - } - function popHiddenContext(fiber) { - entangledRenderLanes = prevEntangledRenderLanesCursor.current; - pop(currentTreeHiddenStackCursor, fiber); - pop(prevEntangledRenderLanesCursor, fiber); - } - function pushPrimaryTreeSuspenseHandler(handler) { - var current = handler.alternate; - push( - suspenseStackCursor, - suspenseStackCursor.current & SubtreeSuspenseContextMask, - handler - ); - push(suspenseHandlerStackCursor, handler, handler); - null === shellBoundary && - (null === current || null !== currentTreeHiddenStackCursor.current - ? (shellBoundary = handler) - : null !== current.memoizedState && (shellBoundary = handler)); - } - function pushOffscreenSuspenseHandler(fiber) { - if (22 === fiber.tag) { - if ( - (push(suspenseStackCursor, suspenseStackCursor.current, fiber), - push(suspenseHandlerStackCursor, fiber, fiber), - null === shellBoundary) - ) { - var current = fiber.alternate; - null !== current && - null !== current.memoizedState && - (shellBoundary = fiber); - } - } else reuseSuspenseHandlerOnStack(fiber); - } - function reuseSuspenseHandlerOnStack(fiber) { - push(suspenseStackCursor, suspenseStackCursor.current, fiber); - push( - suspenseHandlerStackCursor, - suspenseHandlerStackCursor.current, - fiber - ); + return alternate; } - function popSuspenseHandler(fiber) { - pop(suspenseHandlerStackCursor, fiber); - shellBoundary === fiber && (shellBoundary = null); - pop(suspenseStackCursor, fiber); + function findCurrentHostFiber(parent) { + var currentParent = findCurrentFiberUsingSlowPath(parent); + return currentParent !== null + ? findCurrentHostFiberImpl(currentParent) + : null; } - function findFirstSuspended(row) { - for (var node = row; null !== node; ) { - if (13 === node.tag) { - var state = node.memoizedState; - if ( - null !== state && - (null === state.dehydrated || - isSuspenseInstancePending() || - isSuspenseInstanceFallback()) - ) - return node; - } else if ( - 19 === node.tag && - void 0 !== node.memoizedProps.revealOrder - ) { - if (0 !== (node.flags & 128)) return node; - } else if (null !== node.child) { - node.child.return = node; - node = node.child; - continue; - } - if (node === row) break; - for (; null === node.sibling; ) { - if (null === node.return || node.return === row) return null; - node = node.return; + + function findCurrentHostFiberImpl(node) { + // Next we'll drill down this component to find the first HostComponent/Text. + var tag = node.tag; + + if ( + tag === HostComponent || + tag === HostHoistable || + tag === HostSingleton || + tag === HostText + ) { + return node; + } + + var child = node.child; + + while (child !== null) { + var match = findCurrentHostFiberImpl(child); + + if (match !== null) { + return match; } - node.sibling.return = node.return; - node = node.sibling; + + child = child.sibling; } + return null; } - function mountHookTypesDev() { - var hookName = currentHookNameInDev; - null === hookTypesDev - ? (hookTypesDev = [hookName]) - : hookTypesDev.push(hookName); + function doesFiberContain(parentFiber, childFiber) { + var node = childFiber; + var parentFiberAlternate = parentFiber.alternate; + + while (node !== null) { + if (node === parentFiber || node === parentFiberAlternate) { + return true; + } + + node = node.return; + } + + return false; } - function updateHookTypesDev() { - var hookName = currentHookNameInDev; - if ( - null !== hookTypesDev && - (hookTypesUpdateIndexDev++, - hookTypesDev[hookTypesUpdateIndexDev] !== hookName) - ) { - var componentName = getComponentNameFromFiber( - currentlyRenderingFiber$1 + + // Modules provided by RN: + var emptyObject$1 = {}; + /** + * Create a payload that contains all the updates between two sets of props. + * + * These helpers are all encapsulated into a single module, because they use + * mutation as a performance optimization which leads to subtle shared + * dependencies between the code paths. To avoid this mutable state leaking + * across modules, I've kept them isolated to this module. + */ + // Tracks removed keys + + var removedKeys = null; + var removedKeyCount = 0; + var deepDifferOptions = { + unsafelyIgnoreFunctions: true + }; + + function defaultDiffer(prevProp, nextProp) { + if (typeof nextProp !== "object" || nextProp === null) { + // Scalars have already been checked for equality + return true; + } else { + // For objects and arrays, the default diffing algorithm is a deep compare + return ReactNativePrivateInterface.deepDiffer( + prevProp, + nextProp, + deepDifferOptions ); - if ( - !didWarnAboutMismatchedHooksForComponent.has(componentName) && - (didWarnAboutMismatchedHooksForComponent.add(componentName), - null !== hookTypesDev) - ) { - for (var table = "", i = 0; i <= hookTypesUpdateIndexDev; i++) { - var oldHookName = hookTypesDev[i], - newHookName = - i === hookTypesUpdateIndexDev ? hookName : oldHookName; - for ( - oldHookName = i + 1 + ". " + oldHookName; - 30 > oldHookName.length; + } + } - ) - oldHookName += " "; - oldHookName += newHookName + "\n"; - table += oldHookName; - } - error$jscomp$0( - "React has detected a change in the order of Hooks called by %s. This will lead to bugs and errors if not fixed. For more information, read the Rules of Hooks: https://react.dev/link/rules-of-hooks\n\n Previous render Next render\n ------------------------------------------------------\n%s ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", - componentName, - table + function restoreDeletedValuesInNestedArray( + updatePayload, + node, + validAttributes + ) { + if (isArray(node)) { + var i = node.length; + + while (i-- && removedKeyCount > 0) { + restoreDeletedValuesInNestedArray( + updatePayload, + node[i], + validAttributes ); } + } else if (node && removedKeyCount > 0) { + var obj = node; + + for (var propKey in removedKeys) { + // $FlowFixMe[incompatible-use] found when upgrading Flow + if (!removedKeys[propKey]) { + continue; + } + + var nextProp = obj[propKey]; + + if (nextProp === undefined) { + continue; + } + + var attributeConfig = validAttributes[propKey]; + + if (!attributeConfig) { + continue; // not a valid native prop + } + + if (typeof nextProp === "function") { + // $FlowFixMe[incompatible-type] found when upgrading Flow + nextProp = true; + } + + if (typeof nextProp === "undefined") { + // $FlowFixMe[incompatible-type] found when upgrading Flow + nextProp = null; + } + + if (typeof attributeConfig !== "object") { + // case: !Object is the default case + updatePayload[propKey] = nextProp; + } else if ( + typeof attributeConfig.diff === "function" || + typeof attributeConfig.process === "function" + ) { + // case: CustomAttributeConfiguration + var nextValue = + typeof attributeConfig.process === "function" + ? attributeConfig.process(nextProp) + : nextProp; + updatePayload[propKey] = nextValue; + } // $FlowFixMe[incompatible-use] found when upgrading Flow + + removedKeys[propKey] = false; + removedKeyCount--; + } } } - function checkDepsAreArrayDev(deps) { - void 0 === deps || - null === deps || - isArrayImpl(deps) || - error$jscomp$0( - "%s received a final argument that is not an array (instead, received `%s`). When specified, the final argument must be an array.", - currentHookNameInDev, - typeof deps + + function diffNestedArrayProperty( + updatePayload, + prevArray, + nextArray, + validAttributes + ) { + var minLength = + prevArray.length < nextArray.length + ? prevArray.length + : nextArray.length; + var i; + + for (i = 0; i < minLength; i++) { + // Diff any items in the array in the forward direction. Repeated keys + // will be overwritten by later values. + updatePayload = diffNestedProperty( + updatePayload, + prevArray[i], + nextArray[i], + validAttributes ); - } - function warnOnUseFormStateInDev() { - var componentName = getComponentNameFromFiber(currentlyRenderingFiber$1); - didWarnAboutUseFormState.has(componentName) || - (didWarnAboutUseFormState.add(componentName), - error$jscomp$0( - "ReactDOM.useFormState has been renamed to React.useActionState. Please update %s to use React.useActionState.", - componentName - )); - } - function throwInvalidHookError() { - throw Error( - "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://react.dev/link/invalid-hook-call for tips about how to debug and fix this problem." - ); - } - function areHookInputsEqual(nextDeps, prevDeps) { - if (ignorePreviousDependencies) return !1; - if (null === prevDeps) - return ( - error$jscomp$0( - "%s received a final argument during this render, but not during the previous render. Even though the final argument is optional, its type cannot change between renders.", - currentHookNameInDev - ), - !1 + } + + for (; i < prevArray.length; i++) { + // Clear out all remaining properties. + updatePayload = clearNestedProperty( + updatePayload, + prevArray[i], + validAttributes ); - nextDeps.length !== prevDeps.length && - error$jscomp$0( - "The final argument passed to %s changed size between renders. The order and size of this array must remain constant.\n\nPrevious: %s\nIncoming: %s", - currentHookNameInDev, - "[" + prevDeps.join(", ") + "]", - "[" + nextDeps.join(", ") + "]" + } + + for (; i < nextArray.length; i++) { + // Add all remaining properties. + updatePayload = addNestedProperty( + updatePayload, + nextArray[i], + validAttributes ); - for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) - if (!objectIs(nextDeps[i], prevDeps[i])) return !1; - return !0; - } - function renderWithHooks( - current, - workInProgress, - Component, - props, - secondArg, - nextRenderLanes + } + + return updatePayload; + } + + function diffNestedProperty( + updatePayload, + prevProp, + nextProp, + validAttributes ) { - renderLanes = nextRenderLanes; - currentlyRenderingFiber$1 = workInProgress; - hookTypesDev = null !== current ? current._debugHookTypes : null; - hookTypesUpdateIndexDev = -1; - ignorePreviousDependencies = - null !== current && current.type !== workInProgress.type; - if ( - "[object AsyncFunction]" === - Object.prototype.toString.call(Component) || - "[object AsyncGeneratorFunction]" === - Object.prototype.toString.call(Component) - ) - (nextRenderLanes = getComponentNameFromFiber( - currentlyRenderingFiber$1 - )), - didWarnAboutAsyncClientComponent.has(nextRenderLanes) || - (didWarnAboutAsyncClientComponent.add(nextRenderLanes), - error$jscomp$0( - "async/await is not yet supported in Client Components, only Server Components. This error is often caused by accidentally adding `'use client'` to a module that was originally written for the server." - )); - workInProgress.memoizedState = null; - workInProgress.updateQueue = null; - workInProgress.lanes = 0; - ReactSharedInternals.H = - null !== current && null !== current.memoizedState - ? HooksDispatcherOnUpdateInDEV - : null !== hookTypesDev - ? HooksDispatcherOnMountWithHookTypesInDEV - : HooksDispatcherOnMountInDEV; - shouldDoubleInvokeUserFnsInHooksDEV = nextRenderLanes = - 0 !== (workInProgress.mode & 8); - var children = callComponentInDEV(Component, props, secondArg); - shouldDoubleInvokeUserFnsInHooksDEV = !1; - didScheduleRenderPhaseUpdateDuringThisPass && - (children = renderWithHooksAgain( - workInProgress, - Component, - props, - secondArg - )); - if (nextRenderLanes) { - setIsStrictModeForDevtools(!0); - try { - children = renderWithHooksAgain( - workInProgress, - Component, - props, - secondArg - ); - } finally { - setIsStrictModeForDevtools(!1); + if (!updatePayload && prevProp === nextProp) { + // If no properties have been added, then we can bail out quickly on object + // equality. + return updatePayload; + } + + if (!prevProp || !nextProp) { + if (nextProp) { + return addNestedProperty(updatePayload, nextProp, validAttributes); + } + + if (prevProp) { + return clearNestedProperty(updatePayload, prevProp, validAttributes); } + + return updatePayload; } - finishRenderingHooks(current, workInProgress); - return children; - } - function finishRenderingHooks(current, workInProgress) { - workInProgress._debugHookTypes = hookTypesDev; - ReactSharedInternals.H = ContextOnlyDispatcher; - var didRenderTooFewHooks = - null !== currentHook && null !== currentHook.next; - renderLanes = 0; - hookTypesDev = - currentHookNameInDev = - workInProgressHook = - currentHook = - currentlyRenderingFiber$1 = - null; - hookTypesUpdateIndexDev = -1; - null !== current && - (current.flags & 31457280) !== (workInProgress.flags & 31457280) && - 0 !== (current.mode & 1) && - error$jscomp$0( - "Internal React error: Expected static flag was missing. Please notify the React team." + + if (!isArray(prevProp) && !isArray(nextProp)) { + // Both are leaves, we can diff the leaves. + return diffProperties( + updatePayload, + prevProp, + nextProp, + validAttributes ); - didScheduleRenderPhaseUpdate = !1; - thenableIndexCounter = 0; - thenableState = null; - if (didRenderTooFewHooks) - throw Error( - "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." + } + + if (isArray(prevProp) && isArray(nextProp)) { + // Both are arrays, we can diff the arrays. + return diffNestedArrayProperty( + updatePayload, + prevProp, + nextProp, + validAttributes ); - needsToResetSuspendedThenableDEV - ? ((needsToResetSuspendedThenableDEV = !1), (current = !0)) - : (current = !1); - current && - ((workInProgress = - getComponentNameFromFiber(workInProgress) || "Unknown"), - didWarnAboutUseWrappedInTryCatch.has(workInProgress) || - didWarnAboutAsyncClientComponent.has(workInProgress) || - (didWarnAboutUseWrappedInTryCatch.add(workInProgress), - error$jscomp$0( - "`use` was called from inside a try/catch block. This is not allowed and can lead to unexpected behavior. To handle errors triggered by `use`, wrap your component in a error boundary." - ))); - } - function renderWithHooksAgain(workInProgress, Component, props, secondArg) { - currentlyRenderingFiber$1 = workInProgress; - var numberOfReRenders = 0; - do { - didScheduleRenderPhaseUpdateDuringThisPass && (thenableState = null); - thenableIndexCounter = 0; - didScheduleRenderPhaseUpdateDuringThisPass = !1; - if (numberOfReRenders >= RE_RENDER_LIMIT) - throw Error( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." - ); - numberOfReRenders += 1; - ignorePreviousDependencies = !1; - workInProgressHook = currentHook = null; - workInProgress.updateQueue = null; - hookTypesUpdateIndexDev = -1; - ReactSharedInternals.H = HooksDispatcherOnRerenderInDEV; - var children = callComponentInDEV(Component, props, secondArg); - } while (didScheduleRenderPhaseUpdateDuringThisPass); - return children; + } + + if (isArray(prevProp)) { + return diffProperties( + updatePayload, + ReactNativePrivateInterface.flattenStyle(prevProp), + nextProp, + validAttributes + ); + } + + return diffProperties( + updatePayload, + prevProp, + ReactNativePrivateInterface.flattenStyle(nextProp), + validAttributes + ); } - function TransitionAwareHostComponent() { - var dispatcher = ReactSharedInternals.H, - maybeThenable = dispatcher.useState()[0]; - maybeThenable = - "function" === typeof maybeThenable.then - ? useThenable(maybeThenable) - : maybeThenable; - dispatcher = dispatcher.useState()[0]; - (null !== currentHook ? currentHook.memoizedState : null) !== - dispatcher && (currentlyRenderingFiber$1.flags |= 1024); - return maybeThenable; + /** + * addNestedProperty takes a single set of props and valid attribute + * attribute configurations. It processes each prop and adds it to the + * updatePayload. + */ + + function addNestedProperty(updatePayload, nextProp, validAttributes) { + if (!nextProp) { + return updatePayload; + } + + if (!isArray(nextProp)) { + // Add each property of the leaf. + return addProperties(updatePayload, nextProp, validAttributes); + } + + for (var i = 0; i < nextProp.length; i++) { + // Add all the properties of the array. + updatePayload = addNestedProperty( + updatePayload, + nextProp[i], + validAttributes + ); + } + + return updatePayload; } - function bailoutHooks(current, workInProgress, lanes) { - workInProgress.updateQueue = current.updateQueue; - workInProgress.flags = - 0 !== (workInProgress.mode & 16) - ? workInProgress.flags & -201328645 - : workInProgress.flags & -2053; - current.lanes &= ~lanes; + /** + * clearNestedProperty takes a single set of props and valid attributes. It + * adds a null sentinel to the updatePayload, for each prop key. + */ + + function clearNestedProperty(updatePayload, prevProp, validAttributes) { + if (!prevProp) { + return updatePayload; + } + + if (!isArray(prevProp)) { + // Add each property of the leaf. + return clearProperties(updatePayload, prevProp, validAttributes); + } + + for (var i = 0; i < prevProp.length; i++) { + // Add all the properties of the array. + updatePayload = clearNestedProperty( + updatePayload, + prevProp[i], + validAttributes + ); + } + + return updatePayload; } - function resetHooksOnUnwind(workInProgress) { - if (didScheduleRenderPhaseUpdate) { - for ( - workInProgress = workInProgress.memoizedState; - null !== workInProgress; + /** + * diffProperties takes two sets of props and a set of valid attributes + * and write to updatePayload the values that changed or were deleted. + * If no updatePayload is provided, a new one is created and returned if + * anything changed. + */ + + function diffProperties( + updatePayload, + prevProps, + nextProps, + validAttributes + ) { + var attributeConfig; + var nextProp; + var prevProp; + + for (var propKey in nextProps) { + attributeConfig = validAttributes[propKey]; + + if (!attributeConfig) { + continue; // not a valid native prop + } + + prevProp = prevProps[propKey]; + nextProp = nextProps[propKey]; // functions are converted to booleans as markers that the associated + // events should be sent from native. + + if (typeof nextProp === "function") { + nextProp = true; // If nextProp is not a function, then don't bother changing prevProp + // since nextProp will win and go into the updatePayload regardless. + + if (typeof prevProp === "function") { + prevProp = true; + } + } // An explicit value of undefined is treated as a null because it overrides + // any other preceding value. + + if (typeof nextProp === "undefined") { + nextProp = null; + + if (typeof prevProp === "undefined") { + prevProp = null; + } + } + + if (removedKeys) { + removedKeys[propKey] = false; + } + + if (updatePayload && updatePayload[propKey] !== undefined) { + // Something else already triggered an update to this key because another + // value diffed. Since we're now later in the nested arrays our value is + // more important so we need to calculate it and override the existing + // value. It doesn't matter if nothing changed, we'll set it anyway. + // Pattern match on: attributeConfig + if (typeof attributeConfig !== "object") { + // case: !Object is the default case + updatePayload[propKey] = nextProp; + } else if ( + typeof attributeConfig.diff === "function" || + typeof attributeConfig.process === "function" + ) { + // case: CustomAttributeConfiguration + var nextValue = + typeof attributeConfig.process === "function" + ? attributeConfig.process(nextProp) + : nextProp; + updatePayload[propKey] = nextValue; + } + + continue; + } + + if (prevProp === nextProp) { + continue; // nothing changed + } // Pattern match on: attributeConfig + if (typeof attributeConfig !== "object") { + // case: !Object is the default case + if (defaultDiffer(prevProp, nextProp)) { + // a normal leaf has changed + (updatePayload || (updatePayload = {}))[propKey] = nextProp; + } + } else if ( + typeof attributeConfig.diff === "function" || + typeof attributeConfig.process === "function" ) { - var queue = workInProgress.queue; - null !== queue && (queue.pending = null); - workInProgress = workInProgress.next; - } - didScheduleRenderPhaseUpdate = !1; - } - renderLanes = 0; - hookTypesDev = - workInProgressHook = - currentHook = - currentlyRenderingFiber$1 = - null; - hookTypesUpdateIndexDev = -1; - currentHookNameInDev = null; - didScheduleRenderPhaseUpdateDuringThisPass = !1; - thenableIndexCounter = 0; - thenableState = null; - } - function mountWorkInProgressHook() { - var hook = { - memoizedState: null, - baseState: null, - baseQueue: null, - queue: null, - next: null - }; - null === workInProgressHook - ? (currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook) - : (workInProgressHook = workInProgressHook.next = hook); - return workInProgressHook; - } - function updateWorkInProgressHook() { - if (null === currentHook) { - var nextCurrentHook = currentlyRenderingFiber$1.alternate; - nextCurrentHook = - null !== nextCurrentHook ? nextCurrentHook.memoizedState : null; - } else nextCurrentHook = currentHook.next; - var nextWorkInProgressHook = - null === workInProgressHook - ? currentlyRenderingFiber$1.memoizedState - : workInProgressHook.next; - if (null !== nextWorkInProgressHook) - (workInProgressHook = nextWorkInProgressHook), - (currentHook = nextCurrentHook); - else { - if (null === nextCurrentHook) { - if (null === currentlyRenderingFiber$1.alternate) - throw Error( - "Update hook called on initial render. This is likely a bug in React. Please file an issue." + // case: CustomAttributeConfiguration + var shouldUpdate = + prevProp === undefined || + (typeof attributeConfig.diff === "function" + ? attributeConfig.diff(prevProp, nextProp) + : defaultDiffer(prevProp, nextProp)); + + if (shouldUpdate) { + var _nextValue = + typeof attributeConfig.process === "function" // $FlowFixMe[incompatible-use] found when upgrading Flow + ? attributeConfig.process(nextProp) + : nextProp; + + (updatePayload || (updatePayload = {}))[propKey] = _nextValue; + } + } else { + // default: fallthrough case when nested properties are defined + removedKeys = null; + removedKeyCount = 0; // We think that attributeConfig is not CustomAttributeConfiguration at + // this point so we assume it must be AttributeConfiguration. + + updatePayload = diffNestedProperty( + updatePayload, + prevProp, + nextProp, + attributeConfig + ); + + if (removedKeyCount > 0 && updatePayload) { + restoreDeletedValuesInNestedArray( + updatePayload, + nextProp, + attributeConfig ); - throw Error("Rendered more hooks than during the previous render."); + removedKeys = null; + } + } + } // Also iterate through all the previous props to catch any that have been + // removed and make sure native gets the signal so it can reset them to the + // default. + + for (var _propKey in prevProps) { + if (nextProps[_propKey] !== undefined) { + continue; // we've already covered this key in the previous pass + } + + attributeConfig = validAttributes[_propKey]; + + if (!attributeConfig) { + continue; // not a valid native prop + } + + if (updatePayload && updatePayload[_propKey] !== undefined) { + // This was already updated to a diff result earlier. + continue; + } + + prevProp = prevProps[_propKey]; + + if (prevProp === undefined) { + continue; // was already empty anyway + } // Pattern match on: attributeConfig + + if ( + typeof attributeConfig !== "object" || + typeof attributeConfig.diff === "function" || + typeof attributeConfig.process === "function" + ) { + // case: CustomAttributeConfiguration | !Object + // Flag the leaf property for removal by sending a sentinel. + (updatePayload || (updatePayload = {}))[_propKey] = null; + + if (!removedKeys) { + removedKeys = {}; + } + + if (!removedKeys[_propKey]) { + removedKeys[_propKey] = true; + removedKeyCount++; + } + } else { + // default: + // This is a nested attribute configuration where all the properties + // were removed so we need to go through and clear out all of them. + updatePayload = clearNestedProperty( + updatePayload, + prevProp, + attributeConfig + ); } - currentHook = nextCurrentHook; - nextCurrentHook = { - memoizedState: currentHook.memoizedState, - baseState: currentHook.baseState, - baseQueue: currentHook.baseQueue, - queue: currentHook.queue, - next: null - }; - null === workInProgressHook - ? (currentlyRenderingFiber$1.memoizedState = workInProgressHook = - nextCurrentHook) - : (workInProgressHook = workInProgressHook.next = nextCurrentHook); } - return workInProgressHook; - } - function useThenable(thenable) { - var index = thenableIndexCounter; - thenableIndexCounter += 1; - null === thenableState && (thenableState = createThenableState()); - thenable = trackUsedThenable(thenableState, thenable, index); - index = currentlyRenderingFiber$1; - null === - (null === workInProgressHook - ? index.memoizedState - : workInProgressHook.next) && - ((index = index.alternate), - (ReactSharedInternals.H = - null !== index && null !== index.memoizedState - ? HooksDispatcherOnUpdateInDEV - : HooksDispatcherOnMountInDEV)); - return thenable; + + return updatePayload; } - function use(usable) { - if (null !== usable && "object" === typeof usable) { - if ("function" === typeof usable.then) return useThenable(usable); - if (usable.$$typeof === REACT_CONTEXT_TYPE) return readContext(usable); - } - throw Error("An unsupported type was passed to use(): " + String(usable)); + /** + * addProperties adds all the valid props to the payload after being processed. + */ + + function addProperties(updatePayload, props, validAttributes) { + // TODO: Fast path + return diffProperties( + updatePayload, + emptyObject$1, + props, + validAttributes + ); } - function useMemoCache(size) { - var memoCache = null, - updateQueue = currentlyRenderingFiber$1.updateQueue; - null !== updateQueue && (memoCache = updateQueue.memoCache); - if (null == memoCache) { - var current = currentlyRenderingFiber$1.alternate; - null !== current && - ((current = current.updateQueue), - null !== current && - ((current = current.memoCache), - null != current && - (memoCache = { - data: current.data.map(function (array) { - return array.slice(); - }), - index: 0 - }))); - } - null == memoCache && (memoCache = { data: [], index: 0 }); - null === updateQueue && - ((updateQueue = createFunctionComponentUpdateQueue()), - (currentlyRenderingFiber$1.updateQueue = updateQueue)); - updateQueue.memoCache = memoCache; - updateQueue = memoCache.data[memoCache.index]; - if (void 0 === updateQueue) - for ( - updateQueue = memoCache.data[memoCache.index] = Array(size), - current = 0; - current < size; - current++ - ) - updateQueue[current] = REACT_MEMO_CACHE_SENTINEL; - else - updateQueue.length !== size && - error$jscomp$0( - "Expected a constant size argument for each invocation of useMemoCache. The previous cache was allocated with size %s but size %s was requested.", - updateQueue.length, - size - ); - memoCache.index++; - return updateQueue; + /** + * clearProperties clears all the previous props by adding a null sentinel + * to the payload for each valid key. + */ + + function clearProperties(updatePayload, prevProps, validAttributes) { + // TODO: Fast path + return diffProperties( + updatePayload, + prevProps, + emptyObject$1, + validAttributes + ); } - function basicStateReducer(state, action) { - return "function" === typeof action ? action(state) : action; + + function create(props, validAttributes) { + return addProperties( + null, // updatePayload + props, + validAttributes + ); } - function mountReducer(reducer, initialArg, init) { - var hook = mountWorkInProgressHook(); - if (void 0 !== init) { - var initialState = init(initialArg); - shouldDoubleInvokeUserFnsInHooksDEV && - (setIsStrictModeForDevtools(!0), - init(initialArg), - setIsStrictModeForDevtools(!1)); - } else initialState = initialArg; - hook.memoizedState = hook.baseState = initialState; - reducer = { - pending: null, - lanes: 0, - dispatch: null, - lastRenderedReducer: reducer, - lastRenderedState: initialState - }; - hook.queue = reducer; - reducer = reducer.dispatch = dispatchReducerAction.bind( - null, - currentlyRenderingFiber$1, - reducer + function diff(prevProps, nextProps, validAttributes) { + return diffProperties( + null, // updatePayload + prevProps, + nextProps, + validAttributes ); - return [hook.memoizedState, reducer]; } - function updateReducer(reducer) { - var hook = updateWorkInProgressHook(); - return updateReducerImpl(hook, currentHook, reducer); + + /** + * In the future, we should cleanup callbacks by cancelling them instead of + * using this. + */ + function mountSafeCallback_NOT_REALLY_SAFE(context, callback) { + return function () { + if (!callback) { + return undefined; + } // This protects against createClass() components. + // We don't know if there is code depending on it. + // We intentionally don't use isMounted() because even accessing + // isMounted property on a React ES6 class will trigger a warning. + + if (typeof context.__isMounted === "boolean") { + if (!context.__isMounted) { + return undefined; + } + } // FIXME: there used to be other branches that protected + // against unmounted host components. But RN host components don't + // define isMounted() anymore, so those checks didn't do anything. + // They caused false positive warning noise so we removed them: + // https://github.com/facebook/react-native/issues/18868#issuecomment-413579095 + // However, this means that the callback is NOT guaranteed to be safe + // for host components. The solution we should implement is to make + // UIManager.measure() and similar calls truly cancelable. Then we + // can change our own code calling them to cancel when something unmounts. + + return callback.apply(context, arguments); + }; } - function updateReducerImpl(hook, current, reducer) { - var queue = hook.queue; - if (null === queue) - throw Error( - "Should have a queue. You are likely calling Hooks conditionally, which is not allowed. (https://react.dev/link/invalid-hook-call)" - ); - queue.lastRenderedReducer = reducer; - var baseQueue = hook.baseQueue, - pendingQueue = queue.pending; - if (null !== pendingQueue) { - if (null !== baseQueue) { - var baseFirst = baseQueue.next; - baseQueue.next = pendingQueue.next; - pendingQueue.next = baseFirst; + function warnForStyleProps(props, validAttributes) { + { + for (var key in validAttributes.style) { + if (!(validAttributes[key] || props[key] === undefined)) { + error( + "You are setting the style `{ %s" + + ": ... }` as a prop. You " + + "should nest it in a style object. " + + "E.g. `{ style: { %s" + + ": ... } }`", + key, + key + ); + } } - current.baseQueue !== baseQueue && - error$jscomp$0( - "Internal error: Expected work-in-progress queue to be a clone. This is a bug in React." - ); - current.baseQueue = baseQueue = pendingQueue; - queue.pending = null; } - pendingQueue = hook.baseState; - if (null === baseQueue) hook.memoizedState = pendingQueue; - else { - current = baseQueue.next; - var newBaseQueueFirst = (baseFirst = null), - newBaseQueueLast = null, - update = current, - didReadFromEntangledAsyncAction = !1; - do { - var updateLane = update.lane & ~OffscreenLane; - if ( - updateLane !== update.lane - ? (workInProgressRootRenderLanes & updateLane) === updateLane - : (renderLanes & updateLane) === updateLane - ) { - var revertLane = update.revertLane; - if (0 === revertLane) - null !== newBaseQueueLast && - (newBaseQueueLast = newBaseQueueLast.next = - { - lane: 0, - revertLane: 0, - action: update.action, - hasEagerState: update.hasEagerState, - eagerState: update.eagerState, - next: null - }), - updateLane === currentEntangledLane && - (didReadFromEntangledAsyncAction = !0); - else if ((renderLanes & revertLane) === revertLane) { - update = update.next; - revertLane === currentEntangledLane && - (didReadFromEntangledAsyncAction = !0); - continue; - } else - (updateLane = { - lane: 0, - revertLane: update.revertLane, - action: update.action, - hasEagerState: update.hasEagerState, - eagerState: update.eagerState, - next: null - }), - null === newBaseQueueLast - ? ((newBaseQueueFirst = newBaseQueueLast = updateLane), - (baseFirst = pendingQueue)) - : (newBaseQueueLast = newBaseQueueLast.next = updateLane), - (currentlyRenderingFiber$1.lanes |= revertLane), - (workInProgressRootSkippedLanes |= revertLane); - updateLane = update.action; - shouldDoubleInvokeUserFnsInHooksDEV && - reducer(pendingQueue, updateLane); - pendingQueue = update.hasEagerState - ? update.eagerState - : reducer(pendingQueue, updateLane); - } else - (revertLane = { - lane: updateLane, - revertLane: update.revertLane, - action: update.action, - hasEagerState: update.hasEagerState, - eagerState: update.eagerState, - next: null - }), - null === newBaseQueueLast - ? ((newBaseQueueFirst = newBaseQueueLast = revertLane), - (baseFirst = pendingQueue)) - : (newBaseQueueLast = newBaseQueueLast.next = revertLane), - (currentlyRenderingFiber$1.lanes |= updateLane), - (workInProgressRootSkippedLanes |= updateLane); - update = update.next; - } while (null !== update && update !== current); - null === newBaseQueueLast - ? (baseFirst = pendingQueue) - : (newBaseQueueLast.next = newBaseQueueFirst); - if ( - !objectIs(pendingQueue, hook.memoizedState) && - ((didReceiveUpdate = !0), - didReadFromEntangledAsyncAction && - ((reducer = currentEntangledActionThenable), null !== reducer)) - ) - throw reducer; - hook.memoizedState = pendingQueue; - hook.baseState = baseFirst; - hook.baseQueue = newBaseQueueLast; - queue.lastRenderedState = pendingQueue; - } - null === baseQueue && (queue.lanes = 0); - return [hook.memoizedState, queue.dispatch]; - } - function rerenderReducer(reducer) { - var hook = updateWorkInProgressHook(), - queue = hook.queue; - if (null === queue) - throw Error( - "Should have a queue. You are likely calling Hooks conditionally, which is not allowed. (https://react.dev/link/invalid-hook-call)" - ); - queue.lastRenderedReducer = reducer; - var dispatch = queue.dispatch, - lastRenderPhaseUpdate = queue.pending, - newState = hook.memoizedState; - if (null !== lastRenderPhaseUpdate) { - queue.pending = null; - var update = (lastRenderPhaseUpdate = lastRenderPhaseUpdate.next); - do - (newState = reducer(newState, update.action)), (update = update.next); - while (update !== lastRenderPhaseUpdate); - objectIs(newState, hook.memoizedState) || (didReceiveUpdate = !0); - hook.memoizedState = newState; - null === hook.baseQueue && (hook.baseState = newState); - queue.lastRenderedState = newState; - } - return [newState, dispatch]; } - function mountSyncExternalStore(subscribe, getSnapshot) { - var fiber = currentlyRenderingFiber$1, - hook = mountWorkInProgressHook(); - var nextSnapshot = getSnapshot(); - if (!didWarnUncachedGetSnapshot) { - var cachedSnapshot = getSnapshot(); - objectIs(nextSnapshot, cachedSnapshot) || - (error$jscomp$0( - "The result of getSnapshot should be cached to avoid an infinite loop" - ), - (didWarnUncachedGetSnapshot = !0)); + + var ReactNativeFiberHostComponent = /*#__PURE__*/ (function () { + function ReactNativeFiberHostComponent( + tag, + viewConfig, + internalInstanceHandleDEV + ) { + this._children = void 0; + this._nativeTag = void 0; + this._internalFiberInstanceHandleDEV = void 0; + this.viewConfig = void 0; + this._nativeTag = tag; + this._children = []; + this.viewConfig = viewConfig; + + { + this._internalFiberInstanceHandleDEV = internalInstanceHandleDEV; + } } - if (null === workInProgressRoot) - throw Error( - "Expected a work-in-progress root. This is a bug in React. Please file an issue." + + var _proto = ReactNativeFiberHostComponent.prototype; + + _proto.blur = function blur() { + ReactNativePrivateInterface.TextInputState.blurTextInput(this); + }; + + _proto.focus = function focus() { + ReactNativePrivateInterface.TextInputState.focusTextInput(this); + }; + + _proto.measure = function measure(callback) { + ReactNativePrivateInterface.UIManager.measure( + this._nativeTag, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) ); - 0 !== - (workInProgressRootRenderLanes & - (InputContinuousHydrationLane | - InputContinuousLane | - DefaultHydrationLane | - DefaultLane)) || - pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot); - hook.memoizedState = nextSnapshot; - cachedSnapshot = { value: nextSnapshot, getSnapshot: getSnapshot }; - hook.queue = cachedSnapshot; - mountEffect( - subscribeToStore.bind(null, fiber, cachedSnapshot, subscribe), - [subscribe] - ); - fiber.flags |= 2048; - pushEffect( - HasEffect | Passive, - updateStoreInstance.bind( - null, - fiber, - cachedSnapshot, - nextSnapshot, - getSnapshot - ), - { destroy: void 0 }, - null - ); - return nextSnapshot; - } - function updateSyncExternalStore(subscribe, getSnapshot) { - var fiber = currentlyRenderingFiber$1, - hook = updateWorkInProgressHook(); - var nextSnapshot = getSnapshot(); - if (!didWarnUncachedGetSnapshot) { - var cachedSnapshot = getSnapshot(); - objectIs(nextSnapshot, cachedSnapshot) || - (error$jscomp$0( - "The result of getSnapshot should be cached to avoid an infinite loop" - ), - (didWarnUncachedGetSnapshot = !0)); - } - if ( - (cachedSnapshot = !objectIs( - (currentHook || hook).memoizedState, - nextSnapshot - )) - ) - (hook.memoizedState = nextSnapshot), (didReceiveUpdate = !0); - hook = hook.queue; - var create = subscribeToStore.bind(null, fiber, hook, subscribe); - updateEffectImpl(2048, Passive, create, [subscribe]); - if ( - hook.getSnapshot !== getSnapshot || - cachedSnapshot || - (null !== workInProgressHook && - workInProgressHook.memoizedState.tag & HasEffect) + }; + + _proto.measureInWindow = function measureInWindow(callback) { + ReactNativePrivateInterface.UIManager.measureInWindow( + this._nativeTag, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + }; + + _proto.measureLayout = function measureLayout( + relativeToNativeNode, + onSuccess, + onFail + /* currently unused */ ) { - fiber.flags |= 2048; - pushEffect( - HasEffect | Passive, - updateStoreInstance.bind( - null, - fiber, - hook, - nextSnapshot, - getSnapshot - ), - { destroy: void 0 }, - null + var relativeNode; + + if (typeof relativeToNativeNode === "number") { + // Already a node handle + relativeNode = relativeToNativeNode; + } else { + var nativeNode = relativeToNativeNode; + + if (nativeNode._nativeTag) { + relativeNode = nativeNode._nativeTag; + } + } + + if (relativeNode == null) { + { + error( + "Warning: ref.measureLayout must be called with a node handle or a ref to a native component." + ); + } + + return; + } + + ReactNativePrivateInterface.UIManager.measureLayout( + this._nativeTag, + relativeNode, + mountSafeCallback_NOT_REALLY_SAFE(this, onFail), + mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) ); - if (null === workInProgressRoot) - throw Error( - "Expected a work-in-progress root. This is a bug in React. Please file an issue." + }; + + _proto.setNativeProps = function setNativeProps(nativeProps) { + { + warnForStyleProps(nativeProps, this.viewConfig.validAttributes); + } + + var updatePayload = create( + nativeProps, + this.viewConfig.validAttributes + ); // Avoid the overhead of bridge calls if there's no update. + // This is an expensive no-op for Android, and causes an unnecessary + // view invalidation for certain components (eg RCTTextInput) on iOS. + + if (updatePayload != null) { + ReactNativePrivateInterface.UIManager.updateView( + this._nativeTag, + this.viewConfig.uiViewClassName, + updatePayload ); - 0 !== - (renderLanes & - (InputContinuousHydrationLane | - InputContinuousLane | - DefaultHydrationLane | - DefaultLane)) || - pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot); + } + }; + + return ReactNativeFiberHostComponent; + })(); + + // This module only exists as an ESM wrapper around the external CommonJS + var scheduleCallback$2 = Scheduler.unstable_scheduleCallback; + var cancelCallback$1 = Scheduler.unstable_cancelCallback; + var shouldYield = Scheduler.unstable_shouldYield; + var requestPaint = Scheduler.unstable_requestPaint; + var now$1 = Scheduler.unstable_now; + var ImmediatePriority = Scheduler.unstable_ImmediatePriority; + var UserBlockingPriority = Scheduler.unstable_UserBlockingPriority; + var NormalPriority = Scheduler.unstable_NormalPriority; + var IdlePriority = Scheduler.unstable_IdlePriority; // this doesn't actually exist on the scheduler, but it *does* + + // Helpers to patch console.logs to avoid logging during side-effect free + // replaying on render function. This currently only patches the object + // lazily which won't cover if the log function was extracted eagerly. + // We could also eagerly patch the method. + var disabledDepth = 0; + var prevLog; + var prevInfo; + var prevWarn; + var prevError; + var prevGroup; + var prevGroupCollapsed; + var prevGroupEnd; + + function disabledLog() {} + + disabledLog.__reactDisabledLog = true; + function disableLogs() { + { + if (disabledDepth === 0) { + /* eslint-disable react-internal/no-production-logging */ + prevLog = console.log; + prevInfo = console.info; + prevWarn = console.warn; + prevError = console.error; + prevGroup = console.group; + prevGroupCollapsed = console.groupCollapsed; + prevGroupEnd = console.groupEnd; // https://github.com/facebook/react/issues/19099 + + var props = { + configurable: true, + enumerable: true, + value: disabledLog, + writable: true + }; // $FlowFixMe[cannot-write] Flow thinks console is immutable. + + Object.defineProperties(console, { + info: props, + log: props, + warn: props, + error: props, + group: props, + groupCollapsed: props, + groupEnd: props + }); + /* eslint-enable react-internal/no-production-logging */ + } + + disabledDepth++; } - return nextSnapshot; - } - function pushStoreConsistencyCheck(fiber, getSnapshot, renderedSnapshot) { - fiber.flags |= 16384; - fiber = { getSnapshot: getSnapshot, value: renderedSnapshot }; - getSnapshot = currentlyRenderingFiber$1.updateQueue; - null === getSnapshot - ? ((getSnapshot = createFunctionComponentUpdateQueue()), - (currentlyRenderingFiber$1.updateQueue = getSnapshot), - (getSnapshot.stores = [fiber])) - : ((renderedSnapshot = getSnapshot.stores), - null === renderedSnapshot - ? (getSnapshot.stores = [fiber]) - : renderedSnapshot.push(fiber)); - } - function updateStoreInstance(fiber, inst, nextSnapshot, getSnapshot) { - inst.value = nextSnapshot; - inst.getSnapshot = getSnapshot; - checkIfSnapshotChanged(inst) && forceStoreRerender(fiber); } - function subscribeToStore(fiber, inst, subscribe) { - return subscribe(function () { - checkIfSnapshotChanged(inst) && forceStoreRerender(fiber); - }); + function reenableLogs() { + { + disabledDepth--; + + if (disabledDepth === 0) { + /* eslint-disable react-internal/no-production-logging */ + var props = { + configurable: true, + enumerable: true, + writable: true + }; // $FlowFixMe[cannot-write] Flow thinks console is immutable. + + Object.defineProperties(console, { + log: assign({}, props, { + value: prevLog + }), + info: assign({}, props, { + value: prevInfo + }), + warn: assign({}, props, { + value: prevWarn + }), + error: assign({}, props, { + value: prevError + }), + group: assign({}, props, { + value: prevGroup + }), + groupCollapsed: assign({}, props, { + value: prevGroupCollapsed + }), + groupEnd: assign({}, props, { + value: prevGroupEnd + }) + }); + /* eslint-enable react-internal/no-production-logging */ + } + + if (disabledDepth < 0) { + error( + "disabledDepth fell below zero. " + + "This is a bug in React. Please file an issue." + ); + } + } } - function checkIfSnapshotChanged(inst) { - var latestGetSnapshot = inst.getSnapshot; - inst = inst.value; + + 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://react.dev/link/react-devtools" + ); + } // DevTools exists, even though it doesn't support Fiber. + + return true; + } + try { - var nextValue = latestGetSnapshot(); - return !objectIs(inst, nextValue); - } catch (error$4) { - return !0; + if (enableSchedulingProfiler); + + 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); + } } - } - function forceStoreRerender(fiber) { - var root = enqueueConcurrentRenderForLane(fiber, SyncLane); - null !== root && scheduleUpdateOnFiber(root, fiber, SyncLane); - } - function mountStateImpl(initialState) { - var hook = mountWorkInProgressHook(); - if ("function" === typeof initialState) { - var initialStateInitializer = initialState; - initialState = initialStateInitializer(); - shouldDoubleInvokeUserFnsInHooksDEV && - (setIsStrictModeForDevtools(!0), - initialStateInitializer(), - setIsStrictModeForDevtools(!1)); + + if (hook.checkDCE) { + // This is the real DevTools. + return true; + } else { + // This is likely a hook installed by Fast Refresh runtime. + return false; } - hook.memoizedState = hook.baseState = initialState; - hook.queue = { - pending: null, - lanes: 0, - dispatch: null, - lastRenderedReducer: basicStateReducer, - lastRenderedState: initialState - }; - return hook; - } - function mountState(initialState) { - initialState = mountStateImpl(initialState); - var queue = initialState.queue, - dispatch = dispatchSetState.bind( - null, - currentlyRenderingFiber$1, - queue - ); - queue.dispatch = dispatch; - return [initialState.memoizedState, dispatch]; - } - function mountOptimistic(passthrough) { - var hook = mountWorkInProgressHook(); - hook.memoizedState = hook.baseState = passthrough; - var queue = { - pending: null, - lanes: 0, - dispatch: null, - lastRenderedReducer: null, - lastRenderedState: null - }; - hook.queue = queue; - hook = dispatchOptimisticSetState.bind( - null, - currentlyRenderingFiber$1, - !0, - queue - ); - queue.dispatch = hook; - return [passthrough, hook]; - } - function updateOptimistic(passthrough, reducer) { - var hook = updateWorkInProgressHook(); - return updateOptimisticImpl(hook, currentHook, passthrough, reducer); - } - function updateOptimisticImpl(hook, current, passthrough, reducer) { - hook.baseState = passthrough; - return updateReducerImpl( - hook, - currentHook, - "function" === typeof reducer ? reducer : basicStateReducer - ); - } - function rerenderOptimistic(passthrough, reducer) { - var hook = updateWorkInProgressHook(); - if (null !== currentHook) - return updateOptimisticImpl(hook, currentHook, passthrough, reducer); - hook.baseState = passthrough; - return [passthrough, hook.queue.dispatch]; } - function dispatchActionState( - fiber, - actionQueue, - setPendingState, - setState, - payload - ) { - if (isRenderPhaseUpdate(fiber)) - throw Error("Cannot update form state while rendering."); - fiber = actionQueue.action; - if (null !== fiber) { - var actionNode = { - payload: payload, - action: fiber, - next: null, - isTransition: !0, - status: "pending", - value: null, - reason: null, - listeners: [], - then: function (listener) { - actionNode.listeners.push(listener); + 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); + } } - }; - null !== ReactSharedInternals.T - ? setPendingState(!0) - : (actionNode.isTransition = !1); - setState(actionNode); - setPendingState = actionQueue.pending; - null === setPendingState - ? ((actionNode.next = actionQueue.pending = actionNode), - runActionStateAction(actionQueue, actionNode)) - : ((actionNode.next = setPendingState.next), - (actionQueue.pending = setPendingState.next = actionNode)); - } - } - function runActionStateAction(actionQueue, node) { - var action = node.action, - payload = node.payload, - prevState = actionQueue.state; - if (node.isTransition) { - var prevTransition = ReactSharedInternals.T, - currentTransition = {}; - ReactSharedInternals.T = currentTransition; - ReactSharedInternals.T._updatedFibers = new Set(); + } + } + } + function onCommitRoot(root, eventPriority) { + if ( + injectedHook && + typeof injectedHook.onCommitFiberRoot === "function" + ) { try { - var returnValue = action(prevState, payload), - onStartTransitionFinish = ReactSharedInternals.S; - null !== onStartTransitionFinish && - onStartTransitionFinish(currentTransition, returnValue); - handleActionReturnValue(actionQueue, node, returnValue); - } catch (error$5) { - onActionError(actionQueue, node, error$5); - } finally { - (ReactSharedInternals.T = prevTransition), - null === prevTransition && - currentTransition._updatedFibers && - ((actionQueue = currentTransition._updatedFibers.size), - currentTransition._updatedFibers.clear(), - 10 < actionQueue && - warn( - "Detected a large number of updates inside startTransition. If this is due to a subscription please re-write it to use React provided hooks. Otherwise concurrent mode guarantees are off the table." - )); - } - } else + 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 + ); + } + } catch (err) { + { + if (!hasLoggedError) { + hasLoggedError = true; + + error("React instrumentation encountered an error: %s", err); + } + } + } + } + } + function onPostCommitRoot(root) { + if ( + injectedHook && + typeof injectedHook.onPostCommitFiberRoot === "function" + ) { try { - (currentTransition = action(prevState, payload)), - handleActionReturnValue(actionQueue, node, currentTransition); - } catch (error$6) { - onActionError(actionQueue, node, error$6); - } - } - function handleActionReturnValue(actionQueue, node, returnValue) { - null !== returnValue && - "object" === typeof returnValue && - "function" === typeof returnValue.then - ? (returnValue.then( - function (nextState) { - onActionSuccess(actionQueue, node, nextState); - }, - function (error) { - return onActionError(actionQueue, node, error); + injectedHook.onPostCommitFiberRoot(rendererID, root); + } catch (err) { + { + if (!hasLoggedError) { + hasLoggedError = true; + + error("React instrumentation encountered an error: %s", err); } - ), - node.isTransition || - error$jscomp$0( - "An async function was passed to useActionState, but it was dispatched outside of an action context. This is likely not what you intended. Either pass the dispatch function to an `action` prop, or dispatch manually inside `startTransition`" - )) - : onActionSuccess(actionQueue, node, returnValue); - } - function onActionSuccess(actionQueue, actionNode, nextState) { - actionNode.status = "fulfilled"; - actionNode.value = nextState; - notifyActionListeners(actionNode); - actionQueue.state = nextState; - actionNode = actionQueue.pending; - null !== actionNode && - ((nextState = actionNode.next), - nextState === actionNode - ? (actionQueue.pending = null) - : ((nextState = nextState.next), - (actionNode.next = nextState), - runActionStateAction(actionQueue, nextState))); - } - function onActionError(actionQueue, actionNode, error) { - var last = actionQueue.pending; - actionQueue.pending = null; - if (null !== last) { - last = last.next; - do - (actionNode.status = "rejected"), - (actionNode.reason = error), - notifyActionListeners(actionNode), - (actionNode = actionNode.next); - while (actionNode !== last); - } - actionQueue.action = null; - } - function notifyActionListeners(actionNode) { - actionNode = actionNode.listeners; - for (var i = 0; i < actionNode.length; i++) (0, actionNode[i])(); - } - function actionStateReducer(oldState, newState) { - return newState; - } - function mountActionState(action, initialStateProp) { - var stateHook = mountWorkInProgressHook(); - stateHook.memoizedState = stateHook.baseState = initialStateProp; - var stateQueue = { - pending: null, - lanes: 0, - dispatch: null, - lastRenderedReducer: actionStateReducer, - lastRenderedState: initialStateProp - }; - stateHook.queue = stateQueue; - stateHook = dispatchSetState.bind( - null, - currentlyRenderingFiber$1, - stateQueue - ); - stateQueue.dispatch = stateHook; - stateQueue = mountStateImpl(!1); - var setPendingState = dispatchOptimisticSetState.bind( - null, - currentlyRenderingFiber$1, - !1, - stateQueue.queue - ); - stateQueue = mountWorkInProgressHook(); - var actionQueue = { - state: initialStateProp, - dispatch: null, - action: action, - pending: null - }; - stateQueue.queue = actionQueue; - stateHook = dispatchActionState.bind( - null, - currentlyRenderingFiber$1, - actionQueue, - setPendingState, - stateHook - ); - actionQueue.dispatch = stateHook; - stateQueue.memoizedState = action; - return [initialStateProp, stateHook, !1]; - } - function updateActionState(action) { - var stateHook = updateWorkInProgressHook(); - return updateActionStateImpl(stateHook, currentHook, action); - } - function updateActionStateImpl(stateHook, currentStateHook, action) { - currentStateHook = updateReducerImpl( - stateHook, - currentStateHook, - actionStateReducer - )[0]; - stateHook = updateReducer(basicStateReducer)[0]; - currentStateHook = - "object" === typeof currentStateHook && - null !== currentStateHook && - "function" === typeof currentStateHook.then - ? useThenable(currentStateHook) - : currentStateHook; - var actionQueueHook = updateWorkInProgressHook(), - actionQueue = actionQueueHook.queue, - dispatch = actionQueue.dispatch; - action !== actionQueueHook.memoizedState && - ((currentlyRenderingFiber$1.flags |= 2048), - pushEffect( - HasEffect | Passive, - actionStateActionEffect.bind(null, actionQueue, action), - { destroy: void 0 }, - null - )); - return [currentStateHook, dispatch, stateHook]; - } - function actionStateActionEffect(actionQueue, action) { - actionQueue.action = action; - } - function rerenderActionState(action) { - var stateHook = updateWorkInProgressHook(), - currentStateHook = currentHook; - if (null !== currentStateHook) - return updateActionStateImpl(stateHook, currentStateHook, action); - updateWorkInProgressHook(); - stateHook = stateHook.memoizedState; - currentStateHook = updateWorkInProgressHook(); - var dispatch = currentStateHook.queue.dispatch; - currentStateHook.memoizedState = action; - return [stateHook, dispatch, !1]; + } + } + } } - function pushEffect(tag, create, inst, deps) { - tag = { tag: tag, create: create, inst: inst, deps: deps, next: null }; - create = currentlyRenderingFiber$1.updateQueue; - null === create - ? ((create = createFunctionComponentUpdateQueue()), - (currentlyRenderingFiber$1.updateQueue = create), - (create.lastEffect = tag.next = tag)) - : ((inst = create.lastEffect), - null === inst - ? (create.lastEffect = tag.next = tag) - : ((deps = inst.next), - (inst.next = tag), - (tag.next = deps), - (create.lastEffect = tag))); - return tag; + 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 mountRef(initialValue) { - var hook = mountWorkInProgressHook(); - initialValue = { current: initialValue }; - return (hook.memoizedState = initialValue); + function setIsStrictModeForDevtools(newIsStrictMode) { + { + if (newIsStrictMode) { + disableLogs(); + } else { + reenableLogs(); + } + } + } // Profiler API hooks + + function injectProfilingHooks(profilingHooks) {} + + function getLaneLabelMap() { + { + return null; + } } - function mountEffectImpl(fiberFlags, hookFlags, create, deps) { - var hook = mountWorkInProgressHook(); - currentlyRenderingFiber$1.flags |= fiberFlags; - hook.memoizedState = pushEffect( - HasEffect | hookFlags, - create, - { destroy: void 0 }, - void 0 === deps ? null : deps - ); + + var NoMode = + /* */ + 0; // TODO: Remove ConcurrentMode by reading from the root tag instead + + var ConcurrentMode = + /* */ + 1; + var ProfileMode = + /* */ + 2; + var StrictLegacyMode = + /* */ + 8; + var StrictEffectsMode = + /* */ + 16; + var NoStrictPassiveEffectsMode = + /* */ + 64; + + // TODO: This is pretty well supported by browsers. Maybe we can drop it. + var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback; // Count leading zeros. + // 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 clz32Fallback(x) { + var asUint = x >>> 0; + + if (asUint === 0) { + return 32; + } + + return (31 - ((log(asUint) / LN2) | 0)) | 0; } - function updateEffectImpl(fiberFlags, hookFlags, create, deps) { - var hook = updateWorkInProgressHook(); - deps = void 0 === deps ? null : deps; - var inst = hook.memoizedState.inst; - null !== currentHook && - null !== deps && - areHookInputsEqual(deps, currentHook.memoizedState.deps) - ? (hook.memoizedState = pushEffect(hookFlags, create, inst, deps)) - : ((currentlyRenderingFiber$1.flags |= fiberFlags), - (hook.memoizedState = pushEffect( - HasEffect | hookFlags, - create, - inst, - deps - ))); + + // If those values are changed that package should be rebuilt and redeployed. + + var TotalLanes = 31; + var NoLanes = + /* */ + 0; + var NoLane = + /* */ + 0; + var SyncHydrationLane = + /* */ + 1; + var SyncLane = + /* */ + 2; + var SyncLaneIndex = 1; + var InputContinuousHydrationLane = + /* */ + 4; + var InputContinuousLane = + /* */ + 8; + var DefaultHydrationLane = + /* */ + 16; + var DefaultLane = + /* */ + 32; + var SyncUpdateLanes = SyncLane | InputContinuousLane | DefaultLane; + var TransitionHydrationLane = + /* */ + 64; + var TransitionLanes = + /* */ + 4194176; + var TransitionLane1 = + /* */ + 128; + var TransitionLane2 = + /* */ + 256; + var TransitionLane3 = + /* */ + 512; + var TransitionLane4 = + /* */ + 1024; + var TransitionLane5 = + /* */ + 2048; + var TransitionLane6 = + /* */ + 4096; + var TransitionLane7 = + /* */ + 8192; + var TransitionLane8 = + /* */ + 16384; + var TransitionLane9 = + /* */ + 32768; + var TransitionLane10 = + /* */ + 65536; + var TransitionLane11 = + /* */ + 131072; + var TransitionLane12 = + /* */ + 262144; + var TransitionLane13 = + /* */ + 524288; + var TransitionLane14 = + /* */ + 1048576; + var TransitionLane15 = + /* */ + 2097152; + var RetryLanes = + /* */ + 62914560; + var RetryLane1 = + /* */ + 4194304; + var RetryLane2 = + /* */ + 8388608; + var RetryLane3 = + /* */ + 16777216; + var RetryLane4 = + /* */ + 33554432; + var SomeRetryLane = RetryLane1; + var SelectiveHydrationLane = + /* */ + 67108864; + var NonIdleLanes = + /* */ + 134217727; + var IdleHydrationLane = + /* */ + 134217728; + var IdleLane = + /* */ + 268435456; + var OffscreenLane = + /* */ + 536870912; + var DeferredLane = + /* */ + 1073741824; // Any lane that might schedule an update. This is used to detect infinite + // update loops, so it doesn't include hydration lanes or retries. + + var UpdateLanes = + SyncLane | InputContinuousLane | DefaultLane | TransitionLanes; // This function is used for the experimental timeline (react-devtools-timeline) + var NoTimestamp = -1; + var nextTransitionLane = TransitionLane1; + var nextRetryLane = RetryLane1; + + function getHighestPriorityLanes(lanes) { + { + var pendingSyncLanes = lanes & SyncUpdateLanes; + + if (pendingSyncLanes !== 0) { + return pendingSyncLanes; + } + } + + switch (getHighestPriorityLane(lanes)) { + case SyncHydrationLane: + return SyncHydrationLane; + + case SyncLane: + return SyncLane; + + 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: + return lanes & TransitionLanes; + + case RetryLane1: + case RetryLane2: + case RetryLane3: + case RetryLane4: + return lanes & RetryLanes; + + case SelectiveHydrationLane: + return SelectiveHydrationLane; + + case IdleHydrationLane: + return IdleHydrationLane; + + case IdleLane: + return IdleLane; + + case OffscreenLane: + return OffscreenLane; + + case DeferredLane: + // This shouldn't be reachable because deferred work is always entangled + // with something else. + return NoLanes; + + 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; + } } - function mountEffect(create, deps) { - 0 !== (currentlyRenderingFiber$1.mode & 16) && - 0 === (currentlyRenderingFiber$1.mode & 64) - ? mountEffectImpl(142608384, Passive, create, deps) - : mountEffectImpl(8390656, Passive, create, deps); + + function getNextLanes(root, wipLanes) { + // Early bailout if there's no pending work left. + var pendingLanes = root.pendingLanes; + + if (pendingLanes === NoLanes) { + return NoLanes; + } + + 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. + + var nonIdlePendingLanes = pendingLanes & NonIdleLanes; + + if (nonIdlePendingLanes !== NoLanes) { + var nonIdleUnblockedLanes = nonIdlePendingLanes & ~suspendedLanes; + + 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; + + if (unblockedLanes !== NoLanes) { + nextLanes = getHighestPriorityLanes(unblockedLanes); + } else { + if (pingedLanes !== NoLanes) { + nextLanes = getHighestPriorityLanes(pingedLanes); + } + } + } + + 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. + + 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; + } + } + + return nextLanes; } - function mountLayoutEffect(create, deps) { - var fiberFlags = 4194308; - 0 !== (currentlyRenderingFiber$1.mode & 16) && (fiberFlags |= 67108864); - return mountEffectImpl(fiberFlags, Layout, create, deps); + function getEntangledLanes(root, renderLanes) { + var entangledLanes = renderLanes; + + if ((entangledLanes & 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. + entangledLanes |= entangledLanes & 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, + // we should ensure that there is no partial work at the + // time we apply the entanglement. + + var allEntangledLanes = root.entangledLanes; + + if (allEntangledLanes !== NoLanes) { + var entanglements = root.entanglements; + var lanes = entangledLanes & allEntangledLanes; + + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + entangledLanes |= entanglements[index]; + lanes &= ~lane; + } + } + + return entangledLanes; } - function imperativeHandleEffect(create, ref) { - if ("function" === typeof ref) { - create = create(); - var refCleanup = ref(create); - return function () { - "function" === typeof refCleanup ? refCleanup() : ref(null); - }; + + function computeExpirationTime(lane, currentTime) { + switch (lane) { + case SyncHydrationLane: + 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 + syncLaneExpirationMs; + + 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: + return currentTime + transitionLaneExpirationMs; + + case RetryLane1: + case RetryLane2: + case RetryLane3: + case RetryLane4: + // 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: + case DeferredLane: + // Anything idle priority or lower should never expire. + return NoTimestamp; + + default: + { + error("Should have found matching lanes. This is a bug in React."); + } + + return NoTimestamp; } - if (null !== ref && void 0 !== ref) - return ( - ref.hasOwnProperty("current") || - error$jscomp$0( - "Expected useImperativeHandle() first argument to either be a ref callback or React.createRef() object. Instead received: %s.", - "an object with keys {" + Object.keys(ref).join(", ") + "}" - ), - (create = create()), - (ref.current = create), - function () { - ref.current = null; + } + + 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. + // TODO: We should be able to replace this with upgradePendingLanesToSync + // + // We exclude retry lanes because those must always be time sliced, in order + // to unwrap uncached promises. + // TODO: Write a test for this + + var lanes = pendingLanes & ~RetryLanes; + + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + var expirationTime = expirationTimes[index]; + + if (expirationTime === NoTimestamp) { + // Found a pending lane with no expiration time. If it's not suspended, or + // if it's pinged, assume it's CPU-bound. Compute a new expiration time + // using the current time. + if ( + (lane & suspendedLanes) === NoLanes || + (lane & pingedLanes) !== NoLanes + ) { + // Assumes timestamps are monotonically increasing. + expirationTimes[index] = computeExpirationTime(lane, currentTime); } - ); + } else if (expirationTime <= currentTime) { + // This lane expired + root.expiredLanes |= lane; + } + + lanes &= ~lane; + } + } // This returns the highest priority pending lanes regardless of whether they + function getLanesToRetrySynchronouslyOnError( + root, + originallyAttemptedLanes + ) { + if (root.errorRecoveryDisabledLanes & originallyAttemptedLanes) { + // The error recovery mechanism is disabled until these lanes are cleared. + return NoLanes; + } + + var everythingButOffscreen = root.pendingLanes & ~OffscreenLane; + + if (everythingButOffscreen !== NoLanes) { + return everythingButOffscreen; + } + + if (everythingButOffscreen & OffscreenLane) { + return OffscreenLane; + } + + return NoLanes; } - function mountImperativeHandle(ref, create, deps) { - "function" !== typeof create && - error$jscomp$0( - "Expected useImperativeHandle() second argument to be a function that creates a handle. Instead received: %s.", - null !== create ? typeof create : "null" - ); - deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; - var fiberFlags = 4194308; - 0 !== (currentlyRenderingFiber$1.mode & 16) && (fiberFlags |= 67108864); - mountEffectImpl( - fiberFlags, - Layout, - imperativeHandleEffect.bind(null, create, ref), - deps - ); + function includesSyncLane(lanes) { + return (lanes & (SyncLane | SyncHydrationLane)) !== NoLanes; } - function updateImperativeHandle(ref, create, deps) { - "function" !== typeof create && - error$jscomp$0( - "Expected useImperativeHandle() second argument to be a function that creates a handle. Instead received: %s.", - null !== create ? typeof create : "null" - ); - deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; - updateEffectImpl( - 4, - Layout, - imperativeHandleEffect.bind(null, create, ref), - deps - ); + function includesNonIdleWork(lanes) { + return (lanes & NonIdleLanes) !== NoLanes; } - function mountCallback(callback, deps) { - mountWorkInProgressHook().memoizedState = [ - callback, - void 0 === deps ? null : deps - ]; - return callback; + function includesOnlyRetries(lanes) { + return (lanes & RetryLanes) === lanes; } - function updateCallback(callback, deps) { - var hook = updateWorkInProgressHook(); - deps = void 0 === deps ? null : deps; - var prevState = hook.memoizedState; - if (null !== deps && areHookInputsEqual(deps, prevState[1])) - return prevState[0]; - hook.memoizedState = [callback, deps]; - return callback; + function includesOnlyNonUrgentLanes(lanes) { + // TODO: Should hydration lanes be included here? This function is only + // used in `updateDeferredValueImpl`. + var UrgentLanes = SyncLane | InputContinuousLane | DefaultLane; + return (lanes & UrgentLanes) === NoLanes; } - function mountMemo(nextCreate, deps) { - var hook = mountWorkInProgressHook(); - deps = void 0 === deps ? null : deps; - var nextValue = nextCreate(); - shouldDoubleInvokeUserFnsInHooksDEV && - (setIsStrictModeForDevtools(!0), - nextCreate(), - setIsStrictModeForDevtools(!1)); - hook.memoizedState = [nextValue, deps]; - return nextValue; + function includesOnlyTransitions(lanes) { + return (lanes & TransitionLanes) === lanes; } - function updateMemo(nextCreate, deps) { - var hook = updateWorkInProgressHook(); - deps = void 0 === deps ? null : deps; - var prevState = hook.memoizedState; - if (null !== deps && areHookInputsEqual(deps, prevState[1])) - return prevState[0]; - prevState = nextCreate(); - shouldDoubleInvokeUserFnsInHooksDEV && - (setIsStrictModeForDevtools(!0), - nextCreate(), - setIsStrictModeForDevtools(!1)); - hook.memoizedState = [prevState, deps]; - return prevState; + function includesBlockingLane(root, lanes) { + var SyncDefaultLanes = + InputContinuousHydrationLane | + InputContinuousLane | + DefaultHydrationLane | + DefaultLane; + return (lanes & SyncDefaultLanes) !== NoLanes; } - function mountDeferredValue(value, initialValue) { - var hook = mountWorkInProgressHook(); - return mountDeferredValueImpl(hook, value, initialValue); + function includesExpiredLane(root, lanes) { + // This is a separate check from includesBlockingLane because a lane can + // expire after a render has already started. + return (lanes & root.expiredLanes) !== NoLanes; } - function updateDeferredValue(value, initialValue) { - var hook = updateWorkInProgressHook(); - return updateDeferredValueImpl( - hook, - currentHook.memoizedState, - value, - initialValue - ); + function isTransitionLane(lane) { + return (lane & TransitionLanes) !== NoLanes; } - function rerenderDeferredValue(value, initialValue) { - var hook = updateWorkInProgressHook(); - return null === currentHook - ? mountDeferredValueImpl(hook, value, initialValue) - : updateDeferredValueImpl( - hook, - currentHook.memoizedState, - value, - initialValue - ); + 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; + + if ((nextTransitionLane & TransitionLanes) === NoLanes) { + nextTransitionLane = TransitionLane1; + } + + return lane; } - function mountDeferredValueImpl(hook, value, initialValue) { - if (void 0 === initialValue || 0 !== (renderLanes & DeferredLane)) - return (hook.memoizedState = value); - hook.memoizedState = initialValue; - hook = requestDeferredLane(); - currentlyRenderingFiber$1.lanes |= hook; - workInProgressRootSkippedLanes |= hook; - return initialValue; + function claimNextRetryLane() { + var lane = nextRetryLane; + nextRetryLane <<= 1; + + if ((nextRetryLane & RetryLanes) === NoLanes) { + nextRetryLane = RetryLane1; + } + + return lane; } - function updateDeferredValueImpl(hook, prevValue, value, initialValue) { - if (objectIs(value, prevValue)) return value; - if (null !== currentTreeHiddenStackCursor.current) - return ( - (hook = mountDeferredValueImpl(hook, value, initialValue)), - objectIs(hook, prevValue) || (didReceiveUpdate = !0), - hook - ); - if (0 === (renderLanes & (SyncLane | InputContinuousLane | DefaultLane))) - return (didReceiveUpdate = !0), (hook.memoizedState = value); - hook = requestDeferredLane(); - currentlyRenderingFiber$1.lanes |= hook; - workInProgressRootSkippedLanes |= hook; - return prevValue; + function getHighestPriorityLane(lanes) { + return lanes & -lanes; } - function startTransition( - fiber, - queue, - pendingState, - finishedState, - callback - ) { - var previousPriority = currentUpdatePriority; - currentUpdatePriority = - 0 !== previousPriority && previousPriority < ContinuousEventPriority - ? previousPriority - : ContinuousEventPriority; - var prevTransition = ReactSharedInternals.T, - currentTransition = {}; - ReactSharedInternals.T = currentTransition; - dispatchOptimisticSetState(fiber, !1, queue, pendingState); - currentTransition._updatedFibers = new Set(); - try { - var returnValue = callback(), - onStartTransitionFinish = ReactSharedInternals.S; - null !== onStartTransitionFinish && - onStartTransitionFinish(currentTransition, returnValue); - if ( - null !== returnValue && - "object" === typeof returnValue && - "function" === typeof returnValue.then - ) { - var thenableForFinishedState = chainThenableValue( - returnValue, - finishedState - ); - dispatchSetState(fiber, queue, thenableForFinishedState); - } else dispatchSetState(fiber, queue, finishedState); - } catch (error$7) { - dispatchSetState(fiber, queue, { - then: function () {}, - status: "rejected", - reason: error$7 - }); - } finally { - (currentUpdatePriority = previousPriority), - (ReactSharedInternals.T = prevTransition), - null === prevTransition && - currentTransition._updatedFibers && - ((fiber = currentTransition._updatedFibers.size), - currentTransition._updatedFibers.clear(), - 10 < fiber && - warn( - "Detected a large number of updates inside startTransition. If this is due to a subscription please re-write it to use React provided hooks. Otherwise concurrent mode guarantees are off the table." - )); - } + 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); } - function mountTransition() { - var stateHook = mountStateImpl(!1); - stateHook = startTransition.bind( - null, - currentlyRenderingFiber$1, - stateHook.queue, - !0, - !1 - ); - mountWorkInProgressHook().memoizedState = stateHook; - return [!1, stateHook]; + + function pickArbitraryLaneIndex(lanes) { + return 31 - clz32(lanes); } - function updateTransition() { - var booleanOrThenable = updateReducer(basicStateReducer)[0], - start = updateWorkInProgressHook().memoizedState; - return [ - "boolean" === typeof booleanOrThenable - ? booleanOrThenable - : useThenable(booleanOrThenable), - start - ]; + + function laneToIndex(lane) { + return pickArbitraryLaneIndex(lane); } - function rerenderTransition() { - var booleanOrThenable = rerenderReducer(basicStateReducer)[0], - start = updateWorkInProgressHook().memoizedState; - return [ - "boolean" === typeof booleanOrThenable - ? booleanOrThenable - : useThenable(booleanOrThenable), - start - ]; - } - function useHostTransitionStatus() { - var status = readContext(HostTransitionContext); - return null !== status ? status : null; + + function includesSomeLane(a, b) { + return (a & b) !== NoLanes; } - function mountId() { - var hook = mountWorkInProgressHook(), - identifierPrefix = workInProgressRoot.identifierPrefix, - globalClientId = globalClientIdCounter++; - identifierPrefix = - ":" + identifierPrefix + "r" + globalClientId.toString(32) + ":"; - return (hook.memoizedState = identifierPrefix); - } - function mountRefresh() { - return (mountWorkInProgressHook().memoizedState = refreshCache.bind( - null, - currentlyRenderingFiber$1 - )); + function isSubsetOfLanes(set, subset) { + return (set & subset) === subset; } - function refreshCache(fiber, seedKey) { - for (var provider = fiber.return; null !== provider; ) { - switch (provider.tag) { - case 24: - case 3: - var lane = requestUpdateLane(provider); - fiber = createUpdate(lane); - var root = enqueueUpdate(provider, fiber, lane); - null !== root && - (scheduleUpdateOnFiber(root, provider, lane), - entangleTransitions(root, provider, lane)); - provider = createCache(); - null !== seedKey && - void 0 !== seedKey && - null !== root && - error$jscomp$0( - "The seed argument is not enabled outside experimental channels." - ); - fiber.payload = { cache: provider }; - return; - } - provider = provider.return; - } + function mergeLanes(a, b) { + return a | b; } - function dispatchReducerAction( - fiber, - queue, - action, - JSCompiler_OptimizeArgumentsArray_p0 - ) { - "function" === typeof JSCompiler_OptimizeArgumentsArray_p0 && - error$jscomp$0( - "State updates from the useState() and useReducer() Hooks don't support the second callback argument. To execute a side effect after rendering, declare it in the component body with useEffect()." - ); - JSCompiler_OptimizeArgumentsArray_p0 = requestUpdateLane(fiber); - action = { - lane: JSCompiler_OptimizeArgumentsArray_p0, - revertLane: 0, - action: action, - hasEagerState: !1, - eagerState: null, - next: null - }; - isRenderPhaseUpdate(fiber) - ? enqueueRenderPhaseUpdate(queue, action) - : ((action = enqueueConcurrentHookUpdate( - fiber, - queue, - action, - JSCompiler_OptimizeArgumentsArray_p0 - )), - null !== action && - (scheduleUpdateOnFiber( - action, - fiber, - JSCompiler_OptimizeArgumentsArray_p0 - ), - entangleTransitionUpdate( - action, - queue, - JSCompiler_OptimizeArgumentsArray_p0 - ))); - markStateUpdateScheduled(fiber, JSCompiler_OptimizeArgumentsArray_p0); + function removeLanes(set, subset) { + return set & ~subset; } - function dispatchSetState( - fiber, - queue, - action, - JSCompiler_OptimizeArgumentsArray_p1 - ) { - "function" === typeof JSCompiler_OptimizeArgumentsArray_p1 && - error$jscomp$0( - "State updates from the useState() and useReducer() Hooks don't support the second callback argument. To execute a side effect after rendering, declare it in the component body with useEffect()." - ); - JSCompiler_OptimizeArgumentsArray_p1 = requestUpdateLane(fiber); - var update = { - lane: JSCompiler_OptimizeArgumentsArray_p1, - revertLane: 0, - action: action, - hasEagerState: !1, - eagerState: null, - next: null - }; - if (isRenderPhaseUpdate(fiber)) enqueueRenderPhaseUpdate(queue, update); - else { - var alternate = fiber.alternate; - if ( - 0 === fiber.lanes && - (null === alternate || 0 === alternate.lanes) && - ((alternate = queue.lastRenderedReducer), null !== alternate) - ) { - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = InvalidNestedHooksDispatcherOnUpdateInDEV; - try { - var currentState = queue.lastRenderedState, - eagerState = alternate(currentState, action); - update.hasEagerState = !0; - update.eagerState = eagerState; - if (objectIs(eagerState, currentState)) { - enqueueUpdate$1(fiber, queue, update, 0); - null === workInProgressRoot && finishQueueingConcurrentUpdates(); - return; + 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 laneToLanes(lane) { + return lane; + } + 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); + } + + return laneMap; + } + function markRootUpdated$1(root, updateLane) { + root.pendingLanes |= updateLane; // If there are any suspended transitions, it's possible this new update + // could unblock them. Clear the suspended lanes so that we can try rendering + // them again. + // + // 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. + + if (updateLane !== IdleLane) { + root.suspendedLanes = NoLanes; + root.pingedLanes = NoLanes; + } + } + function markRootSuspended$1(root, suspendedLanes, spawnedLane) { + 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; + } + + if (spawnedLane !== NoLane) { + markSpawnedDeferredLane(root, spawnedLane, suspendedLanes); + } + } + function markRootPinged$1(root, pingedLanes) { + root.pingedLanes |= root.suspendedLanes & pingedLanes; + } + function markRootFinished(root, remainingLanes, spawnedLane) { + var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; + root.pendingLanes = remainingLanes; // Let's try everything again + + root.suspendedLanes = NoLanes; + root.pingedLanes = NoLanes; + root.expiredLanes &= remainingLanes; + root.entangledLanes &= remainingLanes; + root.errorRecoveryDisabledLanes &= remainingLanes; + root.shellSuspendCounter = 0; + var entanglements = root.entanglements; + var expirationTimes = root.expirationTimes; + var hiddenUpdates = root.hiddenUpdates; // Clear the lanes that no longer have pending work + + var lanes = noLongerPendingLanes; + + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + entanglements[index] = NoLanes; + expirationTimes[index] = NoTimestamp; + var hiddenUpdatesForLane = hiddenUpdates[index]; + + if (hiddenUpdatesForLane !== null) { + hiddenUpdates[index] = null; // "Hidden" updates are updates that were made to a hidden component. They + // have special logic associated with them because they may be entangled + // with updates that occur outside that tree. But once the outer tree + // commits, they behave like regular updates. + + for (var i = 0; i < hiddenUpdatesForLane.length; i++) { + var update = hiddenUpdatesForLane[i]; + + if (update !== null) { + update.lane &= ~OffscreenLane; } - } catch (error$8) { - } finally { - ReactSharedInternals.H = prevDispatcher; } } - action = enqueueConcurrentHookUpdate( - fiber, - queue, - update, - JSCompiler_OptimizeArgumentsArray_p1 + + lanes &= ~lane; + } + + if (spawnedLane !== NoLane) { + markSpawnedDeferredLane( + root, + spawnedLane, // This render finished successfully without suspending, so we don't need + // to entangle the spawned task with the parent task. + NoLanes ); - null !== action && - (scheduleUpdateOnFiber( - action, - fiber, - JSCompiler_OptimizeArgumentsArray_p1 - ), - entangleTransitionUpdate( - action, - queue, - JSCompiler_OptimizeArgumentsArray_p1 - )); } - markStateUpdateScheduled(fiber, JSCompiler_OptimizeArgumentsArray_p1); } - function dispatchOptimisticSetState( - fiber, - throwIfDuringRender, - queue, - action - ) { - null === ReactSharedInternals.T && - 0 === currentEntangledLane && - error$jscomp$0( - "An optimistic state update occurred outside a transition or action. To fix, move the update to an action, or wrap with startTransition." - ); - action = { - lane: SyncLane, - revertLane: requestTransitionLane(), - action: action, - hasEagerState: !1, - eagerState: null, - next: null - }; - if (isRenderPhaseUpdate(fiber)) { - if (throwIfDuringRender) - throw Error("Cannot update optimistic state while rendering."); - error$jscomp$0("Cannot call startTransition while rendering."); - } else - (throwIfDuringRender = enqueueConcurrentHookUpdate( - fiber, - queue, - action, - SyncLane - )), - null !== throwIfDuringRender && - scheduleUpdateOnFiber(throwIfDuringRender, fiber, SyncLane); - markStateUpdateScheduled(fiber, SyncLane); + + function markSpawnedDeferredLane(root, spawnedLane, entangledLanes) { + // This render spawned a deferred task. Mark it as pending. + root.pendingLanes |= spawnedLane; + root.suspendedLanes &= ~spawnedLane; // Entangle the spawned lane with the DeferredLane bit so that we know it + // was the result of another render. This lets us avoid a useDeferredValue + // waterfall — only the first level will defer. + + var spawnedLaneIndex = laneToIndex(spawnedLane); + root.entangledLanes |= spawnedLane; + root.entanglements[spawnedLaneIndex] |= + DeferredLane | // If the parent render task suspended, we must also entangle those lanes + // with the spawned task, so that the deferred task includes all the same + // updates that the parent task did. We can exclude any lane that is not + // used for updates (e.g. Offscreen). + (entangledLanes & UpdateLanes); } - function isRenderPhaseUpdate(fiber) { - var alternate = fiber.alternate; - return ( - fiber === currentlyRenderingFiber$1 || - (null !== alternate && alternate === currentlyRenderingFiber$1) - ); + + 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; + + while (lanes) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + + if ( + // Is this one of the newly entangled lanes? + (lane & entangledLanes) | // Is this lane transitively entangled with the newly entangled lanes? + (entanglements[index] & entangledLanes) + ) { + entanglements[index] |= entangledLanes; + } + + lanes &= ~lane; + } } - function enqueueRenderPhaseUpdate(queue, update) { - didScheduleRenderPhaseUpdateDuringThisPass = - didScheduleRenderPhaseUpdate = !0; - var pending = queue.pending; - null === pending - ? (update.next = update) - : ((update.next = pending.next), (pending.next = update)); - queue.pending = update; + function upgradePendingLaneToSync(root, lane) { + // Since we're upgrading the priority of the given lane, there is now pending + // sync work. + root.pendingLanes |= SyncLane; // Entangle the sync lane with the lane we're upgrading. This means SyncLane + // will not be allowed to finish without also finishing the given lane. + + root.entangledLanes |= SyncLane; + root.entanglements[SyncLaneIndex] |= lane; } - function entangleTransitionUpdate(root, queue, lane) { - if (0 !== (lane & TransitionLanes)) { - var queueLanes = queue.lanes; - queueLanes &= root.pendingLanes; - lane |= queueLanes; - queue.lanes = lane; - markRootEntangled(root, lane); + function markHiddenUpdate(root, update, lane) { + var index = laneToIndex(lane); + var hiddenUpdates = root.hiddenUpdates; + var hiddenUpdatesForLane = hiddenUpdates[index]; + + if (hiddenUpdatesForLane === null) { + hiddenUpdates[index] = [update]; + } else { + hiddenUpdatesForLane.push(update); } + + update.lane = lane | OffscreenLane; } - function startProfilerTimer(fiber) { - profilerStartTime = now(); - 0 > fiber.actualStartTime && (fiber.actualStartTime = now()); + function getBumpedLaneForHydration(root, renderLanes) { + var renderLane = getHighestPriorityLane(renderLanes); + var lane; + + if ((renderLane & SyncUpdateLanes) !== NoLane) { + lane = SyncHydrationLane; + } else { + switch (renderLane) { + case SyncLane: + lane = SyncHydrationLane; + break; + + case InputContinuousLane: + lane = InputContinuousHydrationLane; + break; + + case DefaultLane: + lane = DefaultHydrationLane; + break; + + case TransitionLane1: + case TransitionLane2: + case TransitionLane3: + case TransitionLane4: + case TransitionLane5: + case TransitionLane6: + case TransitionLane7: + case TransitionLane8: + case TransitionLane9: + case TransitionLane10: + case TransitionLane11: + case TransitionLane12: + case TransitionLane13: + case TransitionLane14: + case TransitionLane15: + case RetryLane1: + case RetryLane2: + case RetryLane3: + case RetryLane4: + lane = TransitionHydrationLane; + break; + + case IdleLane: + lane = IdleHydrationLane; + break; + + default: + // Everything else is already either a hydration lane, or shouldn't + // be retried at a hydration lane. + lane = NoLane; + break; + } + } // Check if the lane we chose is suspended. If so, that indicates that we + // already attempted and failed to hydrate at that level. Also check if we're + // already rendering that lane, which is rare but could happen. + + if ((lane & (root.suspendedLanes | renderLanes)) !== NoLane) { + // Give up trying to hydrate and fall back to client render. + return NoLane; + } + + return lane; } - function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) { - if (0 <= profilerStartTime) { - var elapsedTime = now() - profilerStartTime; - fiber.actualDuration += elapsedTime; - overrideBaseTime && (fiber.selfBaseDuration = elapsedTime); - profilerStartTime = -1; + function addFiberToLanesMap(root, fiber, lanes) { + if (!isDevToolsPresent) { + return; + } + + var pendingUpdatersLaneMap = root.pendingUpdatersLaneMap; + + while (lanes > 0) { + var index = laneToIndex(lanes); + var lane = 1 << index; + var updaters = pendingUpdatersLaneMap[index]; + updaters.add(fiber); + lanes &= ~lane; } } - function recordLayoutEffectDuration(fiber) { - if (0 <= layoutEffectStartTime) { - var elapsedTime = now() - layoutEffectStartTime; - layoutEffectStartTime = -1; - for (fiber = fiber.return; null !== fiber; ) { - switch (fiber.tag) { - case 3: - fiber.stateNode.effectDuration += elapsedTime; - return; - case 12: - fiber.stateNode.effectDuration += elapsedTime; - return; - } - fiber = fiber.return; + function movePendingFibersToMemoized(root, lanes) { + if (!isDevToolsPresent) { + return; + } + + var pendingUpdatersLaneMap = root.pendingUpdatersLaneMap; + var memoizedUpdaters = root.memoizedUpdaters; + + while (lanes > 0) { + var index = laneToIndex(lanes); + var lane = 1 << index; + var updaters = pendingUpdatersLaneMap[index]; + + if (updaters.size > 0) { + updaters.forEach(function (fiber) { + var alternate = fiber.alternate; + + if (alternate === null || !memoizedUpdaters.has(alternate)) { + memoizedUpdaters.add(fiber); + } + }); + updaters.clear(); } + + lanes &= ~lane; } } - function recordPassiveEffectDuration(fiber) { - if (0 <= passiveEffectStartTime) { - var elapsedTime = now() - passiveEffectStartTime; - passiveEffectStartTime = -1; - for (fiber = fiber.return; null !== fiber; ) { - switch (fiber.tag) { - case 3: - fiber = fiber.stateNode; - null !== fiber && (fiber.passiveEffectDuration += elapsedTime); - return; - case 12: - fiber = fiber.stateNode; - null !== fiber && (fiber.passiveEffectDuration += elapsedTime); - return; - } - fiber = fiber.return; - } + function getTransitionsForLanes(root, lanes) { + { + return null; } } - function startLayoutEffectTimer() { - layoutEffectStartTime = now(); + + var DiscreteEventPriority = SyncLane; + var ContinuousEventPriority = InputContinuousLane; + var DefaultEventPriority = DefaultLane; + var IdleEventPriority = IdleLane; + var currentUpdatePriority = NoLane; + function getCurrentUpdatePriority() { + return currentUpdatePriority; } - function transferActualDuration(fiber) { - for (var child = fiber.child; child; ) - (fiber.actualDuration += child.actualDuration), (child = child.sibling); + function setCurrentUpdatePriority(newPriority) { + currentUpdatePriority = newPriority; } - function warnOnInvalidCallback(callback) { - if (null !== callback && "function" !== typeof callback) { - var key = String(callback); - didWarnOnInvalidCallback.has(key) || - (didWarnOnInvalidCallback.add(key), - error$jscomp$0( - "Expected the last optional `callback` argument to be a function. Instead received: %s.", - callback - )); + 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); + + if (!isHigherEventPriority(DiscreteEventPriority, lane)) { + return DiscreteEventPriority; + } + + if (!isHigherEventPriority(ContinuousEventPriority, lane)) { + return ContinuousEventPriority; + } + + if (includesNonIdleWork(lane)) { + return DefaultEventPriority; } + + return IdleEventPriority; } - function applyDerivedStateFromProps( - workInProgress, - ctor, - getDerivedStateFromProps, - nextProps - ) { - var prevState = workInProgress.memoizedState, - partialState = getDerivedStateFromProps(nextProps, prevState); - if (workInProgress.mode & 8) { - setIsStrictModeForDevtools(!0); - try { - partialState = getDerivedStateFromProps(nextProps, prevState); - } finally { - setIsStrictModeForDevtools(!1); - } - } - void 0 === partialState && - ((ctor = getComponentNameFromType(ctor) || "Component"), - didWarnAboutUndefinedDerivedState.has(ctor) || - (didWarnAboutUndefinedDerivedState.add(ctor), - error$jscomp$0( - "%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. You have returned undefined.", - ctor - ))); - prevState = - null === partialState || void 0 === partialState - ? prevState - : assign({}, prevState, partialState); - workInProgress.memoizedState = prevState; - 0 === workInProgress.lanes && - (workInProgress.updateQueue.baseState = prevState); + + // Renderers that don't support hydration + // can re-export everything from this module. + function shim$1() { + throw new 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 getSuspenseInstanceFallbackErrorDetails = shim$1; + var registerSuspenseInstanceRetry = shim$1; + var clearSuspenseBoundary = shim$1; + var clearSuspenseBoundaryFromContainer = shim$1; + var errorHydratingContainer = shim$1; + + // Renderers that don't support hydration + // can re-export everything from this module. + function shim() { + throw new Error( + "The current renderer does not support Resources. " + + "This error is likely caused by a bug in React. " + + "Please file an issue." + ); + } // Resources (when unsupported) + var suspendResource = shim; + + var getViewConfigForType = + ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get; // Unused + // Unused + // Counter for uniquely identifying views. + // % 10 === 1 means it is a rootTag. + // % 2 === 0 means it is a Fabric tag. + + var nextReactTag = 3; + + function allocateTag() { + var tag = nextReactTag; + + if (tag % 10 === 1) { + tag += 2; + } + + nextReactTag = tag + 2; + return tag; } - function checkShouldComponentUpdate( - workInProgress, - ctor, - oldProps, - newProps, - oldState, - newState, - nextContext + + function recursivelyUncacheFiberNode(node) { + if (typeof node === "number") { + // Leaf node (eg text) + uncacheFiberNode(node); + } else { + uncacheFiberNode(node._nativeTag); + + node._children.forEach(recursivelyUncacheFiberNode); + } + } + function appendInitialChild(parentInstance, child) { + parentInstance._children.push(child); + } + function createInstance( + type, + props, + rootContainerInstance, + hostContext, + internalInstanceHandle ) { - var instance = workInProgress.stateNode; - if ("function" === typeof instance.shouldComponentUpdate) { - oldProps = instance.shouldComponentUpdate( - newProps, - newState, - nextContext - ); - if (workInProgress.mode & 8) { - setIsStrictModeForDevtools(!0); - try { - oldProps = instance.shouldComponentUpdate( - newProps, - newState, - nextContext + var tag = allocateTag(); + var viewConfig = getViewConfigForType(type); + + { + for (var key in viewConfig.validAttributes) { + if (props.hasOwnProperty(key)) { + ReactNativePrivateInterface.deepFreezeAndThrowOnMutationInDev( + props[key] ); - } finally { - setIsStrictModeForDevtools(!1); } } - void 0 === oldProps && - error$jscomp$0( - "%s.shouldComponentUpdate(): Returned undefined instead of a boolean value. Make sure to return true or false.", - getComponentNameFromType(ctor) || "Component" - ); - return oldProps; } - return ctor.prototype && ctor.prototype.isPureReactComponent - ? !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState) - : !0; + + var updatePayload = create(props, viewConfig.validAttributes); + ReactNativePrivateInterface.UIManager.createView( + tag, // reactTag + viewConfig.uiViewClassName, // viewName + rootContainerInstance, // rootTag + updatePayload // props + ); + var component = new ReactNativeFiberHostComponent( + tag, + viewConfig, + internalInstanceHandle + ); + precacheFiberNode(internalInstanceHandle, tag); + updateFiberProps(tag, props); // Not sure how to avoid this cast. Flow is okay if the component is defined + // in the same file but if it's external it can't see the types. + + return component; } - function constructClassInstance(workInProgress, ctor, props) { - var context = emptyContextObject, - contextType = ctor.contextType; - if ( - "contextType" in ctor && - null !== contextType && - (void 0 === contextType || - contextType.$$typeof !== REACT_CONTEXT_TYPE) && - !didWarnAboutInvalidateContextType.has(ctor) - ) { - didWarnAboutInvalidateContextType.add(ctor); - var addendum = - void 0 === contextType - ? " However, it is set to undefined. This can be caused by a typo or by mixing up named and default imports. This can also happen due to a circular dependency, so try moving the createContext() call to a separate file." - : "object" !== typeof contextType - ? " However, it is set to a " + typeof contextType + "." - : contextType.$$typeof === REACT_CONSUMER_TYPE - ? " Did you accidentally pass the Context.Consumer instead?" - : " However, it is set to an object with keys {" + - Object.keys(contextType).join(", ") + - "}."; - error$jscomp$0( - "%s defines an invalid contextType. contextType should point to the Context object returned by React.createContext().%s", - getComponentNameFromType(ctor) || "Component", - addendum + function createTextInstance( + text, + rootContainerInstance, + hostContext, + internalInstanceHandle + ) { + if (!hostContext.isInAParentText) { + throw new Error( + "Text strings must be rendered within a component." ); } - "object" === typeof contextType && - null !== contextType && - (context = readContext(contextType)); - contextType = new ctor(props, context); - if (workInProgress.mode & 8) { - setIsStrictModeForDevtools(!0); - try { - contextType = new ctor(props, context); - } finally { - setIsStrictModeForDevtools(!1); - } - } - props = workInProgress.memoizedState = - null !== contextType.state && void 0 !== contextType.state - ? contextType.state - : null; - contextType.updater = classComponentUpdater; - workInProgress.stateNode = contextType; - contextType._reactInternals = workInProgress; - contextType._reactInternalInstance = fakeInternalInstance; - "function" === typeof ctor.getDerivedStateFromProps && - null === props && - ((workInProgress = getComponentNameFromType(ctor) || "Component"), - didWarnAboutUninitializedState.has(workInProgress) || - (didWarnAboutUninitializedState.add(workInProgress), - error$jscomp$0( - "`%s` uses `getDerivedStateFromProps` but its initial state is %s. This is not recommended. Instead, define the initial state by assigning an object to `this.state` in the constructor of `%s`. This ensures that `getDerivedStateFromProps` arguments have a consistent shape.", - workInProgress, - null === contextType.state ? "null" : "undefined", - workInProgress - ))); - if ( - "function" === typeof ctor.getDerivedStateFromProps || - "function" === typeof contextType.getSnapshotBeforeUpdate - ) - if ( - ((context = props = workInProgress = null), - "function" === typeof contextType.componentWillMount && - !0 !== contextType.componentWillMount.__suppressDeprecationWarning - ? (workInProgress = "componentWillMount") - : "function" === typeof contextType.UNSAFE_componentWillMount && - (workInProgress = "UNSAFE_componentWillMount"), - "function" === typeof contextType.componentWillReceiveProps && - !0 !== - contextType.componentWillReceiveProps.__suppressDeprecationWarning - ? (props = "componentWillReceiveProps") - : "function" === - typeof contextType.UNSAFE_componentWillReceiveProps && - (props = "UNSAFE_componentWillReceiveProps"), - "function" === typeof contextType.componentWillUpdate && - !0 !== contextType.componentWillUpdate.__suppressDeprecationWarning - ? (context = "componentWillUpdate") - : "function" === typeof contextType.UNSAFE_componentWillUpdate && - (context = "UNSAFE_componentWillUpdate"), - null !== workInProgress || null !== props || null !== context) - ) - (addendum = getComponentNameFromType(ctor) || "Component"), - (ctor = - "function" === typeof ctor.getDerivedStateFromProps - ? "getDerivedStateFromProps()" - : "getSnapshotBeforeUpdate()"), - didWarnAboutLegacyLifecyclesAndDerivedState.has(addendum) || - (didWarnAboutLegacyLifecyclesAndDerivedState.add(addendum), - error$jscomp$0( - "Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n%s uses %s but also contains the following legacy lifecycles:%s%s%s\n\nThe above lifecycles should be removed. Learn more about this warning here:\nhttps://react.dev/link/unsafe-component-lifecycles", - addendum, - ctor, - null !== workInProgress ? "\n " + workInProgress : "", - null !== props ? "\n " + props : "", - null !== context ? "\n " + context : "" - )); - return contextType; - } - function callComponentWillReceiveProps( - workInProgress, - instance, - newProps, - nextContext - ) { - var oldState = instance.state; - "function" === typeof instance.componentWillReceiveProps && - instance.componentWillReceiveProps(newProps, nextContext); - "function" === typeof instance.UNSAFE_componentWillReceiveProps && - instance.UNSAFE_componentWillReceiveProps(newProps, nextContext); - instance.state !== oldState && - ((workInProgress = - getComponentNameFromFiber(workInProgress) || "Component"), - didWarnAboutStateAssignmentForComponent.has(workInProgress) || - (didWarnAboutStateAssignmentForComponent.add(workInProgress), - error$jscomp$0( - "%s.componentWillReceiveProps(): Assigning directly to this.state is deprecated (except inside a component's constructor). Use setState instead.", - workInProgress - )), - classComponentUpdater.enqueueReplaceState( - instance, - instance.state, - null - )); - } - function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { - var instance = workInProgress.stateNode, - name = getComponentNameFromType(ctor) || "Component"; - instance.render || - (ctor.prototype && "function" === typeof ctor.prototype.render - ? error$jscomp$0( - "No `render` method found on the %s instance: did you accidentally return an object from the constructor?", - name - ) - : error$jscomp$0( - "No `render` method found on the %s instance: you may have forgotten to define `render`.", - name - )); - !instance.getInitialState || - instance.getInitialState.isReactClassApproved || - instance.state || - error$jscomp$0( - "getInitialState was defined on %s, a plain JavaScript class. This is only supported for classes created using React.createClass. Did you mean to define a state property instead?", - name - ); - instance.getDefaultProps && - !instance.getDefaultProps.isReactClassApproved && - error$jscomp$0( - "getDefaultProps was defined on %s, a plain JavaScript class. This is only supported for classes created using React.createClass. Use a static property to define defaultProps instead.", - name - ); - instance.propTypes && - error$jscomp$0( - "propTypes was defined as an instance property on %s. Use a static property to define propTypes instead.", - name - ); - instance.contextType && - error$jscomp$0( - "contextType was defined as an instance property on %s. Use a static property to define contextType instead.", - name - ); - ctor.childContextTypes && - error$jscomp$0( - "%s uses the legacy childContextTypes API which was removed in React 19. Use React.createContext() instead.", - name - ); - ctor.contextTypes && - error$jscomp$0( - "%s uses the legacy contextTypes API which was removed in React 19. Use React.createContext() with static contextType instead.", - name - ); - "function" === typeof instance.componentShouldUpdate && - error$jscomp$0( - "%s has a method called componentShouldUpdate(). Did you mean shouldComponentUpdate()? The name is phrased as a question because the function is expected to return a value.", - name - ); - ctor.prototype && - ctor.prototype.isPureReactComponent && - "undefined" !== typeof instance.shouldComponentUpdate && - error$jscomp$0( - "%s has a method called shouldComponentUpdate(). shouldComponentUpdate should not be used when extending React.PureComponent. Please extend React.Component if shouldComponentUpdate is used.", - getComponentNameFromType(ctor) || "A pure component" - ); - "function" === typeof instance.componentDidUnmount && - error$jscomp$0( - "%s has a method called componentDidUnmount(). But there is no such lifecycle method. Did you mean componentWillUnmount()?", - name - ); - "function" === typeof instance.componentDidReceiveProps && - error$jscomp$0( - "%s has a method called componentDidReceiveProps(). But there is no such lifecycle method. If you meant to update the state in response to changing props, use componentWillReceiveProps(). If you meant to fetch data or run side-effects or mutations after React has updated the UI, use componentDidUpdate().", - name - ); - "function" === typeof instance.componentWillRecieveProps && - error$jscomp$0( - "%s has a method called componentWillRecieveProps(). Did you mean componentWillReceiveProps()?", - name - ); - "function" === typeof instance.UNSAFE_componentWillRecieveProps && - error$jscomp$0( - "%s has a method called UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?", - name - ); - var hasMutatedProps = instance.props !== newProps; - void 0 !== instance.props && - hasMutatedProps && - error$jscomp$0( - "When calling super() in `%s`, make sure to pass up the same props that your component's constructor was passed.", - name - ); - instance.defaultProps && - error$jscomp$0( - "Setting defaultProps as an instance property on %s is not supported and will be ignored. Instead, define defaultProps as a static property on %s.", - name, - name - ); - "function" !== typeof instance.getSnapshotBeforeUpdate || - "function" === typeof instance.componentDidUpdate || - didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor) || - (didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor), - error$jscomp$0( - "%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). This component defines getSnapshotBeforeUpdate() only.", - getComponentNameFromType(ctor) - )); - "function" === typeof instance.getDerivedStateFromProps && - error$jscomp$0( - "%s: getDerivedStateFromProps() is defined as an instance method and will be ignored. Instead, declare it as a static method.", - name - ); - "function" === typeof instance.getDerivedStateFromError && - error$jscomp$0( - "%s: getDerivedStateFromError() is defined as an instance method and will be ignored. Instead, declare it as a static method.", - name - ); - "function" === typeof ctor.getSnapshotBeforeUpdate && - error$jscomp$0( - "%s: getSnapshotBeforeUpdate() is defined as a static method and will be ignored. Instead, declare it as an instance method.", - name - ); - (hasMutatedProps = instance.state) && - ("object" !== typeof hasMutatedProps || isArrayImpl(hasMutatedProps)) && - error$jscomp$0("%s.state: must be set to an object or null", name); - "function" === typeof instance.getChildContext && - "object" !== typeof ctor.childContextTypes && - error$jscomp$0( - "%s.getChildContext(): childContextTypes must be defined in order to use getChildContext().", - name - ); - instance = workInProgress.stateNode; - instance.props = newProps; - instance.state = workInProgress.memoizedState; - instance.refs = {}; - initializeUpdateQueue(workInProgress); - name = ctor.contextType; - instance.context = - "object" === typeof name && null !== name - ? readContext(name) - : emptyContextObject; - instance.state === newProps && - ((name = getComponentNameFromType(ctor) || "Component"), - didWarnAboutDirectlyAssigningPropsToState.has(name) || - (didWarnAboutDirectlyAssigningPropsToState.add(name), - error$jscomp$0( - "%s: It is not recommended to assign props directly to state because updates to props won't be reflected in state. In most cases, it is better to use props directly.", - name - ))); - workInProgress.mode & 8 && - ReactStrictModeWarnings.recordLegacyContextWarning( - workInProgress, - instance - ); - ReactStrictModeWarnings.recordUnsafeLifecycleWarnings( - workInProgress, - instance + + var tag = allocateTag(); + ReactNativePrivateInterface.UIManager.createView( + tag, // reactTag + "RCTRawText", // viewName + rootContainerInstance, // rootTag + { + text: text + } // props ); - instance.state = workInProgress.memoizedState; - name = ctor.getDerivedStateFromProps; - "function" === typeof name && - (applyDerivedStateFromProps(workInProgress, ctor, name, newProps), - (instance.state = workInProgress.memoizedState)); - "function" === typeof ctor.getDerivedStateFromProps || - "function" === typeof instance.getSnapshotBeforeUpdate || - ("function" !== typeof instance.UNSAFE_componentWillMount && - "function" !== typeof instance.componentWillMount) || - ((ctor = instance.state), - "function" === typeof instance.componentWillMount && - instance.componentWillMount(), - "function" === typeof instance.UNSAFE_componentWillMount && - instance.UNSAFE_componentWillMount(), - ctor !== instance.state && - (error$jscomp$0( - "%s.componentWillMount(): Assigning directly to this.state is deprecated (except inside a component's constructor). Use setState instead.", - getComponentNameFromFiber(workInProgress) || "Component" - ), - classComponentUpdater.enqueueReplaceState( - instance, - instance.state, - null - )), - processUpdateQueue(workInProgress, newProps, instance, renderLanes), - suspendIfUpdateReadFromEntangledAsyncAction(), - (instance.state = workInProgress.memoizedState)); - "function" === typeof instance.componentDidMount && - (workInProgress.flags |= 4194308); - 0 !== (workInProgress.mode & 16) && (workInProgress.flags |= 67108864); - } - function resolveClassComponentProps(Component, baseProps) { - var newProps = baseProps; - if ("ref" in baseProps) { - newProps = {}; - for (var propName in baseProps) - "ref" !== propName && (newProps[propName] = baseProps[propName]); - } - if ((Component = Component.defaultProps)) { - newProps === baseProps && (newProps = assign({}, newProps)); - for (var _propName in Component) - void 0 === newProps[_propName] && - (newProps[_propName] = Component[_propName]); - } - return newProps; - } - function defaultOnRecoverableError(error) { - reportGlobalError(error); - } - function logUncaughtError(root, errorInfo) { - try { - componentName = errorInfo.source - ? getComponentNameFromFiber(errorInfo.source) - : null; - errorBoundaryName = null; - var error = errorInfo.value; - if (null !== ReactSharedInternals.actQueue) - ReactSharedInternals.thrownErrors.push(error); - else { - var onUncaughtError = root.onUncaughtError; - onUncaughtError(error, { componentStack: errorInfo.stack }); - } - } catch (e) { - setTimeout(function () { - throw e; - }); - } + precacheFiberNode(internalInstanceHandle, tag); + return tag; } - function logCaughtError(root, boundary, errorInfo) { - try { - componentName = errorInfo.source - ? getComponentNameFromFiber(errorInfo.source) - : null; - errorBoundaryName = getComponentNameFromFiber(boundary); - var onCaughtError = root.onCaughtError; - onCaughtError(errorInfo.value, { - componentStack: errorInfo.stack, - errorBoundary: 1 === boundary.tag ? boundary.stateNode : null - }); - } catch (e) { - setTimeout(function () { - throw e; - }); - } + function finalizeInitialChildren(parentInstance, type, props, hostContext) { + // Don't send a no-op message over the bridge. + if (parentInstance._children.length === 0) { + return false; + } // Map from child objects to native tags. + // Either way we need to pass a copy of the Array to prevent it from being frozen. + + var nativeTags = parentInstance._children.map(function (child) { + return typeof child === "number" + ? child // Leaf node (eg text) + : child._nativeTag; + }); + + ReactNativePrivateInterface.UIManager.setChildren( + parentInstance._nativeTag, // containerTag + nativeTags // reactTags + ); + return false; } - function createRootErrorUpdate(root, errorInfo, lane) { - lane = createUpdate(lane); - lane.tag = CaptureUpdate; - lane.payload = { element: null }; - lane.callback = function () { - runWithFiberInDEV(errorInfo.source, logUncaughtError, root, errorInfo); + function getRootHostContext(rootContainerInstance) { + return { + isInAParentText: false }; - return lane; - } - function createClassErrorUpdate(lane) { - lane = createUpdate(lane); - lane.tag = CaptureUpdate; - return lane; } - function initializeClassErrorUpdate(update, root, fiber, errorInfo) { - var getDerivedStateFromError = fiber.type.getDerivedStateFromError; - if ("function" === typeof getDerivedStateFromError) { - var error$1 = errorInfo.value; - update.payload = function () { - return getDerivedStateFromError(error$1); - }; - update.callback = function () { - markFailedErrorBoundaryForHotReloading(fiber); - runWithFiberInDEV( - errorInfo.source, - logCaughtError, - root, - fiber, - errorInfo - ); + function getChildHostContext(parentHostContext, type) { + var prevIsInAParentText = parentHostContext.isInAParentText; + var isInAParentText = + type === "AndroidTextInput" || // Android + type === "RCTMultilineTextInputView" || // iOS + type === "RCTSinglelineTextInputView" || // iOS + type === "RCTText" || + type === "RCTVirtualText"; + + if (prevIsInAParentText !== isInAParentText) { + return { + isInAParentText: isInAParentText }; + } else { + return parentHostContext; } - var inst = fiber.stateNode; - null !== inst && - "function" === typeof inst.componentDidCatch && - (update.callback = function () { - markFailedErrorBoundaryForHotReloading(fiber); - runWithFiberInDEV( - errorInfo.source, - logCaughtError, - root, - fiber, - errorInfo - ); - "function" !== typeof getDerivedStateFromError && - (null === legacyErrorBoundariesThatAlreadyFailed - ? (legacyErrorBoundariesThatAlreadyFailed = new Set([this])) - : legacyErrorBoundariesThatAlreadyFailed.add(this)); - var stack = errorInfo.stack; - this.componentDidCatch(errorInfo.value, { - componentStack: null !== stack ? stack : "" - }); - "function" === typeof getDerivedStateFromError || - (0 === (fiber.lanes & SyncLane) && - error$jscomp$0( - "%s: Error boundaries should implement getDerivedStateFromError(). In that method, return a state update to display an error message or fallback UI.", - getComponentNameFromFiber(fiber) || "Unknown" - )); - }); } - function throwException( - root, - returnFiber, - sourceFiber, - value, - rootRenderLanes - ) { - sourceFiber.flags |= 32768; - isDevToolsPresent && restorePendingUpdaters(root, rootRenderLanes); + function getPublicInstance(instance) { + // $FlowExpectedError[prop-missing] For compatibility with Fabric if ( - null !== value && - "object" === typeof value && - "function" === typeof value.then + instance.canonical != null && + instance.canonical.publicInstance != null ) { - var tag = sourceFiber.tag; - 0 !== (sourceFiber.mode & 1) || - (0 !== tag && 11 !== tag && 15 !== tag) || - ((tag = sourceFiber.alternate) - ? ((sourceFiber.updateQueue = tag.updateQueue), - (sourceFiber.memoizedState = tag.memoizedState), - (sourceFiber.lanes = tag.lanes)) - : ((sourceFiber.updateQueue = null), - (sourceFiber.memoizedState = null))); - tag = suspenseHandlerStackCursor.current; - if (null !== tag) { - switch (tag.tag) { - case 13: - return ( - sourceFiber.mode & 1 && - (null === shellBoundary - ? renderDidSuspendDelayIfPossible() - : null === tag.alternate && - workInProgressRootExitStatus === RootInProgress && - (workInProgressRootExitStatus = RootSuspended)), - (tag.flags &= -257), - 0 === (tag.mode & 1) - ? tag === returnFiber - ? (tag.flags |= 65536) - : ((tag.flags |= 128), - (sourceFiber.flags |= 131072), - (sourceFiber.flags &= -52805), - 1 === sourceFiber.tag - ? null === sourceFiber.alternate - ? (sourceFiber.tag = 17) - : ((returnFiber = createUpdate(SyncLane)), - (returnFiber.tag = ForceUpdate), - enqueueUpdate(sourceFiber, returnFiber, SyncLane)) - : 0 === sourceFiber.tag && - null === sourceFiber.alternate && - (sourceFiber.tag = 28), - (sourceFiber.lanes |= SyncLane)) - : ((tag.flags |= 65536), (tag.lanes = rootRenderLanes)), - value === noopSuspenseyCommitThenable - ? (tag.flags |= 16384) - : ((returnFiber = tag.updateQueue), - null === returnFiber - ? (tag.updateQueue = new Set([value])) - : returnFiber.add(value), - tag.mode & 1 && - attachPingListener(root, value, rootRenderLanes)), - !1 - ); - case 22: - if (tag.mode & 1) - return ( - (tag.flags |= 65536), - value === noopSuspenseyCommitThenable - ? (tag.flags |= 16384) - : ((returnFiber = tag.updateQueue), - null === returnFiber - ? ((returnFiber = { - transitions: null, - markerInstances: null, - retryQueue: new Set([value]) - }), - (tag.updateQueue = returnFiber)) - : ((sourceFiber = returnFiber.retryQueue), - null === sourceFiber - ? (returnFiber.retryQueue = new Set([value])) - : sourceFiber.add(value)), - attachPingListener(root, value, rootRenderLanes)), - !1 - ); - } - throw Error( - "Unexpected Suspense handler tag (" + - tag.tag + - "). This is a bug in React." - ); - } - if (1 === root.tag) - return ( - attachPingListener(root, value, rootRenderLanes), - renderDidSuspendDelayIfPossible(), - !1 - ); - value = Error( - "A component suspended while responding to synchronous input. This will cause the UI to be replaced with a loading indicator. To fix, updates that suspend should be wrapped with startTransition." + // $FlowFixMe[incompatible-return] + return instance.canonical.publicInstance; + } + + return instance; + } + 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 shouldAttemptEagerTransition() { + return false; + } // ------------------- + function appendChild(parentInstance, child) { + var childTag = typeof child === "number" ? child : child._nativeTag; + var children = parentInstance._children; + var index = children.indexOf(child); + + 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 ); } - tag = createCapturedValueAtFiber( - Error( - "There was an error during concurrent rendering but React was able to recover by instead synchronously rendering the entire root.", - { cause: value } - ), - sourceFiber + } + function appendChildToContainer(parentInstance, child) { + var childTag = typeof child === "number" ? child : child._nativeTag; + ReactNativePrivateInterface.UIManager.setChildren( + parentInstance, // containerTag + [childTag] // reactTags ); - null === workInProgressRootConcurrentErrors - ? (workInProgressRootConcurrentErrors = [tag]) - : workInProgressRootConcurrentErrors.push(tag); - workInProgressRootExitStatus !== RootSuspendedWithDelay && - (workInProgressRootExitStatus = RootErrored); - if (null === returnFiber) return !0; - value = createCapturedValueAtFiber(value, sourceFiber); - do { - switch (returnFiber.tag) { - case 3: - return ( - (returnFiber.flags |= 65536), - (root = rootRenderLanes & -rootRenderLanes), - (returnFiber.lanes |= root), - (root = createRootErrorUpdate( - returnFiber.stateNode, - value, - root - )), - enqueueCapturedUpdate(returnFiber, root), - !1 - ); - case 1: - if ( - ((sourceFiber = returnFiber.type), - (tag = returnFiber.stateNode), - 0 === (returnFiber.flags & 128) && - ("function" === typeof sourceFiber.getDerivedStateFromError || - (null !== tag && - "function" === typeof tag.componentDidCatch && - (null === legacyErrorBoundariesThatAlreadyFailed || - !legacyErrorBoundariesThatAlreadyFailed.has(tag))))) - ) - return ( - (returnFiber.flags |= 65536), - (rootRenderLanes &= -rootRenderLanes), - (returnFiber.lanes |= rootRenderLanes), - (rootRenderLanes = createClassErrorUpdate(rootRenderLanes)), - initializeClassErrorUpdate( - rootRenderLanes, - root, - returnFiber, - value - ), - enqueueCapturedUpdate(returnFiber, rootRenderLanes), - !1 - ); - } - returnFiber = returnFiber.return; - } while (null !== returnFiber); - return !1; } - function reconcileChildren( - current, - workInProgress, - nextChildren, - renderLanes - ) { - workInProgress.child = - null === current - ? mountChildFibers(workInProgress, null, nextChildren, renderLanes) - : reconcileChildFibers( - workInProgress, - current.child, - nextChildren, - renderLanes - ); + function commitTextUpdate(textInstance, oldText, newText) { + ReactNativePrivateInterface.UIManager.updateView( + textInstance, // reactTag + "RCTRawText", // viewName + { + text: newText + } // props + ); } - function updateForwardRef( - current, - workInProgress, - Component, - nextProps, - renderLanes + function commitMount(instance, type, newProps, internalInstanceHandle) { + // Noop + } + function commitUpdate( + instance, + updatePayloadTODO, + type, + oldProps, + newProps, + internalInstanceHandle ) { - Component = Component.render; - var ref = workInProgress.ref; - if ("ref" in nextProps) { - var propsWithoutRef = {}; - for (var key in nextProps) - "ref" !== key && (propsWithoutRef[key] = nextProps[key]); - } else propsWithoutRef = nextProps; - prepareToReadContext(workInProgress, renderLanes); - markComponentRenderStarted(workInProgress); - nextProps = renderWithHooks( - current, - workInProgress, - Component, - propsWithoutRef, - ref, - renderLanes - ); - markComponentRenderStopped(); - if (null !== current && !didReceiveUpdate) - return ( - bailoutHooks(current, workInProgress, renderLanes), - bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) + var viewConfig = instance.viewConfig; + updateFiberProps(instance._nativeTag, newProps); + var updatePayload = diff(oldProps, newProps, viewConfig.validAttributes); // Avoid the overhead of bridge calls if there's no update. + // This is an expensive no-op for Android, and causes an unnecessary + // view invalidation for certain components (eg RCTTextInput) on iOS. + + if (updatePayload != null) { + ReactNativePrivateInterface.UIManager.updateView( + instance._nativeTag, // reactTag + viewConfig.uiViewClassName, // viewName + updatePayload // props ); - workInProgress.flags |= 1; - reconcileChildren(current, workInProgress, nextProps, renderLanes); - return workInProgress.child; + } } - function updateMemoComponent( - current, - workInProgress, - Component, - nextProps, - renderLanes - ) { - if (null === current) { - var type = Component.type; - if ( - "function" === typeof type && - !shouldConstruct(type) && - void 0 === type.defaultProps && - null === Component.compare - ) - return ( - (Component = resolveFunctionForHotReloading(type)), - (workInProgress.tag = 15), - (workInProgress.type = Component), - validateFunctionComponentInDev(workInProgress, type), - updateSimpleMemoComponent( - current, - workInProgress, - Component, - nextProps, - renderLanes - ) - ); - current = createFiberFromTypeAndProps( - Component.type, - null, - nextProps, - workInProgress, - workInProgress.mode, - renderLanes + function insertBefore(parentInstance, child, beforeChild) { + var children = parentInstance._children; + var index = children.indexOf(child); // Move existing child or add new child? + + if (index >= 0) { + children.splice(index, 1); + var beforeChildIndex = children.indexOf(beforeChild); + children.splice(beforeChildIndex, 0, child); + ReactNativePrivateInterface.UIManager.manageChildren( + parentInstance._nativeTag, // containerID + [index], // moveFromIndices + [beforeChildIndex], // moveToIndices + [], // addChildReactTags + [], // addAtIndices + [] // removeAtIndices + ); + } else { + var _beforeChildIndex = children.indexOf(beforeChild); + + children.splice(_beforeChildIndex, 0, child); + var childTag = typeof child === "number" ? child : child._nativeTag; + ReactNativePrivateInterface.UIManager.manageChildren( + parentInstance._nativeTag, // containerID + [], // moveFromIndices + [], // moveToIndices + [childTag], // addChildReactTags + [_beforeChildIndex], // addAtIndices + [] // removeAtIndices ); - current.ref = workInProgress.ref; - current.return = workInProgress; - return (workInProgress.child = current); - } - type = current.child; - if (0 === (current.lanes & renderLanes)) { - var prevProps = type.memoizedProps; - Component = Component.compare; - Component = null !== Component ? Component : shallowEqual; - if ( - Component(prevProps, nextProps) && - current.ref === workInProgress.ref - ) - return bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderLanes - ); } - workInProgress.flags |= 1; - current = createWorkInProgress(type, nextProps); - current.ref = workInProgress.ref; - current.return = workInProgress; - return (workInProgress.child = current); } - function updateSimpleMemoComponent( - current, - workInProgress, - Component, - nextProps, - renderLanes - ) { - if (null !== current) { - var prevProps = current.memoizedProps; - if ( - shallowEqual(prevProps, nextProps) && - current.ref === workInProgress.ref && - workInProgress.type === current.type - ) - if ( - ((didReceiveUpdate = !1), - (workInProgress.pendingProps = nextProps = prevProps), - 0 !== (current.lanes & renderLanes)) - ) - 0 !== (current.flags & 131072) && (didReceiveUpdate = !0); - else - return ( - (workInProgress.lanes = current.lanes), - bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) - ); + 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 new Error("Container does not support insertBefore operation"); } - return updateFunctionComponent( - current, - workInProgress, - Component, - nextProps, - renderLanes + } + 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 updateOffscreenComponent(current, workInProgress, renderLanes) { - var nextProps = workInProgress.pendingProps, - nextChildren = nextProps.children, - nextIsDetached = - 0 !== (workInProgress.stateNode._pendingVisibility & 2), - prevState = null !== current ? current.memoizedState : null; - markRef(current, workInProgress); - if ("hidden" === nextProps.mode || nextIsDetached) { - if (0 !== (workInProgress.flags & 128)) { - renderLanes = - null !== prevState - ? prevState.baseLanes | renderLanes - : renderLanes; - if (null !== current) { - nextProps = workInProgress.child = current.child; - for (nextChildren = 0; null !== nextProps; ) - (nextChildren = - nextChildren | nextProps.lanes | nextProps.childLanes), - (nextProps = nextProps.sibling); - workInProgress.childLanes = nextChildren & ~renderLanes; - } else (workInProgress.childLanes = 0), (workInProgress.child = null); - return deferHiddenOffscreenComponent( - current, - workInProgress, - renderLanes - ); - } - if (0 === (workInProgress.mode & 1)) - (workInProgress.memoizedState = { baseLanes: 0, cachePool: null }), - null !== current && pushTransition(workInProgress, null), - reuseHiddenContextOnStack(workInProgress), - pushOffscreenSuspenseHandler(workInProgress); - else if (0 !== (renderLanes & OffscreenLane)) - (workInProgress.memoizedState = { baseLanes: 0, cachePool: null }), - null !== current && - pushTransition( - workInProgress, - null !== prevState ? prevState.cachePool : null - ), - null !== prevState - ? pushHiddenContext(workInProgress, prevState) - : reuseHiddenContextOnStack(workInProgress), - pushOffscreenSuspenseHandler(workInProgress); - else - return ( - (workInProgress.lanes = workInProgress.childLanes = OffscreenLane), - deferHiddenOffscreenComponent( - current, - workInProgress, - null !== prevState - ? prevState.baseLanes | renderLanes - : renderLanes - ) - ); - } else - null !== prevState - ? (pushTransition(workInProgress, prevState.cachePool), - pushHiddenContext(workInProgress, prevState), - reuseSuspenseHandlerOnStack(workInProgress), - (workInProgress.memoizedState = null)) - : (null !== current && pushTransition(workInProgress, null), - reuseHiddenContextOnStack(workInProgress), - reuseSuspenseHandlerOnStack(workInProgress)); - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - return workInProgress.child; + function removeChildFromContainer(parentInstance, child) { + recursivelyUncacheFiberNode(child); + ReactNativePrivateInterface.UIManager.manageChildren( + parentInstance, // containerID + [], // moveFromIndices + [], // moveToIndices + [], // addChildReactTags + [], // addAtIndices + [0] // removeAtIndices + ); } - function deferHiddenOffscreenComponent( - current, - workInProgress, - nextBaseLanes - ) { - var JSCompiler_inline_result = peekCacheFromPool(); - JSCompiler_inline_result = - null === JSCompiler_inline_result - ? null - : { - parent: CacheContext._currentValue, - pool: JSCompiler_inline_result - }; - workInProgress.memoizedState = { - baseLanes: nextBaseLanes, - cachePool: JSCompiler_inline_result - }; - null !== current && pushTransition(workInProgress, null); - reuseHiddenContextOnStack(workInProgress); - pushOffscreenSuspenseHandler(workInProgress); - return null; + function resetTextContent(instance) { + // Noop } - function markRef(current, workInProgress) { - var ref = workInProgress.ref; - if (null === ref) - null !== current && - null !== current.ref && - (workInProgress.flags |= 2097664); - else { - if ("function" !== typeof ref && "object" !== typeof ref) - throw Error( - "Expected ref to be a function, an object returned by React.createRef(), or undefined/null." - ); - if (null === current || current.ref !== ref) - workInProgress.flags |= 2097664; - } - } - function updateFunctionComponent( - current, - workInProgress, - Component, - nextProps, - renderLanes - ) { - if ( - Component.prototype && - "function" === typeof Component.prototype.render - ) { - var componentName = getComponentNameFromType(Component) || "Unknown"; - didWarnAboutBadClass[componentName] || - (error$jscomp$0( - "The <%s /> component appears to have a render method, but doesn't extend React.Component. This is likely to cause errors. Change %s to extend React.Component instead.", - componentName, - componentName - ), - (didWarnAboutBadClass[componentName] = !0)); - } - workInProgress.mode & 8 && - ReactStrictModeWarnings.recordLegacyContextWarning( - workInProgress, - null - ); - null === current && - (validateFunctionComponentInDev(workInProgress, workInProgress.type), - Component.contextTypes && - error$jscomp$0( - "%s uses the legacy contextTypes API which was removed in React 19. Use React.createContext() with React.useContext() instead.", - getComponentNameFromType(Component) || "Unknown" - )); - prepareToReadContext(workInProgress, renderLanes); - markComponentRenderStarted(workInProgress); - Component = renderWithHooks( - current, - workInProgress, - Component, - nextProps, - void 0, - renderLanes + function hideInstance(instance) { + var viewConfig = instance.viewConfig; + var updatePayload = create( + { + style: { + display: "none" + } + }, + viewConfig.validAttributes ); - markComponentRenderStopped(); - if (null !== current && !didReceiveUpdate) - return ( - bailoutHooks(current, workInProgress, renderLanes), - bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) - ); - workInProgress.flags |= 1; - reconcileChildren(current, workInProgress, Component, renderLanes); - return workInProgress.child; - } - function replayFunctionComponent( - current, - workInProgress, - nextProps, - Component, - secondArg, - renderLanes - ) { - prepareToReadContext(workInProgress, renderLanes); - markComponentRenderStarted(workInProgress); - hookTypesUpdateIndexDev = -1; - ignorePreviousDependencies = - null !== current && current.type !== workInProgress.type; - nextProps = renderWithHooksAgain( - workInProgress, - Component, - nextProps, - secondArg + ReactNativePrivateInterface.UIManager.updateView( + instance._nativeTag, + viewConfig.uiViewClassName, + updatePayload ); - finishRenderingHooks(current, workInProgress); - markComponentRenderStopped(); - if (null !== current && !didReceiveUpdate) - return ( - bailoutHooks(current, workInProgress, renderLanes), - bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) - ); - workInProgress.flags |= 1; - reconcileChildren(current, workInProgress, nextProps, renderLanes); - return workInProgress.child; } - function updateClassComponent( - current, - workInProgress, - Component, - nextProps, - renderLanes - ) { - switch (shouldErrorImpl(workInProgress)) { - case !1: - var _instance = workInProgress.stateNode, - state = new workInProgress.type( - workInProgress.memoizedProps, - _instance.context - ).state; - _instance.updater.enqueueSetState(_instance, state, null); - break; - case !0: - workInProgress.flags |= 128; - workInProgress.flags |= 65536; - _instance = Error("Simulated error coming from DevTools"); - var lane = renderLanes & -renderLanes; - workInProgress.lanes |= lane; - state = workInProgressRoot; - if (null === state) - throw Error( - "Expected a work-in-progress root. This is a bug in React. Please file an issue." - ); - lane = createClassErrorUpdate(lane); - initializeClassErrorUpdate( - lane, - state, - workInProgress, - createCapturedValueAtFiber(_instance, workInProgress) - ); - enqueueCapturedUpdate(workInProgress, lane); - } - prepareToReadContext(workInProgress, renderLanes); - if (null === workInProgress.stateNode) - resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress), - constructClassInstance(workInProgress, Component, nextProps), - mountClassInstance(workInProgress, Component, nextProps, renderLanes), - (_instance = !0); - else if (null === current) { - _instance = workInProgress.stateNode; - var unresolvedOldProps = workInProgress.memoizedProps; - lane = resolveClassComponentProps(Component, unresolvedOldProps); - _instance.props = lane; - var oldContext = _instance.context, - contextType = Component.contextType; - state = emptyContextObject; - "object" === typeof contextType && - null !== contextType && - (state = readContext(contextType)); - var getDerivedStateFromProps = Component.getDerivedStateFromProps; - contextType = - "function" === typeof getDerivedStateFromProps || - "function" === typeof _instance.getSnapshotBeforeUpdate; - unresolvedOldProps = workInProgress.pendingProps !== unresolvedOldProps; - contextType || - ("function" !== typeof _instance.UNSAFE_componentWillReceiveProps && - "function" !== typeof _instance.componentWillReceiveProps) || - ((unresolvedOldProps || oldContext !== state) && - callComponentWillReceiveProps( - workInProgress, - _instance, - nextProps, - state - )); - hasForceUpdate = !1; - var oldState = workInProgress.memoizedState; - _instance.state = oldState; - processUpdateQueue(workInProgress, nextProps, _instance, renderLanes); - suspendIfUpdateReadFromEntangledAsyncAction(); - oldContext = workInProgress.memoizedState; - unresolvedOldProps || oldState !== oldContext || hasForceUpdate - ? ("function" === typeof getDerivedStateFromProps && - (applyDerivedStateFromProps( - workInProgress, - Component, - getDerivedStateFromProps, - nextProps - ), - (oldContext = workInProgress.memoizedState)), - (lane = - hasForceUpdate || - checkShouldComponentUpdate( - workInProgress, - Component, - lane, - nextProps, - oldState, - oldContext, - state - )) - ? (contextType || - ("function" !== typeof _instance.UNSAFE_componentWillMount && - "function" !== typeof _instance.componentWillMount) || - ("function" === typeof _instance.componentWillMount && - _instance.componentWillMount(), - "function" === typeof _instance.UNSAFE_componentWillMount && - _instance.UNSAFE_componentWillMount()), - "function" === typeof _instance.componentDidMount && - (workInProgress.flags |= 4194308), - 0 !== (workInProgress.mode & 16) && - (workInProgress.flags |= 67108864)) - : ("function" === typeof _instance.componentDidMount && - (workInProgress.flags |= 4194308), - 0 !== (workInProgress.mode & 16) && - (workInProgress.flags |= 67108864), - (workInProgress.memoizedProps = nextProps), - (workInProgress.memoizedState = oldContext)), - (_instance.props = nextProps), - (_instance.state = oldContext), - (_instance.context = state), - (_instance = lane)) - : ("function" === typeof _instance.componentDidMount && - (workInProgress.flags |= 4194308), - 0 !== (workInProgress.mode & 16) && - (workInProgress.flags |= 67108864), - (_instance = !1)); - } else { - _instance = workInProgress.stateNode; - cloneUpdateQueue(current, workInProgress); - state = workInProgress.memoizedProps; - contextType = resolveClassComponentProps(Component, state); - _instance.props = contextType; - getDerivedStateFromProps = workInProgress.pendingProps; - oldState = _instance.context; - oldContext = Component.contextType; - lane = emptyContextObject; - "object" === typeof oldContext && - null !== oldContext && - (lane = readContext(oldContext)); - unresolvedOldProps = Component.getDerivedStateFromProps; - (oldContext = - "function" === typeof unresolvedOldProps || - "function" === typeof _instance.getSnapshotBeforeUpdate) || - ("function" !== typeof _instance.UNSAFE_componentWillReceiveProps && - "function" !== typeof _instance.componentWillReceiveProps) || - ((state !== getDerivedStateFromProps || oldState !== lane) && - callComponentWillReceiveProps( - workInProgress, - _instance, - nextProps, - lane - )); - hasForceUpdate = !1; - oldState = workInProgress.memoizedState; - _instance.state = oldState; - processUpdateQueue(workInProgress, nextProps, _instance, renderLanes); - suspendIfUpdateReadFromEntangledAsyncAction(); - var newState = workInProgress.memoizedState; - state !== getDerivedStateFromProps || - oldState !== newState || - hasForceUpdate - ? ("function" === typeof unresolvedOldProps && - (applyDerivedStateFromProps( - workInProgress, - Component, - unresolvedOldProps, - nextProps - ), - (newState = workInProgress.memoizedState)), - (contextType = - hasForceUpdate || - checkShouldComponentUpdate( - workInProgress, - Component, - contextType, - nextProps, - oldState, - newState, - lane - ) || - !1) - ? (oldContext || - ("function" !== typeof _instance.UNSAFE_componentWillUpdate && - "function" !== typeof _instance.componentWillUpdate) || - ("function" === typeof _instance.componentWillUpdate && - _instance.componentWillUpdate(nextProps, newState, lane), - "function" === typeof _instance.UNSAFE_componentWillUpdate && - _instance.UNSAFE_componentWillUpdate( - nextProps, - newState, - lane - )), - "function" === typeof _instance.componentDidUpdate && - (workInProgress.flags |= 4), - "function" === typeof _instance.getSnapshotBeforeUpdate && - (workInProgress.flags |= 1024)) - : ("function" !== typeof _instance.componentDidUpdate || - (state === current.memoizedProps && - oldState === current.memoizedState) || - (workInProgress.flags |= 4), - "function" !== typeof _instance.getSnapshotBeforeUpdate || - (state === current.memoizedProps && - oldState === current.memoizedState) || - (workInProgress.flags |= 1024), - (workInProgress.memoizedProps = nextProps), - (workInProgress.memoizedState = newState)), - (_instance.props = nextProps), - (_instance.state = newState), - (_instance.context = lane), - (_instance = contextType)) - : ("function" !== typeof _instance.componentDidUpdate || - (state === current.memoizedProps && - oldState === current.memoizedState) || - (workInProgress.flags |= 4), - "function" !== typeof _instance.getSnapshotBeforeUpdate || - (state === current.memoizedProps && - oldState === current.memoizedState) || - (workInProgress.flags |= 1024), - (_instance = !1)); - } - current = finishClassComponent( - current, - workInProgress, - Component, - _instance, - !1, - renderLanes + function hideTextInstance(textInstance) { + throw new Error("Not yet implemented."); + } + function unhideInstance(instance, props) { + var viewConfig = instance.viewConfig; + var updatePayload = diff( + assign({}, props, { + style: [ + props.style, + { + display: "none" + } + ] + }), + props, + viewConfig.validAttributes + ); + ReactNativePrivateInterface.UIManager.updateView( + instance._nativeTag, + viewConfig.uiViewClassName, + updatePayload ); - Component = workInProgress.stateNode; - _instance && - Component.props !== nextProps && - (didWarnAboutReassigningProps || - error$jscomp$0( - "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" - ), - (didWarnAboutReassigningProps = !0)); - return current; } - function finishClassComponent( - current$jscomp$0, - workInProgress, - Component, - shouldUpdate, - hasContext, - renderLanes - ) { - markRef(current$jscomp$0, workInProgress); - hasContext = 0 !== (workInProgress.flags & 128); - if (!shouldUpdate && !hasContext) - return bailoutOnAlreadyFinishedWork( - current$jscomp$0, - workInProgress, - renderLanes - ); - shouldUpdate = workInProgress.stateNode; - ReactSharedInternals.getCurrentStack = - null === workInProgress ? null : getCurrentFiberStackInDev; - isRendering = !1; - current = workInProgress; - if ( - hasContext && - "function" !== typeof Component.getDerivedStateFromError - ) - (Component = null), (profilerStartTime = -1); - else { - markComponentRenderStarted(workInProgress); - Component = callRenderInDEV(shouldUpdate); - if (workInProgress.mode & 8) { - setIsStrictModeForDevtools(!0); - try { - callRenderInDEV(shouldUpdate); - } finally { - setIsStrictModeForDevtools(!1); - } + function unhideTextInstance(textInstance, text) { + throw new Error("Not yet implemented."); + } + function preloadInstance(type, props) { + // Return true to indicate it's already loaded + return true; + } + function waitForCommitToBeReady() { + return null; + } + + var valueStack = []; + var fiberStack; + + { + fiberStack = []; + } + + var index = -1; + + function createCursor(defaultValue) { + return { + current: defaultValue + }; + } + + function pop(cursor, fiber) { + if (index < 0) { + { + error("Unexpected pop."); } - markComponentRenderStopped(); + + return; } - workInProgress.flags |= 1; - null !== current$jscomp$0 && hasContext - ? ((workInProgress.child = reconcileChildFibers( - workInProgress, - current$jscomp$0.child, - null, - renderLanes - )), - (workInProgress.child = reconcileChildFibers( - workInProgress, - null, - Component, - renderLanes - ))) - : reconcileChildren( - current$jscomp$0, - workInProgress, - Component, - renderLanes - ); - workInProgress.memoizedState = shouldUpdate.state; - return workInProgress.child; + + { + if (fiber !== fiberStack[index]) { + error("Unexpected Fiber popped."); + } + } + + cursor.current = valueStack[index]; + valueStack[index] = null; + + { + fiberStack[index] = null; + } + + index--; } - function validateFunctionComponentInDev(workInProgress, Component) { - Component && - Component.childContextTypes && - error$jscomp$0( - "childContextTypes cannot be defined on a function component.\n %s.childContextTypes = ...", - Component.displayName || Component.name || "Component" - ); - "function" === typeof Component.getDerivedStateFromProps && - ((workInProgress = getComponentNameFromType(Component) || "Unknown"), - didWarnAboutGetDerivedStateOnFunctionComponent[workInProgress] || - (error$jscomp$0( - "%s: Function components do not support getDerivedStateFromProps.", - workInProgress - ), - (didWarnAboutGetDerivedStateOnFunctionComponent[workInProgress] = - !0))); - "object" === typeof Component.contextType && - null !== Component.contextType && - ((Component = getComponentNameFromType(Component) || "Unknown"), - didWarnAboutContextTypeOnFunctionComponent[Component] || - (error$jscomp$0( - "%s: Function components do not support contextType.", - Component - ), - (didWarnAboutContextTypeOnFunctionComponent[Component] = !0))); + + function push(cursor, value, fiber) { + index++; + valueStack[index] = cursor.current; + + { + fiberStack[index] = fiber; + } + + cursor.current = value; } - function mountSuspenseOffscreenState(renderLanes) { - return { baseLanes: renderLanes, cachePool: getSuspendedCache() }; + + var emptyContextObject = {}; + + { + Object.freeze(emptyContextObject); + } // A cursor to the current merged context object on the stack. + + function hasContextChanged() { + { + return false; + } } - function getRemainingWorkInPrimaryTree( - current, - primaryTreeDidDefer, - renderLanes - ) { - current = null !== current ? current.childLanes & ~renderLanes : 0; - primaryTreeDidDefer && (current |= workInProgressDeferredLane); - return current; + + function isContextProvider(type) { + { + return false; + } } - function updateSuspenseComponent(current, workInProgress, renderLanes) { - var nextProps = workInProgress.pendingProps; - shouldSuspendImpl(workInProgress) && (workInProgress.flags |= 128); - var showFallback = !1, - didSuspend = 0 !== (workInProgress.flags & 128), - JSCompiler_temp; - (JSCompiler_temp = didSuspend) || - (JSCompiler_temp = - null !== current && null === current.memoizedState - ? !1 - : 0 !== (suspenseStackCursor.current & ForceSuspenseFallback)); - JSCompiler_temp && ((showFallback = !0), (workInProgress.flags &= -129)); - JSCompiler_temp = 0 !== (workInProgress.flags & 32); - workInProgress.flags &= -33; - if (null === current) { - var nextPrimaryChildren = nextProps.children; - nextProps = nextProps.fallback; - if (showFallback) - return ( - reuseSuspenseHandlerOnStack(workInProgress), - (showFallback = workInProgress.mode), - (didSuspend = workInProgress.child), - (nextPrimaryChildren = { - mode: "hidden", - children: nextPrimaryChildren - }), - 0 === (showFallback & 1) && null !== didSuspend - ? ((didSuspend.childLanes = 0), - (didSuspend.pendingProps = nextPrimaryChildren), - workInProgress.mode & 2 && - ((didSuspend.actualDuration = 0), - (didSuspend.actualStartTime = -1), - (didSuspend.selfBaseDuration = 0), - (didSuspend.treeBaseDuration = 0))) - : (didSuspend = createFiberFromOffscreen( - nextPrimaryChildren, - showFallback, - 0, - null - )), - (nextProps = createFiberFromFragment( - nextProps, - showFallback, - renderLanes, - null - )), - (didSuspend.return = workInProgress), - (nextProps.return = workInProgress), - (didSuspend.sibling = nextProps), - (workInProgress.child = didSuspend), - (nextPrimaryChildren = workInProgress.child), - (nextPrimaryChildren.memoizedState = - mountSuspenseOffscreenState(renderLanes)), - (nextPrimaryChildren.childLanes = getRemainingWorkInPrimaryTree( - current, - JSCompiler_temp, - renderLanes - )), - (workInProgress.memoizedState = SUSPENDED_MARKER), - nextProps - ); - pushPrimaryTreeSuspenseHandler(workInProgress); - return mountSuspensePrimaryChildren( - workInProgress, - nextPrimaryChildren - ); + + function processChildContext(fiber, type, parentContext) { + { + return parentContext; } - nextPrimaryChildren = current.memoizedState; - if ( - null !== nextPrimaryChildren && - null !== nextPrimaryChildren.dehydrated - ) { - if (didSuspend) - workInProgress.flags & 256 - ? (pushPrimaryTreeSuspenseHandler(workInProgress), - (workInProgress.flags &= -257), - (workInProgress = retrySuspenseComponentWithoutHydrating( - current, - workInProgress, - renderLanes - ))) - : null !== workInProgress.memoizedState - ? (reuseSuspenseHandlerOnStack(workInProgress), - (workInProgress.child = current.child), - (workInProgress.flags |= 128), - (workInProgress = null)) - : (reuseSuspenseHandlerOnStack(workInProgress), - (nextPrimaryChildren = nextProps.fallback), - (showFallback = workInProgress.mode), - (nextProps = createFiberFromOffscreen( - { mode: "visible", children: nextProps.children }, - showFallback, - 0, - null - )), - (nextPrimaryChildren = createFiberFromFragment( - nextPrimaryChildren, - showFallback, - renderLanes, - null - )), - (nextPrimaryChildren.flags |= 2), - (nextProps.return = workInProgress), - (nextPrimaryChildren.return = workInProgress), - (nextProps.sibling = nextPrimaryChildren), - (workInProgress.child = nextProps), - 0 !== (workInProgress.mode & 1) && - reconcileChildFibers( - workInProgress, - current.child, - null, - renderLanes - ), - (nextProps = workInProgress.child), - (nextProps.memoizedState = - mountSuspenseOffscreenState(renderLanes)), - (nextProps.childLanes = getRemainingWorkInPrimaryTree( - current, - JSCompiler_temp, - renderLanes - )), - (workInProgress.memoizedState = SUSPENDED_MARKER), - (workInProgress = nextPrimaryChildren)); - else if ( - (pushPrimaryTreeSuspenseHandler(workInProgress), - isSuspenseInstanceFallback()) - ) - (showFallback = getSuspenseInstanceFallbackErrorDetails()), - (JSCompiler_temp = showFallback.digest), - (nextPrimaryChildren = showFallback.message), - (nextProps = showFallback.stack), - (showFallback = showFallback.componentStack), - (nextPrimaryChildren = nextPrimaryChildren - ? Error(nextPrimaryChildren) - : Error( - "The server could not finish this Suspense boundary, likely due to an error during server rendering. Switched to client rendering." - )), - (nextPrimaryChildren.stack = nextProps || ""), - (nextPrimaryChildren.digest = JSCompiler_temp), - (JSCompiler_temp = void 0 === showFallback ? null : showFallback), - "string" === typeof JSCompiler_temp && - CapturedStacks.set(nextPrimaryChildren, JSCompiler_temp), - (JSCompiler_temp = { - value: nextPrimaryChildren, - source: null, - stack: JSCompiler_temp - }), - null === hydrationErrors - ? (hydrationErrors = [JSCompiler_temp]) - : hydrationErrors.push(JSCompiler_temp), - (workInProgress = retrySuspenseComponentWithoutHydrating( - current, - workInProgress, - renderLanes - )); - else if ( - ((JSCompiler_temp = 0 !== (renderLanes & current.childLanes)), - didReceiveUpdate || JSCompiler_temp) - ) { - JSCompiler_temp = workInProgressRoot; - if (null !== JSCompiler_temp) { - nextProps = renderLanes & -renderLanes; - if (0 !== (nextProps & SyncUpdateLanes)) - nextProps = SyncHydrationLane; - else - switch (nextProps) { - case SyncLane: - nextProps = SyncHydrationLane; - break; - case InputContinuousLane: - nextProps = InputContinuousHydrationLane; - break; - case DefaultLane: - nextProps = DefaultHydrationLane; - break; - case 128: - case 256: - case 512: - case 1024: - case 2048: - case 4096: - case 8192: - case 16384: - case 32768: - case 65536: - case 131072: - case 262144: - case 524288: - case 1048576: - case 2097152: - case 4194304: - case 8388608: - case 16777216: - case 33554432: - nextProps = TransitionHydrationLane; - break; - case IdleLane: - nextProps = IdleHydrationLane; - break; - default: - nextProps = 0; - } - nextProps = - 0 !== (nextProps & (JSCompiler_temp.suspendedLanes | renderLanes)) - ? 0 - : nextProps; - if (0 !== nextProps && nextProps !== nextPrimaryChildren.retryLane) - throw ( - ((nextPrimaryChildren.retryLane = nextProps), - enqueueConcurrentRenderForLane(current, nextProps), - scheduleUpdateOnFiber(JSCompiler_temp, current, nextProps), - SelectiveHydrationException) - ); - } - isSuspenseInstancePending() || renderDidSuspendDelayIfPossible(); - workInProgress = retrySuspenseComponentWithoutHydrating( - current, - workInProgress, - renderLanes - ); - } else - isSuspenseInstancePending() - ? ((workInProgress.flags |= 128), - (workInProgress.child = current.child), - retryDehydratedSuspenseBoundary.bind(null, current), - registerSuspenseInstanceRetry(), - (workInProgress = null)) - : ((workInProgress = mountSuspensePrimaryChildren( - workInProgress, - nextProps.children - )), - (workInProgress.flags |= 4096)); - return workInProgress; - } - if (showFallback) { - reuseSuspenseHandlerOnStack(workInProgress); - nextPrimaryChildren = nextProps.fallback; - showFallback = workInProgress.mode; - didSuspend = current.child; - var currentFallbackChildFragment = didSuspend.sibling, - primaryChildProps = { mode: "hidden", children: nextProps.children }; - 0 === (showFallback & 1) && workInProgress.child !== didSuspend - ? ((nextProps = workInProgress.child), - (nextProps.childLanes = 0), - (nextProps.pendingProps = primaryChildProps), - workInProgress.mode & 2 && - ((nextProps.actualDuration = 0), - (nextProps.actualStartTime = -1), - (nextProps.selfBaseDuration = didSuspend.selfBaseDuration), - (nextProps.treeBaseDuration = didSuspend.treeBaseDuration)), - (workInProgress.deletions = null)) - : ((nextProps = createWorkInProgress(didSuspend, primaryChildProps)), - (nextProps.subtreeFlags = didSuspend.subtreeFlags & 31457280)); - null !== currentFallbackChildFragment - ? (nextPrimaryChildren = createWorkInProgress( - currentFallbackChildFragment, - nextPrimaryChildren - )) - : ((nextPrimaryChildren = createFiberFromFragment( - nextPrimaryChildren, - showFallback, - renderLanes, - null - )), - (nextPrimaryChildren.flags |= 2)); - nextPrimaryChildren.return = workInProgress; - nextProps.return = workInProgress; - nextProps.sibling = nextPrimaryChildren; - workInProgress.child = nextProps; - nextProps = nextPrimaryChildren; - nextPrimaryChildren = workInProgress.child; - showFallback = current.child.memoizedState; - null === showFallback - ? (showFallback = mountSuspenseOffscreenState(renderLanes)) - : ((didSuspend = showFallback.cachePool), - null !== didSuspend - ? ((currentFallbackChildFragment = CacheContext._currentValue), - (didSuspend = - didSuspend.parent !== currentFallbackChildFragment - ? { - parent: currentFallbackChildFragment, - pool: currentFallbackChildFragment - } - : didSuspend)) - : (didSuspend = getSuspendedCache()), - (showFallback = { - baseLanes: showFallback.baseLanes | renderLanes, - cachePool: didSuspend - })); - nextPrimaryChildren.memoizedState = showFallback; - nextPrimaryChildren.childLanes = getRemainingWorkInPrimaryTree( - current, - JSCompiler_temp, - renderLanes - ); - workInProgress.memoizedState = SUSPENDED_MARKER; - return nextProps; + } + + function findCurrentUnmaskedContext(fiber) { + { + return emptyContextObject; } - pushPrimaryTreeSuspenseHandler(workInProgress); - JSCompiler_temp = current.child; - current = JSCompiler_temp.sibling; - JSCompiler_temp = createWorkInProgress(JSCompiler_temp, { - mode: "visible", - children: nextProps.children - }); - 0 === (workInProgress.mode & 1) && (JSCompiler_temp.lanes = renderLanes); - JSCompiler_temp.return = workInProgress; - JSCompiler_temp.sibling = null; - null !== current && - ((renderLanes = workInProgress.deletions), - null === renderLanes - ? ((workInProgress.deletions = [current]), - (workInProgress.flags |= 16)) - : renderLanes.push(current)); - workInProgress.child = JSCompiler_temp; - workInProgress.memoizedState = null; - return JSCompiler_temp; } - function mountSuspensePrimaryChildren(workInProgress, primaryChildren) { - primaryChildren = createFiberFromOffscreen( - { mode: "visible", children: primaryChildren }, - workInProgress.mode, - 0, - null + + var LegacyRoot = 0; + var ConcurrentRoot = 1; + + // We use the existence of the state object as an indicator that the component + // is hidden. + var OffscreenVisible = + /* */ + 1; + var OffscreenDetached = + /* */ + 2; + var OffscreenPassiveEffectsConnected = + /* */ + 4; + function isOffscreenManual(offscreenFiber) { + return ( + offscreenFiber.memoizedProps !== null && + offscreenFiber.memoizedProps.mode === "manual" ); - primaryChildren.return = workInProgress; - return (workInProgress.child = primaryChildren); } - function retrySuspenseComponentWithoutHydrating( - current, - workInProgress, - renderLanes - ) { - reconcileChildFibers(workInProgress, current.child, null, renderLanes); - current = mountSuspensePrimaryChildren( - workInProgress, - workInProgress.pendingProps.children + + /** + * inlined Object.is polyfill to avoid requiring consumers ship their own + * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is + */ + function is(x, y) { + return ( + (x === y && (x !== 0 || 1 / x === 1 / y)) || (x !== x && y !== y) // eslint-disable-line no-self-compare ); - current.flags |= 2; - workInProgress.memoizedState = null; - return current; } - function scheduleSuspenseWorkOnFiber(fiber, renderLanes, propagationRoot) { - fiber.lanes |= renderLanes; - var alternate = fiber.alternate; - null !== alternate && (alternate.lanes |= renderLanes); - scheduleContextWorkOnParentPath( - fiber.return, - renderLanes, - propagationRoot - ); + + var objectIs = typeof Object.is === "function" ? Object.is : is; // $FlowFixMe[method-unbinding] + + // This is imported by the event replaying implementation in React DOM. It's + // in a separate file to break a circular dependency between the renderer and + // the reconciler. + function isRootDehydrated(root) { + var currentState = root.current.memoizedState; + return currentState.isDehydrated; } - function validateSuspenseListNestedChild(childSlot, index) { - var isAnArray = isArrayImpl(childSlot); - childSlot = !isAnArray && "function" === typeof getIteratorFn(childSlot); - return isAnArray || childSlot - ? ((isAnArray = isAnArray ? "array" : "iterable"), - error$jscomp$0( - "A nested %s was passed to row #%s in . Wrap it in an additional SuspenseList to configure its revealOrder: ... {%s} ... ", - isAnArray, - index, - isAnArray - ), - !1) - : !0; + + var contextStackCursor = createCursor(null); + var contextFiberStackCursor = createCursor(null); + var rootInstanceStackCursor = createCursor(null); // Represents the nearest host transition provider (in React DOM, a ) + + function requiredContext(c) { + { + if (c === null) { + error( + "Expected host context to exist. This error is likely caused by a bug " + + "in React. Please file an issue." + ); + } + } + + return c; } - function initSuspenseListRenderState( - workInProgress, - isBackwards, - tail, - lastContentRow, - tailMode - ) { - var renderState = workInProgress.memoizedState; - null === renderState - ? (workInProgress.memoizedState = { - isBackwards: isBackwards, - rendering: null, - renderingStartTime: 0, - last: lastContentRow, - tail: tail, - tailMode: tailMode - }) - : ((renderState.isBackwards = isBackwards), - (renderState.rendering = null), - (renderState.renderingStartTime = 0), - (renderState.last = lastContentRow), - (renderState.tail = tail), - (renderState.tailMode = tailMode)); + + function getRootHostContainer() { + var rootInstance = requiredContext(rootInstanceStackCursor.current); + return rootInstance; } - function updateSuspenseListComponent(current, workInProgress, renderLanes) { - var nextProps = workInProgress.pendingProps, - revealOrder = nextProps.revealOrder, - tailMode = nextProps.tail; - nextProps = nextProps.children; - if ( - void 0 !== revealOrder && - "forwards" !== revealOrder && - "backwards" !== revealOrder && - "together" !== revealOrder && - !didWarnAboutRevealOrder[revealOrder] - ) - if ( - ((didWarnAboutRevealOrder[revealOrder] = !0), - "string" === typeof revealOrder) - ) - switch (revealOrder.toLowerCase()) { - case "together": - case "forwards": - case "backwards": - error$jscomp$0( - '"%s" is not a valid value for revealOrder on . Use lowercase "%s" instead.', - revealOrder, - revealOrder.toLowerCase() - ); - break; - case "forward": - case "backward": - error$jscomp$0( - '"%s" is not a valid value for revealOrder on . React uses the -s suffix in the spelling. Use "%ss" instead.', - revealOrder, - revealOrder.toLowerCase() - ); - break; - default: - error$jscomp$0( - '"%s" is not a supported revealOrder on . Did you mean "together", "forwards" or "backwards"?', - revealOrder - ); - } - else - error$jscomp$0( - '%s is not a supported value for revealOrder on . Did you mean "together", "forwards" or "backwards"?', - revealOrder - ); - void 0 === tailMode || - didWarnAboutTailOptions[tailMode] || - ("collapsed" !== tailMode && "hidden" !== tailMode - ? ((didWarnAboutTailOptions[tailMode] = !0), - error$jscomp$0( - '"%s" is not a supported value for tail on . Did you mean "collapsed" or "hidden"?', - tailMode - )) - : "forwards" !== revealOrder && - "backwards" !== revealOrder && - ((didWarnAboutTailOptions[tailMode] = !0), - error$jscomp$0( - ' is only valid if revealOrder is "forwards" or "backwards". Did you mean to specify revealOrder="forwards"?', - tailMode - ))); - a: if ( - ("forwards" === revealOrder || "backwards" === revealOrder) && - void 0 !== nextProps && - null !== nextProps && - !1 !== nextProps - ) - if (isArrayImpl(nextProps)) - for (var i = 0; i < nextProps.length; i++) { - if (!validateSuspenseListNestedChild(nextProps[i], i)) break a; - } - else if (((i = getIteratorFn(nextProps)), "function" === typeof i)) { - if ((i = i.call(nextProps))) - for (var step = i.next(), _i = 0; !step.done; step = i.next()) { - if (!validateSuspenseListNestedChild(step.value, _i)) break a; - _i++; - } - } else - error$jscomp$0( - '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 - ); - reconcileChildren(current, workInProgress, nextProps, renderLanes); - nextProps = suspenseStackCursor.current; - if (0 !== (nextProps & ForceSuspenseFallback)) - (nextProps = - (nextProps & SubtreeSuspenseContextMask) | ForceSuspenseFallback), - (workInProgress.flags |= 128); - else { - if (null !== current && 0 !== (current.flags & 128)) - a: for (current = workInProgress.child; null !== current; ) { - if (13 === current.tag) - null !== current.memoizedState && - scheduleSuspenseWorkOnFiber( - current, - renderLanes, - workInProgress - ); - else if (19 === current.tag) - scheduleSuspenseWorkOnFiber(current, renderLanes, workInProgress); - else if (null !== current.child) { - current.child.return = current; - current = current.child; - continue; - } - if (current === workInProgress) break a; - for (; null === current.sibling; ) { - if (null === current.return || current.return === workInProgress) - break a; - current = current.return; - } - current.sibling.return = current.return; - current = current.sibling; - } - nextProps &= SubtreeSuspenseContextMask; + + function pushHostContainer(fiber, nextRootInstance) { + // Push current root instance onto the stack; + // This allows us to reset root when portals are popped. + push(rootInstanceStackCursor, nextRootInstance, fiber); // Track the context and the Fiber that provided it. + // This enables us to pop only Fibers that provide unique contexts. + + push(contextFiberStackCursor, fiber, fiber); // Finally, we need to push the host context to the stack. + // However, we can't just call getRootHostContext() and push it because + // we'd have a different number of entries on the stack depending on + // whether getRootHostContext() throws somewhere in renderer code or not. + // So we push an empty value first. This lets us safely unwind on errors. + + push(contextStackCursor, null, fiber); + var nextRootContext = getRootHostContext(); // Now that we know this function doesn't throw, replace it. + + pop(contextStackCursor, fiber); + push(contextStackCursor, nextRootContext, fiber); + } + + function popHostContainer(fiber) { + pop(contextStackCursor, fiber); + pop(contextFiberStackCursor, fiber); + pop(rootInstanceStackCursor, fiber); + } + + function getHostContext() { + var context = requiredContext(contextStackCursor.current); + return context; + } + + function pushHostContext(fiber) { + var context = requiredContext(contextStackCursor.current); + var nextContext = getChildHostContext(context, fiber.type); // Don't push this Fiber's context unless it's unique. + + if (context !== nextContext) { + // Track the context and the Fiber that provided it. + // This enables us to pop only Fibers that provide unique contexts. + push(contextFiberStackCursor, fiber, fiber); + push(contextStackCursor, nextContext, fiber); } - push(suspenseStackCursor, nextProps, workInProgress); - if (0 === (workInProgress.mode & 1)) workInProgress.memoizedState = null; - else - switch (revealOrder) { - case "forwards": - renderLanes = workInProgress.child; - for (revealOrder = null; null !== renderLanes; ) - (current = renderLanes.alternate), - null !== current && - null === findFirstSuspended(current) && - (revealOrder = renderLanes), - (renderLanes = renderLanes.sibling); - renderLanes = revealOrder; - null === renderLanes - ? ((revealOrder = workInProgress.child), - (workInProgress.child = null)) - : ((revealOrder = renderLanes.sibling), - (renderLanes.sibling = null)); - initSuspenseListRenderState( - workInProgress, - !1, - revealOrder, - renderLanes, - tailMode - ); - break; - case "backwards": - renderLanes = null; - revealOrder = workInProgress.child; - for (workInProgress.child = null; null !== revealOrder; ) { - current = revealOrder.alternate; - if (null !== current && null === findFirstSuspended(current)) { - workInProgress.child = revealOrder; - break; - } - current = revealOrder.sibling; - revealOrder.sibling = renderLanes; - renderLanes = revealOrder; - revealOrder = current; - } - initSuspenseListRenderState( - workInProgress, - !0, - renderLanes, - null, - tailMode - ); - break; - case "together": - initSuspenseListRenderState(workInProgress, !1, null, null, void 0); - break; - default: - workInProgress.memoizedState = null; + } + + function popHostContext(fiber) { + if (contextFiberStackCursor.current === fiber) { + // Do not pop unless this Fiber provided the current context. + // pushHostContext() only pushes Fibers that provide unique contexts. + pop(contextStackCursor, fiber); + pop(contextFiberStackCursor, fiber); + } + } + + var isHydrating = false; // This flag allows for warning supression when we expect there to be mismatches + + var hydrationErrors = null; + + function prepareToHydrateHostInstance(fiber, hostContext) { + { + throw new Error( + "Expected prepareToHydrateHostInstance() to never be called. " + + "This error is likely caused by a bug in React. Please file an issue." + ); + } + } + + function prepareToHydrateHostTextInstance(fiber) { + { + throw new Error( + "Expected prepareToHydrateHostTextInstance() to never be called. " + + "This error is likely caused by a bug in React. Please file an issue." + ); + } + } + + function prepareToHydrateHostSuspenseInstance(fiber) { + { + throw new Error( + "Expected prepareToHydrateHostSuspenseInstance() to never be called. " + + "This error is likely caused by a bug in React. Please file an issue." + ); + } + } + + function popHydrationState(fiber) { + { + return false; + } + } + + function upgradeHydrationErrorsToRecoverable() { + if (hydrationErrors !== null) { + // Successfully completed a forced client render. The errors that occurred + // during the hydration attempt are now recovered. We will log them in + // commit phase, once the entire tree has finished. + queueRecoverableErrors(hydrationErrors); + hydrationErrors = null; + } + } + + function getIsHydrating() { + return isHydrating; + } + + function queueHydrationError(error) { + if (hydrationErrors === null) { + hydrationErrors = [error]; + } else { + hydrationErrors.push(error); + } + } + + // we wait until the current render is over (either finished or interrupted) + // before adding it to the fiber/hook queue. Push to this array so we can + // access the queue, fiber, update, et al later. + + var concurrentQueues = []; + var concurrentQueuesIndex = 0; + var concurrentlyUpdatedLanes = NoLanes; + function finishQueueingConcurrentUpdates() { + var endIndex = concurrentQueuesIndex; + concurrentQueuesIndex = 0; + concurrentlyUpdatedLanes = NoLanes; + var i = 0; + + while (i < endIndex) { + var fiber = concurrentQueues[i]; + concurrentQueues[i++] = null; + var queue = concurrentQueues[i]; + concurrentQueues[i++] = null; + var update = concurrentQueues[i]; + concurrentQueues[i++] = null; + var lane = concurrentQueues[i]; + concurrentQueues[i++] = null; + + if (queue !== null && update !== null) { + 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; } - return workInProgress.child; + + if (lane !== NoLane) { + markUpdateLaneFromFiberToRoot(fiber, update, lane); + } + } } - function resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress) { - 0 === (workInProgress.mode & 1) && - null !== current && - ((current.alternate = null), - (workInProgress.alternate = null), - (workInProgress.flags |= 2)); + function getConcurrentlyUpdatedLanes() { + return concurrentlyUpdatedLanes; } - function bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderLanes - ) { - null !== current && (workInProgress.dependencies = current.dependencies); - profilerStartTime = -1; - workInProgressRootSkippedLanes |= workInProgress.lanes; - 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; + + function enqueueUpdate$1(fiber, queue, update, lane) { + // Don't update the `childLanes` on the return path yet. If we already in + // the middle of rendering, wait until after it has completed. + concurrentQueues[concurrentQueuesIndex++] = fiber; + concurrentQueues[concurrentQueuesIndex++] = queue; + concurrentQueues[concurrentQueuesIndex++] = update; + concurrentQueues[concurrentQueuesIndex++] = lane; + concurrentlyUpdatedLanes = mergeLanes(concurrentlyUpdatedLanes, lane); // The fiber's `lane` field is used in some places to check if any work is + // scheduled, to perform an eager bailout, so we need to update it immediately. + // TODO: We should probably move this to the "shared" queue instead. + + fiber.lanes = mergeLanes(fiber.lanes, lane); + var alternate = fiber.alternate; + + if (alternate !== null) { + alternate.lanes = mergeLanes(alternate.lanes, lane); } - return workInProgress.child; } - function attemptEarlyBailoutIfNoScheduledUpdate( - current, - workInProgress, - renderLanes + + function enqueueConcurrentHookUpdate(fiber, queue, update, lane) { + var concurrentQueue = queue; + var concurrentUpdate = update; + enqueueUpdate$1(fiber, concurrentQueue, concurrentUpdate, lane); + return getRootForUpdatedFiber(fiber); + } + function enqueueConcurrentHookUpdateAndEagerlyBailout( + fiber, + queue, + update ) { - switch (workInProgress.tag) { - case 3: - pushHostContainer( - workInProgress, - workInProgress.stateNode.containerInfo - ); - pushProvider( - workInProgress, - CacheContext, - current.memoizedState.cache - ); - break; - case 27: - case 5: - pushHostContext(workInProgress); - break; - case 4: - pushHostContainer( - workInProgress, - workInProgress.stateNode.containerInfo - ); - break; - case 10: - pushProvider( - workInProgress, - workInProgress.type, - workInProgress.memoizedProps.value - ); - break; - case 12: - 0 !== (renderLanes & workInProgress.childLanes) && - (workInProgress.flags |= 4); - var stateNode = workInProgress.stateNode; - stateNode.effectDuration = 0; - stateNode.passiveEffectDuration = 0; - break; - case 13: - stateNode = workInProgress.memoizedState; - if (null !== stateNode) { - if (null !== stateNode.dehydrated) - return ( - pushPrimaryTreeSuspenseHandler(workInProgress), - (workInProgress.flags |= 128), - null - ); - if (0 !== (renderLanes & workInProgress.child.childLanes)) - return updateSuspenseComponent( - current, - workInProgress, - renderLanes - ); - pushPrimaryTreeSuspenseHandler(workInProgress); - current = bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderLanes - ); - return null !== current ? current.sibling : null; - } - pushPrimaryTreeSuspenseHandler(workInProgress); - break; - case 19: - stateNode = 0 !== (renderLanes & workInProgress.childLanes); - if (0 !== (current.flags & 128)) { - if (stateNode) - return updateSuspenseListComponent( - current, - workInProgress, - renderLanes - ); - workInProgress.flags |= 128; + // This function is used to queue an update that doesn't need a rerender. The + // only reason we queue it is in case there's a subsequent higher priority + // update that causes it to be rebased. + var lane = NoLane; + var concurrentQueue = queue; + var concurrentUpdate = update; + enqueueUpdate$1(fiber, concurrentQueue, concurrentUpdate, lane); // Usually we can rely on the upcoming render phase to process the concurrent + // queue. However, since this is a bail out, we're not scheduling any work + // here. So the update we just queued will leak until something else happens + // to schedule work (if ever). + // + // Check if we're currently in the middle of rendering a tree, and if not, + // process the queue immediately to prevent a leak. + + var isConcurrentlyRendering = getWorkInProgressRoot() !== null; + + if (!isConcurrentlyRendering) { + finishQueueingConcurrentUpdates(); + } + } + function enqueueConcurrentClassUpdate(fiber, queue, update, lane) { + var concurrentQueue = queue; + var concurrentUpdate = update; + enqueueUpdate$1(fiber, concurrentQueue, concurrentUpdate, lane); + return getRootForUpdatedFiber(fiber); + } + function enqueueConcurrentRenderForLane(fiber, lane) { + enqueueUpdate$1(fiber, null, null, lane); + return getRootForUpdatedFiber(fiber); + } // Calling this function outside this module should only be done for backwards + // compatibility and should always be accompanied by a warning. + + function unsafe_markUpdateLaneFromFiberToRoot(sourceFiber, lane) { + // NOTE: For Hyrum's Law reasons, if an infinite update loop is detected, it + // should throw before `markUpdateLaneFromFiberToRoot` is called. But this is + // undefined behavior and we can change it if we need to; it just so happens + // that, at the time of this writing, there's an internal product test that + // happens to rely on this. + var root = getRootForUpdatedFiber(sourceFiber); + markUpdateLaneFromFiberToRoot(sourceFiber, null, lane); + return root; + } + + function markUpdateLaneFromFiberToRoot(sourceFiber, update, lane) { + // Update the source fiber's lanes + sourceFiber.lanes = mergeLanes(sourceFiber.lanes, lane); + var alternate = sourceFiber.alternate; + + if (alternate !== null) { + alternate.lanes = mergeLanes(alternate.lanes, lane); + } // Walk the parent path to the root and update the child lanes. + + var isHidden = false; + var parent = sourceFiber.return; + var node = sourceFiber; + + while (parent !== null) { + parent.childLanes = mergeLanes(parent.childLanes, lane); + alternate = parent.alternate; + + if (alternate !== null) { + alternate.childLanes = mergeLanes(alternate.childLanes, lane); + } + + if (parent.tag === OffscreenComponent) { + // Check if this offscreen boundary is currently hidden. + // + // The instance may be null if the Offscreen parent was unmounted. Usually + // the parent wouldn't be reachable in that case because we disconnect + // fibers from the tree when they are deleted. However, there's a weird + // edge case where setState is called on a fiber that was interrupted + // before it ever mounted. Because it never mounts, it also never gets + // deleted. Because it never gets deleted, its return pointer never gets + // disconnected. Which means it may be attached to a deleted Offscreen + // parent node. (This discovery suggests it may be better for memory usage + // if we don't attach the `return` pointer until the commit phase, though + // in order to do that we'd need some other way to track the return + // pointer during the initial render, like on the stack.) + // + // This case is always accompanied by a warning, but we still need to + // account for it. (There may be other cases that we haven't discovered, + // too.) + var offscreenInstance = parent.stateNode; + + if ( + offscreenInstance !== null && + !(offscreenInstance._visibility & OffscreenVisible) + ) { + isHidden = true; } - var renderState = workInProgress.memoizedState; - null !== renderState && - ((renderState.rendering = null), - (renderState.tail = null), - (renderState.lastEffect = null)); - push( - suspenseStackCursor, - suspenseStackCursor.current, - workInProgress - ); - if (stateNode) break; - else return null; - case 22: - case 23: - return ( - (workInProgress.lanes = 0), - updateOffscreenComponent(current, workInProgress, renderLanes) - ); - case 24: - pushProvider( - workInProgress, - CacheContext, - current.memoizedState.cache - ); + } + + node = parent; + parent = parent.return; + } + + if (isHidden && update !== null && node.tag === HostRoot) { + var root = node.stateNode; + markHiddenUpdate(root, update, lane); } - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); } - function beginWork(current, workInProgress, renderLanes) { - if (workInProgress._debugNeedsRemount && null !== current) { - renderLanes = createFiberFromTypeAndProps( - workInProgress.type, - workInProgress.key, - workInProgress.pendingProps, - workInProgress._debugOwner || null, - workInProgress.mode, - workInProgress.lanes - ); - renderLanes._debugStack = workInProgress._debugStack; - renderLanes._debugTask = workInProgress._debugTask; - var returnFiber = workInProgress.return; - if (null === returnFiber) throw Error("Cannot swap the root fiber."); - current.alternate = null; - workInProgress.alternate = null; - renderLanes.index = workInProgress.index; - renderLanes.sibling = workInProgress.sibling; - renderLanes.return = workInProgress.return; - renderLanes.ref = workInProgress.ref; - renderLanes._debugInfo = workInProgress._debugInfo; - if (workInProgress === returnFiber.child) - returnFiber.child = renderLanes; - else { - var prevSibling = returnFiber.child; - if (null === prevSibling) - throw Error("Expected parent to have a child."); - for (; prevSibling.sibling !== workInProgress; ) - if (((prevSibling = prevSibling.sibling), null === prevSibling)) - throw Error("Expected to find the previous sibling."); - prevSibling.sibling = renderLanes; - } - workInProgress = returnFiber.deletions; - null === workInProgress - ? ((returnFiber.deletions = [current]), (returnFiber.flags |= 16)) - : workInProgress.push(current); - renderLanes.flags |= 2; - return renderLanes; - } - if (null !== current) + + function getRootForUpdatedFiber(sourceFiber) { + // TODO: We will detect and infinite update loop and throw even if this fiber + // has already unmounted. This isn't really necessary but it happens to be the + // current behavior we've used for several release cycles. Consider not + // performing this check if the updated fiber already unmounted, since it's + // not possible for that to cause an infinite update loop. + throwIfInfiniteUpdateLoopDetected(); // When a setState happens, we must ensure the root is scheduled. Because + // update queues do not have a backpointer to the root, the only way to do + // this currently is to walk up the return path. This used to not be a big + // deal because we would have to walk up the return path to set + // the `childLanes`, anyway, but now those two traversals happen at + // different times. + // TODO: Consider adding a `root` backpointer on the update queue. + + detectUpdateOnUnmountedFiber(sourceFiber, sourceFiber); + var node = sourceFiber; + var parent = node.return; + + while (parent !== null) { + detectUpdateOnUnmountedFiber(sourceFiber, node); + node = parent; + parent = node.return; + } + + return node.tag === HostRoot ? node.stateNode : null; + } + + function detectUpdateOnUnmountedFiber(sourceFiber, parent) { + { + var alternate = parent.alternate; + if ( - current.memoizedProps !== workInProgress.pendingProps || - workInProgress.type !== current.type - ) - didReceiveUpdate = !0; - else { - if ( - 0 === (current.lanes & renderLanes) && - 0 === (workInProgress.flags & 128) - ) - return ( - (didReceiveUpdate = !1), - attemptEarlyBailoutIfNoScheduledUpdate( - current, - workInProgress, - renderLanes - ) - ); - didReceiveUpdate = 0 !== (current.flags & 131072) ? !0 : !1; + alternate === null && + (parent.flags & (Placement | Hydrating)) !== NoFlags$1 + ) { + warnAboutUpdateOnNotYetMountedFiberInDEV(sourceFiber); } - else didReceiveUpdate = !1; - workInProgress.lanes = 0; - switch (workInProgress.tag) { - case 16: - a: if ( - ((prevSibling = workInProgress.elementType), - resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress), - (returnFiber = workInProgress.pendingProps), - (current = callLazyInitInDEV(prevSibling)), - (workInProgress.type = current), - "function" === typeof current) - ) - shouldConstruct(current) - ? ((returnFiber = resolveClassComponentProps( - current, - returnFiber - )), - (workInProgress.tag = 1), - (workInProgress.type = current = - resolveFunctionForHotReloading(current)), - (workInProgress = updateClassComponent( - null, - workInProgress, - current, - returnFiber, - renderLanes - ))) - : ((workInProgress.tag = 0), - validateFunctionComponentInDev(workInProgress, current), - (workInProgress.type = current = - resolveFunctionForHotReloading(current)), - (workInProgress = updateFunctionComponent( - null, - workInProgress, - current, - returnFiber, - renderLanes - ))); - else { - if (void 0 !== current && null !== current) - if ( - ((prevSibling = current.$$typeof), - prevSibling === REACT_FORWARD_REF_TYPE) - ) { - workInProgress.tag = 11; - workInProgress.type = current = - resolveForwardRefForHotReloading(current); - workInProgress = updateForwardRef( - null, - workInProgress, - current, - returnFiber, - renderLanes - ); - break a; - } else if (prevSibling === REACT_MEMO_TYPE) { - workInProgress.tag = 14; - workInProgress = updateMemoComponent( - null, - workInProgress, - current, - returnFiber, - renderLanes - ); - break a; - } - workInProgress = ""; - null !== current && - "object" === typeof current && - current.$$typeof === REACT_LAZY_TYPE && - (workInProgress = - " Did you wrap a component in React.lazy() more than once?"); - throw Error( - "Element type is invalid. Received a promise that resolves to: " + - current + - ". Lazy element type must resolve to a class or function." + - workInProgress - ); - } - return workInProgress; - case 0: - return updateFunctionComponent( - current, - workInProgress, - workInProgress.type, - workInProgress.pendingProps, - renderLanes - ); - case 1: - return ( - (returnFiber = workInProgress.type), - (prevSibling = resolveClassComponentProps( - returnFiber, - workInProgress.pendingProps - )), - updateClassComponent( - current, - workInProgress, - returnFiber, - prevSibling, - renderLanes - ) - ); - case 3: - pushHostContainer( - workInProgress, - workInProgress.stateNode.containerInfo - ); - if (null === current) - throw Error("Should have a current fiber. This is a bug in React."); - var nextProps = workInProgress.pendingProps; - prevSibling = workInProgress.memoizedState; - returnFiber = prevSibling.element; - cloneUpdateQueue(current, workInProgress); - processUpdateQueue(workInProgress, nextProps, null, renderLanes); - nextProps = workInProgress.memoizedState; - var nextCache = nextProps.cache; - pushProvider(workInProgress, CacheContext, nextCache); - nextCache !== prevSibling.cache && - propagateContextChange(workInProgress, CacheContext, renderLanes); - suspendIfUpdateReadFromEntangledAsyncAction(); - prevSibling = nextProps.element; - prevSibling === returnFiber - ? (workInProgress = bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderLanes - )) - : (reconcileChildren( - current, - workInProgress, - prevSibling, - renderLanes - ), - (workInProgress = workInProgress.child)); - return workInProgress; - case 26: - case 27: - case 5: - return ( - pushHostContext(workInProgress), - (returnFiber = workInProgress.pendingProps.children), - null !== workInProgress.memoizedState && - ((prevSibling = renderWithHooks( - current, - workInProgress, - TransitionAwareHostComponent, - null, - null, - renderLanes - )), - (HostTransitionContext._currentValue = prevSibling), - didReceiveUpdate && - null !== current && - current.memoizedState.memoizedState !== prevSibling && - propagateContextChange( - workInProgress, - HostTransitionContext, - renderLanes - )), - markRef(current, workInProgress), - reconcileChildren( - current, - workInProgress, - returnFiber, - renderLanes - ), - workInProgress.child - ); - case 6: - return null; - case 13: - return updateSuspenseComponent(current, workInProgress, renderLanes); - case 4: - return ( - pushHostContainer( - workInProgress, - workInProgress.stateNode.containerInfo - ), - (returnFiber = workInProgress.pendingProps), - null === current - ? (workInProgress.child = reconcileChildFibers( - workInProgress, - null, - returnFiber, - renderLanes - )) - : reconcileChildren( - current, - workInProgress, - returnFiber, - renderLanes - ), - workInProgress.child - ); - case 11: - return updateForwardRef( - current, - workInProgress, - workInProgress.type, - workInProgress.pendingProps, - renderLanes - ); - case 7: - return ( - reconcileChildren( - current, - workInProgress, - workInProgress.pendingProps, - renderLanes - ), - workInProgress.child - ); - case 8: - return ( - reconcileChildren( - current, - workInProgress, - workInProgress.pendingProps.children, - renderLanes - ), - workInProgress.child - ); - case 12: - return ( - (workInProgress.flags |= 4), - (returnFiber = workInProgress.stateNode), - (returnFiber.effectDuration = 0), - (returnFiber.passiveEffectDuration = 0), - reconcileChildren( - current, - workInProgress, - workInProgress.pendingProps.children, - renderLanes - ), - workInProgress.child - ); - case 10: - a: { - returnFiber = workInProgress.type; - prevSibling = workInProgress.pendingProps; - nextProps = workInProgress.memoizedProps; - nextCache = prevSibling.value; - "value" in prevSibling || - hasWarnedAboutUsingNoValuePropOnContextProvider || - ((hasWarnedAboutUsingNoValuePropOnContextProvider = !0), - error$jscomp$0( - "The `value` prop is required for the ``. Did you misspell it or forget to pass it?" - )); - pushProvider(workInProgress, returnFiber, nextCache); - if (null !== nextProps) - if (objectIs(nextProps.value, nextCache)) { - if (nextProps.children === prevSibling.children) { - workInProgress = bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderLanes - ); - break a; - } - } else - propagateContextChange( - workInProgress, - returnFiber, - renderLanes - ); - reconcileChildren( - current, - workInProgress, - prevSibling.children, - renderLanes - ); - workInProgress = workInProgress.child; - } - return workInProgress; - case 9: - return ( - (prevSibling = workInProgress.type._context), - (returnFiber = workInProgress.pendingProps.children), - "function" !== typeof returnFiber && - error$jscomp$0( - "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." - ), - prepareToReadContext(workInProgress, renderLanes), - (prevSibling = readContext(prevSibling)), - markComponentRenderStarted(workInProgress), - (returnFiber = callComponentInDEV( - returnFiber, - prevSibling, - void 0 - )), - markComponentRenderStopped(), - (workInProgress.flags |= 1), - reconcileChildren( - current, - workInProgress, - returnFiber, - renderLanes - ), - workInProgress.child - ); - case 14: - return updateMemoComponent( - current, - workInProgress, - workInProgress.type, - workInProgress.pendingProps, - renderLanes - ); - case 15: - return updateSimpleMemoComponent( - current, - workInProgress, - workInProgress.type, - workInProgress.pendingProps, - renderLanes - ); - case 17: - return ( - (returnFiber = workInProgress.type), - (prevSibling = resolveClassComponentProps( - returnFiber, - workInProgress.pendingProps - )), - resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress), - (workInProgress.tag = 1), - prepareToReadContext(workInProgress, renderLanes), - constructClassInstance(workInProgress, returnFiber, prevSibling), - mountClassInstance( - workInProgress, - returnFiber, - prevSibling, - renderLanes - ), - finishClassComponent( - null, - workInProgress, - returnFiber, - !0, - !1, - renderLanes - ) - ); - case 28: - return ( - (returnFiber = workInProgress.type), - (prevSibling = resolveClassComponentProps( - returnFiber, - workInProgress.pendingProps - )), - resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress), - (workInProgress.tag = 0), - updateFunctionComponent( - null, - workInProgress, - returnFiber, - prevSibling, - renderLanes - ) - ); - case 19: - return updateSuspenseListComponent( - current, - workInProgress, - renderLanes - ); - case 22: - return updateOffscreenComponent(current, workInProgress, renderLanes); - case 24: - return ( - prepareToReadContext(workInProgress, renderLanes), - (returnFiber = readContext(CacheContext)), - null === current - ? ((prevSibling = peekCacheFromPool()), - null === prevSibling && - ((prevSibling = workInProgressRoot), - (nextProps = createCache()), - (prevSibling.pooledCache = nextProps), - retainCache(nextProps), - null !== nextProps && - (prevSibling.pooledCacheLanes |= renderLanes), - (prevSibling = nextProps)), - (workInProgress.memoizedState = { - parent: returnFiber, - cache: prevSibling - }), - initializeUpdateQueue(workInProgress), - pushProvider(workInProgress, CacheContext, prevSibling)) - : (0 !== (current.lanes & renderLanes) && - (cloneUpdateQueue(current, workInProgress), - processUpdateQueue(workInProgress, null, null, renderLanes), - suspendIfUpdateReadFromEntangledAsyncAction()), - (prevSibling = current.memoizedState), - (nextProps = workInProgress.memoizedState), - prevSibling.parent !== returnFiber - ? ((prevSibling = { - parent: returnFiber, - cache: returnFiber - }), - (workInProgress.memoizedState = prevSibling), - 0 === workInProgress.lanes && - (workInProgress.memoizedState = - workInProgress.updateQueue.baseState = - prevSibling), - pushProvider(workInProgress, CacheContext, returnFiber)) - : ((returnFiber = nextProps.cache), - pushProvider(workInProgress, CacheContext, returnFiber), - returnFiber !== prevSibling.cache && - propagateContextChange( - workInProgress, - CacheContext, - renderLanes - ))), - reconcileChildren( - current, - workInProgress, - workInProgress.pendingProps.children, - renderLanes - ), - workInProgress.child - ); - case 29: - throw workInProgress.pendingProps; } - throw Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in React. Please file an issue." - ); } - function resetContextDependencies() { - lastFullyObservedContext = - lastContextDependency = - currentlyRenderingFiber = - null; - isDisallowedContextReadInDEV = !1; + + var ReactCurrentActQueue$3 = ReactSharedInternals.ReactCurrentActQueue; // A linked list of all the roots with pending work. In an idiomatic app, + // there's only a single root, but we do support multi root apps, hence this + // extra complexity. But this module is optimized for the single root case. + + var firstScheduledRoot = null; + var lastScheduledRoot = null; // Used to prevent redundant mircotasks from being scheduled. + + var didScheduleMicrotask = false; // `act` "microtasks" are scheduled on the `act` queue instead of an actual + // microtask, so we have to dedupe those separately. This wouldn't be an issue + // if we required all `act` calls to be awaited, which we might in the future. + + var didScheduleMicrotask_act = false; // Used to quickly bail out of flushSync if there's no sync work to do. + + var mightHavePendingSyncWork = false; + var isFlushingWork = false; + var currentEventTransitionLane = NoLane; + function ensureRootIsScheduled(root) { + // This function is called whenever a root receives an update. It does two + // things 1) it ensures the root is in the root schedule, and 2) it ensures + // there's a pending microtask to process the root schedule. + // + // Most of the actual scheduling logic does not happen until + // `scheduleTaskForRootDuringMicrotask` runs. + // Add the root to the schedule + if (root === lastScheduledRoot || root.next !== null); + else { + if (lastScheduledRoot === null) { + firstScheduledRoot = lastScheduledRoot = root; + } else { + lastScheduledRoot.next = root; + lastScheduledRoot = root; + } + } // Any time a root received an update, we set this to true until the next time + // we process the schedule. If it's false, then we can quickly exit flushSync + // without consulting the schedule. + + mightHavePendingSyncWork = true; // At the end of the current event, go through each of the roots and ensure + // there's a task scheduled for each one at the correct priority. + + if (ReactCurrentActQueue$3.current !== null) { + // We're inside an `act` scope. + if (!didScheduleMicrotask_act) { + didScheduleMicrotask_act = true; + scheduleImmediateTask(processRootScheduleInMicrotask); + } + } else { + if (!didScheduleMicrotask) { + didScheduleMicrotask = true; + scheduleImmediateTask(processRootScheduleInMicrotask); + } + } + + { + // While this flag is disabled, we schedule the render task immediately + // instead of waiting a microtask. + // TODO: We need to land enableDeferRootSchedulingToMicrotask ASAP to + // unblock additional features we have planned. + scheduleTaskForRootDuringMicrotask(root, now$1()); + } + + if (ReactCurrentActQueue$3.isBatchingLegacy && root.tag === LegacyRoot) { + // Special `act` case: Record whenever a legacy update is scheduled. + ReactCurrentActQueue$3.didScheduleLegacyUpdate = true; + } } - function pushProvider(providerFiber, context, nextValue) { - push(valueCursor, context._currentValue, providerFiber); - context._currentValue = nextValue; - push(rendererCursorDEV, context._currentRenderer, providerFiber); - void 0 !== context._currentRenderer && - null !== context._currentRenderer && - context._currentRenderer !== rendererSigil && - error$jscomp$0( - "Detected multiple renderers concurrently rendering the same context provider. This is currently unsupported." - ); - context._currentRenderer = rendererSigil; + function flushSyncWorkOnAllRoots() { + // This is allowed to be called synchronously, but the caller should check + // the execution context first. + flushSyncWorkAcrossRoots_impl(false); } - function popProvider(context, providerFiber) { - context._currentValue = valueCursor.current; - var currentRenderer = rendererCursorDEV.current; - pop(rendererCursorDEV, providerFiber); - context._currentRenderer = currentRenderer; - pop(valueCursor, providerFiber); + function flushSyncWorkOnLegacyRootsOnly() { + // This is allowed to be called synchronously, but the caller should check + // the execution context first. + flushSyncWorkAcrossRoots_impl(true); } - function scheduleContextWorkOnParentPath( - parent, - renderLanes, - propagationRoot - ) { - for (; null !== parent; ) { - var alternate = parent.alternate; - (parent.childLanes & renderLanes) !== renderLanes - ? ((parent.childLanes |= renderLanes), - null !== alternate && (alternate.childLanes |= renderLanes)) - : null !== alternate && - (alternate.childLanes & renderLanes) !== renderLanes && - (alternate.childLanes |= renderLanes); - if (parent === propagationRoot) break; - parent = parent.return; + + function flushSyncWorkAcrossRoots_impl(onlyLegacy) { + if (isFlushingWork) { + // Prevent reentrancy. + // TODO: Is this overly defensive? The callers must check the execution + // context first regardless. + return; } - parent !== propagationRoot && - error$jscomp$0( - "Expected to find the propagation root when scheduling context work. This error is likely caused by a bug in React. Please file an issue." - ); - } - function propagateContextChange(workInProgress, context, renderLanes) { - var fiber = workInProgress.child; - null !== fiber && (fiber.return = workInProgress); - for (; null !== fiber; ) { - var list = fiber.dependencies; - if (null !== list) { - var nextFiber = fiber.child; - for (var dependency = list.firstContext; null !== dependency; ) { - if (dependency.context === context) { - if (1 === fiber.tag) { - dependency = createUpdate(renderLanes & -renderLanes); - dependency.tag = ForceUpdate; - var updateQueue = fiber.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; + + if (!mightHavePendingSyncWork) { + // Fast path. There's no sync work to do. + return; + } // There may or may not be synchronous work scheduled. Let's check. + + var didPerformSomeWork; + var errors = null; + isFlushingWork = true; + + do { + didPerformSomeWork = false; + var root = firstScheduledRoot; + + while (root !== null) { + if (onlyLegacy && root.tag !== LegacyRoot); + else { + var workInProgressRoot = getWorkInProgressRoot(); + var workInProgressRootRenderLanes = + getWorkInProgressRootRenderLanes(); + var nextLanes = getNextLanes( + root, + root === workInProgressRoot + ? workInProgressRootRenderLanes + : NoLanes + ); + + if (includesSyncLane(nextLanes)) { + // This root has pending sync work. Flush it now. + try { + didPerformSomeWork = true; + performSyncWorkOnRoot(root, nextLanes); + } catch (error) { + // Collect errors so we can rethrow them at the end + if (errors === null) { + errors = [error]; + } else { + errors.push(error); } } - fiber.lanes |= renderLanes; - dependency = fiber.alternate; - null !== dependency && (dependency.lanes |= renderLanes); - scheduleContextWorkOnParentPath( - fiber.return, - renderLanes, - workInProgress - ); - list.lanes |= renderLanes; - break; } - dependency = dependency.next; } - } else if (10 === fiber.tag) - nextFiber = fiber.type === workInProgress.type ? null : fiber.child; - else if (18 === fiber.tag) { - nextFiber = fiber.return; - if (null === nextFiber) - throw Error( - "We just came from a parent so we must have had a parent. This is a bug in React." - ); - nextFiber.lanes |= renderLanes; - list = nextFiber.alternate; - null !== list && (list.lanes |= renderLanes); - scheduleContextWorkOnParentPath( - nextFiber, - renderLanes, - workInProgress - ); - nextFiber = fiber.sibling; - } else nextFiber = fiber.child; - if (null !== nextFiber) nextFiber.return = fiber; - else - for (nextFiber = fiber; null !== nextFiber; ) { - if (nextFiber === workInProgress) { - nextFiber = null; - break; - } - fiber = nextFiber.sibling; - if (null !== fiber) { - fiber.return = nextFiber.return; - nextFiber = fiber; - break; + + root = root.next; + } + } while (didPerformSomeWork); + + isFlushingWork = false; // If any errors were thrown, rethrow them right before exiting. + // TODO: Consider returning these to the caller, to allow them to decide + // how/when to rethrow. + + if (errors !== null) { + if (errors.length > 1) { + if (typeof AggregateError === "function") { + // eslint-disable-next-line no-undef + throw new AggregateError(errors); + } else { + for (var i = 1; i < errors.length; i++) { + scheduleImmediateTask(throwError.bind(null, errors[i])); } - nextFiber = nextFiber.return; + + var firstError = errors[0]; + throw firstError; } - fiber = nextFiber; + } else { + var error = errors[0]; + throw error; + } } } - function prepareToReadContext(workInProgress, renderLanes) { - currentlyRenderingFiber = workInProgress; - lastFullyObservedContext = lastContextDependency = null; - workInProgress = workInProgress.dependencies; - null !== workInProgress && - null !== workInProgress.firstContext && - (0 !== (workInProgress.lanes & renderLanes) && (didReceiveUpdate = !0), - (workInProgress.firstContext = null)); - } - function readContext(context) { - isDisallowedContextReadInDEV && - error$jscomp$0( - "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()." - ); - return readContextForConsumer(currentlyRenderingFiber, context); - } - function readContextDuringReconciliation(consumer, context, renderLanes) { - null === currentlyRenderingFiber && - prepareToReadContext(consumer, renderLanes); - return readContextForConsumer(consumer, context); + + function throwError(error) { + throw error; } - function readContextForConsumer(consumer, context) { - var value = context._currentValue; - if (lastFullyObservedContext !== context) + + function processRootScheduleInMicrotask() { + // This function is always called inside a microtask. It should never be + // called synchronously. + didScheduleMicrotask = false; + + { + didScheduleMicrotask_act = false; + } // We'll recompute this as we iterate through all the roots and schedule them. + + mightHavePendingSyncWork = false; + var currentTime = now$1(); + var prev = null; + var root = firstScheduledRoot; + + while (root !== null) { + var next = root.next; + if ( - ((context = { context: context, memoizedValue: value, next: null }), - null === lastContextDependency) + currentEventTransitionLane !== NoLane && + shouldAttemptEagerTransition() ) { - if (null === consumer) - 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 = context; - consumer.dependencies = { lanes: 0, firstContext: context }; - } else lastContextDependency = lastContextDependency.next = context; - return value; - } - function createCache() { - return { - controller: new AbortControllerLocal(), - data: new Map(), - refCount: 0 - }; - } - function retainCache(cache) { - cache.controller.signal.aborted && - warn( - "A cache instance was retained after it was already freed. This likely indicates a bug in React." - ); - cache.refCount++; - } - function releaseCache(cache) { - cache.refCount--; - 0 > cache.refCount && - warn( - "A cache instance was released after it was already freed. This likely indicates a bug in React." - ); - 0 === cache.refCount && - scheduleCallback$1(NormalPriority, function () { - cache.controller.abort(); - }); + // A transition was scheduled during an event, but we're going to try to + // render it synchronously anyway. We do this during a popstate event to + // preserve the scroll position of the previous page. + upgradePendingLaneToSync(root, currentEventTransitionLane); + } + + var nextLanes = scheduleTaskForRootDuringMicrotask(root, currentTime); + + if (nextLanes === NoLane) { + // This root has no more pending work. Remove it from the schedule. To + // guard against subtle reentrancy bugs, this microtask is the only place + // we do this — you can add roots to the schedule whenever, but you can + // only remove them here. + // Null this out so we know it's been removed from the schedule. + root.next = null; + + if (prev === null) { + // This is the new head of the list + firstScheduledRoot = next; + } else { + prev.next = next; + } + + if (next === null) { + // This is the new tail of the list + lastScheduledRoot = prev; + } + } else { + // This root still has work. Keep it in the list. + prev = root; + + if (includesSyncLane(nextLanes)) { + mightHavePendingSyncWork = true; + } + } + + root = next; + } + + currentEventTransitionLane = NoLane; // At the end of the microtask, flush any pending synchronous work. This has + // to come at the end, because it does actual rendering work that might throw. + + flushSyncWorkOnAllRoots(); } - function peekCacheFromPool() { - var cacheResumedFromPreviousRender = resumedCache.current; - return null !== cacheResumedFromPreviousRender - ? cacheResumedFromPreviousRender - : workInProgressRoot.pooledCache; - } - function pushTransition(offscreenWorkInProgress, prevCachePool) { - null === prevCachePool - ? push(resumedCache, resumedCache.current, offscreenWorkInProgress) - : push(resumedCache, prevCachePool.pool, offscreenWorkInProgress); - } - function getSuspendedCache() { - var cacheFromPool = peekCacheFromPool(); - return null === cacheFromPool - ? null - : { parent: CacheContext._currentValue, pool: cacheFromPool }; - } - function scheduleRetryEffect(workInProgress, retryQueue) { - null !== retryQueue - ? (workInProgress.flags |= 4) - : workInProgress.flags & 16384 && - ((retryQueue = - 22 !== workInProgress.tag ? claimNextRetryLane() : OffscreenLane), - (workInProgress.lanes |= retryQueue)); - } - function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { - switch (renderState.tailMode) { - case "hidden": - hasRenderedATailFallback = renderState.tail; - for (var lastTailNode = null; null !== hasRenderedATailFallback; ) - null !== hasRenderedATailFallback.alternate && - (lastTailNode = hasRenderedATailFallback), - (hasRenderedATailFallback = hasRenderedATailFallback.sibling); - null === lastTailNode - ? (renderState.tail = null) - : (lastTailNode.sibling = null); - break; - case "collapsed": - lastTailNode = renderState.tail; - for (var _lastTailNode = null; null !== lastTailNode; ) - null !== lastTailNode.alternate && (_lastTailNode = lastTailNode), - (lastTailNode = lastTailNode.sibling); - null === _lastTailNode - ? hasRenderedATailFallback || null === renderState.tail - ? (renderState.tail = null) - : (renderState.tail.sibling = null) - : (_lastTailNode.sibling = null); - } - } - function 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 = completedWork.selfBaseDuration, - _child2 = completedWork.child; - null !== _child2; - ) - (newChildLanes |= _child2.lanes | _child2.childLanes), - (subtreeFlags |= _child2.subtreeFlags & 31457280), - (subtreeFlags |= _child2.flags & 31457280), - (_treeBaseDuration += _child2.treeBaseDuration), - (_child2 = _child2.sibling); - completedWork.treeBaseDuration = _treeBaseDuration; - } else - for ( - _treeBaseDuration = completedWork.child; - null !== _treeBaseDuration; + function scheduleTaskForRootDuringMicrotask(root, currentTime) { + // This function is always called inside a microtask, or at the very end of a + // rendering task right before we yield to the main thread. It should never be + // called synchronously. + // + // TODO: Unless enableDeferRootSchedulingToMicrotask is off. We need to land + // that ASAP to unblock additional features we have planned. + // + // This function also never performs React work synchronously; it should + // only schedule work to be performed later, in a separate task or microtask. + // Check if any lanes are being starved by other work. If so, mark them as + // expired so we know to work on those next. + markStarvedLanesAsExpired(root, currentTime); // Determine the next lanes to work on, and their priority. + + var workInProgressRoot = getWorkInProgressRoot(); + var workInProgressRootRenderLanes = getWorkInProgressRootRenderLanes(); + var nextLanes = getNextLanes( + root, + root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes + ); + var existingCallbackNode = root.callbackNode; + + if ( + // Check if there's nothing to work on + nextLanes === NoLanes || // If this root is currently suspended and waiting for data to resolve, don't + // schedule a task to render it. We'll either wait for a ping, or wait to + // receive an update. + // + // Suspended render phase + (root === workInProgressRoot && isWorkLoopSuspendedOnData()) || // Suspended commit phase + root.cancelPendingCommit !== null + ) { + // Fast path: There's nothing to work on. + if (existingCallbackNode !== null) { + cancelCallback(existingCallbackNode); + } + + root.callbackNode = null; + root.callbackPriority = NoLane; + return NoLane; + } // Schedule a new callback in the host environment. + + if (includesSyncLane(nextLanes)) { + // Synchronous work is always flushed at the end of the microtask, so we + // don't need to schedule an additional task. + if (existingCallbackNode !== null) { + cancelCallback(existingCallbackNode); + } + root.callbackPriority = SyncLane; + root.callbackNode = null; + return SyncLane; + } else { + // We use the highest priority lane to represent the priority of the callback. + var existingCallbackPriority = root.callbackPriority; + var newCallbackPriority = getHighestPriorityLane(nextLanes); + + if ( + newCallbackPriority === existingCallbackPriority && // Special case related to `act`. If the currently scheduled task is a + // Scheduler task, rather than an `act` task, cancel it and re-schedule + // on the `act` queue. + !( + ReactCurrentActQueue$3.current !== null && + existingCallbackNode !== fakeActCallbackNode$1 ) - (newChildLanes |= - _treeBaseDuration.lanes | _treeBaseDuration.childLanes), - (subtreeFlags |= _treeBaseDuration.subtreeFlags & 31457280), - (subtreeFlags |= _treeBaseDuration.flags & 31457280), - (_treeBaseDuration.return = completedWork), - (_treeBaseDuration = _treeBaseDuration.sibling); - else if (0 !== (completedWork.mode & 2)) { - _treeBaseDuration = completedWork.actualDuration; - _child2 = completedWork.selfBaseDuration; - for (var child = completedWork.child; null !== child; ) - (newChildLanes |= child.lanes | child.childLanes), - (subtreeFlags |= child.subtreeFlags), - (subtreeFlags |= child.flags), - (_treeBaseDuration += child.actualDuration), - (_child2 += child.treeBaseDuration), - (child = child.sibling); - completedWork.actualDuration = _treeBaseDuration; - completedWork.treeBaseDuration = _child2; - } else - for ( - _treeBaseDuration = completedWork.child; - null !== _treeBaseDuration; + ) { + // The priority hasn't changed. We can reuse the existing task. + return newCallbackPriority; + } else { + // Cancel the existing callback. We'll schedule a new one below. + cancelCallback(existingCallbackNode); + } - ) - (newChildLanes |= - _treeBaseDuration.lanes | _treeBaseDuration.childLanes), - (subtreeFlags |= _treeBaseDuration.subtreeFlags), - (subtreeFlags |= _treeBaseDuration.flags), - (_treeBaseDuration.return = completedWork), - (_treeBaseDuration = _treeBaseDuration.sibling); - completedWork.subtreeFlags |= subtreeFlags; - completedWork.childLanes = newChildLanes; - return didBailout; + 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; + } + + var newCallbackNode = scheduleCallback$1( + schedulerPriorityLevel, + performConcurrentWorkOnRoot.bind(null, root) + ); + root.callbackPriority = newCallbackPriority; + root.callbackNode = newCallbackNode; + return newCallbackPriority; + } } - function completeWork(current, workInProgress, renderLanes) { - var newProps = workInProgress.pendingProps; - switch (workInProgress.tag) { - case 28: - case 16: - case 15: - case 0: - case 11: - case 7: - case 8: - case 12: - case 9: - case 14: - return bubbleProperties(workInProgress), null; - case 1: - return bubbleProperties(workInProgress), null; - case 3: - return ( - (renderLanes = workInProgress.stateNode), - (newProps = null), - null !== current && (newProps = current.memoizedState.cache), - workInProgress.memoizedState.cache !== newProps && - (workInProgress.flags |= 2048), - popProvider(CacheContext, workInProgress), - popHostContainer(workInProgress), - renderLanes.pendingContext && - ((renderLanes.context = renderLanes.pendingContext), - (renderLanes.pendingContext = null)), - (null !== current && null !== current.child) || - null === current || - (current.memoizedState.isDehydrated && - 0 === (workInProgress.flags & 256)) || - ((workInProgress.flags |= 1024), - null !== hydrationErrors && - (queueRecoverableErrors(hydrationErrors), - (hydrationErrors = null))), - bubbleProperties(workInProgress), - null - ); - case 26: - case 27: - case 5: - popHostContext(workInProgress); - var _type2 = workInProgress.type; - if (null !== current && null != workInProgress.stateNode) - current.memoizedProps !== newProps && (workInProgress.flags |= 4); - 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.current); - renderLanes = requiredContext(rootInstanceStackCursor.current); - current = allocateTag(); - _type2 = getViewConfigForType(_type2); - for (var key in _type2.validAttributes) - newProps.hasOwnProperty(key) && - ReactNativePrivateInterface.deepFreezeAndThrowOnMutationInDev( - newProps[key] - ); - key = diffProperties( - null, - emptyObject$1, - newProps, - _type2.validAttributes - ); - ReactNativePrivateInterface.UIManager.createView( - current, - _type2.uiViewClassName, - renderLanes, - key - ); - renderLanes = new ReactNativeFiberHostComponent( - current, - _type2, - workInProgress - ); - instanceCache.set(current, workInProgress); - instanceProps.set(current, newProps); - a: for (current = workInProgress.child; null !== current; ) { - if (5 === current.tag || 6 === current.tag) - renderLanes._children.push(current.stateNode); - else if (4 !== current.tag && null !== current.child) { - current.child.return = current; - current = current.child; - continue; - } - if (current === workInProgress) break a; - for (; null === current.sibling; ) { - if ( - null === current.return || - current.return === workInProgress - ) - break a; - current = current.return; - } - current.sibling.return = current.return; - current = current.sibling; - } - workInProgress.stateNode = renderLanes; - finalizeInitialChildren(renderLanes) && (workInProgress.flags |= 4); - } - bubbleProperties(workInProgress); - workInProgress.flags &= -16777217; - return null; - case 6: - if (current && null != workInProgress.stateNode) - current.memoizedProps !== newProps && (workInProgress.flags |= 4); - else { - if ( - "string" !== typeof newProps && - null === workInProgress.stateNode - ) - throw Error( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." - ); - current = requiredContext(rootInstanceStackCursor.current); - if (!requiredContext(contextStackCursor.current).isInAParentText) - throw Error( - "Text strings must be rendered within a component." - ); - renderLanes = allocateTag(); - ReactNativePrivateInterface.UIManager.createView( - renderLanes, - "RCTRawText", - current, - { text: newProps } - ); - instanceCache.set(renderLanes, workInProgress); - workInProgress.stateNode = renderLanes; - } - bubbleProperties(workInProgress); - return null; - case 13: - newProps = workInProgress.memoizedState; - if ( - null === current || - (null !== current.memoizedState && - null !== current.memoizedState.dehydrated) - ) { - if (null !== newProps && null !== newProps.dehydrated) { - if (null === current) { - throw Error( - "A dehydrated suspense component was completed without a hydrated node. This is probably a bug in React." - ); - throw Error( - "Expected prepareToHydrateHostSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." - ); - } - key = hydrationDiffRootDEV; - if (null !== key) { - hydrationDiffRootDEV = null; - try { - _type2 = "\n\n" + describeNode(key, 0); - } catch (x) { - _type2 = ""; - } - error$jscomp$0( - "A tree hydrated but some attributes of the server rendered HTML didn't match the client properties. This won't be patched up. This can happen if a SSR-ed Client Component used:\n\n- A server/client branch `if (typeof window !== 'undefined')`.\n- Variable input such as `Date.now()` or `Math.random()` which changes each time it's called.\n- Date formatting in a user's locale which doesn't match the server.\n- External changing data without sending a snapshot of it along with the HTML.\n- Invalid HTML tag nesting.\n\nIt can also happen if the client has a browser extension installed which messes with the HTML before React loaded.\n\n%s%s", - "https://react.dev/link/hydration-mismatch", - _type2 - ); - } - 0 === (workInProgress.flags & 128) && - (workInProgress.memoizedState = null); - workInProgress.flags |= 4; - bubbleProperties(workInProgress); - 0 !== (workInProgress.mode & 2) && - null !== newProps && - ((key = workInProgress.child), - null !== key && - (workInProgress.treeBaseDuration -= key.treeBaseDuration)); - key = !1; - } else - null !== hydrationErrors && - (queueRecoverableErrors(hydrationErrors), - (hydrationErrors = null)), - (key = !0); - if (!key) { - if (workInProgress.flags & 256) - return popSuspenseHandler(workInProgress), workInProgress; - popSuspenseHandler(workInProgress); - return null; - } - } - popSuspenseHandler(workInProgress); - if (0 !== (workInProgress.flags & 128)) - return ( - (workInProgress.lanes = renderLanes), - 0 !== (workInProgress.mode & 2) && - transferActualDuration(workInProgress), - workInProgress - ); - renderLanes = null !== newProps; - current = null !== current && null !== current.memoizedState; - renderLanes && - ((newProps = workInProgress.child), - (key = null), - null !== newProps.alternate && - null !== newProps.alternate.memoizedState && - null !== newProps.alternate.memoizedState.cachePool && - (key = newProps.alternate.memoizedState.cachePool.pool), - (_type2 = null), - null !== newProps.memoizedState && - null !== newProps.memoizedState.cachePool && - (_type2 = newProps.memoizedState.cachePool.pool), - _type2 !== key && (newProps.flags |= 2048)); - renderLanes !== current && - renderLanes && - (workInProgress.child.flags |= 8192); - scheduleRetryEffect(workInProgress, workInProgress.updateQueue); - bubbleProperties(workInProgress); - 0 !== (workInProgress.mode & 2) && - renderLanes && - ((current = workInProgress.child), - null !== current && - (workInProgress.treeBaseDuration -= current.treeBaseDuration)); - return null; - case 4: - return ( - popHostContainer(workInProgress), - bubbleProperties(workInProgress), - null - ); - case 10: - return ( - popProvider(workInProgress.type, workInProgress), - bubbleProperties(workInProgress), - null - ); - case 17: - return bubbleProperties(workInProgress), null; - case 19: - pop(suspenseStackCursor, workInProgress); - key = workInProgress.memoizedState; - if (null === key) return bubbleProperties(workInProgress), null; - newProps = 0 !== (workInProgress.flags & 128); - _type2 = key.rendering; - if (null === _type2) - if (newProps) cutOffTailIfNeeded(key, !1); - else { - if ( - workInProgressRootExitStatus !== RootInProgress || - (null !== current && 0 !== (current.flags & 128)) - ) - for (current = workInProgress.child; null !== current; ) { - _type2 = findFirstSuspended(current); - if (null !== _type2) { - workInProgress.flags |= 128; - cutOffTailIfNeeded(key, !1); - current = _type2.updateQueue; - workInProgress.updateQueue = current; - scheduleRetryEffect(workInProgress, current); - workInProgress.subtreeFlags = 0; - current = renderLanes; - for ( - renderLanes = workInProgress.child; - null !== renderLanes; - - ) - resetWorkInProgress(renderLanes, current), - (renderLanes = renderLanes.sibling); - push( - suspenseStackCursor, - (suspenseStackCursor.current & - SubtreeSuspenseContextMask) | - ForceSuspenseFallback, - workInProgress - ); - return workInProgress.child; - } - current = current.sibling; - } - null !== key.tail && - now$1() > workInProgressRootRenderTargetTime && - ((workInProgress.flags |= 128), - (newProps = !0), - cutOffTailIfNeeded(key, !1), - (workInProgress.lanes = 4194304)); - } - else { - if (!newProps) - if (((current = findFirstSuspended(_type2)), null !== current)) { - if ( - ((workInProgress.flags |= 128), - (newProps = !0), - (current = current.updateQueue), - (workInProgress.updateQueue = current), - scheduleRetryEffect(workInProgress, current), - cutOffTailIfNeeded(key, !0), - null === key.tail && - "hidden" === key.tailMode && - !_type2.alternate) - ) - return bubbleProperties(workInProgress), null; - } else - 2 * now$1() - key.renderingStartTime > - workInProgressRootRenderTargetTime && - renderLanes !== OffscreenLane && - ((workInProgress.flags |= 128), - (newProps = !0), - cutOffTailIfNeeded(key, !1), - (workInProgress.lanes = 4194304)); - key.isBackwards - ? ((_type2.sibling = workInProgress.child), - (workInProgress.child = _type2)) - : ((current = key.last), - null !== current - ? (current.sibling = _type2) - : (workInProgress.child = _type2), - (key.last = _type2)); - } - if (null !== key.tail) - return ( - (current = key.tail), - (key.rendering = current), - (key.tail = current.sibling), - (key.renderingStartTime = now$1()), - (current.sibling = null), - (renderLanes = suspenseStackCursor.current), - (renderLanes = newProps - ? (renderLanes & SubtreeSuspenseContextMask) | - ForceSuspenseFallback - : renderLanes & SubtreeSuspenseContextMask), - push(suspenseStackCursor, renderLanes, workInProgress), - current - ); - bubbleProperties(workInProgress); - return null; - case 22: - case 23: - return ( - popSuspenseHandler(workInProgress), - popHiddenContext(workInProgress), - (newProps = null !== workInProgress.memoizedState), - null !== current - ? (null !== current.memoizedState) !== newProps && - (workInProgress.flags |= 8192) - : newProps && (workInProgress.flags |= 8192), - newProps && 0 !== (workInProgress.mode & 1) - ? 0 !== (renderLanes & OffscreenLane) && - 0 === (workInProgress.flags & 128) && - (bubbleProperties(workInProgress), - workInProgress.subtreeFlags & 6 && - (workInProgress.flags |= 8192)) - : bubbleProperties(workInProgress), - (renderLanes = workInProgress.updateQueue), - null !== renderLanes && - scheduleRetryEffect(workInProgress, renderLanes.retryQueue), - (renderLanes = null), - null !== current && - null !== current.memoizedState && - null !== current.memoizedState.cachePool && - (renderLanes = current.memoizedState.cachePool.pool), - (newProps = null), - null !== workInProgress.memoizedState && - null !== workInProgress.memoizedState.cachePool && - (newProps = workInProgress.memoizedState.cachePool.pool), - newProps !== renderLanes && (workInProgress.flags |= 2048), - null !== current && pop(resumedCache, workInProgress), - null - ); - case 24: - return ( - (renderLanes = null), - null !== current && (renderLanes = current.memoizedState.cache), - workInProgress.memoizedState.cache !== renderLanes && - (workInProgress.flags |= 2048), - popProvider(CacheContext, workInProgress), - bubbleProperties(workInProgress), - null - ); - case 25: - return null; - case 29: - return null; + + function getContinuationForRoot(root, originalCallbackNode) { + // This is called at the end of `performConcurrentWorkOnRoot` to determine + // if we need to schedule a continuation task. + // + // Usually `scheduleTaskForRootDuringMicrotask` only runs inside a microtask; + // however, since most of the logic for determining if we need a continuation + // versus a new task is the same, we cheat a bit and call it here. This is + // only safe to do because we know we're at the end of the browser task. + // So although it's not an actual microtask, it might as well be. + scheduleTaskForRootDuringMicrotask(root, now$1()); + + if (root.callbackNode === originalCallbackNode) { + // The task node scheduled for this root is the same one that's + // currently executed. Need to return a continuation. + return performConcurrentWorkOnRoot.bind(null, root); } - throw Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in React. Please file an issue." - ); + + return null; } - function unwindWork(current, workInProgress) { - switch (workInProgress.tag) { - case 1: - return ( - (current = workInProgress.flags), - current & 65536 - ? ((workInProgress.flags = (current & -65537) | 128), - 0 !== (workInProgress.mode & 2) && - transferActualDuration(workInProgress), - workInProgress) - : null - ); - case 3: - return ( - popProvider(CacheContext, workInProgress), - popHostContainer(workInProgress), - (current = workInProgress.flags), - 0 !== (current & 65536) && 0 === (current & 128) - ? ((workInProgress.flags = (current & -65537) | 128), - workInProgress) - : null - ); - case 26: - case 27: - case 5: - return popHostContext(workInProgress), null; - case 13: - popSuspenseHandler(workInProgress); - current = workInProgress.memoizedState; - if ( - null !== current && - null !== current.dehydrated && - null === workInProgress.alternate - ) - throw Error( - "Threw in newly mounted dehydrated component. This is likely a bug in React. Please file an issue." - ); - current = workInProgress.flags; - return current & 65536 - ? ((workInProgress.flags = (current & -65537) | 128), - 0 !== (workInProgress.mode & 2) && - transferActualDuration(workInProgress), - workInProgress) - : null; - case 19: - return pop(suspenseStackCursor, workInProgress), null; - case 4: - return popHostContainer(workInProgress), null; - case 10: - return popProvider(workInProgress.type, workInProgress), null; - case 22: - case 23: - return ( - popSuspenseHandler(workInProgress), - popHiddenContext(workInProgress), - null !== current && pop(resumedCache, workInProgress), - (current = workInProgress.flags), - current & 65536 - ? ((workInProgress.flags = (current & -65537) | 128), - 0 !== (workInProgress.mode & 2) && - transferActualDuration(workInProgress), - workInProgress) - : null - ); - case 24: - return popProvider(CacheContext, workInProgress), null; - case 25: - return null; - default: - return null; + var fakeActCallbackNode$1 = {}; + + function scheduleCallback$1(priorityLevel, callback) { + if (ReactCurrentActQueue$3.current !== null) { + // Special case: We're inside an `act` scope (a testing utility). + // Instead of scheduling work in the host environment, add it to a + // fake internal queue that's managed by the `act` implementation. + ReactCurrentActQueue$3.current.push(callback); + return fakeActCallbackNode$1; + } else { + return scheduleCallback$2(priorityLevel, callback); } } - function unwindInterruptedWork(current, interruptedWork) { - switch (interruptedWork.tag) { - case 3: - popProvider(CacheContext, interruptedWork); - popHostContainer(interruptedWork); - break; - case 26: - case 27: - case 5: - popHostContext(interruptedWork); - break; - case 4: - popHostContainer(interruptedWork); - break; - case 13: - popSuspenseHandler(interruptedWork); - break; - case 19: - pop(suspenseStackCursor, interruptedWork); - break; - case 10: - popProvider(interruptedWork.type, interruptedWork); - break; - case 22: - case 23: - popSuspenseHandler(interruptedWork); - popHiddenContext(interruptedWork); - null !== current && pop(resumedCache, interruptedWork); - break; - case 24: - popProvider(CacheContext, interruptedWork); + + function cancelCallback(callbackNode) { + if (callbackNode === fakeActCallbackNode$1); + else if (callbackNode !== null) { + cancelCallback$1(callbackNode); } } - function shouldProfile(current) { - return ( - 0 !== (current.mode & 2) && - (executionContext & CommitContext) !== NoContext - ); + + function scheduleImmediateTask(cb) { + if (ReactCurrentActQueue$3.current !== null) { + // Special case: Inside an `act` scope, we push microtasks to the fake `act` + // callback queue. This is because we currently support calling `act` + // without awaiting the result. The plan is to deprecate that, and require + // that you always await the result so that the microtasks have a chance to + // run. But it hasn't happened yet. + ReactCurrentActQueue$3.current.push(function () { + cb(); + return null; + }); + } // TODO: Can we land supportsMicrotasks? Which environments don't support it? + // Alternatively, can we move this check to the host config? + + { + // If microtasks are not supported, use Scheduler. + scheduleCallback$2(ImmediatePriority, cb); + } } - function safelyCallComponentWillUnmount( - current, - nearestMountedAncestor, - instance + + function requestTransitionLane( // This argument isn't used, it's only here to encourage the caller to + // check that it's inside a transition before calling this function. + // TODO: Make this non-nullable. Requires a tweak to useOptimistic. + transition ) { - try { - if ( - ((instance.props = resolveClassComponentProps( - current.type, - current.memoizedProps - )), - (instance.state = current.memoizedState), - shouldProfile(current)) - ) - try { - startLayoutEffectTimer(), instance.componentWillUnmount(); - } finally { - recordLayoutEffectDuration(current); - } - else instance.componentWillUnmount(); - } catch (error$9) { - captureCommitPhaseError(current, nearestMountedAncestor, error$9); + // 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 currentEventTransitionLane; } - function safelyAttachRef(current, nearestMountedAncestor) { - try { - var ref = current.ref; - if (null !== ref) { - var instance = current.stateNode; - switch (current.tag) { - case 26: - case 27: - case 5: - var instanceToUse = getPublicInstance(instance); - break; - default: - instanceToUse = instance; - } - if ("function" === typeof ref) - if (shouldProfile(current)) - try { - startLayoutEffectTimer(), - (current.refCleanup = ref(instanceToUse)); - } finally { - recordLayoutEffectDuration(current); - } - else current.refCleanup = ref(instanceToUse); - else - "string" === typeof ref - ? error$jscomp$0("String refs are no longer supported.") - : ref.hasOwnProperty("current") || - error$jscomp$0( - "Unexpected ref object provided for %s. Use either a ref-setter function or React.createRef().", - getComponentNameFromFiber(current) - ), - (ref.current = instanceToUse); + + var currentEntangledLane = NoLane; // A thenable that resolves when the entangled scope completes. It does not + // resolve to a particular value because it's only used for suspending the UI + // until the async action scope has completed. + + var currentEntangledActionThenable = null; + + function chainThenableValue(thenable, result) { + // Equivalent to: Promise.resolve(thenable).then(() => result), except we can + // cheat a bit since we know that that this thenable is only ever consumed + // by React. + // + // We don't technically require promise support on the client yet, hence this + // extra code. + var listeners = []; + var thenableWithOverride = { + status: "pending", + value: null, + reason: null, + then: function (resolve) { + listeners.push(resolve); } - } catch (error$10) { - captureCommitPhaseError(current, nearestMountedAncestor, error$10); - } - } - function safelyDetachRef(current, nearestMountedAncestor) { - var ref = current.ref, - refCleanup = current.refCleanup; - if (null !== ref) - if ("function" === typeof refCleanup) - try { - if (shouldProfile(current)) - try { - startLayoutEffectTimer(), refCleanup(); - } finally { - recordLayoutEffectDuration(current); - } - else refCleanup(); - } catch (error$11) { - captureCommitPhaseError(current, nearestMountedAncestor, error$11); - } finally { - (current.refCleanup = null), - (current = current.alternate), - null != current && (current.refCleanup = null); + }; + thenable.then( + function (value) { + var fulfilledThenable = thenableWithOverride; + fulfilledThenable.status = "fulfilled"; + fulfilledThenable.value = result; + + for (var i = 0; i < listeners.length; i++) { + var listener = listeners[i]; + listener(result); } - else if ("function" === typeof ref) - try { - if (shouldProfile(current)) - try { - startLayoutEffectTimer(), ref(null); - } finally { - recordLayoutEffectDuration(current); - } - else ref(null); - } catch (error$12) { - captureCommitPhaseError(current, nearestMountedAncestor, error$12); + }, + function (error) { + var rejectedThenable = thenableWithOverride; + rejectedThenable.status = "rejected"; + rejectedThenable.reason = error; + + for (var i = 0; i < listeners.length; i++) { + var listener = listeners[i]; // This is a perf hack where we call the `onFulfill` ping function + // instead of `onReject`, because we know that React is the only + // consumer of these promises, and it passes the same listener to both. + // We also know that it will read the error directly off the + // `.reason` field. + + listener(undefined); } - else ref.current = null; + } + ); + return thenableWithOverride; } - function safelyCallDestroy(current, nearestMountedAncestor, destroy) { - try { - destroy(); - } catch (error$13) { - captureCommitPhaseError(current, nearestMountedAncestor, error$13); - } + function peekEntangledActionLane() { + return currentEntangledLane; } - function commitBeforeMutationEffects(root, firstChild) { - for (nextEffect = firstChild; null !== nextEffect; ) - if ( - ((root = nextEffect), - (firstChild = root.child), - 0 !== (root.subtreeFlags & 1028) && null !== firstChild) - ) - (firstChild.return = root), (nextEffect = firstChild); - else - for (; null !== nextEffect; ) { - root = nextEffect; - try { - runWithFiberInDEV(root, commitBeforeMutationEffectsOnFiber, root); - } catch (error$14) { - captureCommitPhaseError(root, root.return, error$14); - } - firstChild = root.sibling; - if (null !== firstChild) { - firstChild.return = root.return; - nextEffect = firstChild; - break; - } - nextEffect = root.return; - } - root = shouldFireAfterActiveInstanceBlur; - shouldFireAfterActiveInstanceBlur = !1; - return root; + function peekEntangledActionThenable() { + return currentEntangledActionThenable; } - function commitBeforeMutationEffectsOnFiber(finishedWork) { - var current = finishedWork.alternate, - flags = finishedWork.flags; - switch (finishedWork.tag) { - case 0: - break; - case 11: - case 15: - break; - case 1: - if (0 !== (flags & 1024) && null !== current) { - flags = current.memoizedProps; - var prevState = current.memoizedState; - current = finishedWork.stateNode; - finishedWork.type.defaultProps || - "ref" in finishedWork.memoizedProps || - didWarnAboutReassigningProps || - (current.props !== finishedWork.memoizedProps && - error$jscomp$0( - "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" - ), - current.state !== finishedWork.memoizedState && - error$jscomp$0( - "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" - )); - flags = current.getSnapshotBeforeUpdate( - resolveClassComponentProps(finishedWork.type, flags), - prevState - ); - prevState = didWarnAboutUndefinedSnapshotBeforeUpdate; - void 0 !== flags || - prevState.has(finishedWork.type) || - (prevState.add(finishedWork.type), - error$jscomp$0( - "%s.getSnapshotBeforeUpdate(): A snapshot value (or null) must be returned. You have returned undefined.", - getComponentNameFromFiber(finishedWork) - )); - current.__reactInternalSnapshotBeforeUpdate = flags; - } - break; - case 3: - break; - case 5: - case 26: - case 27: - case 6: - case 4: - case 17: - break; - default: - if (0 !== (flags & 1024)) - 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." - ); - } + + var UpdateState = 0; + var ReplaceState = 1; + var ForceUpdate = 2; + var CaptureUpdate = 3; // Global state that is reset at the beginning of calling `processUpdateQueue`. + // It should only be read right after calling `processUpdateQueue`, via + // `checkHasForceUpdateAfterProcessing`. + + var hasForceUpdate = false; + var didWarnUpdateInsideUpdate; + var currentlyProcessingQueue; + + { + didWarnUpdateInsideUpdate = false; + currentlyProcessingQueue = null; } - function commitHookEffectListUnmount( - flags, - finishedWork, - nearestMountedAncestor - ) { - 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 inst = effect.inst, - destroy = inst.destroy; - void 0 !== destroy && - ((inst.destroy = void 0), - (flags & Passive) !== NoFlags - ? null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markComponentPassiveEffectUnmountStarted && - injectedProfilingHooks.markComponentPassiveEffectUnmountStarted( - finishedWork - ) - : (flags & Layout) !== NoFlags && - markComponentLayoutEffectUnmountStarted(finishedWork), - (flags & Insertion) !== NoFlags && - (isRunningInsertionEffect = !0), - safelyCallDestroy(finishedWork, nearestMountedAncestor, destroy), - (flags & Insertion) !== NoFlags && - (isRunningInsertionEffect = !1), - (flags & Passive) !== NoFlags - ? null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markComponentPassiveEffectUnmountStopped && - injectedProfilingHooks.markComponentPassiveEffectUnmountStopped() - : (flags & Layout) !== NoFlags && - markComponentLayoutEffectUnmountStopped()); - } - effect = effect.next; - } while (effect !== updateQueue); - } + + function initializeUpdateQueue(fiber) { + var queue = { + baseState: fiber.memoizedState, + firstBaseUpdate: null, + lastBaseUpdate: null, + shared: { + pending: null, + lanes: NoLanes, + hiddenCallbacks: null + }, + callbacks: null + }; + fiber.updateQueue = queue; } - function commitHookEffectListMount(flags, finishedWork) { - var updateQueue = finishedWork.updateQueue; - updateQueue = null !== updateQueue ? updateQueue.lastEffect : null; - if (null !== updateQueue) { - var effect = (updateQueue = updateQueue.next); - do { - if ((effect.tag & flags) === flags) { - (flags & Passive) !== NoFlags - ? null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markComponentPassiveEffectMountStarted && - injectedProfilingHooks.markComponentPassiveEffectMountStarted( - finishedWork - ) - : (flags & Layout) !== NoFlags && - null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markComponentLayoutEffectMountStarted && - injectedProfilingHooks.markComponentLayoutEffectMountStarted( - finishedWork - ); - var create = effect.create; - (flags & Insertion) !== NoFlags && (isRunningInsertionEffect = !0); - var inst = effect.inst; - create = create(); - inst.destroy = create; - (flags & Insertion) !== NoFlags && (isRunningInsertionEffect = !1); - (flags & Passive) !== NoFlags - ? null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markComponentPassiveEffectMountStopped && - injectedProfilingHooks.markComponentPassiveEffectMountStopped() - : (flags & Layout) !== NoFlags && - null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markComponentLayoutEffectMountStopped && - injectedProfilingHooks.markComponentLayoutEffectMountStopped(); - void 0 !== create && - "function" !== typeof create && - ((inst = - 0 !== (effect.tag & Layout) - ? "useLayoutEffect" - : 0 !== (effect.tag & Insertion) - ? "useInsertionEffect" - : "useEffect"), - error$jscomp$0( - "%s must not return anything besides a function, which is used for clean-up.%s", - inst, - null === create - ? " You returned null. If your effect does not require clean up, return undefined (or nothing)." - : "function" === typeof create.then - ? "\n\nIt looks like you wrote " + - inst + - "(async () => ...) or returned a Promise. Instead, write the async function inside your effect and call it immediately:\n\n" + - inst + - "(() => {\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\nLearn more about data fetching with Hooks: https://react.dev/link/hooks-data-fetching" - : " You returned: " + create - )); - } - effect = effect.next; - } while (effect !== updateQueue); + function cloneUpdateQueue(current, workInProgress) { + // Clone the update queue from current. Unless it's already a clone. + var queue = workInProgress.updateQueue; + var currentQueue = current.updateQueue; + + if (queue === currentQueue) { + var clone = { + baseState: currentQueue.baseState, + firstBaseUpdate: currentQueue.firstBaseUpdate, + lastBaseUpdate: currentQueue.lastBaseUpdate, + shared: currentQueue.shared, + callbacks: null + }; + workInProgress.updateQueue = clone; } } - function commitHookLayoutEffects(finishedWork, hookFlags) { - if (shouldProfile(finishedWork)) { - try { - startLayoutEffectTimer(), - commitHookEffectListMount(hookFlags, finishedWork); - } catch (error$15) { - captureCommitPhaseError(finishedWork, finishedWork.return, error$15); + function createUpdate(lane) { + var update = { + lane: lane, + tag: UpdateState, + payload: null, + callback: null, + next: null + }; + return update; + } + function enqueueUpdate(fiber, update, lane) { + var updateQueue = fiber.updateQueue; + + if (updateQueue === null) { + // Only occurs if the fiber has been unmounted. + return null; + } + + var sharedQueue = updateQueue.shared; + + { + if ( + currentlyProcessingQueue === sharedQueue && + !didWarnUpdateInsideUpdate + ) { + var componentName = getComponentNameFromFiber(fiber); + + error( + "An update (setState, replaceState, or forceUpdate) was scheduled " + + "from inside an update function. Update functions should be pure, " + + "with zero side-effects. Consider using componentDidUpdate or a " + + "callback.\n\nPlease update the following component: %s", + componentName + ); + + didWarnUpdateInsideUpdate = true; } - recordLayoutEffectDuration(finishedWork); - } else - try { - commitHookEffectListMount(hookFlags, finishedWork); - } catch (error$16) { - captureCommitPhaseError(finishedWork, finishedWork.return, error$16); + } + + if (isUnsafeClassRenderPhaseUpdate()) { + // This is an unsafe render phase update. Add directly to the update + // queue so we can process it immediately during the current render. + 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; // Update the childLanes even though we're most likely already rendering + // this fiber. This is for backwards compatibility in the case where you + // update a different component during render phase than the one that is + // currently renderings (a pattern that is accompanied by a warning). + + return unsafe_markUpdateLaneFromFiberToRoot(fiber, lane); + } else { + return enqueueConcurrentClassUpdate(fiber, sharedQueue, update, lane); + } } - function commitClassCallbacks(finishedWork) { - var updateQueue = finishedWork.updateQueue; - if (null !== updateQueue) { - var instance = finishedWork.stateNode; - finishedWork.type.defaultProps || - "ref" in finishedWork.memoizedProps || - didWarnAboutReassigningProps || - (instance.props !== finishedWork.memoizedProps && - error$jscomp$0( - "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" - ), - instance.state !== finishedWork.memoizedState && - error$jscomp$0( - "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" - )); - try { - commitCallbacks(updateQueue, instance); - } catch (error$21) { - captureCommitPhaseError(finishedWork, finishedWork.return, error$21); - } + 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 commitProfilerUpdate(finishedWork, current) { - if (executionContext & CommitContext) - try { - var _finishedWork$memoize2 = finishedWork.memoizedProps, - onCommit = _finishedWork$memoize2.onCommit, - onRender = _finishedWork$memoize2.onRender, - effectDuration = finishedWork.stateNode.effectDuration; - _finishedWork$memoize2 = commitTime; - current = null === current ? "mount" : "update"; - currentUpdateIsNested && (current = "nested-update"); - "function" === typeof onRender && - onRender( - finishedWork.memoizedProps.id, - current, - finishedWork.actualDuration, - finishedWork.treeBaseDuration, - finishedWork.actualStartTime, - _finishedWork$memoize2 - ); - "function" === typeof onCommit && - onCommit( - finishedWork.memoizedProps.id, - current, - effectDuration, - _finishedWork$memoize2 - ); - enqueuePendingPassiveProfilerEffect(finishedWork); - var parentFiber = finishedWork.return; - a: for (; null !== parentFiber; ) { - switch (parentFiber.tag) { - case 3: - parentFiber.stateNode.effectDuration += effectDuration; - break a; - case 12: - parentFiber.stateNode.effectDuration += effectDuration; - break a; + 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, + // we should only put them on the work-in-progress queue, not the current one. + var queue = workInProgress.updateQueue; // Check if the work-in-progress queue is a clone. + + var current = workInProgress.alternate; + + if (current !== null) { + var currentQueue = current.updateQueue; + + if (queue === currentQueue) { + // The work-in-progress queue is the same as current. This happens when + // we bail out on a parent fiber that then captures an error thrown by + // a child. Since we want to append the update only to the work-in + // -progress queue, we need to clone the updates. We usually clone during + // processUpdateQueue, but that didn't happen in this case because we + // skipped over the parent when we bailed out. + var newFirst = null; + var newLast = null; + var firstBaseUpdate = queue.firstBaseUpdate; + + if (firstBaseUpdate !== null) { + // Loop through the updates and clone them. + var update = firstBaseUpdate; + + do { + var clone = { + lane: update.lane, + tag: update.tag, + payload: update.payload, + // When this update is rebased, we should not fire its + // callback again. + callback: null, + next: null + }; + + if (newLast === null) { + newFirst = newLast = clone; + } else { + newLast.next = clone; + newLast = clone; + } // $FlowFixMe[incompatible-type] we bail out when we get a null + + update = update.next; + } while (update !== null); // Append the captured update the end of the cloned list. + + if (newLast === null) { + newFirst = newLast = capturedUpdate; + } else { + newLast.next = capturedUpdate; + newLast = capturedUpdate; } - parentFiber = parentFiber.return; + } else { + // There are no base updates. + newFirst = newLast = capturedUpdate; } - } catch (error$23) { - captureCommitPhaseError(finishedWork, finishedWork.return, error$23); + + queue = { + baseState: currentQueue.baseState, + firstBaseUpdate: newFirst, + lastBaseUpdate: newLast, + shared: currentQueue.shared, + callbacks: currentQueue.callbacks + }; + workInProgress.updateQueue = queue; + return; } + } // Append the update to the end of the list. + + var lastBaseUpdate = queue.lastBaseUpdate; + + if (lastBaseUpdate === null) { + queue.firstBaseUpdate = capturedUpdate; + } else { + lastBaseUpdate.next = capturedUpdate; + } + + queue.lastBaseUpdate = capturedUpdate; } - function commitLayoutEffectOnFiber( - finishedRoot, - current, - finishedWork, - committedLanes + + function getStateFromUpdate( + workInProgress, + queue, + update, + prevState, + nextProps, + instance ) { - var flags = finishedWork.flags; - switch (finishedWork.tag) { - case 0: - case 11: - case 15: - recursivelyTraverseLayoutEffects( - finishedRoot, - finishedWork, - committedLanes - ); - flags & 4 && - commitHookLayoutEffects(finishedWork, Layout | HasEffect); - break; - case 1: - recursivelyTraverseLayoutEffects( - finishedRoot, - finishedWork, - committedLanes - ); - if (flags & 4) - if (((finishedRoot = finishedWork.stateNode), null === current)) - if ( - (finishedWork.type.defaultProps || - "ref" in finishedWork.memoizedProps || - didWarnAboutReassigningProps || - (finishedRoot.props !== finishedWork.memoizedProps && - error$jscomp$0( - "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" - ), - finishedRoot.state !== finishedWork.memoizedState && - error$jscomp$0( - "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" - )), - shouldProfile(finishedWork)) - ) { - try { - startLayoutEffectTimer(), finishedRoot.componentDidMount(); - } catch (error$17) { - captureCommitPhaseError( - finishedWork, - finishedWork.return, - error$17 - ); - } - recordLayoutEffectDuration(finishedWork); - } else - try { - finishedRoot.componentDidMount(); - } catch (error$18) { - captureCommitPhaseError( - finishedWork, - finishedWork.return, - error$18 - ); - } - else { - committedLanes = resolveClassComponentProps( - finishedWork.type, - current.memoizedProps - ); - var prevState = current.memoizedState; - finishedWork.type.defaultProps || - "ref" in finishedWork.memoizedProps || - didWarnAboutReassigningProps || - (finishedRoot.props !== finishedWork.memoizedProps && - error$jscomp$0( - "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" - ), - finishedRoot.state !== finishedWork.memoizedState && - error$jscomp$0( - "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 (shouldProfile(finishedWork)) { + switch (update.tag) { + case ReplaceState: { + var payload = update.payload; + + if (typeof payload === "function") { + // Updater function + { + enterDisallowedContextReadInDEV(); + } + + var nextState = payload.call(instance, prevState, nextProps); + + { + if (workInProgress.mode & StrictLegacyMode) { + setIsStrictModeForDevtools(true); + try { - startLayoutEffectTimer(), - finishedRoot.componentDidUpdate( - committedLanes, - prevState, - finishedRoot.__reactInternalSnapshotBeforeUpdate - ); - } catch (error$19) { - captureCommitPhaseError( - finishedWork, - finishedWork.return, - error$19 - ); + payload.call(instance, prevState, nextProps); + } finally { + setIsStrictModeForDevtools(false); } - recordLayoutEffectDuration(finishedWork); - } else + } + + exitDisallowedContextReadInDEV(); + } + + return nextState; + } // State object + + return payload; + } + + case CaptureUpdate: { + workInProgress.flags = + (workInProgress.flags & ~ShouldCapture) | DidCapture; + } + // Intentional fallthrough + + case UpdateState: { + var _payload = update.payload; + var partialState; + + if (typeof _payload === "function") { + // Updater function + { + enterDisallowedContextReadInDEV(); + } + + partialState = _payload.call(instance, prevState, nextProps); + + { + if (workInProgress.mode & StrictLegacyMode) { + setIsStrictModeForDevtools(true); + try { - finishedRoot.componentDidUpdate( - committedLanes, - prevState, - finishedRoot.__reactInternalSnapshotBeforeUpdate - ); - } catch (error$20) { - captureCommitPhaseError( - finishedWork, - finishedWork.return, - error$20 - ); + _payload.call(instance, prevState, nextProps); + } finally { + setIsStrictModeForDevtools(false); } - } - flags & 64 && commitClassCallbacks(finishedWork); - flags & 512 && safelyAttachRef(finishedWork, finishedWork.return); - break; - case 3: - recursivelyTraverseLayoutEffects( - finishedRoot, - finishedWork, - committedLanes - ); - if ( - flags & 64 && - ((flags = finishedWork.updateQueue), null !== flags) - ) { - finishedRoot = null; - if (null !== finishedWork.child) - switch (finishedWork.child.tag) { - case 27: - case 5: - finishedRoot = getPublicInstance( - finishedWork.child.stateNode - ); - break; - case 1: - finishedRoot = finishedWork.child.stateNode; } - try { - commitCallbacks(flags, finishedRoot); - } catch (error$24) { - captureCommitPhaseError( - finishedWork, - finishedWork.return, - error$24 - ); + + exitDisallowedContextReadInDEV(); } + } else { + // Partial state object + partialState = _payload; } - break; - case 26: - case 27: - case 5: - recursivelyTraverseLayoutEffects( - finishedRoot, - finishedWork, - committedLanes - ); - flags & 512 && safelyAttachRef(finishedWork, finishedWork.return); - break; - case 12: - recursivelyTraverseLayoutEffects( - finishedRoot, - finishedWork, - committedLanes - ); - flags & 4 && commitProfilerUpdate(finishedWork, current); - break; - case 13: - recursivelyTraverseLayoutEffects( - finishedRoot, - finishedWork, - committedLanes - ); - break; - case 22: - if (0 !== (finishedWork.mode & 1)) { - if ( - ((prevState = - null !== finishedWork.memoizedState || - offscreenSubtreeIsHidden), - !prevState) - ) { - current = - (null !== current && null !== current.memoizedState) || - offscreenSubtreeWasHidden; - var prevOffscreenSubtreeIsHidden = offscreenSubtreeIsHidden, - prevOffscreenSubtreeWasHidden = offscreenSubtreeWasHidden; - offscreenSubtreeIsHidden = prevState; - (offscreenSubtreeWasHidden = current) && - !prevOffscreenSubtreeWasHidden - ? recursivelyTraverseReappearLayoutEffects( - finishedRoot, - finishedWork, - 0 !== (finishedWork.subtreeFlags & 8772) - ) - : recursivelyTraverseLayoutEffects( - finishedRoot, - finishedWork, - committedLanes - ); - offscreenSubtreeIsHidden = prevOffscreenSubtreeIsHidden; - offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden; - } - } else - recursivelyTraverseLayoutEffects( - finishedRoot, - finishedWork, - committedLanes - ); - flags & 512 && - ("manual" === finishedWork.memoizedProps.mode - ? safelyAttachRef(finishedWork, finishedWork.return) - : safelyDetachRef(finishedWork, finishedWork.return)); - break; - default: - recursivelyTraverseLayoutEffects( - finishedRoot, - finishedWork, - committedLanes - ); + + if (partialState === null || partialState === undefined) { + // Null and undefined are treated as no-ops. + return prevState; + } // Merge the partial state and the previous state. + + return assign({}, prevState, partialState); + } + + case ForceUpdate: { + hasForceUpdate = true; + return prevState; + } } + + return prevState; } - function detachFiberAfterEffects(fiber) { - var alternate = fiber.alternate; - null !== alternate && - ((fiber.alternate = null), detachFiberAfterEffects(alternate)); - fiber.child = null; - fiber.deletions = null; - fiber.sibling = null; - fiber.stateNode = null; - fiber._debugOwner = null; - fiber.return = null; - fiber.dependencies = null; - fiber.memoizedProps = null; - fiber.memoizedState = null; - fiber.pendingProps = null; - fiber.stateNode = null; - fiber.updateQueue = null; - } - function isHostParent(fiber) { - return 5 === fiber.tag || 3 === fiber.tag || 4 === fiber.tag; + + var didReadFromEntangledAsyncAction = false; // Each call to processUpdateQueue should be accompanied by a call to this. It's + // only in a separate function because in updateHostRoot, it must happen after + // all the context stacks have been pushed to, to prevent a stack mismatch. A + // bit unfortunate. + + function suspendIfUpdateReadFromEntangledAsyncAction() { + // Check if this update is part of a pending async action. If so, we'll + // need to suspend until the action has finished, so that it's batched + // together with future updates in the same action. + // TODO: Once we support hooks inside useMemo (or an equivalent + // memoization boundary like Forget), hoist this logic so that it only + // suspends if the memo boundary produces a new value. + if (didReadFromEntangledAsyncAction) { + var entangledActionThenable = peekEntangledActionThenable(); + + if (entangledActionThenable !== null) { + // TODO: Instead of the throwing the thenable directly, throw a + // special object like `use` does so we can detect if it's captured + // by userspace. + throw entangledActionThenable; + } + } } - function getHostSibling(fiber) { - a: for (;;) { - for (; null === fiber.sibling; ) { - if (null === fiber.return || isHostParent(fiber.return)) return null; - fiber = fiber.return; + function processUpdateQueue(workInProgress, props, instance, renderLanes) { + didReadFromEntangledAsyncAction = false; // This is always non-null on a ClassComponent or HostRoot + + var queue = workInProgress.updateQueue; + hasForceUpdate = false; + + { + currentlyProcessingQueue = queue.shared; + } + + var firstBaseUpdate = queue.firstBaseUpdate; + var lastBaseUpdate = queue.lastBaseUpdate; // Check if there are pending updates. If so, transfer them to the base queue. + + var pendingQueue = queue.shared.pending; + + if (pendingQueue !== null) { + queue.shared.pending = null; // The pending queue is circular. Disconnect the pointer between first + // and last so that it's non-circular. + + var lastPendingUpdate = pendingQueue; + var firstPendingUpdate = lastPendingUpdate.next; + lastPendingUpdate.next = null; // Append pending updates to base queue + + if (lastBaseUpdate === null) { + firstBaseUpdate = firstPendingUpdate; + } else { + lastBaseUpdate.next = firstPendingUpdate; } - fiber.sibling.return = fiber.return; - for ( - fiber = fiber.sibling; - 5 !== fiber.tag && 6 !== fiber.tag && 18 !== fiber.tag; - ) { - if (fiber.flags & 2) continue a; - if (null === fiber.child || 4 === fiber.tag) continue a; - else (fiber.child.return = fiber), (fiber = fiber.child); + lastBaseUpdate = lastPendingUpdate; // If there's a current queue, and it's different from the base queue, then + // we need to transfer the updates to that queue, too. Because the base + // queue is a singly-linked list with no cycles, we can append to both + // lists and take advantage of structural sharing. + // TODO: Pass `current` as argument + + var current = workInProgress.alternate; + + if (current !== null) { + // This is always non-null on a ClassComponent or HostRoot + var currentQueue = current.updateQueue; + var currentLastBaseUpdate = currentQueue.lastBaseUpdate; + + if (currentLastBaseUpdate !== lastBaseUpdate) { + if (currentLastBaseUpdate === null) { + currentQueue.firstBaseUpdate = firstPendingUpdate; + } else { + currentLastBaseUpdate.next = firstPendingUpdate; + } + + currentQueue.lastBaseUpdate = lastPendingUpdate; + } + } + } // These values may change as we process the queue. + + if (firstBaseUpdate !== null) { + // Iterate through the list of updates to compute the result. + var newState = queue.baseState; // TODO: Don't need to accumulate this. Instead, we can remove renderLanes + // from the original lanes. + + var newLanes = NoLanes; + var newBaseState = null; + var newFirstBaseUpdate = null; + var newLastBaseUpdate = null; + var update = firstBaseUpdate; + + do { + // An extra OffscreenLane bit is added to updates that were made to + // a hidden tree, so that we can distinguish them from updates that were + // already there when the tree was hidden. + var updateLane = removeLanes(update.lane, OffscreenLane); + var isHiddenUpdate = updateLane !== update.lane; // Check if this update was made while the tree was hidden. If so, then + // it's not a "base" update and we should disregard the extra base lanes + // that were added to renderLanes when we entered the Offscreen tree. + + var shouldSkipUpdate = isHiddenUpdate + ? !isSubsetOfLanes(getWorkInProgressRootRenderLanes(), updateLane) + : !isSubsetOfLanes(renderLanes, updateLane); + + if (shouldSkipUpdate) { + // Priority is insufficient. Skip this update. If this is the first + // skipped update, the previous update/state is the new base + // update/state. + var clone = { + lane: updateLane, + tag: update.tag, + payload: update.payload, + callback: update.callback, + next: null + }; + + if (newLastBaseUpdate === null) { + newFirstBaseUpdate = newLastBaseUpdate = clone; + newBaseState = newState; + } else { + newLastBaseUpdate = newLastBaseUpdate.next = clone; + } // Update the remaining priority in the queue. + + newLanes = mergeLanes(newLanes, updateLane); + } else { + // This update does have sufficient priority. + // Check if this update is part of a pending async action. If so, + // we'll need to suspend until the action has finished, so that it's + // batched together with future updates in the same action. + if ( + updateLane !== NoLane && + updateLane === peekEntangledActionLane() + ) { + didReadFromEntangledAsyncAction = true; + } + + if (newLastBaseUpdate !== null) { + var _clone = { + // This update is going to be committed so we never want uncommit + // it. Using NoLane works because 0 is a subset of all bitmasks, so + // this will never be skipped by the check above. + lane: NoLane, + tag: update.tag, + payload: update.payload, + // When this update is rebased, we should not fire its + // callback again. + callback: null, + next: null + }; + newLastBaseUpdate = newLastBaseUpdate.next = _clone; + } // Process this update. + + newState = getStateFromUpdate( + workInProgress, + queue, + update, + newState, + props, + instance + ); + var callback = update.callback; + + if (callback !== null) { + workInProgress.flags |= Callback; + + if (isHiddenUpdate) { + workInProgress.flags |= Visibility; + } + + var callbacks = queue.callbacks; + + if (callbacks === null) { + queue.callbacks = [callback]; + } else { + callbacks.push(callback); + } + } + } // $FlowFixMe[incompatible-type] we bail out when we get a null + + update = update.next; + + if (update === null) { + pendingQueue = queue.shared.pending; + + if (pendingQueue === null) { + break; + } else { + // An update was scheduled from inside a reducer. Add the new + // pending updates to the end of the list and keep processing. + var _lastPendingUpdate = pendingQueue; // Intentionally unsound. Pending updates form a circular list, but we + // unravel them when transferring them to the base queue. + + var _firstPendingUpdate = _lastPendingUpdate.next; + _lastPendingUpdate.next = null; + update = _firstPendingUpdate; + queue.lastBaseUpdate = _lastPendingUpdate; + queue.shared.pending = null; + } + } + } while (true); + + if (newLastBaseUpdate === null) { + newBaseState = newState; } - if (!(fiber.flags & 2)) return fiber.stateNode; + + queue.baseState = newBaseState; + queue.firstBaseUpdate = newFirstBaseUpdate; + queue.lastBaseUpdate = newLastBaseUpdate; + + 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 + // dealt with the props. Context in components that specify + // shouldComponentUpdate is tricky; but we'll have to account for + // that regardless. + + markSkippedUpdateLanes(newLanes); + workInProgress.lanes = newLanes; + workInProgress.memoizedState = newState; + } + + { + currentlyProcessingQueue = null; } } - function insertOrAppendPlacementNodeIntoContainer(node, before, parent) { - 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 - ReactNativePrivateInterface.UIManager.setChildren(parent, [ - "number" === typeof node ? node : node._nativeTag - ]); - else if (4 !== tag && ((node = node.child), null !== node)) - for ( - insertOrAppendPlacementNodeIntoContainer(node, before, parent), - node = node.sibling; - null !== node; - ) - insertOrAppendPlacementNodeIntoContainer(node, before, parent), - (node = node.sibling); + function callCallback(callback, context) { + if (typeof callback !== "function") { + throw new Error( + "Invalid argument passed as callback. Expected a function. Instead " + + ("received: " + callback) + ); + } + + callback.call(context); } - function insertOrAppendPlacementNode(node, before, parent) { - 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; - null !== node; - ) - insertOrAppendPlacementNode(node, before, parent), - (node = node.sibling); + function resetHasForceUpdateBeforeProcessing() { + hasForceUpdate = false; } - function recursivelyTraverseDeletionEffects( - finishedRoot, - nearestMountedAncestor, - parent - ) { - for (parent = parent.child; null !== parent; ) - commitDeletionEffectsOnFiber( - finishedRoot, - nearestMountedAncestor, - parent - ), - (parent = parent.sibling); + function checkHasForceUpdateAfterProcessing() { + return hasForceUpdate; } - function commitDeletionEffectsOnFiber( - finishedRoot, - nearestMountedAncestor, - deletedFiber - ) { - if ( - injectedHook && - "function" === typeof injectedHook.onCommitFiberUnmount - ) - try { - injectedHook.onCommitFiberUnmount(rendererID, deletedFiber); - } catch (err) { - hasLoggedError || - ((hasLoggedError = !0), - error$jscomp$0( - "React instrumentation encountered an error: %s", - err - )); + function deferHiddenCallbacks(updateQueue) { + // When an update finishes on a hidden component, its callback should not + // be fired until/unless the component is made visible again. Stash the + // callback on the shared queue object so it can be fired later. + var newHiddenCallbacks = updateQueue.callbacks; + + if (newHiddenCallbacks !== null) { + var existingHiddenCallbacks = updateQueue.shared.hiddenCallbacks; + + if (existingHiddenCallbacks === null) { + updateQueue.shared.hiddenCallbacks = newHiddenCallbacks; + } else { + updateQueue.shared.hiddenCallbacks = + existingHiddenCallbacks.concat(newHiddenCallbacks); } - switch (deletedFiber.tag) { - case 26: - case 27: - case 5: - offscreenSubtreeWasHidden || - safelyDetachRef(deletedFiber, nearestMountedAncestor); - case 6: - var _prevHostParent = hostParent, - _prevHostParentIsContainer = hostParentIsContainer; - hostParent = null; - recursivelyTraverseDeletionEffects( - finishedRoot, - nearestMountedAncestor, - deletedFiber - ); - hostParent = _prevHostParent; - hostParentIsContainer = _prevHostParentIsContainer; - null !== hostParent && - (hostParentIsContainer - ? ((finishedRoot = hostParent), - recursivelyUncacheFiberNode(deletedFiber.stateNode), - ReactNativePrivateInterface.UIManager.manageChildren( - finishedRoot, - [], - [], - [], - [], - [0] - )) - : ((finishedRoot = hostParent), - (nearestMountedAncestor = deletedFiber.stateNode), - recursivelyUncacheFiberNode(nearestMountedAncestor), - (deletedFiber = finishedRoot._children), - (nearestMountedAncestor = deletedFiber.indexOf( - nearestMountedAncestor - )), - deletedFiber.splice(nearestMountedAncestor, 1), - ReactNativePrivateInterface.UIManager.manageChildren( - finishedRoot._nativeTag, - [], - [], - [], - [], - [nearestMountedAncestor] - ))); - break; - case 18: - null !== hostParent && - (hostParentIsContainer - ? clearSuspenseBoundaryFromContainer() - : clearSuspenseBoundary()); - break; - case 4: - _prevHostParent = hostParent; - _prevHostParentIsContainer = hostParentIsContainer; - hostParent = deletedFiber.stateNode.containerInfo; - hostParentIsContainer = !0; - recursivelyTraverseDeletionEffects( - finishedRoot, - nearestMountedAncestor, - deletedFiber - ); - hostParent = _prevHostParent; - hostParentIsContainer = _prevHostParentIsContainer; - break; - case 0: - case 11: - case 14: - case 15: - if ( - !offscreenSubtreeWasHidden && - ((_prevHostParent = deletedFiber.updateQueue), - null !== _prevHostParent && - ((_prevHostParent = _prevHostParent.lastEffect), - null !== _prevHostParent)) - ) { - _prevHostParentIsContainer = _prevHostParent = _prevHostParent.next; - do { - var tag = _prevHostParentIsContainer.tag, - inst = _prevHostParentIsContainer.inst, - destroy = inst.destroy; - void 0 !== destroy && - ((tag & Insertion) !== NoFlags - ? ((inst.destroy = void 0), - safelyCallDestroy( - deletedFiber, - nearestMountedAncestor, - destroy - )) - : (tag & Layout) !== NoFlags && - (markComponentLayoutEffectUnmountStarted(deletedFiber), - shouldProfile(deletedFiber) - ? (startLayoutEffectTimer(), - (inst.destroy = void 0), - safelyCallDestroy( - deletedFiber, - nearestMountedAncestor, - destroy - ), - recordLayoutEffectDuration(deletedFiber)) - : ((inst.destroy = void 0), - safelyCallDestroy( - deletedFiber, - nearestMountedAncestor, - destroy - )), - markComponentLayoutEffectUnmountStopped())); - _prevHostParentIsContainer = _prevHostParentIsContainer.next; - } while (_prevHostParentIsContainer !== _prevHostParent); - } - recursivelyTraverseDeletionEffects( - finishedRoot, - nearestMountedAncestor, - deletedFiber - ); - break; - case 1: - offscreenSubtreeWasHidden || - (safelyDetachRef(deletedFiber, nearestMountedAncestor), - (_prevHostParent = deletedFiber.stateNode), - "function" === typeof _prevHostParent.componentWillUnmount && - safelyCallComponentWillUnmount( - deletedFiber, - nearestMountedAncestor, - _prevHostParent - )); - recursivelyTraverseDeletionEffects( - finishedRoot, - nearestMountedAncestor, - deletedFiber - ); - break; - case 21: - recursivelyTraverseDeletionEffects( - finishedRoot, - nearestMountedAncestor, - deletedFiber - ); - break; - case 22: - safelyDetachRef(deletedFiber, nearestMountedAncestor); - deletedFiber.mode & 1 - ? ((offscreenSubtreeWasHidden = - (_prevHostParent = offscreenSubtreeWasHidden) || - null !== deletedFiber.memoizedState), - recursivelyTraverseDeletionEffects( - finishedRoot, - nearestMountedAncestor, - deletedFiber - ), - (offscreenSubtreeWasHidden = _prevHostParent)) - : recursivelyTraverseDeletionEffects( - finishedRoot, - nearestMountedAncestor, - deletedFiber - ); - break; - default: - recursivelyTraverseDeletionEffects( - finishedRoot, - nearestMountedAncestor, - deletedFiber - ); } } - function getRetryCache(finishedWork) { - switch (finishedWork.tag) { - case 13: - case 19: - var retryCache = finishedWork.stateNode; - null === retryCache && - (retryCache = finishedWork.stateNode = new PossiblyWeakSet()); - return retryCache; - case 22: - return ( - (finishedWork = finishedWork.stateNode), - (retryCache = finishedWork._retryCache), - null === retryCache && - (retryCache = finishedWork._retryCache = new PossiblyWeakSet()), - retryCache - ); - default: - throw Error( - "Unexpected Suspense handler tag (" + - finishedWork.tag + - "). This is a bug in React." - ); + function commitHiddenCallbacks(updateQueue, context) { + // This component is switching from hidden -> visible. Commit any callbacks + // that were previously deferred. + var hiddenCallbacks = updateQueue.shared.hiddenCallbacks; + + if (hiddenCallbacks !== null) { + updateQueue.shared.hiddenCallbacks = null; + + for (var i = 0; i < hiddenCallbacks.length; i++) { + var callback = hiddenCallbacks[i]; + callCallback(callback, context); + } } } - function attachSuspenseRetryListeners(finishedWork, wakeables) { - var retryCache = getRetryCache(finishedWork); - wakeables.forEach(function (wakeable) { - var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable); - if (!retryCache.has(wakeable)) { - retryCache.add(wakeable); - if (isDevToolsPresent) - if (null !== inProgressLanes && null !== inProgressRoot) - restorePendingUpdaters(inProgressRoot, inProgressLanes); - else - throw Error( - "Expected finished root and lanes to be set. This is a bug in React." - ); - wakeable.then(retry, retry); + function commitCallbacks(updateQueue, context) { + var callbacks = updateQueue.callbacks; + + if (callbacks !== null) { + updateQueue.callbacks = null; + + for (var i = 0; i < callbacks.length; i++) { + var callback = callbacks[i]; + callCallback(callback, context); } - }); + } } - function commitMutationEffects(root, finishedWork, committedLanes) { - inProgressLanes = committedLanes; - inProgressRoot = root; - runWithFiberInDEV( - finishedWork, - commitMutationEffectsOnFiber, - finishedWork, - root, - committedLanes - ); - inProgressRoot = inProgressLanes = null; + + // $FlowFixMe[method-unbinding] + 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. + * Returns true when the values of all keys are strictly equal. + */ + + function shallowEqual(objA, objB) { + if (objectIs(objA, objB)) { + return true; + } + + if ( + typeof objA !== "object" || + objA === null || + typeof objB !== "object" || + objB === null + ) { + return false; + } + + var keysA = Object.keys(objA); + var keysB = Object.keys(objB); + + if (keysA.length !== keysB.length) { + return false; + } // Test for A's keys different from B. + + for (var i = 0; i < keysA.length; i++) { + var currentKey = keysA[i]; + + if ( + !hasOwnProperty.call(objB, currentKey) || // $FlowFixMe[incompatible-use] lost refinement of `objB` + !objectIs(objA[currentKey], objB[currentKey]) + ) { + return false; + } + } + + return true; } - function recursivelyTraverseMutationEffects( - root$jscomp$0, - parentFiber, - lanes - ) { - var deletions = parentFiber.deletions; - if (null !== deletions) - for (var i = 0; i < deletions.length; i++) { - var childToDelete = deletions[i]; - try { - var root = root$jscomp$0, - returnFiber = parentFiber, - deletedFiber = childToDelete, - parent = returnFiber; - a: for (; null !== parent; ) { - switch (parent.tag) { - case 27: - case 5: - hostParent = parent.stateNode; - hostParentIsContainer = !1; - break a; - case 3: - hostParent = parent.stateNode.containerInfo; - hostParentIsContainer = !0; - break a; - case 4: - hostParent = parent.stateNode.containerInfo; - hostParentIsContainer = !0; - break a; - } - parent = parent.return; - } - if (null === hostParent) - throw Error( - "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." - ); - commitDeletionEffectsOnFiber(root, returnFiber, deletedFiber); - hostParent = null; - hostParentIsContainer = !1; - root = deletedFiber; - var alternate = root.alternate; - null !== alternate && (alternate.return = null); - root.return = null; - } catch (error$27) { - captureCommitPhaseError(childToDelete, parentFiber, error$27); - } - } - if (parentFiber.subtreeFlags & 13878) - for (parentFiber = parentFiber.child; null !== parentFiber; ) - runWithFiberInDEV( - parentFiber, - commitMutationEffectsOnFiber, - parentFiber, - root$jscomp$0, - lanes - ), - (parentFiber = parentFiber.sibling); + + function describeBuiltInComponentFrame(name, ownerFn) { + { + var ownerName = null; + + if (ownerFn) { + ownerName = ownerFn.displayName || ownerFn.name || null; + } + + return describeComponentFrame(name, ownerName); + } } - function commitMutationEffectsOnFiber(finishedWork, root, lanes) { - var current = finishedWork.alternate, - flags = finishedWork.flags; - switch (finishedWork.tag) { - case 0: - case 11: - case 14: - case 15: - recursivelyTraverseMutationEffects(root, finishedWork, lanes); - commitReconciliationEffects(finishedWork); - if (flags & 4) { - try { - commitHookEffectListUnmount( - Insertion | HasEffect, - finishedWork, - finishedWork.return - ), - commitHookEffectListMount(Insertion | HasEffect, finishedWork); - } catch (error$28) { - captureCommitPhaseError( - finishedWork, - finishedWork.return, - error$28 - ); - } - if (shouldProfile(finishedWork)) { - try { - startLayoutEffectTimer(), - commitHookEffectListUnmount( - Layout | HasEffect, - finishedWork, - finishedWork.return - ); - } catch (error$29) { - captureCommitPhaseError( - finishedWork, - finishedWork.return, - error$29 - ); - } - recordLayoutEffectDuration(finishedWork); - } else - try { - commitHookEffectListUnmount( - Layout | HasEffect, - finishedWork, - finishedWork.return - ); - } catch (error$30) { - captureCommitPhaseError( - finishedWork, - finishedWork.return, - error$30 - ); - } - } - break; - case 1: - recursivelyTraverseMutationEffects(root, finishedWork, lanes); - commitReconciliationEffects(finishedWork); - flags & 512 && - null !== current && - safelyDetachRef(current, current.return); - if ( - flags & 64 && - offscreenSubtreeIsHidden && - ((finishedWork = finishedWork.updateQueue), - null !== finishedWork && - ((flags = finishedWork.callbacks), null !== flags)) - ) { - var existingHiddenCallbacks = finishedWork.shared.hiddenCallbacks; - finishedWork.shared.hiddenCallbacks = - null === existingHiddenCallbacks - ? flags - : existingHiddenCallbacks.concat(flags); - } - break; - case 26: - case 27: - case 5: - recursivelyTraverseMutationEffects(root, finishedWork, lanes); - commitReconciliationEffects(finishedWork); - flags & 512 && - null !== current && - safelyDetachRef(current, current.return); - if ( - flags & 4 && - ((existingHiddenCallbacks = finishedWork.stateNode), - null != existingHiddenCallbacks) - ) { - var newProps = finishedWork.memoizedProps, - oldProps = null !== current ? current.memoizedProps : newProps; - try { - var viewConfig = existingHiddenCallbacks.viewConfig; - instanceProps.set(existingHiddenCallbacks._nativeTag, newProps); - var updatePayload = diffProperties( - null, - oldProps, - newProps, - viewConfig.validAttributes - ); - null != updatePayload && - ReactNativePrivateInterface.UIManager.updateView( - existingHiddenCallbacks._nativeTag, - viewConfig.uiViewClassName, - updatePayload - ); - } catch (error$32) { - captureCommitPhaseError( - finishedWork, - finishedWork.return, - error$32 - ); - } - } - flags & 1024 && - "form" !== finishedWork.type && - error$jscomp$0( - "Unexpected host component type. Expected a form. This is a bug in React." - ); - break; - case 6: - recursivelyTraverseMutationEffects(root, finishedWork, lanes); - commitReconciliationEffects(finishedWork); - if (flags & 4) { - if (null === finishedWork.stateNode) - throw Error( - "This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue." - ); - flags = finishedWork.stateNode; - existingHiddenCallbacks = finishedWork.memoizedProps; - try { - ReactNativePrivateInterface.UIManager.updateView( - flags, - "RCTRawText", - { text: existingHiddenCallbacks } - ); - } catch (error$33) { - captureCommitPhaseError( - finishedWork, - finishedWork.return, - error$33 - ); - } - } - break; - case 3: - recursivelyTraverseMutationEffects(root, finishedWork, lanes); - commitReconciliationEffects(finishedWork); - break; - case 4: - recursivelyTraverseMutationEffects(root, finishedWork, lanes); - commitReconciliationEffects(finishedWork); - break; - case 13: - recursivelyTraverseMutationEffects(root, finishedWork, lanes); - commitReconciliationEffects(finishedWork); - finishedWork.child.flags & 8192 && - ((existingHiddenCallbacks = - null !== current && null !== current.memoizedState), - null === finishedWork.memoizedState || - existingHiddenCallbacks || - (globalMostRecentFallbackTime = now$1())); - flags & 4 && - ((flags = finishedWork.updateQueue), - null !== flags && - ((finishedWork.updateQueue = null), - attachSuspenseRetryListeners(finishedWork, flags))); - break; - case 22: - flags & 512 && - null !== current && - safelyDetachRef(current, current.return); - viewConfig = null !== finishedWork.memoizedState; - updatePayload = null !== current && null !== current.memoizedState; - if (finishedWork.mode & 1) { - var prevOffscreenSubtreeIsHidden = offscreenSubtreeIsHidden, - prevOffscreenSubtreeWasHidden = offscreenSubtreeWasHidden; - offscreenSubtreeIsHidden = - prevOffscreenSubtreeIsHidden || viewConfig; - offscreenSubtreeWasHidden = - prevOffscreenSubtreeWasHidden || updatePayload; - recursivelyTraverseMutationEffects(root, finishedWork, lanes); - offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden; - offscreenSubtreeIsHidden = prevOffscreenSubtreeIsHidden; - } else recursivelyTraverseMutationEffects(root, finishedWork, lanes); - commitReconciliationEffects(finishedWork); - root = finishedWork.stateNode; - root._current = finishedWork; - root._visibility &= -3; - root._visibility |= root._pendingVisibility & 2; - if ( - flags & 8192 && - ((root._visibility = viewConfig - ? root._visibility & -2 - : root._visibility | 1), - viewConfig && - ((root = offscreenSubtreeIsHidden || offscreenSubtreeWasHidden), - null === current || - updatePayload || - root || - (0 !== (finishedWork.mode & 1) && - recursivelyTraverseDisappearLayoutEffects(finishedWork))), - null === finishedWork.memoizedProps || - "manual" !== finishedWork.memoizedProps.mode) - ) - a: for (current = null, root = finishedWork; ; ) { - if (5 === root.tag) { - if (null === current) { - current = root; - try { - if ( - ((existingHiddenCallbacks = root.stateNode), viewConfig) - ) - (lanes = existingHiddenCallbacks), - (newProps = lanes.viewConfig), - (oldProps = diffProperties( - null, - emptyObject$1, - { style: { display: "none" } }, - newProps.validAttributes - )), - ReactNativePrivateInterface.UIManager.updateView( - lanes._nativeTag, - newProps.uiViewClassName, - oldProps - ); - else { - var instance = root.stateNode, - props = root.memoizedProps, - viewConfig$jscomp$0 = instance.viewConfig, - prevProps = assign({}, props, { - style: [props.style, { display: "none" }] - }); - var updatePayload$jscomp$0 = diffProperties( - null, - prevProps, - props, - viewConfig$jscomp$0.validAttributes - ); - ReactNativePrivateInterface.UIManager.updateView( - instance._nativeTag, - viewConfig$jscomp$0.uiViewClassName, - updatePayload$jscomp$0 - ); - } - } catch (error$25) { - captureCommitPhaseError( - finishedWork, - finishedWork.return, - error$25 - ); - } - } - } else if (6 === root.tag) { - if (null === current) - try { - throw Error("Not yet implemented."); - } catch (error$26) { - captureCommitPhaseError( - finishedWork, - finishedWork.return, - error$26 - ); - } - } else if ( - ((22 !== root.tag && 23 !== root.tag) || - null === root.memoizedState || - root === finishedWork) && - null !== root.child - ) { - root.child.return = root; - root = root.child; - continue; - } - if (root === finishedWork) break a; - for (; null === root.sibling; ) { - if (null === root.return || root.return === finishedWork) - break a; - current === root && (current = null); - root = root.return; - } - current === root && (current = null); - root.sibling.return = root.return; - root = root.sibling; - } - flags & 4 && - ((flags = finishedWork.updateQueue), - null !== flags && - ((existingHiddenCallbacks = flags.retryQueue), - null !== existingHiddenCallbacks && - ((flags.retryQueue = null), - attachSuspenseRetryListeners( - finishedWork, - existingHiddenCallbacks - )))); - break; - case 19: - recursivelyTraverseMutationEffects(root, finishedWork, lanes); - commitReconciliationEffects(finishedWork); - flags & 4 && - ((flags = finishedWork.updateQueue), - null !== flags && - ((finishedWork.updateQueue = null), - attachSuspenseRetryListeners(finishedWork, flags))); - break; - case 21: - break; + function describeDebugInfoFrame(name, env) { + return describeBuiltInComponentFrame( + name + (env ? " (" + env + ")" : ""), + null + ); + } + + { + var PossiblyWeakMap$1 = typeof WeakMap === "function" ? WeakMap : Map; + new PossiblyWeakMap$1(); + } + + function describeComponentFrame(name, ownerName) { + var sourceInfo = ""; + + if (ownerName) { + sourceInfo = " (created by " + ownerName + ")"; + } + + return "\n in " + (name || "Unknown") + sourceInfo; + } + + function describeClassComponentFrame(ctor, ownerFn) { + { + return describeFunctionComponentFrame(ctor, ownerFn); + } + } + function describeFunctionComponentFrame(fn, ownerFn) { + { + if (!fn) { + return ""; + } + + var name = fn.displayName || fn.name || null; + var ownerName = null; + + if (ownerFn) { + ownerName = ownerFn.displayName || ownerFn.name || null; + } + + return describeComponentFrame(name, ownerName); + } + } + + function describeFiber(fiber) { + var owner = fiber._debugOwner ? fiber._debugOwner.type : null; + + switch (fiber.tag) { + case HostHoistable: + case HostSingleton: + case HostComponent: + return describeBuiltInComponentFrame(fiber.type, owner); + + case LazyComponent: + return describeBuiltInComponentFrame("Lazy", owner); + + case SuspenseComponent: + return describeBuiltInComponentFrame("Suspense", owner); + + case SuspenseListComponent: + return describeBuiltInComponentFrame("SuspenseList", owner); + + case FunctionComponent: + case IndeterminateComponent: + case SimpleMemoComponent: + return describeFunctionComponentFrame(fiber.type, owner); + + case ForwardRef: + return describeFunctionComponentFrame(fiber.type.render, owner); + + case ClassComponent: + return describeClassComponentFrame(fiber.type, owner); + default: - recursivelyTraverseMutationEffects(root, finishedWork, lanes), - commitReconciliationEffects(finishedWork); + return ""; } } - function commitReconciliationEffects(finishedWork) { - var flags = finishedWork.flags; - if (flags & 2) { - try { - a: { - for (var parent = finishedWork.return; null !== parent; ) { - if (isHostParent(parent)) { - var parentFiber = parent; - break a; + + function getStackByFiberInDevAndProd(workInProgress) { + try { + var info = ""; + var node = workInProgress; + + do { + info += describeFiber(node); + + if (true) { + // Add any Server Component stack frames in reverse order. + var debugInfo = node._debugInfo; + + if (debugInfo) { + for (var i = debugInfo.length - 1; i >= 0; i--) { + var entry = debugInfo[i]; + + if (typeof entry.name === "string") { + info += describeDebugInfoFrame(entry.name, entry.env); + } } - parent = parent.return; } - throw Error( - "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." - ); - } - switch (parentFiber.tag) { - case 27: - case 5: - var _parent = parentFiber.stateNode; - parentFiber.flags & 32 && (parentFiber.flags &= -33); - var _before = getHostSibling(finishedWork); - insertOrAppendPlacementNode(finishedWork, _before, _parent); - break; - case 3: - case 4: - var _parent2 = parentFiber.stateNode.containerInfo, - _before2 = getHostSibling(finishedWork); - insertOrAppendPlacementNodeIntoContainer( - finishedWork, - _before2, - _parent2 - ); - break; - default: - throw Error( - "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." - ); - } - } catch (error$35) { - captureCommitPhaseError(finishedWork, finishedWork.return, error$35); + } // $FlowFixMe[incompatible-type] we bail out when we get a null + + node = node.return; + } while (node); + + return info; + } catch (x) { + return "\nError generating stack: " + x.message + "\n" + x.stack; + } + } + + var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; + var current = null; + var isRendering = false; + function getCurrentFiberOwnerNameInDevOrNull() { + { + if (current === null) { + return null; + } + + var owner = current._debugOwner; + + if (owner !== null && typeof owner !== "undefined") { + return getComponentNameFromFiber(owner); } - finishedWork.flags &= -3; } - flags & 4096 && (finishedWork.flags &= -4097); + + return null; } - function commitLayoutEffects(finishedWork, root, committedLanes) { - inProgressLanes = committedLanes; - inProgressRoot = root; - runWithFiberInDEV( - finishedWork, - commitLayoutEffectOnFiber, - root, - finishedWork.alternate, - finishedWork, - committedLanes - ); - inProgressRoot = inProgressLanes = null; + + function getCurrentFiberStackInDev() { + { + if (current === null) { + return ""; + } // Safe because if current fiber exists, we are reconciling, + // and it is guaranteed to be the work-in-progress version. + + return getStackByFiberInDevAndProd(current); + } } - function recursivelyTraverseLayoutEffects(root, parentFiber, lanes) { - if (parentFiber.subtreeFlags & 8772) - for (parentFiber = parentFiber.child; null !== parentFiber; ) - runWithFiberInDEV( - parentFiber, - commitLayoutEffectOnFiber, - root, - parentFiber.alternate, - parentFiber, - lanes - ), - (parentFiber = parentFiber.sibling); + + function resetCurrentFiber() { + { + ReactDebugCurrentFrame.getCurrentStack = null; + current = null; + isRendering = false; + } } - function disappearLayoutEffects(finishedWork) { - switch (finishedWork.tag) { - case 0: - case 11: - case 14: - case 15: - if (shouldProfile(finishedWork)) - try { - startLayoutEffectTimer(), - commitHookEffectListUnmount( - Layout, - finishedWork, - finishedWork.return - ); - } finally { - recordLayoutEffectDuration(finishedWork); - } - else - commitHookEffectListUnmount( - Layout, - finishedWork, - finishedWork.return - ); - recursivelyTraverseDisappearLayoutEffects(finishedWork); - break; - case 1: - safelyDetachRef(finishedWork, finishedWork.return); - var instance = finishedWork.stateNode; - "function" === typeof instance.componentWillUnmount && - safelyCallComponentWillUnmount( - finishedWork, - finishedWork.return, - instance - ); - recursivelyTraverseDisappearLayoutEffects(finishedWork); - break; - case 26: - case 27: - case 5: - safelyDetachRef(finishedWork, finishedWork.return); - recursivelyTraverseDisappearLayoutEffects(finishedWork); - break; - case 22: - safelyDetachRef(finishedWork, finishedWork.return); - null === finishedWork.memoizedState && - recursivelyTraverseDisappearLayoutEffects(finishedWork); - break; - default: - recursivelyTraverseDisappearLayoutEffects(finishedWork); + function setCurrentFiber(fiber) { + { + ReactDebugCurrentFrame.getCurrentStack = + fiber === null ? null : getCurrentFiberStackInDev; + current = fiber; + isRendering = false; } } - function recursivelyTraverseDisappearLayoutEffects(parentFiber) { - for (parentFiber = parentFiber.child; null !== parentFiber; ) - disappearLayoutEffects(parentFiber), - (parentFiber = parentFiber.sibling); + function getCurrentFiber() { + { + return current; + } } - function reappearLayoutEffects( - finishedRoot, - current, - finishedWork, - includeWorkInProgressEffects - ) { - var flags = finishedWork.flags; - switch (finishedWork.tag) { - case 0: - case 11: - case 15: - recursivelyTraverseReappearLayoutEffects( - finishedRoot, - finishedWork, - includeWorkInProgressEffects - ); - commitHookLayoutEffects(finishedWork, Layout); - break; - case 1: - recursivelyTraverseReappearLayoutEffects( - finishedRoot, - finishedWork, - includeWorkInProgressEffects - ); - finishedRoot = finishedWork.stateNode; - if ("function" === typeof finishedRoot.componentDidMount) - try { - finishedRoot.componentDidMount(); - } catch (error$36) { - captureCommitPhaseError( - finishedWork, - finishedWork.return, - error$36 - ); - } - var updateQueue = finishedWork.updateQueue; - if ( - null !== updateQueue && - ((current = updateQueue.shared.hiddenCallbacks), null !== current) - ) - for ( - updateQueue.shared.hiddenCallbacks = null, updateQueue = 0; - updateQueue < current.length; - updateQueue++ - ) - callCallback(current[updateQueue], finishedRoot); - includeWorkInProgressEffects && - flags & 64 && - commitClassCallbacks(finishedWork); - safelyAttachRef(finishedWork, finishedWork.return); - break; - case 26: - case 27: - case 5: - recursivelyTraverseReappearLayoutEffects( - finishedRoot, - finishedWork, - includeWorkInProgressEffects - ); - safelyAttachRef(finishedWork, finishedWork.return); - break; - case 12: - recursivelyTraverseReappearLayoutEffects( - finishedRoot, - finishedWork, - includeWorkInProgressEffects - ); - includeWorkInProgressEffects && - flags & 4 && - commitProfilerUpdate(finishedWork, current); - break; - case 13: - recursivelyTraverseReappearLayoutEffects( - finishedRoot, - finishedWork, - includeWorkInProgressEffects - ); - break; - case 22: - null === finishedWork.memoizedState && - recursivelyTraverseReappearLayoutEffects( - finishedRoot, - finishedWork, - includeWorkInProgressEffects - ); - safelyAttachRef(finishedWork, finishedWork.return); - break; - default: - recursivelyTraverseReappearLayoutEffects( - finishedRoot, - finishedWork, - includeWorkInProgressEffects - ); + function setIsRendering(rendering) { + { + isRendering = rendering; } } - function recursivelyTraverseReappearLayoutEffects( - finishedRoot, - parentFiber, - includeWorkInProgressEffects - ) { - includeWorkInProgressEffects = - includeWorkInProgressEffects && 0 !== (parentFiber.subtreeFlags & 8772); - for (parentFiber = parentFiber.child; null !== parentFiber; ) - runWithFiberInDEV( - parentFiber, - reappearLayoutEffects, - finishedRoot, - parentFiber.alternate, - parentFiber, - includeWorkInProgressEffects - ), - (parentFiber = parentFiber.sibling); + + var ReactStrictModeWarnings = { + recordUnsafeLifecycleWarnings: function (fiber, instance) {}, + flushPendingUnsafeLifecycleWarnings: function () {}, + recordLegacyContextWarning: function (fiber, instance) {}, + flushLegacyContextWarning: function () {}, + discardPendingWarnings: function () {} + }; + + { + var findStrictRoot = function (fiber) { + var maybeStrictRoot = null; + var node = fiber; + + while (node !== null) { + if (node.mode & StrictLegacyMode) { + maybeStrictRoot = node; + } + + node = node.return; + } + + return maybeStrictRoot; + }; + + var setToSortedString = function (set) { + var array = []; + set.forEach(function (value) { + array.push(value); + }); + return array.sort().join(", "); + }; + + var pendingComponentWillMountWarnings = []; + var pendingUNSAFE_ComponentWillMountWarnings = []; + var pendingComponentWillReceivePropsWarnings = []; + var pendingUNSAFE_ComponentWillReceivePropsWarnings = []; + var pendingComponentWillUpdateWarnings = []; + var pendingUNSAFE_ComponentWillUpdateWarnings = []; // Tracks components we have already warned about. + + var didWarnAboutUnsafeLifecycles = new Set(); + + ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function ( + fiber, + instance + ) { + // Dedupe strategy: Warn once per component. + if (didWarnAboutUnsafeLifecycles.has(fiber.type)) { + return; + } + + if ( + typeof instance.componentWillMount === "function" && // Don't warn about react-lifecycles-compat polyfilled components. + instance.componentWillMount.__suppressDeprecationWarning !== true + ) { + pendingComponentWillMountWarnings.push(fiber); + } + + if ( + fiber.mode & StrictLegacyMode && + typeof instance.UNSAFE_componentWillMount === "function" + ) { + pendingUNSAFE_ComponentWillMountWarnings.push(fiber); + } + + if ( + typeof instance.componentWillReceiveProps === "function" && + instance.componentWillReceiveProps.__suppressDeprecationWarning !== + true + ) { + pendingComponentWillReceivePropsWarnings.push(fiber); + } + + if ( + fiber.mode & StrictLegacyMode && + typeof instance.UNSAFE_componentWillReceiveProps === "function" + ) { + pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber); + } + + if ( + typeof instance.componentWillUpdate === "function" && + instance.componentWillUpdate.__suppressDeprecationWarning !== true + ) { + pendingComponentWillUpdateWarnings.push(fiber); + } + + if ( + fiber.mode & StrictLegacyMode && + typeof instance.UNSAFE_componentWillUpdate === "function" + ) { + pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber); + } + }; + + ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = + function () { + // We do an initial pass to gather component names + var componentWillMountUniqueNames = new Set(); + + if (pendingComponentWillMountWarnings.length > 0) { + pendingComponentWillMountWarnings.forEach(function (fiber) { + componentWillMountUniqueNames.add( + getComponentNameFromFiber(fiber) || "Component" + ); + didWarnAboutUnsafeLifecycles.add(fiber.type); + }); + pendingComponentWillMountWarnings = []; + } + + var UNSAFE_componentWillMountUniqueNames = new Set(); + + if (pendingUNSAFE_ComponentWillMountWarnings.length > 0) { + pendingUNSAFE_ComponentWillMountWarnings.forEach(function (fiber) { + UNSAFE_componentWillMountUniqueNames.add( + getComponentNameFromFiber(fiber) || "Component" + ); + didWarnAboutUnsafeLifecycles.add(fiber.type); + }); + pendingUNSAFE_ComponentWillMountWarnings = []; + } + + var componentWillReceivePropsUniqueNames = new Set(); + + if (pendingComponentWillReceivePropsWarnings.length > 0) { + pendingComponentWillReceivePropsWarnings.forEach(function (fiber) { + componentWillReceivePropsUniqueNames.add( + getComponentNameFromFiber(fiber) || "Component" + ); + didWarnAboutUnsafeLifecycles.add(fiber.type); + }); + pendingComponentWillReceivePropsWarnings = []; + } + + var UNSAFE_componentWillReceivePropsUniqueNames = new Set(); + + if (pendingUNSAFE_ComponentWillReceivePropsWarnings.length > 0) { + pendingUNSAFE_ComponentWillReceivePropsWarnings.forEach( + function (fiber) { + UNSAFE_componentWillReceivePropsUniqueNames.add( + getComponentNameFromFiber(fiber) || "Component" + ); + didWarnAboutUnsafeLifecycles.add(fiber.type); + } + ); + pendingUNSAFE_ComponentWillReceivePropsWarnings = []; + } + + var componentWillUpdateUniqueNames = new Set(); + + if (pendingComponentWillUpdateWarnings.length > 0) { + pendingComponentWillUpdateWarnings.forEach(function (fiber) { + componentWillUpdateUniqueNames.add( + getComponentNameFromFiber(fiber) || "Component" + ); + didWarnAboutUnsafeLifecycles.add(fiber.type); + }); + pendingComponentWillUpdateWarnings = []; + } + + var UNSAFE_componentWillUpdateUniqueNames = new Set(); + + if (pendingUNSAFE_ComponentWillUpdateWarnings.length > 0) { + pendingUNSAFE_ComponentWillUpdateWarnings.forEach(function (fiber) { + UNSAFE_componentWillUpdateUniqueNames.add( + getComponentNameFromFiber(fiber) || "Component" + ); + didWarnAboutUnsafeLifecycles.add(fiber.type); + }); + pendingUNSAFE_ComponentWillUpdateWarnings = []; + } // Finally, we flush all the warnings + // UNSAFE_ ones before the deprecated ones, since they'll be 'louder' + + if (UNSAFE_componentWillMountUniqueNames.size > 0) { + var sortedNames = setToSortedString( + UNSAFE_componentWillMountUniqueNames + ); + + error( + "Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. " + + "See https://react.dev/link/unsafe-component-lifecycles for details.\n\n" + + "* Move code with side effects to componentDidMount, and set initial state in the constructor.\n" + + "\nPlease update the following components: %s", + sortedNames + ); + } + + if (UNSAFE_componentWillReceivePropsUniqueNames.size > 0) { + var _sortedNames = setToSortedString( + UNSAFE_componentWillReceivePropsUniqueNames + ); + + error( + "Using UNSAFE_componentWillReceiveProps in strict mode is not recommended " + + "and may indicate bugs in your code. " + + "See https://react.dev/link/unsafe-component-lifecycles for details.\n\n" + + "* Move data fetching code or side effects to componentDidUpdate.\n" + + "* If you're updating state whenever props change, " + + "refactor your code to use memoization techniques or move it to " + + "static getDerivedStateFromProps. Learn more at: https://react.dev/link/derived-state\n" + + "\nPlease update the following components: %s", + _sortedNames + ); + } + + if (UNSAFE_componentWillUpdateUniqueNames.size > 0) { + var _sortedNames2 = setToSortedString( + UNSAFE_componentWillUpdateUniqueNames + ); + + error( + "Using UNSAFE_componentWillUpdate in strict mode is not recommended " + + "and may indicate bugs in your code. " + + "See https://react.dev/link/unsafe-component-lifecycles for details.\n\n" + + "* Move data fetching code or side effects to componentDidUpdate.\n" + + "\nPlease update the following components: %s", + _sortedNames2 + ); + } + + if (componentWillMountUniqueNames.size > 0) { + var _sortedNames3 = setToSortedString( + componentWillMountUniqueNames + ); + + warn( + "componentWillMount has been renamed, and is not recommended for use. " + + "See https://react.dev/link/unsafe-component-lifecycles for details.\n\n" + + "* Move code with side effects to componentDidMount, and set initial state in the constructor.\n" + + "* Rename componentWillMount to UNSAFE_componentWillMount to suppress " + + "this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. " + + "To rename all deprecated lifecycles to their new names, you can run " + + "`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n" + + "\nPlease update the following components: %s", + _sortedNames3 + ); + } + + if (componentWillReceivePropsUniqueNames.size > 0) { + var _sortedNames4 = setToSortedString( + componentWillReceivePropsUniqueNames + ); + + warn( + "componentWillReceiveProps has been renamed, and is not recommended for use. " + + "See https://react.dev/link/unsafe-component-lifecycles for details.\n\n" + + "* Move data fetching code or side effects to componentDidUpdate.\n" + + "* If you're updating state whenever props change, refactor your " + + "code to use memoization techniques or move it to " + + "static getDerivedStateFromProps. Learn more at: https://react.dev/link/derived-state\n" + + "* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress " + + "this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. " + + "To rename all deprecated lifecycles to their new names, you can run " + + "`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n" + + "\nPlease update the following components: %s", + _sortedNames4 + ); + } + + if (componentWillUpdateUniqueNames.size > 0) { + var _sortedNames5 = setToSortedString( + componentWillUpdateUniqueNames + ); + + warn( + "componentWillUpdate has been renamed, and is not recommended for use. " + + "See https://react.dev/link/unsafe-component-lifecycles for details.\n\n" + + "* Move data fetching code or side effects to componentDidUpdate.\n" + + "* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress " + + "this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. " + + "To rename all deprecated lifecycles to their new names, you can run " + + "`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n" + + "\nPlease update the following components: %s", + _sortedNames5 + ); + } + }; + + var pendingLegacyContextWarning = new Map(); // Tracks components we have already warned about. + + var didWarnAboutLegacyContext = new Set(); + + ReactStrictModeWarnings.recordLegacyContextWarning = function ( + fiber, + instance + ) { + var strictRoot = findStrictRoot(fiber); + + if (strictRoot === null) { + error( + "Expected to find a StrictMode component in a strict mode tree. " + + "This error is likely caused by a bug in React. Please file an issue." + ); + + return; + } // Dedup strategy: Warn once per component. + + if (didWarnAboutLegacyContext.has(fiber.type)) { + return; + } + + var warningsForRoot = pendingLegacyContextWarning.get(strictRoot); + + if ( + fiber.type.contextTypes != null || + fiber.type.childContextTypes != null || + (instance !== null && typeof instance.getChildContext === "function") + ) { + if (warningsForRoot === undefined) { + warningsForRoot = []; + pendingLegacyContextWarning.set(strictRoot, warningsForRoot); + } + + warningsForRoot.push(fiber); + } + }; + + ReactStrictModeWarnings.flushLegacyContextWarning = function () { + pendingLegacyContextWarning.forEach(function (fiberArray, strictRoot) { + if (fiberArray.length === 0) { + return; + } + + var firstFiber = fiberArray[0]; + var uniqueNames = new Set(); + fiberArray.forEach(function (fiber) { + uniqueNames.add(getComponentNameFromFiber(fiber) || "Component"); + didWarnAboutLegacyContext.add(fiber.type); + }); + var sortedNames = setToSortedString(uniqueNames); + + try { + setCurrentFiber(firstFiber); + + error( + "Legacy context API has been detected within a strict-mode tree." + + "\n\nThe old API will be supported in all 16.x releases, but applications " + + "using it should migrate to the new version." + + "\n\nPlease update the following components: %s" + + "\n\nLearn more about this warning here: https://react.dev/link/legacy-context", + sortedNames + ); + } finally { + resetCurrentFiber(); + } + }); + }; + + ReactStrictModeWarnings.discardPendingWarnings = function () { + pendingComponentWillMountWarnings = []; + pendingUNSAFE_ComponentWillMountWarnings = []; + pendingComponentWillReceivePropsWarnings = []; + pendingUNSAFE_ComponentWillReceivePropsWarnings = []; + pendingComponentWillUpdateWarnings = []; + pendingUNSAFE_ComponentWillUpdateWarnings = []; + pendingLegacyContextWarning = new Map(); + }; } - function commitHookPassiveMountEffects(finishedWork, hookFlags) { - if (shouldProfile(finishedWork)) { - passiveEffectStartTime = now(); + + /* + * The `'' + value` pattern (used in perf-sensitive code) throws for Symbol + * and Temporal.* types. See https://github.com/facebook/react/pull/22064. + * + * The functions in this module will throw an easier-to-understand, + * easier-to-debug exception with a clear errors message message explaining the + * problem. (Instead of a confusing exception thrown inside the implementation + * of the `value` object). + */ + // $FlowFixMe[incompatible-return] only called in DEV, so void return is not possible. + function typeName(value) { + { + // toStringTag is needed for namespaced types like Temporal.Instant + var hasToStringTag = typeof Symbol === "function" && Symbol.toStringTag; + var type = + (hasToStringTag && value[Symbol.toStringTag]) || + value.constructor.name || + "Object"; // $FlowFixMe[incompatible-return] + + return type; + } + } // $FlowFixMe[incompatible-return] only called in DEV, so void return is not possible. + + function willCoercionThrow(value) { + { try { - commitHookEffectListMount(hookFlags, finishedWork); - } catch (error$37) { - captureCommitPhaseError(finishedWork, finishedWork.return, error$37); + testStringCoercion(value); + return false; + } catch (e) { + return true; } - recordPassiveEffectDuration(finishedWork); - } else - try { - commitHookEffectListMount(hookFlags, finishedWork); - } catch (error$38) { - captureCommitPhaseError(finishedWork, finishedWork.return, error$38); - } - } - function commitOffscreenPassiveMountEffects(current, finishedWork) { - var previousCache = null; - null !== current && - null !== current.memoizedState && - null !== current.memoizedState.cachePool && - (previousCache = current.memoizedState.cachePool.pool); - current = null; - null !== finishedWork.memoizedState && - null !== finishedWork.memoizedState.cachePool && - (current = finishedWork.memoizedState.cachePool.pool); - current !== previousCache && - (null != current && retainCache(current), - null != previousCache && releaseCache(previousCache)); - } - function commitCachePassiveMountEffect(current, finishedWork) { - current = null; - null !== finishedWork.alternate && - (current = finishedWork.alternate.memoizedState.cache); - finishedWork = finishedWork.memoizedState.cache; - finishedWork !== current && - (retainCache(finishedWork), null != current && releaseCache(current)); + } } - function recursivelyTraversePassiveMountEffects( - root, - parentFiber, - committedLanes, - committedTransitions - ) { - if (parentFiber.subtreeFlags & 10256) - for (parentFiber = parentFiber.child; null !== parentFiber; ) - runWithFiberInDEV( - parentFiber, - commitPassiveMountOnFiber, - root, - parentFiber, - committedLanes, - committedTransitions - ), - (parentFiber = parentFiber.sibling); + + function testStringCoercion(value) { + // If you ended up here by following an exception call stack, here's what's + // happened: you supplied an object or symbol value to React (as a prop, key, + // DOM attribute, CSS property, string ref, etc.) and when React tried to + // coerce it to a string using `'' + value`, an exception was thrown. + // + // The most common types that will cause this exception are `Symbol` instances + // and Temporal objects like `Temporal.Instant`. But any object that has a + // `valueOf` or `[Symbol.toPrimitive]` method that throws will also cause this + // exception. (Library authors do this to prevent users from using built-in + // numeric operators like `+` or comparison operators like `>=` because custom + // methods are needed to perform accurate arithmetic or comparison.) + // + // To fix the problem, coerce this object or symbol value to a string before + // passing it to React. The most reliable way is usually `String(value)`. + // + // To find which value is throwing, check the browser or debugger console. + // Before this exception was thrown, there should be `console.error` output + // that shows the type (Symbol, Temporal.PlainDate, etc.) that caused the + // problem and how that type was used: key, atrribute, input value prop, etc. + // In most cases, this console output also shows the component and its + // ancestor components where the exception happened. + // + // eslint-disable-next-line react-internal/safe-string-coercion + return "" + value; } - function commitPassiveMountOnFiber( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - ) { - var flags = finishedWork.flags; - switch (finishedWork.tag) { - case 0: - case 11: - case 15: - recursivelyTraversePassiveMountEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - ); - flags & 2048 && - commitHookPassiveMountEffects(finishedWork, Passive | HasEffect); - break; - case 3: - recursivelyTraversePassiveMountEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - ); - flags & 2048 && - ((finishedRoot = null), - null !== finishedWork.alternate && - (finishedRoot = finishedWork.alternate.memoizedState.cache), - (finishedWork = finishedWork.memoizedState.cache), - finishedWork !== finishedRoot && - (retainCache(finishedWork), - null != finishedRoot && releaseCache(finishedRoot))); - break; - case 23: - break; - case 22: - var _instance3 = finishedWork.stateNode; - null !== finishedWork.memoizedState - ? _instance3._visibility & 4 - ? recursivelyTraversePassiveMountEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - ) - : finishedWork.mode & 1 - ? recursivelyTraverseAtomicPassiveEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - ) - : ((_instance3._visibility |= 4), - recursivelyTraversePassiveMountEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - )) - : _instance3._visibility & 4 - ? recursivelyTraversePassiveMountEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - ) - : ((_instance3._visibility |= 4), - recursivelyTraverseReconnectPassiveEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions, - 0 !== (finishedWork.subtreeFlags & 10256) - )); - flags & 2048 && - commitOffscreenPassiveMountEffects( - finishedWork.alternate, - finishedWork - ); - break; - case 24: - recursivelyTraversePassiveMountEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions + function checkKeyStringCoercion(value) { + { + if (willCoercionThrow(value)) { + error( + "The provided key is an unsupported type %s." + + " This value must be coerced to a string before using it here.", + typeName(value) ); - flags & 2048 && - commitCachePassiveMountEffect(finishedWork.alternate, finishedWork); - break; - default: - recursivelyTraversePassiveMountEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions + + return testStringCoercion(value); // throw (to help callers find troubleshooting comments) + } + } + } + function checkPropStringCoercion(value, propName) { + { + if (willCoercionThrow(value)) { + error( + "The provided `%s` prop is an unsupported type %s." + + " This value must be coerced to a string before using it here.", + propName, + typeName(value) ); + + return testStringCoercion(value); // throw (to help callers find troubleshooting comments) + } } } - function recursivelyTraverseReconnectPassiveEffects( - finishedRoot, - parentFiber, - committedLanes, - committedTransitions, - includeWorkInProgressEffects - ) { - includeWorkInProgressEffects = - includeWorkInProgressEffects && - 0 !== (parentFiber.subtreeFlags & 10256); - for (parentFiber = parentFiber.child; null !== parentFiber; ) - runWithFiberInDEV( - parentFiber, - reconnectPassiveEffects, - finishedRoot, - parentFiber, - committedLanes, - committedTransitions, - includeWorkInProgressEffects - ), - (parentFiber = parentFiber.sibling); - } - function reconnectPassiveEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions, - includeWorkInProgressEffects - ) { - var flags = finishedWork.flags; - switch (finishedWork.tag) { - case 0: - case 11: - case 15: - recursivelyTraverseReconnectPassiveEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions, - includeWorkInProgressEffects - ); - commitHookPassiveMountEffects(finishedWork, Passive); - break; - case 23: - break; - case 22: - var _instance4 = finishedWork.stateNode; - null !== finishedWork.memoizedState - ? _instance4._visibility & 4 - ? recursivelyTraverseReconnectPassiveEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions, - includeWorkInProgressEffects - ) - : finishedWork.mode & 1 - ? recursivelyTraverseAtomicPassiveEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - ) - : ((_instance4._visibility |= 4), - recursivelyTraverseReconnectPassiveEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions, - includeWorkInProgressEffects - )) - : ((_instance4._visibility |= 4), - recursivelyTraverseReconnectPassiveEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions, - includeWorkInProgressEffects - )); - includeWorkInProgressEffects && - flags & 2048 && - commitOffscreenPassiveMountEffects( - finishedWork.alternate, - finishedWork - ); - break; - case 24: - recursivelyTraverseReconnectPassiveEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions, - includeWorkInProgressEffects - ); - includeWorkInProgressEffects && - flags & 2048 && - commitCachePassiveMountEffect(finishedWork.alternate, finishedWork); - break; - default: - recursivelyTraverseReconnectPassiveEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions, - includeWorkInProgressEffects - ); + + var ReactCurrentActQueue$2 = ReactSharedInternals.ReactCurrentActQueue; + + function getThenablesFromState(state) { + { + var devState = state; + return devState.thenables; } - } - function recursivelyTraverseAtomicPassiveEffects( - finishedRoot, - parentFiber, - committedLanes, - committedTransitions - ) { - if (parentFiber.subtreeFlags & 10256) - for (parentFiber = parentFiber.child; null !== parentFiber; ) - runWithFiberInDEV( - parentFiber, - commitAtomicPassiveEffects, - finishedRoot, - parentFiber, - committedLanes, - committedTransitions - ), - (parentFiber = parentFiber.sibling); - } - function commitAtomicPassiveEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - ) { - var flags = finishedWork.flags; - switch (finishedWork.tag) { - case 22: - recursivelyTraverseAtomicPassiveEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - ); - flags & 2048 && - commitOffscreenPassiveMountEffects( - finishedWork.alternate, - finishedWork - ); - break; - case 24: - recursivelyTraverseAtomicPassiveEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - ); - flags & 2048 && - commitCachePassiveMountEffect(finishedWork.alternate, finishedWork); - break; - default: - recursivelyTraverseAtomicPassiveEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions + } // An error that is thrown (e.g. by `use`) to trigger Suspense. If we + // detect this is caught by userspace, we'll log a warning in development. + + var SuspenseException = new Error( + "Suspense Exception: This is not a real error! It's an implementation " + + "detail of `use` to interrupt the current render. You must either " + + "rethrow it immediately, or move the `use` call outside of the " + + "`try/catch` block. Capturing without rethrowing will lead to " + + "unexpected behavior.\n\n" + + "To handle async errors, wrap your component in an error boundary, or " + + "call the promise's `.catch` method and pass the result to `use`" + ); + var SuspenseyCommitException = new Error( + "Suspense Exception: This is not a real error, and should not leak into " + + "userspace. If you're seeing this, it's likely a bug in React." + ); // This is a noop thenable that we use to trigger a fallback in throwException. + // TODO: It would be better to refactor throwException into multiple functions + // so we can trigger a fallback directly without having to check the type. But + // for now this will do. + + var noopSuspenseyCommitThenable = { + then: function () { + { + error( + "Internal React error: A listener was unexpectedly attached to a " + + '"noop" thenable. This is a bug in React. Please file an issue.' ); + } } - } - function recursivelyAccumulateSuspenseyCommit(parentFiber) { - if (parentFiber.subtreeFlags & suspenseyCommitFlag) - for (parentFiber = parentFiber.child; null !== parentFiber; ) - accumulateSuspenseyCommitOnFiber(parentFiber), - (parentFiber = parentFiber.sibling); - } - function accumulateSuspenseyCommitOnFiber(fiber) { - switch (fiber.tag) { - case 26: - recursivelyAccumulateSuspenseyCommit(fiber); - fiber.flags & suspenseyCommitFlag && - null !== fiber.memoizedState && - suspendResource(); - break; - case 5: - recursivelyAccumulateSuspenseyCommit(fiber); - break; - case 3: - case 4: - recursivelyAccumulateSuspenseyCommit(fiber); - break; - case 22: - if (null === fiber.memoizedState) { - var current = fiber.alternate; - null !== current && null !== current.memoizedState - ? ((current = suspenseyCommitFlag), - (suspenseyCommitFlag = 16777216), - recursivelyAccumulateSuspenseyCommit(fiber), - (suspenseyCommitFlag = current)) - : recursivelyAccumulateSuspenseyCommit(fiber); - } - break; - default: - recursivelyAccumulateSuspenseyCommit(fiber); - } - } - function detachAlternateSiblings(parentFiber) { - var previousFiber = parentFiber.alternate; - if ( - null !== previousFiber && - ((parentFiber = previousFiber.child), null !== parentFiber) - ) { - previousFiber.child = null; - do - (previousFiber = parentFiber.sibling), - (parentFiber.sibling = null), - (parentFiber = previousFiber); - while (null !== parentFiber); + }; + function createThenableState() { + // The ThenableState is created the first time a component suspends. If it + // suspends again, we'll reuse the same state. + { + return { + didWarnAboutUncachedPromise: false, + thenables: [] + }; } } - function commitHookPassiveUnmountEffects( - finishedWork, - nearestMountedAncestor, - hookFlags - ) { - shouldProfile(finishedWork) - ? ((passiveEffectStartTime = now()), - commitHookEffectListUnmount( - hookFlags, - finishedWork, - nearestMountedAncestor - ), - recordPassiveEffectDuration(finishedWork)) - : commitHookEffectListUnmount( - hookFlags, - finishedWork, - nearestMountedAncestor - ); + function isThenableResolved(thenable) { + var status = thenable.status; + return status === "fulfilled" || status === "rejected"; } - function recursivelyTraversePassiveUnmountEffects(parentFiber) { - var deletions = parentFiber.deletions; - if (0 !== (parentFiber.flags & 16)) { - if (null !== deletions) - for (var i = 0; i < deletions.length; i++) { - var childToDelete = deletions[i]; - nextEffect = childToDelete; - commitPassiveUnmountEffectsInsideOfDeletedTree_begin( - childToDelete, - parentFiber + + function noop() {} + + function trackUsedThenable(thenableState, thenable, index) { + if (ReactCurrentActQueue$2.current !== null) { + ReactCurrentActQueue$2.didUsePromise = true; + } + + var trackedThenables = getThenablesFromState(thenableState); + var previous = trackedThenables[index]; + + if (previous === undefined) { + trackedThenables.push(thenable); + } else { + if (previous !== thenable) { + // Reuse the previous thenable, and drop the new one. We can assume + // they represent the same value, because components are idempotent. + { + var thenableStateDev = thenableState; + + if (!thenableStateDev.didWarnAboutUncachedPromise) { + // We should only warn the first time an uncached thenable is + // discovered per component, because if there are multiple, the + // subsequent ones are likely derived from the first. + // + // We track this on the thenableState instead of deduping using the + // component name like we usually do, because in the case of a + // promise-as-React-node, the owner component is likely different from + // the parent that's currently being reconciled. We'd have to track + // the owner using state, which we're trying to move away from. Though + // since this is dev-only, maybe that'd be OK. + // + // However, another benefit of doing it this way is we might + // eventually have a thenableState per memo/Forget boundary instead + // of per component, so this would allow us to have more + // granular warnings. + thenableStateDev.didWarnAboutUncachedPromise = true; // TODO: This warning should link to a corresponding docs page. + + error( + "A component was suspended by an uncached promise. Creating " + + "promises inside a Client Component or hook is not yet " + + "supported, except via a Suspense-compatible library or framework." + ); + } + } // Avoid an unhandled rejection errors for the Promises that we'll + // intentionally ignore. + + thenable.then(noop, noop); + thenable = previous; + } + } // We use an expando to track the status and result of a thenable so that we + // can synchronously unwrap the value. Think of this as an extension of the + // Promise API, or a custom interface that is a superset of Thenable. + // + // If the thenable doesn't have a status, set it to "pending" and attach + // a listener that will update its status and result when it resolves. + + switch (thenable.status) { + case "fulfilled": { + var fulfilledValue = thenable.value; + return fulfilledValue; + } + + case "rejected": { + var rejectedError = thenable.reason; + checkIfUseWrappedInAsyncCatch(rejectedError); + throw rejectedError; + } + + default: { + if (typeof thenable.status === "string") { + // Only instrument the thenable if the status if not defined. If + // it's defined, but an unknown value, assume it's been instrumented by + // some custom userspace implementation. We treat it as "pending". + // Attach a dummy listener, to ensure that any lazy initialization can + // happen. Flight lazily parses JSON when the value is actually awaited. + thenable.then(noop, noop); + } else { + // This is an uncached thenable that we haven't seen before. + // Detect infinite ping loops caused by uncached promises. + var root = getWorkInProgressRoot(); + + if (root !== null && root.shellSuspendCounter > 100) { + // This root has suspended repeatedly in the shell without making any + // progress (i.e. committing something). This is highly suggestive of + // an infinite ping loop, often caused by an accidental Async Client + // Component. + // + // During a transition, we can suspend the work loop until the promise + // to resolve, but this is a sync render, so that's not an option. We + // also can't show a fallback, because none was provided. So our last + // resort is to throw an error. + // + // TODO: Remove this error in a future release. Other ways of handling + // this case include forcing a concurrent render, or putting the whole + // root into offscreen mode. + throw new Error( + "async/await is not yet supported in Client Components, only " + + "Server Components. This error is often caused by accidentally " + + "adding `'use client'` to a module that was originally written " + + "for the server." + ); + } + + var pendingThenable = thenable; + pendingThenable.status = "pending"; + pendingThenable.then( + function (fulfilledValue) { + if (thenable.status === "pending") { + var fulfilledThenable = thenable; + fulfilledThenable.status = "fulfilled"; + fulfilledThenable.value = fulfilledValue; + } + }, + function (error) { + if (thenable.status === "pending") { + var rejectedThenable = thenable; + rejectedThenable.status = "rejected"; + rejectedThenable.reason = error; + } + } ); + } // Check one more time in case the thenable resolved synchronously. + + switch (thenable.status) { + case "fulfilled": { + var fulfilledThenable = thenable; + return fulfilledThenable.value; + } + + case "rejected": { + var rejectedThenable = thenable; + var _rejectedError = rejectedThenable.reason; + checkIfUseWrappedInAsyncCatch(_rejectedError); + throw _rejectedError; + } + } // Suspend. + // + // Throwing here is an implementation detail that allows us to unwind the + // call stack. But we shouldn't allow it to leak into userspace. Throw an + // opaque placeholder value instead of the actual thenable. If it doesn't + // get captured by the work loop, log a warning, because that means + // something in userspace must have caught it. + + suspendedThenable = thenable; + + { + needsToResetSuspendedThenableDEV = true; } - detachAlternateSiblings(parentFiber); + + throw SuspenseException; + } } - if (parentFiber.subtreeFlags & 10256) - for (parentFiber = parentFiber.child; null !== parentFiber; ) - runWithFiberInDEV( - parentFiber, - commitPassiveUnmountOnFiber, - parentFiber - ), - (parentFiber = parentFiber.sibling); } - function commitPassiveUnmountOnFiber(finishedWork) { - switch (finishedWork.tag) { - case 0: - case 11: - case 15: - recursivelyTraversePassiveUnmountEffects(finishedWork); - finishedWork.flags & 2048 && - commitHookPassiveUnmountEffects( - finishedWork, - finishedWork.return, - Passive | HasEffect - ); - break; - case 22: - var instance = finishedWork.stateNode; - null !== finishedWork.memoizedState && - instance._visibility & 4 && - (null === finishedWork.return || 13 !== finishedWork.return.tag) - ? ((instance._visibility &= -5), - recursivelyTraverseDisconnectPassiveEffects(finishedWork)) - : recursivelyTraversePassiveUnmountEffects(finishedWork); - break; - default: - recursivelyTraversePassiveUnmountEffects(finishedWork); + // passed to the rest of the Suspense implementation — which, for historical + // reasons, expects to receive a thenable. + + var suspendedThenable = null; + var needsToResetSuspendedThenableDEV = false; + function getSuspendedThenable() { + // This is called right after `use` suspends by throwing an exception. `use` + // throws an opaque value instead of the thenable itself so that it can't be + // caught in userspace. Then the work loop accesses the actual thenable using + // this function. + if (suspendedThenable === null) { + throw new Error( + "Expected a suspended thenable. This is a bug in React. Please file " + + "an issue." + ); } - } - function recursivelyTraverseDisconnectPassiveEffects(parentFiber) { - var deletions = parentFiber.deletions; - if (0 !== (parentFiber.flags & 16)) { - if (null !== deletions) - for (var i = 0; i < deletions.length; i++) { - var childToDelete = deletions[i]; - nextEffect = childToDelete; - commitPassiveUnmountEffectsInsideOfDeletedTree_begin( - childToDelete, - parentFiber - ); - } - detachAlternateSiblings(parentFiber); + + var thenable = suspendedThenable; + suspendedThenable = null; + + { + needsToResetSuspendedThenableDEV = false; } - for (parentFiber = parentFiber.child; null !== parentFiber; ) - runWithFiberInDEV(parentFiber, disconnectPassiveEffect, parentFiber), - (parentFiber = parentFiber.sibling); + + return thenable; } - function disconnectPassiveEffect(finishedWork) { - switch (finishedWork.tag) { - case 0: - case 11: - case 15: - commitHookPassiveUnmountEffects( - finishedWork, - finishedWork.return, - Passive - ); - recursivelyTraverseDisconnectPassiveEffects(finishedWork); - break; - case 22: - var instance = finishedWork.stateNode; - instance._visibility & 4 && - ((instance._visibility &= -5), - recursivelyTraverseDisconnectPassiveEffects(finishedWork)); - break; - default: - recursivelyTraverseDisconnectPassiveEffects(finishedWork); + function checkIfUseWrappedInTryCatch() { + { + // This was set right before SuspenseException was thrown, and it should + // have been cleared when the exception was handled. If it wasn't, + // it must have been caught by userspace. + if (needsToResetSuspendedThenableDEV) { + needsToResetSuspendedThenableDEV = false; + return true; + } } + + return false; } - function commitPassiveUnmountEffectsInsideOfDeletedTree_begin( - deletedSubtreeRoot, - nearestMountedAncestor - ) { - for (; null !== nextEffect; ) { - var fiber = nextEffect; - runWithFiberInDEV( - fiber, - commitPassiveUnmountInsideDeletedTreeOnFiber, - fiber, - nearestMountedAncestor + function checkIfUseWrappedInAsyncCatch(rejectedReason) { + // This check runs in prod, too, because it prevents a more confusing + // downstream error, where SuspenseException is caught by a promise and + // thrown asynchronously. + // TODO: Another way to prevent SuspenseException from leaking into an async + // execution context is to check the dispatcher every time `use` is called, + // or some equivalent. That might be preferable for other reasons, too, since + // it matches how we prevent similar mistakes for other hooks. + if (rejectedReason === SuspenseException) { + throw new Error( + "Hooks are not supported inside an async component. This " + + "error is often caused by accidentally adding `'use client'` " + + "to a module that was originally written for the server." ); - var child = fiber.child; - if (null !== child) (child.return = fiber), (nextEffect = child); - else - a: for (fiber = deletedSubtreeRoot; null !== nextEffect; ) { - child = nextEffect; - var sibling = child.sibling, - returnFiber = child.return; - detachFiberAfterEffects(child); - if (child === fiber) { - nextEffect = null; - break a; - } - if (null !== sibling) { - sibling.return = returnFiber; - nextEffect = sibling; - break a; - } - nextEffect = returnFiber; - } - } - } - function commitPassiveUnmountInsideDeletedTreeOnFiber( - current, - nearestMountedAncestor - ) { - switch (current.tag) { - case 0: - case 11: - case 15: - commitHookPassiveUnmountEffects( - current, - nearestMountedAncestor, - Passive - ); - break; - case 23: - case 22: - null !== current.memoizedState && - null !== current.memoizedState.cachePool && - ((current = current.memoizedState.cachePool.pool), - null != current && retainCache(current)); - break; - case 24: - releaseCache(current.memoizedState.cache); } } - function invokeLayoutEffectMountInDEV(fiber) { - switch (fiber.tag) { - case 0: - case 11: - case 15: - try { - commitHookEffectListMount(Layout | HasEffect, fiber); - } catch (error$39) { - captureCommitPhaseError(fiber, fiber.return, error$39); - } - break; - case 1: - var instance = fiber.stateNode; - if ("function" === typeof instance.componentDidMount) - try { - instance.componentDidMount(); - } catch (error$40) { - captureCommitPhaseError(fiber, fiber.return, error$40); - } + + var thenableState$1 = null; + var thenableIndexCounter$1 = 0; + + function mergeDebugInfo(outer, inner) { + if (inner == null) { + return outer; + } else if (outer === null) { + return inner; + } else { + // If we have two debugInfo, we need to create a new one. This makes the array no longer + // live so we'll miss any future updates if we received more so ideally we should always + // do this after both have fully resolved/unsuspended. + return outer.concat(inner); } } - function invokePassiveEffectMountInDEV(fiber) { - switch (fiber.tag) { - case 0: - case 11: - case 15: - try { - commitHookEffectListMount(Passive | HasEffect, fiber); - } catch (error$41) { - captureCommitPhaseError(fiber, fiber.return, error$41); - } - } + + var didWarnAboutMaps; + var didWarnAboutGenerators; + var didWarnAboutStringRefs; + var ownerHasKeyUseWarning; + var ownerHasFunctionTypeWarning; + var ownerHasSymbolTypeWarning; + + var warnForMissingKey = function (child, returnFiber) {}; + + { + didWarnAboutMaps = false; + didWarnAboutGenerators = false; + didWarnAboutStringRefs = {}; + /** + * Warn if there's no key explicitly set on dynamic arrays of children or + * object keys are not valid. This allows us to keep track of children between + * updates. + */ + + ownerHasKeyUseWarning = {}; + ownerHasFunctionTypeWarning = {}; + ownerHasSymbolTypeWarning = {}; + + warnForMissingKey = function (child, returnFiber) { + if (child === null || typeof child !== "object") { + return; + } + + if (!child._store || child._store.validated || child.key != null) { + return; + } + + if (typeof child._store !== "object") { + throw new Error( + "React Component in warnForMissingKey should have a _store. " + + "This error is likely caused by a bug in React. Please file an issue." + ); + } // $FlowFixMe[cannot-write] unable to narrow type from mixed to writable object + + child._store.validated = true; + var componentName = + getComponentNameFromFiber(returnFiber) || "Component"; + + if (ownerHasKeyUseWarning[componentName]) { + return; + } + + ownerHasKeyUseWarning[componentName] = true; + + error( + "Each child in a list should have a unique " + + '"key" prop. See https://react.dev/link/warning-keys for ' + + "more information." + ); + }; } - function invokeLayoutEffectUnmountInDEV(fiber) { - switch (fiber.tag) { - case 0: - case 11: - case 15: - try { - commitHookEffectListUnmount( - Layout | HasEffect, - fiber, - fiber.return - ); - } catch (error$42) { - captureCommitPhaseError(fiber, fiber.return, error$42); - } - break; - case 1: - var instance = fiber.stateNode; - "function" === typeof instance.componentWillUnmount && - safelyCallComponentWillUnmount(fiber, fiber.return, instance); + + function isReactClass(type) { + return type.prototype && type.prototype.isReactComponent; + } + + function unwrapThenable(thenable) { + var index = thenableIndexCounter$1; + thenableIndexCounter$1 += 1; + + if (thenableState$1 === null) { + thenableState$1 = createThenableState(); } + + return trackUsedThenable(thenableState$1, thenable, index); } - function invokePassiveEffectUnmountInDEV(fiber) { - switch (fiber.tag) { - case 0: - case 11: - case 15: - try { - commitHookEffectListUnmount( - Passive | HasEffect, - fiber, - fiber.return + + function convertStringRefToCallbackRef( + returnFiber, + current, + element, + mixedRef + ) { + { + checkPropStringCoercion(mixedRef, "ref"); + } + + var stringRef = "" + mixedRef; + var owner = element._owner; + + if (!owner) { + throw new Error( + "Element ref was specified as a string (" + + stringRef + + ") but no owner was set. This could happen for one of" + + " the following reasons:\n" + + "1. You may be adding a ref to a function component\n" + + "2. You may be adding a ref to a component that was not created inside a component's render method\n" + + "3. You have multiple copies of React loaded\n" + + "See https://react.dev/link/refs-must-have-owner for more information." + ); + } + + if (owner.tag !== ClassComponent) { + throw new Error( + "Function components cannot have string refs. " + + "We recommend using useRef() instead. " + + "Learn more about using refs safely here: " + + "https://react.dev/link/strict-mode-string-ref" + ); + } + + { + if ( + // Will already warn with "Function components cannot be given refs" + !(typeof element.type === "function" && !isReactClass(element.type)) + ) { + var componentName = + getComponentNameFromFiber(returnFiber) || "Component"; + + if (!didWarnAboutStringRefs[componentName]) { + error( + 'Component "%s" contains the string ref "%s". Support for string refs ' + + "will be removed in a future major release. We recommend using " + + "useRef() or createRef() instead. " + + "Learn more about using refs safely here: " + + "https://react.dev/link/strict-mode-string-ref", + componentName, + stringRef ); - } catch (error$43) { - captureCommitPhaseError(fiber, fiber.return, error$43); + + didWarnAboutStringRefs[componentName] = true; } + } } - } - function isLegacyActEnvironment() { - var isReactActEnvironmentGlobal = - "undefined" !== typeof IS_REACT_ACT_ENVIRONMENT - ? IS_REACT_ACT_ENVIRONMENT - : void 0; - return "undefined" !== typeof jest && !1 !== isReactActEnvironmentGlobal; - } - function isConcurrentActEnvironment() { - var isReactActEnvironmentGlobal = - "undefined" !== typeof IS_REACT_ACT_ENVIRONMENT - ? IS_REACT_ACT_ENVIRONMENT - : void 0; - isReactActEnvironmentGlobal || - null === ReactSharedInternals.actQueue || - error$jscomp$0( - "The current testing environment is not configured to support act(...)" + + var inst = owner.stateNode; + + if (!inst) { + throw new Error( + "Missing owner for string ref " + + stringRef + + ". This error is likely caused by a " + + "bug in React. Please file an issue." ); - return isReactActEnvironmentGlobal; - } - function requestUpdateLane(fiber) { - if (0 === (fiber.mode & 1)) return SyncLane; + } // Check if previous string ref matches new string ref + if ( - (executionContext & RenderContext) !== NoContext && - 0 !== workInProgressRootRenderLanes - ) - return workInProgressRootRenderLanes & -workInProgressRootRenderLanes; - var transition = ReactSharedInternals.T; - if (null !== transition) - return ( - transition._updatedFibers || (transition._updatedFibers = new Set()), - transition._updatedFibers.add(fiber), - (fiber = currentEntangledLane), - 0 !== fiber ? fiber : requestTransitionLane() - ); - fiber = - 0 !== currentUpdatePriority - ? currentUpdatePriority - : DefaultEventPriority; - return fiber; - } - function requestDeferredLane() { - 0 === workInProgressDeferredLane && - (workInProgressDeferredLane = - 0 !== (workInProgressRootRenderLanes & OffscreenLane) - ? OffscreenLane - : claimNextTransitionLane()); - var suspenseHandler = suspenseHandlerStackCursor.current; - null !== suspenseHandler && (suspenseHandler.flags |= 32); - return workInProgressDeferredLane; + current !== null && + current.ref !== null && + typeof current.ref === "function" && + current.ref._stringRef === stringRef + ) { + // Reuse the existing string ref + var currentRef = current.ref; + return currentRef; + } // Create a new string ref + + var ref = function (value) { + var refs = inst.refs; + + if (value === null) { + delete refs[stringRef]; + } else { + refs[stringRef] = value; + } + }; + + ref._stringRef = stringRef; + return ref; } - function scheduleUpdateOnFiber(root, fiber, lane) { - isRunningInsertionEffect && - error$jscomp$0("useInsertionEffect must not schedule updates."); - isFlushingPassiveEffects && (didScheduleUpdateDuringPassiveEffects = !0); - if ( - (root === workInProgressRoot && - workInProgressSuspendedReason === SuspendedOnData) || - null !== root.cancelPendingCommit - ) - prepareFreshStack(root, 0), - markRootSuspended( - root, - workInProgressRootRenderLanes, - workInProgressDeferredLane - ); - markRootUpdated(root, lane); + + function coerceRef(returnFiber, current, workInProgress, element) { + var mixedRef; + + { + // Old behavior. + mixedRef = element.ref; + } + + var coercedRef; + if ( - 0 !== (executionContext & RenderContext) && - root === workInProgressRoot + typeof mixedRef === "string" || + typeof mixedRef === "number" || + typeof mixedRef === "boolean" ) { - if (isRendering) - switch (fiber.tag) { - case 0: - case 11: - case 15: - root = - (workInProgress && getComponentNameFromFiber(workInProgress)) || - "Unknown"; - didWarnAboutUpdateInRenderForAnotherComponent.has(root) || - (didWarnAboutUpdateInRenderForAnotherComponent.add(root), - (fiber = getComponentNameFromFiber(fiber) || "Unknown"), - error$jscomp$0( - "Cannot update a component (`%s`) while rendering a different component (`%s`). To locate the bad setState() call inside `%s`, follow the stack trace as described in https://react.dev/link/setstate-in-render", - fiber, - root, - root - )); - break; - case 1: - didWarnAboutUpdateInRender || - (error$jscomp$0( - "Cannot update during an existing state transition (such as within `render`). Render methods should be a pure function of props and state." - ), - (didWarnAboutUpdateInRender = !0)); - } - } else - isDevToolsPresent && addFiberToLanesMap(root, fiber, lane), - warnIfUpdatesNotWrappedWithActDEV(fiber), - root === workInProgressRoot && - ((executionContext & RenderContext) === NoContext && - (workInProgressRootInterleavedUpdatedLanes |= lane), - workInProgressRootExitStatus === RootSuspendedWithDelay && - markRootSuspended( - root, - workInProgressRootRenderLanes, - workInProgressDeferredLane - )), - ensureRootIsScheduled(root), - lane !== SyncLane || - executionContext !== NoContext || - 0 !== (fiber.mode & 1) || - ReactSharedInternals.isBatchingLegacy || - ((workInProgressRootRenderTargetTime = now$1() + RENDER_TIMEOUT_MS), - flushSyncWorkAcrossRoots_impl(!0)); + coercedRef = convertStringRefToCallbackRef( + returnFiber, + current, + element, + mixedRef + ); + } else { + coercedRef = mixedRef; + } // TODO: If enableRefAsProp is on, we shouldn't use the `ref` field. We + // should always read the ref from the prop. + + workInProgress.ref = coercedRef; } - function performConcurrentWorkOnRoot(root, didTimeout) { - nestedUpdateScheduled = currentUpdateIsNested = !1; - if ((executionContext & (RenderContext | CommitContext)) !== NoContext) - 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 + + function throwOnInvalidObjectType(returnFiber, newChild) { + // $FlowFixMe[method-unbinding] + var childString = Object.prototype.toString.call(newChild); + throw new 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." ); - if (0 === lanes) return null; - var shouldTimeSlice = - 0 === - (lanes & - (InputContinuousHydrationLane | - InputContinuousLane | - DefaultHydrationLane | - DefaultLane)) && - 0 === (lanes & root.expiredLanes) && - !didTimeout; - didTimeout = shouldTimeSlice - ? renderRootConcurrent(root, lanes) - : renderRootSync(root, lanes); - if (didTimeout !== RootInProgress) { - var renderWasConcurrent = shouldTimeSlice; - do { - if (didTimeout === RootDidNotComplete) - markRootSuspended(root, lanes, 0); - else { - shouldTimeSlice = root.current.alternate; - if ( - renderWasConcurrent && - !isRenderConsistentWithExternalStores(shouldTimeSlice) - ) { - didTimeout = renderRootSync(root, lanes); - renderWasConcurrent = !1; - continue; - } - if (didTimeout === RootErrored) { - renderWasConcurrent = lanes; - var errorRetryLanes = getLanesToRetrySynchronouslyOnError( - root, - renderWasConcurrent - ); - if ( - 0 !== errorRetryLanes && - ((lanes = errorRetryLanes), - (didTimeout = recoverFromConcurrentError( - root, - renderWasConcurrent, - errorRetryLanes - )), - (renderWasConcurrent = !1), - didTimeout !== RootErrored) - ) - continue; - } - if (didTimeout === RootFatalErrored) { - prepareFreshStack(root, 0); - markRootSuspended(root, lanes, 0); - break; - } - root.finishedWork = shouldTimeSlice; - root.finishedLanes = lanes; - a: { - renderWasConcurrent = root; - switch (didTimeout) { - case RootInProgress: - case RootFatalErrored: - throw Error("Root did not complete. This is a bug in React."); - case RootSuspendedWithDelay: - if ((lanes & TransitionLanes) === lanes) { - markRootSuspended( - renderWasConcurrent, - lanes, - workInProgressDeferredLane - ); - break a; - } - break; - case RootErrored: - workInProgressRootRecoverableErrors = null; - break; - case RootSuspended: - case RootCompleted: - break; - default: - throw Error("Unknown root exit status."); - } - if (null !== ReactSharedInternals.actQueue) - commitRoot( - renderWasConcurrent, - workInProgressRootRecoverableErrors, - workInProgressTransitions, - workInProgressRootDidIncludeRecursiveRenderUpdate, - workInProgressDeferredLane - ); - else { - if ( - (lanes & RetryLanes) === lanes && - didTimeout === RootSuspended && - ((didTimeout = - globalMostRecentFallbackTime + - FALLBACK_THROTTLE_MS - - now$1()), - 10 < didTimeout) - ) { - markRootSuspended( - renderWasConcurrent, - lanes, - workInProgressDeferredLane - ); - if (0 !== getNextLanes(renderWasConcurrent, 0)) break a; - renderWasConcurrent.timeoutHandle = scheduleTimeout( - commitRootWhenReady.bind( - null, - renderWasConcurrent, - shouldTimeSlice, - workInProgressRootRecoverableErrors, - workInProgressTransitions, - workInProgressRootDidIncludeRecursiveRenderUpdate, - lanes, - workInProgressDeferredLane - ), - didTimeout - ); - break a; - } - commitRootWhenReady( - renderWasConcurrent, - shouldTimeSlice, - workInProgressRootRecoverableErrors, - workInProgressTransitions, - workInProgressRootDidIncludeRecursiveRenderUpdate, - lanes, - workInProgressDeferredLane - ); - } - } - } - break; - } while (1); - } - ensureRootIsScheduled(root); - scheduleTaskForRootDuringMicrotask(root, now$1()); - root = - root.callbackNode === originalCallbackNode - ? performConcurrentWorkOnRoot.bind(null, root) - : null; - return root; } - function recoverFromConcurrentError( - root, - originallyAttemptedLanes, - errorRetryLanes - ) { - var errorsFromFirstAttempt = workInProgressRootConcurrentErrors; - errorRetryLanes = renderRootSync(root, errorRetryLanes); - if (errorRetryLanes !== RootErrored) { - if (workInProgressRootDidAttachPingListener) - return ( - (root.errorRecoveryDisabledLanes |= originallyAttemptedLanes), - (workInProgressRootInterleavedUpdatedLanes |= - originallyAttemptedLanes), - RootSuspendedWithDelay + + function warnOnFunctionType(returnFiber, invalidChild) { + { + var parentName = getComponentNameFromFiber(returnFiber) || "Component"; + + if (ownerHasFunctionTypeWarning[parentName]) { + return; + } + + ownerHasFunctionTypeWarning[parentName] = true; + var name = invalidChild.displayName || invalidChild.name || "Component"; + + if (returnFiber.tag === HostRoot) { + error( + "Functions are not valid as a React child. This may happen if " + + "you return %s instead of <%s /> from render. " + + "Or maybe you meant to call this function rather than return it.\n" + + " root.render(%s)", + name, + name, + name + ); + } else { + error( + "Functions are not valid as a React child. This may happen if " + + "you return %s instead of <%s /> from render. " + + "Or maybe you meant to call this function rather than return it.\n" + + " <%s>{%s}", + name, + name, + parentName, + name, + parentName ); - root = workInProgressRootRecoverableErrors; - workInProgressRootRecoverableErrors = errorsFromFirstAttempt; - null !== root && queueRecoverableErrors(root); + } } - return errorRetryLanes; } - function queueRecoverableErrors(errors) { - null === workInProgressRootRecoverableErrors - ? (workInProgressRootRecoverableErrors = errors) - : workInProgressRootRecoverableErrors.push.apply( - workInProgressRootRecoverableErrors, - errors + + function warnOnSymbolType(returnFiber, invalidChild) { + { + var parentName = getComponentNameFromFiber(returnFiber) || "Component"; + + if (ownerHasSymbolTypeWarning[parentName]) { + return; + } + + ownerHasSymbolTypeWarning[parentName] = true; // eslint-disable-next-line react-internal/safe-string-coercion + + var name = String(invalidChild); + + if (returnFiber.tag === HostRoot) { + error( + "Symbols are not valid as a React child.\n" + " root.render(%s)", + name ); + } else { + error( + "Symbols are not valid as a React child.\n" + " <%s>%s", + parentName, + name, + parentName + ); + } + } } - function commitRootWhenReady( - root, - finishedWork, - recoverableErrors, - transitions, - didIncludeRenderPhaseUpdate, - lanes, - spawnedLane - ) { - lanes = finishedWork.subtreeFlags; - (lanes & 8192 || 16785408 === (lanes & 16785408)) && - accumulateSuspenseyCommitOnFiber(finishedWork); - commitRoot( - root, - recoverableErrors, - transitions, - didIncludeRenderPhaseUpdate, - spawnedLane - ); - } - function isRenderConsistentWithExternalStores(finishedWork) { - for (var node = finishedWork; ; ) { - if (node.flags & 16384) { - var updateQueue = node.updateQueue; - if ( - null !== updateQueue && - ((updateQueue = updateQueue.stores), null !== updateQueue) - ) - for (var i = 0; i < updateQueue.length; i++) { - var check = updateQueue[i], - getSnapshot = check.getSnapshot; - check = check.value; - try { - if (!objectIs(getSnapshot(), check)) return !1; - } catch (error$44) { - return !1; - } - } + + function resolveLazy(lazyType) { + var payload = lazyType._payload; + var init = lazyType._init; + return init(payload); + } // This wrapper function exists because I expect to clone the code in each path + // to be able to optimize each path individually by branching early. This needs + // a compiler or we can do it manually. Helpers that don't need this branching + // live outside of this function. + + function createChildReconciler(shouldTrackSideEffects) { + function deleteChild(returnFiber, childToDelete) { + if (!shouldTrackSideEffects) { + // Noop. + return; } - updateQueue = node.child; - if (node.subtreeFlags & 16384 && null !== updateQueue) - (updateQueue.return = node), (node = updateQueue); - else { - if (node === finishedWork) break; - for (; null === node.sibling; ) { - if (null === node.return || node.return === finishedWork) return !0; - node = node.return; - } - node.sibling.return = node.return; - node = node.sibling; + + var deletions = returnFiber.deletions; + + if (deletions === null) { + returnFiber.deletions = [childToDelete]; + returnFiber.flags |= ChildDeletion; + } else { + deletions.push(childToDelete); } } - return !0; - } - function markRootUpdated(root, updatedLanes) { - root.pendingLanes |= updatedLanes; - updatedLanes !== IdleLane && - ((root.suspendedLanes = 0), (root.pingedLanes = 0)); - executionContext & RenderContext - ? (workInProgressRootDidIncludeRecursiveRenderUpdate = !0) - : executionContext & CommitContext && - (didIncludeCommitPhaseUpdate = !0); - throwIfInfiniteUpdateLoopDetected(); - } - function markRootSuspended(root, suspendedLanes, spawnedLane) { - suspendedLanes &= ~workInProgressRootPingedLanes; - suspendedLanes &= ~workInProgressRootInterleavedUpdatedLanes; - root.suspendedLanes |= suspendedLanes; - root.pingedLanes &= ~suspendedLanes; - for ( - var expirationTimes = root.expirationTimes, lanes = suspendedLanes; - 0 < lanes; - ) { - var index = 31 - clz32(lanes), - lane = 1 << index; - expirationTimes[index] = -1; - lanes &= ~lane; + function deleteRemainingChildren(returnFiber, currentFirstChild) { + if (!shouldTrackSideEffects) { + // Noop. + return null; + } // TODO: For the shouldClone case, this could be micro-optimized a bit by + // assuming that after the first child we've already added everything. + + var childToDelete = currentFirstChild; + + while (childToDelete !== null) { + deleteChild(returnFiber, childToDelete); + childToDelete = childToDelete.sibling; + } + + return null; } - 0 !== spawnedLane && - markSpawnedDeferredLane(root, spawnedLane, suspendedLanes); - } - function performSyncWorkOnRoot(root, lanes) { - if ((executionContext & (RenderContext | CommitContext)) !== NoContext) - throw Error("Should not already be working."); - if (flushPassiveEffects()) return ensureRootIsScheduled(root), null; - currentUpdateIsNested = nestedUpdateScheduled; - nestedUpdateScheduled = !1; - var exitStatus = renderRootSync(root, lanes); - if (0 !== root.tag && exitStatus === RootErrored) { - var originallyAttemptedLanes = lanes, - errorRetryLanes = getLanesToRetrySynchronouslyOnError( - root, - originallyAttemptedLanes - ); - 0 !== errorRetryLanes && - ((lanes = errorRetryLanes), - (exitStatus = recoverFromConcurrentError( - root, - originallyAttemptedLanes, - errorRetryLanes - ))); + + function mapRemainingChildren(currentFirstChild) { + // Add the remaining children to a temporary map so that we can find them by + // keys quickly. Implicit (null) keys get added to this set with their index + // instead. + var existingChildren = new Map(); + var existingChild = currentFirstChild; + + while (existingChild !== null) { + if (existingChild.key !== null) { + existingChildren.set(existingChild.key, existingChild); + } else { + existingChildren.set(existingChild.index, existingChild); + } + + existingChild = existingChild.sibling; + } + + return existingChildren; } - if (exitStatus === RootFatalErrored) - return ( - prepareFreshStack(root, 0), - markRootSuspended(root, lanes, 0), - ensureRootIsScheduled(root), - null - ); - if (exitStatus === RootDidNotComplete) - return ( - markRootSuspended(root, lanes, workInProgressDeferredLane), - ensureRootIsScheduled(root), - null - ); - root.finishedWork = root.current.alternate; - root.finishedLanes = lanes; - commitRoot( - root, - workInProgressRootRecoverableErrors, - workInProgressTransitions, - workInProgressRootDidIncludeRecursiveRenderUpdate, - workInProgressDeferredLane - ); - ensureRootIsScheduled(root); - return null; - } - function flushSyncWork() { - return (executionContext & (RenderContext | CommitContext)) === NoContext - ? (flushSyncWorkAcrossRoots_impl(!1), !1) - : !0; - } - function resetWorkInProgressStack() { - if (null !== workInProgress) { - if (workInProgressSuspendedReason === NotSuspended) - var interruptedWork = workInProgress.return; - else - (interruptedWork = workInProgress), - resetContextDependencies(), - resetHooksOnUnwind(interruptedWork), - (thenableState$1 = null), - (thenableIndexCounter$1 = 0), - (interruptedWork = workInProgress); - for (; null !== interruptedWork; ) - unwindInterruptedWork(interruptedWork.alternate, interruptedWork), - (interruptedWork = interruptedWork.return); - workInProgress = null; + + function useFiber(fiber, pendingProps) { + // We currently set sibling to null and index to 0 here because it is easy + // to forget to do before returning it. E.g. for the single child case. + var clone = createWorkInProgress(fiber, pendingProps); + clone.index = 0; + clone.sibling = null; + return clone; } - } - function prepareFreshStack(root, lanes) { - root.finishedWork = null; - root.finishedLanes = 0; - var timeoutHandle = root.timeoutHandle; - -1 !== timeoutHandle && - ((root.timeoutHandle = -1), cancelTimeout(timeoutHandle)); - timeoutHandle = root.cancelPendingCommit; - null !== timeoutHandle && - ((root.cancelPendingCommit = null), timeoutHandle()); - resetWorkInProgressStack(); - workInProgressRoot = root; - workInProgress = timeoutHandle = createWorkInProgress(root.current, null); - workInProgressRootRenderLanes = lanes; - workInProgressSuspendedReason = NotSuspended; - workInProgressThrownValue = null; - workInProgressRootDidAttachPingListener = !1; - workInProgressRootExitStatus = RootInProgress; - workInProgressDeferredLane = - workInProgressRootPingedLanes = - workInProgressRootInterleavedUpdatedLanes = - workInProgressRootSkippedLanes = - 0; - workInProgressRootRecoverableErrors = workInProgressRootConcurrentErrors = - null; - workInProgressRootDidIncludeRecursiveRenderUpdate = !1; - 0 !== (lanes & InputContinuousLane) && (lanes |= lanes & DefaultLane); - var allEntangledLanes = root.entangledLanes; - if (0 !== allEntangledLanes) - for ( - root = root.entanglements, allEntangledLanes &= lanes; - 0 < allEntangledLanes; - ) { - var index = 31 - clz32(allEntangledLanes), - lane = 1 << index; - lanes |= root[index]; - allEntangledLanes &= ~lane; + function placeChild(newFiber, lastPlacedIndex, newIndex) { + newFiber.index = newIndex; + + if (!shouldTrackSideEffects) { + // During hydration, the useId algorithm needs to know which fibers are + // part of a list of children (arrays, iterators). + newFiber.flags |= Forked; + return lastPlacedIndex; } - entangledRenderLanes = lanes; - finishQueueingConcurrentUpdates(); - ReactStrictModeWarnings.discardPendingWarnings(); - return timeoutHandle; - } - function handleThrow(root, thrownValue) { - currentlyRenderingFiber$1 = null; - ReactSharedInternals.H = ContextOnlyDispatcher; - ReactSharedInternals.getCurrentStack = null; - isRendering = !1; - current = null; - if (thrownValue === SuspenseException) { - thrownValue = getSuspendedThenable(); - var handler = suspenseHandlerStackCursor.current; - workInProgressSuspendedReason = - (null !== handler && - ((workInProgressRootRenderLanes & TransitionLanes) === - workInProgressRootRenderLanes - ? null !== shellBoundary - : ((workInProgressRootRenderLanes & RetryLanes) !== - workInProgressRootRenderLanes && - 0 === (workInProgressRootRenderLanes & OffscreenLane)) || - handler !== shellBoundary)) || - 0 !== (workInProgressRootSkippedLanes & 134217727) || - 0 !== (workInProgressRootInterleavedUpdatedLanes & 134217727) - ? SuspendedOnImmediate - : SuspendedOnData; - } else - thrownValue === SuspenseyCommitException - ? ((thrownValue = getSuspendedThenable()), - (workInProgressSuspendedReason = SuspendedOnInstance)) - : (workInProgressSuspendedReason = - thrownValue === SelectiveHydrationException - ? SuspendedOnHydration - : null !== thrownValue && - "object" === typeof thrownValue && - "function" === typeof thrownValue.then - ? SuspendedOnDeprecatedThrowPromise - : SuspendedOnError); - workInProgressThrownValue = thrownValue; - handler = workInProgress; - if (null === handler) - (workInProgressRootExitStatus = RootFatalErrored), - logUncaughtError( - root, - createCapturedValueAtFiber(thrownValue, root.current) - ); - else - switch ( - (handler.mode & 2 && - stopProfilerTimerIfRunningAndRecordDelta(handler, !0), - markComponentRenderStopped(), - workInProgressSuspendedReason) - ) { - case SuspendedOnError: - null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markComponentErrored && - injectedProfilingHooks.markComponentErrored( - handler, - thrownValue, - workInProgressRootRenderLanes - ); - break; - case SuspendedOnData: - case SuspendedOnImmediate: - case SuspendedOnDeprecatedThrowPromise: - case SuspendedAndReadyToContinue: - null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markComponentSuspended && - injectedProfilingHooks.markComponentSuspended( - handler, - thrownValue, - workInProgressRootRenderLanes - ); + + var current = newFiber.alternate; + + if (current !== null) { + var oldIndex = current.index; + + if (oldIndex < lastPlacedIndex) { + // This is a move. + newFiber.flags |= Placement | PlacementDEV; + return lastPlacedIndex; + } else { + // This item can stay in place. + return oldIndex; + } + } else { + // This is an insertion. + newFiber.flags |= Placement | PlacementDEV; + return lastPlacedIndex; } - } - function pushDispatcher() { - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = ContextOnlyDispatcher; - return null === prevDispatcher ? ContextOnlyDispatcher : prevDispatcher; - } - function pushAsyncDispatcher() { - var prevAsyncDispatcher = ReactSharedInternals.A; - ReactSharedInternals.A = DefaultAsyncDispatcher; - return prevAsyncDispatcher; - } - function renderDidSuspendDelayIfPossible() { - workInProgressRootExitStatus = RootSuspendedWithDelay; - (0 === (workInProgressRootSkippedLanes & 134217727) && - 0 === (workInProgressRootInterleavedUpdatedLanes & 134217727)) || - null === workInProgressRoot || - markRootSuspended( - workInProgressRoot, - workInProgressRootRenderLanes, - workInProgressDeferredLane - ); - } - function renderRootSync(root, lanes) { - var prevExecutionContext = executionContext; - executionContext |= RenderContext; - var prevDispatcher = pushDispatcher(), - prevAsyncDispatcher = pushAsyncDispatcher(); - if ( - workInProgressRoot !== root || - workInProgressRootRenderLanes !== lanes + } + + function placeSingleChild(newFiber) { + // 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 | PlacementDEV; + } + + return newFiber; + } + + function updateTextNode( + returnFiber, + current, + textContent, + lanes, + debugInfo ) { - if (isDevToolsPresent) { - var memoizedUpdaters = root.memoizedUpdaters; - 0 < memoizedUpdaters.size && - (restorePendingUpdaters(root, workInProgressRootRenderLanes), - memoizedUpdaters.clear()); - movePendingFibersToMemoized(root, lanes); + if (current === null || current.tag !== HostText) { + // Insert + var created = createFiberFromText( + textContent, + returnFiber.mode, + lanes + ); + created.return = returnFiber; + + { + created._debugInfo = debugInfo; + } + + return created; + } else { + // Update + var existing = useFiber(current, textContent); + existing.return = returnFiber; + + { + existing._debugInfo = debugInfo; + } + + return existing; } - workInProgressTransitions = null; - prepareFreshStack(root, lanes); } - markRenderStarted(lanes); - lanes = !1; - a: do - try { + + function updateElement(returnFiber, current, element, lanes, debugInfo) { + var elementType = element.type; + + if (elementType === REACT_FRAGMENT_TYPE) { + return updateFragment( + returnFiber, + current, + element.props.children, + lanes, + element.key, + debugInfo + ); + } + + if (current !== null) { if ( - workInProgressSuspendedReason !== NotSuspended && - null !== workInProgress + 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. + (typeof elementType === "object" && + elementType !== null && + elementType.$$typeof === REACT_LAZY_TYPE && + resolveLazy(elementType) === current.type) ) { - memoizedUpdaters = workInProgress; - var thrownValue = workInProgressThrownValue; - switch (workInProgressSuspendedReason) { - case SuspendedOnHydration: - resetWorkInProgressStack(); - workInProgressRootExitStatus = RootDidNotComplete; - break a; - case SuspendedOnImmediate: - case SuspendedOnData: - lanes || - null !== suspenseHandlerStackCursor.current || - (lanes = !0); - default: - (workInProgressSuspendedReason = NotSuspended), - (workInProgressThrownValue = null), - throwAndUnwindWorkLoop(root, memoizedUpdaters, thrownValue); + // Move based on index + var existing = useFiber(current, element.props); + coerceRef(returnFiber, current, existing, element); + existing.return = returnFiber; + + { + existing._debugOwner = element._owner; + existing._debugInfo = debugInfo; } + + return existing; } - workLoopSync(); - break; - } catch (thrownValue$45) { - handleThrow(root, thrownValue$45); + } // Insert + + var created = createFiberFromElement(element, returnFiber.mode, lanes); + coerceRef(returnFiber, current, created, element); + created.return = returnFiber; + + { + created._debugInfo = debugInfo; } - while (1); - lanes && root.shellSuspendCounter++; - resetContextDependencies(); - executionContext = prevExecutionContext; - ReactSharedInternals.H = prevDispatcher; - ReactSharedInternals.A = prevAsyncDispatcher; - if (null !== workInProgress) - throw Error( - "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." - ); - markRenderStopped(); - workInProgressRoot = null; - workInProgressRootRenderLanes = 0; - finishQueueingConcurrentUpdates(); - return workInProgressRootExitStatus; - } - function workLoopSync() { - for (; null !== workInProgress; ) performUnitOfWork(workInProgress); - } - function renderRootConcurrent(root, lanes) { - var prevExecutionContext = executionContext; - executionContext |= RenderContext; - var prevDispatcher = pushDispatcher(), - prevAsyncDispatcher = pushAsyncDispatcher(); - if ( - workInProgressRoot !== root || - workInProgressRootRenderLanes !== lanes + + return created; + } + + function updatePortal(returnFiber, current, portal, lanes, debugInfo) { + if ( + current === null || + current.tag !== HostPortal || + current.stateNode.containerInfo !== portal.containerInfo || + current.stateNode.implementation !== portal.implementation + ) { + // Insert + var created = createFiberFromPortal(portal, returnFiber.mode, lanes); + created.return = returnFiber; + + { + created._debugInfo = debugInfo; + } + + return created; + } else { + // Update + var existing = useFiber(current, portal.children || []); + existing.return = returnFiber; + + { + existing._debugInfo = debugInfo; + } + + return existing; + } + } + + function updateFragment( + returnFiber, + current, + fragment, + lanes, + key, + debugInfo ) { - if (isDevToolsPresent) { - var memoizedUpdaters = root.memoizedUpdaters; - 0 < memoizedUpdaters.size && - (restorePendingUpdaters(root, workInProgressRootRenderLanes), - memoizedUpdaters.clear()); - movePendingFibersToMemoized(root, lanes); + if (current === null || current.tag !== Fragment) { + // Insert + var created = createFiberFromFragment( + fragment, + returnFiber.mode, + lanes, + key + ); + created.return = returnFiber; + + { + created._debugInfo = debugInfo; + } + + return created; + } else { + // Update + var existing = useFiber(current, fragment); + existing.return = returnFiber; + + { + existing._debugInfo = debugInfo; + } + + return existing; } - workInProgressTransitions = null; - workInProgressRootRenderTargetTime = now$1() + RENDER_TIMEOUT_MS; - prepareFreshStack(root, lanes); } - markRenderStarted(lanes); - a: do - try { - if ( - workInProgressSuspendedReason !== NotSuspended && - null !== workInProgress - ) - b: switch ( - ((lanes = workInProgress), - (memoizedUpdaters = workInProgressThrownValue), - workInProgressSuspendedReason) - ) { - case SuspendedOnError: - workInProgressSuspendedReason = NotSuspended; - workInProgressThrownValue = null; - throwAndUnwindWorkLoop(root, lanes, memoizedUpdaters); - break; - case SuspendedOnData: - if (isThenableResolved(memoizedUpdaters)) { - workInProgressSuspendedReason = NotSuspended; - workInProgressThrownValue = null; - replaySuspendedUnitOfWork(lanes); - break; - } - lanes = function () { - workInProgressSuspendedReason === SuspendedOnData && - workInProgressRoot === root && - (workInProgressSuspendedReason = - SuspendedAndReadyToContinue); - ensureRootIsScheduled(root); - }; - memoizedUpdaters.then(lanes, lanes); - break a; - case SuspendedOnImmediate: - workInProgressSuspendedReason = SuspendedAndReadyToContinue; - break a; - case SuspendedOnInstance: - workInProgressSuspendedReason = - SuspendedOnInstanceAndReadyToContinue; - break a; - case SuspendedAndReadyToContinue: - isThenableResolved(memoizedUpdaters) - ? ((workInProgressSuspendedReason = NotSuspended), - (workInProgressThrownValue = null), - replaySuspendedUnitOfWork(lanes)) - : ((workInProgressSuspendedReason = NotSuspended), - (workInProgressThrownValue = null), - throwAndUnwindWorkLoop(root, lanes, memoizedUpdaters)); - break; - case SuspendedOnInstanceAndReadyToContinue: - var resource = null; - switch (workInProgress.tag) { - case 26: - resource = workInProgress.memoizedState; - case 5: - case 27: - var hostFiber = workInProgress; - if (resource ? preloadResource(resource) : 1) { - workInProgressSuspendedReason = NotSuspended; - workInProgressThrownValue = null; - var sibling = hostFiber.sibling; - if (null !== sibling) workInProgress = sibling; - else { - var returnFiber = hostFiber.return; - null !== returnFiber - ? ((workInProgress = returnFiber), - completeUnitOfWork(returnFiber)) - : (workInProgress = null); - } - break b; - } - break; - default: - error$jscomp$0( - "Unexpected type of fiber triggered a suspensey commit. This is a bug in React." - ); - } - workInProgressSuspendedReason = NotSuspended; - workInProgressThrownValue = null; - throwAndUnwindWorkLoop(root, lanes, memoizedUpdaters); - break; - case SuspendedOnDeprecatedThrowPromise: - workInProgressSuspendedReason = NotSuspended; - workInProgressThrownValue = null; - throwAndUnwindWorkLoop(root, lanes, memoizedUpdaters); - break; - case SuspendedOnHydration: - resetWorkInProgressStack(); - workInProgressRootExitStatus = RootDidNotComplete; - break a; - default: - throw Error( - "Unexpected SuspendedReason. This is a bug in React." + + function createChild(returnFiber, newChild, lanes, debugInfo) { + if ( + (typeof newChild === "string" && newChild !== "") || + typeof newChild === "number" || + enableBigIntSupport + ) { + // Text nodes don't have keys. If the previous node is implicitly keyed + // we can continue to replace it without aborting even if it is not a text + // node. + var created = createFiberFromText( + // $FlowFixMe[unsafe-addition] Flow doesn't want us to use `+` operator with string and bigint + "" + newChild, + returnFiber.mode, + lanes + ); + created.return = returnFiber; + + { + created._debugInfo = debugInfo; + } + + return created; + } + + if (typeof newChild === "object" && newChild !== null) { + switch (newChild.$$typeof) { + case REACT_ELEMENT_TYPE: { + var _created = createFiberFromElement( + newChild, + returnFiber.mode, + lanes + ); + + coerceRef(returnFiber, null, _created, newChild); + _created.return = returnFiber; + + { + _created._debugInfo = mergeDebugInfo( + debugInfo, + newChild._debugInfo ); + } + + return _created; } - null !== ReactSharedInternals.actQueue - ? workLoopSync() - : workLoopConcurrent(); - break; - } catch (thrownValue$46) { - handleThrow(root, thrownValue$46); - } - while (1); - resetContextDependencies(); - ReactSharedInternals.H = prevDispatcher; - ReactSharedInternals.A = prevAsyncDispatcher; - executionContext = prevExecutionContext; - if (null !== workInProgress) - return ( - null !== injectedProfilingHooks && - "function" === typeof injectedProfilingHooks.markRenderYielded && - injectedProfilingHooks.markRenderYielded(), - RootInProgress - ); - markRenderStopped(); - workInProgressRoot = null; - workInProgressRootRenderLanes = 0; - finishQueueingConcurrentUpdates(); - return workInProgressRootExitStatus; - } - function workLoopConcurrent() { - for (; null !== workInProgress && !shouldYield(); ) - performUnitOfWork(workInProgress); - } - function performUnitOfWork(unitOfWork) { - var current = unitOfWork.alternate; - 0 !== (unitOfWork.mode & 2) - ? (startProfilerTimer(unitOfWork), - (current = runWithFiberInDEV( - unitOfWork, - beginWork, - current, - unitOfWork, - entangledRenderLanes - )), - stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, !0)) - : (current = runWithFiberInDEV( - unitOfWork, - beginWork, - current, - unitOfWork, - entangledRenderLanes - )); - unitOfWork.memoizedProps = unitOfWork.pendingProps; - null === current - ? completeUnitOfWork(unitOfWork) - : (workInProgress = current); - } - function replaySuspendedUnitOfWork(unitOfWork) { - var next = runWithFiberInDEV(unitOfWork, replayBeginWork, unitOfWork); - unitOfWork.memoizedProps = unitOfWork.pendingProps; - null === next ? completeUnitOfWork(unitOfWork) : (workInProgress = next); - } - function replayBeginWork(unitOfWork) { - var current = unitOfWork.alternate, - isProfilingMode = 0 !== (unitOfWork.mode & 2); - isProfilingMode && startProfilerTimer(unitOfWork); - switch (unitOfWork.tag) { - case 15: - case 0: - current = replayFunctionComponent( - current, - unitOfWork, - unitOfWork.pendingProps, - unitOfWork.type, - void 0, - workInProgressRootRenderLanes - ); - break; - case 11: - current = replayFunctionComponent( - current, - unitOfWork, - unitOfWork.pendingProps, - unitOfWork.type.render, - unitOfWork.ref, - workInProgressRootRenderLanes - ); - break; - case 5: - resetHooksOnUnwind(unitOfWork); - default: - unwindInterruptedWork(current, unitOfWork), - (unitOfWork = workInProgress = - resetWorkInProgress(unitOfWork, entangledRenderLanes)), - (current = beginWork(current, unitOfWork, entangledRenderLanes)); - } - isProfilingMode && - stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, !0); - return current; - } - function throwAndUnwindWorkLoop(root, unitOfWork, thrownValue) { - resetContextDependencies(); - resetHooksOnUnwind(unitOfWork); - thenableState$1 = null; - thenableIndexCounter$1 = 0; - var returnFiber = unitOfWork.return; - try { - if ( - throwException( - root, - returnFiber, - unitOfWork, - thrownValue, - workInProgressRootRenderLanes - ) - ) { - workInProgressRootExitStatus = RootFatalErrored; - logUncaughtError( - root, - createCapturedValueAtFiber(thrownValue, root.current) - ); - workInProgress = null; - return; - } - } catch (error$47) { - if (null !== returnFiber) - throw ((workInProgress = returnFiber), error$47); - workInProgressRootExitStatus = RootFatalErrored; - logUncaughtError( - root, - createCapturedValueAtFiber(thrownValue, root.current) - ); - workInProgress = null; - return; - } - if (unitOfWork.flags & 32768) - a: { - root = unitOfWork; - do { - unitOfWork = unwindWork(root.alternate, root); - if (null !== unitOfWork) { - unitOfWork.flags &= 32767; - workInProgress = unitOfWork; - break a; + + case REACT_PORTAL_TYPE: { + var _created2 = createFiberFromPortal( + newChild, + returnFiber.mode, + lanes + ); + + _created2.return = returnFiber; + + { + _created2._debugInfo = debugInfo; + } + + return _created2; + } + + case REACT_LAZY_TYPE: { + var payload = newChild._payload; + var init = newChild._init; + return createChild( + returnFiber, + init(payload), + lanes, + mergeDebugInfo(debugInfo, newChild._debugInfo) // call merge after init + ); } - if (0 !== (root.mode & 2)) { - stopProfilerTimerIfRunningAndRecordDelta(root, !1); - unitOfWork = root.actualDuration; - for (thrownValue = root.child; null !== thrownValue; ) - (unitOfWork += thrownValue.actualDuration), - (thrownValue = thrownValue.sibling); - root.actualDuration = unitOfWork; + } + + if (isArray(newChild) || getIteratorFn(newChild)) { + var _created3 = createFiberFromFragment( + newChild, + returnFiber.mode, + lanes, + null + ); + + _created3.return = returnFiber; + + { + _created3._debugInfo = mergeDebugInfo( + debugInfo, + newChild._debugInfo + ); } - root = root.return; - null !== root && - ((root.flags |= 32768), - (root.subtreeFlags = 0), - (root.deletions = null)); - workInProgress = root; - } while (null !== root); - workInProgressRootExitStatus = RootDidNotComplete; - workInProgress = null; - } - else completeUnitOfWork(unitOfWork); - } - function completeUnitOfWork(unitOfWork) { - var completedWork = unitOfWork; - do { - 0 !== (completedWork.flags & 32768) && - error$jscomp$0( - "Internal React error: Expected this fiber to be complete, but it isn't. It should have been unwound. This is a bug in React." - ); - var current = completedWork.alternate; - unitOfWork = completedWork.return; - 0 === (completedWork.mode & 2) - ? (current = runWithFiberInDEV( - completedWork, - completeWork, - current, - completedWork, - entangledRenderLanes - )) - : (startProfilerTimer(completedWork), - (current = runWithFiberInDEV( - completedWork, - completeWork, - current, - completedWork, - entangledRenderLanes - )), - stopProfilerTimerIfRunningAndRecordDelta(completedWork, !1)); - if (null !== current) { - workInProgress = current; - return; + + return _created3; + } // Usable node types + // + // Unwrap the inner value and recursively call this function again. + + if (typeof newChild.then === "function") { + var thenable = newChild; + return createChild( + returnFiber, + unwrapThenable(thenable), + lanes, + mergeDebugInfo(debugInfo, newChild._debugInfo) + ); + } + + if (newChild.$$typeof === REACT_CONTEXT_TYPE) { + var context = newChild; + return createChild( + returnFiber, + readContextDuringReconciliation(returnFiber, context, lanes), + lanes, + debugInfo + ); + } + + throwOnInvalidObjectType(returnFiber, newChild); } - completedWork = completedWork.sibling; - if (null !== completedWork) { - workInProgress = completedWork; - return; + + { + if (typeof newChild === "function") { + warnOnFunctionType(returnFiber, newChild); + } + + if (typeof newChild === "symbol") { + warnOnSymbolType(returnFiber, newChild); + } } - workInProgress = completedWork = unitOfWork; - } while (null !== completedWork); - workInProgressRootExitStatus === RootInProgress && - (workInProgressRootExitStatus = RootCompleted); - } - function commitRoot( - root, - recoverableErrors, - transitions, - didIncludeRenderPhaseUpdate, - spawnedLane - ) { - var prevTransition = ReactSharedInternals.T, - previousUpdateLanePriority = currentUpdatePriority; - try { - (currentUpdatePriority = DiscreteEventPriority), - (ReactSharedInternals.T = null), - commitRootImpl( - root, - recoverableErrors, - transitions, - didIncludeRenderPhaseUpdate, - previousUpdateLanePriority, - spawnedLane - ); - } finally { - (ReactSharedInternals.T = prevTransition), - (currentUpdatePriority = previousUpdateLanePriority); + + return null; } - return null; - } - function commitRootImpl( - root, - recoverableErrors, - transitions, - didIncludeRenderPhaseUpdate, - renderPriorityLevel, - spawnedLane - ) { - do flushPassiveEffects(); - while (null !== rootWithPendingPassiveEffects); - ReactStrictModeWarnings.flushLegacyContextWarning(); - ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings(); - if ((executionContext & (RenderContext | CommitContext)) !== NoContext) - throw Error("Should not already be working."); - var finishedWork = root.finishedWork, - lanes = root.finishedLanes; - null !== injectedProfilingHooks && - "function" === typeof injectedProfilingHooks.markCommitStarted && - injectedProfilingHooks.markCommitStarted(lanes); - if (null === finishedWork) return markCommitStopped(), null; - 0 === lanes && - error$jscomp$0( - "root.finishedLanes should not be empty during a commit. This is a bug in React." - ); - root.finishedWork = null; - root.finishedLanes = 0; - if (finishedWork === root.current) - throw Error( - "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." - ); - root.callbackNode = null; - root.callbackPriority = 0; - root.cancelPendingCommit = null; - var remainingLanes = finishedWork.lanes | finishedWork.childLanes; - remainingLanes |= concurrentlyUpdatedLanes; - markRootFinished(root, remainingLanes, spawnedLane); - didIncludeCommitPhaseUpdate = !1; - root === workInProgressRoot && - ((workInProgress = workInProgressRoot = null), - (workInProgressRootRenderLanes = 0)); - (0 === (finishedWork.subtreeFlags & 10256) && - 0 === (finishedWork.flags & 10256)) || - rootDoesHavePassiveEffects || - ((rootDoesHavePassiveEffects = !0), - (pendingPassiveEffectsRemainingLanes = remainingLanes), - (pendingPassiveTransitions = transitions), - scheduleCallback(NormalPriority$1, function () { - flushPassiveEffects(); - return null; - })); - transitions = 0 !== (finishedWork.flags & 15990); - if (0 !== (finishedWork.subtreeFlags & 15990) || transitions) { - transitions = ReactSharedInternals.T; - ReactSharedInternals.T = null; - spawnedLane = currentUpdatePriority; - currentUpdatePriority = DiscreteEventPriority; - var prevExecutionContext = executionContext; - executionContext |= CommitContext; - commitBeforeMutationEffects(root, finishedWork); - commitTime = now(); - commitMutationEffects(root, finishedWork, lanes); - root.current = finishedWork; - null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markLayoutEffectsStarted && - injectedProfilingHooks.markLayoutEffectsStarted(lanes); - commitLayoutEffects(finishedWork, root, lanes); - null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markLayoutEffectsStopped && - injectedProfilingHooks.markLayoutEffectsStopped(); - requestPaint(); - executionContext = prevExecutionContext; - currentUpdatePriority = spawnedLane; - ReactSharedInternals.T = transitions; - } else (root.current = finishedWork), (commitTime = now()); - (transitions = rootDoesHavePassiveEffects) - ? ((rootDoesHavePassiveEffects = !1), - (rootWithPendingPassiveEffects = root), - (pendingPassiveEffectsLanes = lanes)) - : (releaseRootPooledCache(root, remainingLanes), - (nestedPassiveUpdateCount = 0), - (rootWithPassiveNestedUpdates = null)); - remainingLanes = root.pendingLanes; - 0 === remainingLanes && (legacyErrorBoundariesThatAlreadyFailed = null); - transitions || commitDoubleInvokeEffectsInDEV(root, !1); - onCommitRoot(finishedWork.stateNode, renderPriorityLevel); - isDevToolsPresent && root.memoizedUpdaters.clear(); - ensureRootIsScheduled(root); - if (null !== recoverableErrors) - for ( - renderPriorityLevel = root.onRecoverableError, finishedWork = 0; - finishedWork < recoverableErrors.length; - finishedWork++ - ) - (remainingLanes = recoverableErrors[finishedWork]), - (transitions = makeErrorInfo(remainingLanes.stack)), - runWithFiberInDEV( - remainingLanes.source, - renderPriorityLevel, - remainingLanes.value, - transitions - ); - 0 !== (pendingPassiveEffectsLanes & (SyncLane | SyncHydrationLane)) && - 0 !== root.tag && - flushPassiveEffects(); - remainingLanes = root.pendingLanes; - didIncludeRenderPhaseUpdate || - didIncludeCommitPhaseUpdate || - (0 !== (lanes & UpdateLanes) && 0 !== (remainingLanes & SyncUpdateLanes)) - ? ((nestedUpdateScheduled = !0), - root === rootWithNestedUpdates - ? nestedUpdateCount++ - : ((nestedUpdateCount = 0), (rootWithNestedUpdates = root))) - : (nestedUpdateCount = 0); - flushSyncWorkAcrossRoots_impl(!1); - markCommitStopped(); - return null; - } - function makeErrorInfo(componentStack) { - componentStack = { componentStack: componentStack }; - Object.defineProperty(componentStack, "digest", { - get: function () { - error$jscomp$0( - 'You are accessing "digest" from the errorInfo object passed to onRecoverableError. This property is no longer provided as part of errorInfo but can be accessed as a property of the Error instance itself.' + + function updateSlot(returnFiber, oldFiber, newChild, lanes, debugInfo) { + // Update the fiber if the keys match, otherwise return null. + var key = oldFiber !== null ? oldFiber.key : null; + + if ( + (typeof newChild === "string" && newChild !== "") || + typeof newChild === "number" || + enableBigIntSupport + ) { + // Text nodes don't have keys. If the previous node is implicitly keyed + // we can continue to replace it without aborting even if it is not a text + // node. + if (key !== null) { + return null; + } + + return updateTextNode( + returnFiber, + oldFiber, // $FlowFixMe[unsafe-addition] Flow doesn't want us to use `+` operator with string and bigint + "" + newChild, + lanes, + debugInfo ); } - }); - return componentStack; - } - function releaseRootPooledCache(root, remainingLanes) { - 0 === (root.pooledCacheLanes &= remainingLanes) && - ((remainingLanes = root.pooledCache), - null != remainingLanes && - ((root.pooledCache = null), releaseCache(remainingLanes))); - } - function flushPassiveEffects() { - if (null !== rootWithPendingPassiveEffects) { - var root = rootWithPendingPassiveEffects, - remainingLanes = pendingPassiveEffectsRemainingLanes; - pendingPassiveEffectsRemainingLanes = 0; - var renderPriority = lanesToEventPriority(pendingPassiveEffectsLanes), - priority = - 0 === DefaultEventPriority || DefaultEventPriority > renderPriority - ? DefaultEventPriority - : renderPriority; - renderPriority = ReactSharedInternals.T; - var previousPriority = currentUpdatePriority; - try { - currentUpdatePriority = priority; - ReactSharedInternals.T = null; - if (null === rootWithPendingPassiveEffects) - var JSCompiler_inline_result = !1; - else { - var transitions = pendingPassiveTransitions; - pendingPassiveTransitions = null; - priority = rootWithPendingPassiveEffects; - var lanes = pendingPassiveEffectsLanes; - rootWithPendingPassiveEffects = null; - pendingPassiveEffectsLanes = 0; - if ( - (executionContext & (RenderContext | CommitContext)) !== - NoContext - ) - throw Error( - "Cannot flush passive effects while already rendering." + + if (typeof newChild === "object" && newChild !== null) { + switch (newChild.$$typeof) { + case REACT_ELEMENT_TYPE: { + if (newChild.key === key) { + return updateElement( + returnFiber, + oldFiber, + newChild, + lanes, + mergeDebugInfo(debugInfo, newChild._debugInfo) + ); + } else { + return null; + } + } + + case REACT_PORTAL_TYPE: { + if (newChild.key === key) { + return updatePortal( + returnFiber, + oldFiber, + newChild, + lanes, + debugInfo + ); + } else { + return null; + } + } + + case REACT_LAZY_TYPE: { + var payload = newChild._payload; + var init = newChild._init; + return updateSlot( + returnFiber, + oldFiber, + init(payload), + lanes, + mergeDebugInfo(debugInfo, newChild._debugInfo) ); - isFlushingPassiveEffects = !0; - didScheduleUpdateDuringPassiveEffects = !1; - null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markPassiveEffectsStarted && - injectedProfilingHooks.markPassiveEffectsStarted(lanes); - var prevExecutionContext = executionContext; - executionContext |= CommitContext; - var finishedWork = priority.current; - runWithFiberInDEV( - finishedWork, - commitPassiveUnmountOnFiber, - finishedWork + } + } + + if (isArray(newChild) || getIteratorFn(newChild)) { + if (key !== null) { + return null; + } + + return updateFragment( + returnFiber, + oldFiber, + newChild, + lanes, + null, + mergeDebugInfo(debugInfo, newChild._debugInfo) ); - var finishedWork$jscomp$0 = priority.current; - runWithFiberInDEV( - finishedWork$jscomp$0, - commitPassiveMountOnFiber, - priority, - finishedWork$jscomp$0, + } // Usable node types + // + // Unwrap the inner value and recursively call this function again. + + if (typeof newChild.then === "function") { + var thenable = newChild; + return updateSlot( + returnFiber, + oldFiber, + unwrapThenable(thenable), lanes, - transitions + debugInfo ); - finishedWork = pendingPassiveProfilerEffects; - pendingPassiveProfilerEffects = []; - for ( - finishedWork$jscomp$0 = 0; - finishedWork$jscomp$0 < finishedWork.length; - finishedWork$jscomp$0++ - ) { - var finishedWork$jscomp$1 = finishedWork[finishedWork$jscomp$0]; - if ( - executionContext & CommitContext && - 0 !== (finishedWork$jscomp$1.flags & 4) - ) - switch (finishedWork$jscomp$1.tag) { - case 12: - var passiveEffectDuration = - finishedWork$jscomp$1.stateNode.passiveEffectDuration, - _finishedWork$memoize = - finishedWork$jscomp$1.memoizedProps, - id = _finishedWork$memoize.id, - onPostCommit = _finishedWork$memoize.onPostCommit; - transitions = commitTime; - var phase = - null === finishedWork$jscomp$1.alternate - ? "mount" - : "update"; - currentUpdateIsNested && (phase = "nested-update"); - "function" === typeof onPostCommit && - onPostCommit( - id, - phase, - passiveEffectDuration, - transitions - ); - var parentFiber = finishedWork$jscomp$1.return; - b: for (; null !== parentFiber; ) { - switch (parentFiber.tag) { - case 3: - parentFiber.stateNode.passiveEffectDuration += - passiveEffectDuration; - break b; - case 12: - parentFiber.stateNode.passiveEffectDuration += - passiveEffectDuration; - break b; - } - parentFiber = parentFiber.return; - } - } - } - null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markPassiveEffectsStopped && - injectedProfilingHooks.markPassiveEffectsStopped(); - commitDoubleInvokeEffectsInDEV(priority, !0); - executionContext = prevExecutionContext; - flushSyncWorkAcrossRoots_impl(!1); - didScheduleUpdateDuringPassiveEffects - ? priority === rootWithPassiveNestedUpdates - ? nestedPassiveUpdateCount++ - : ((nestedPassiveUpdateCount = 0), - (rootWithPassiveNestedUpdates = priority)) - : (nestedPassiveUpdateCount = 0); - didScheduleUpdateDuringPassiveEffects = isFlushingPassiveEffects = - !1; - if ( - injectedHook && - "function" === typeof injectedHook.onPostCommitFiberRoot - ) - try { - injectedHook.onPostCommitFiberRoot(rendererID, priority); - } catch (err) { - hasLoggedError || - ((hasLoggedError = !0), - error$jscomp$0( - "React instrumentation encountered an error: %s", - err - )); - } - var stateNode = priority.current.stateNode; - stateNode.effectDuration = 0; - stateNode.passiveEffectDuration = 0; - JSCompiler_inline_result = !0; } - return JSCompiler_inline_result; - } finally { - (currentUpdatePriority = previousPriority), - (ReactSharedInternals.T = renderPriority), - releaseRootPooledCache(root, remainingLanes); - } - } - return !1; - } - function enqueuePendingPassiveProfilerEffect(fiber) { - pendingPassiveProfilerEffects.push(fiber); - rootDoesHavePassiveEffects || - ((rootDoesHavePassiveEffects = !0), - scheduleCallback(NormalPriority$1, function () { - flushPassiveEffects(); - return null; - })); - } - function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { - sourceFiber = createCapturedValueAtFiber(error, sourceFiber); - sourceFiber = createRootErrorUpdate( - rootFiber.stateNode, - sourceFiber, - SyncLane - ); - rootFiber = enqueueUpdate(rootFiber, sourceFiber, SyncLane); - null !== rootFiber && - (markRootUpdated(rootFiber, SyncLane), - ensureRootIsScheduled(rootFiber)); - } - function captureCommitPhaseError( - sourceFiber, - nearestMountedAncestor, - error$1 - ) { - isRunningInsertionEffect = !1; - if (3 === sourceFiber.tag) - captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error$1); - else { - for (; null !== nearestMountedAncestor; ) { - if (3 === nearestMountedAncestor.tag) { - captureCommitPhaseErrorOnRoot( - nearestMountedAncestor, - sourceFiber, - error$1 + + if (newChild.$$typeof === REACT_CONTEXT_TYPE) { + var context = newChild; + return updateSlot( + returnFiber, + oldFiber, + readContextDuringReconciliation(returnFiber, context, lanes), + lanes, + debugInfo ); - return; } - if (1 === nearestMountedAncestor.tag) { - var instance = nearestMountedAncestor.stateNode; - if ( - "function" === - typeof nearestMountedAncestor.type.getDerivedStateFromError || - ("function" === typeof instance.componentDidCatch && - (null === legacyErrorBoundariesThatAlreadyFailed || - !legacyErrorBoundariesThatAlreadyFailed.has(instance))) - ) { - sourceFiber = createCapturedValueAtFiber(error$1, sourceFiber); - error$1 = createClassErrorUpdate(SyncLane); - instance = enqueueUpdate( - nearestMountedAncestor, - error$1, - SyncLane - ); - null !== instance && - (initializeClassErrorUpdate( - error$1, - instance, - nearestMountedAncestor, - sourceFiber - ), - markRootUpdated(instance, SyncLane), - ensureRootIsScheduled(instance)); - return; - } + + throwOnInvalidObjectType(returnFiber, newChild); + } + + { + if (typeof newChild === "function") { + warnOnFunctionType(returnFiber, newChild); + } + + if (typeof newChild === "symbol") { + warnOnSymbolType(returnFiber, newChild); } - nearestMountedAncestor = nearestMountedAncestor.return; } - error$jscomp$0( - "Internal React error: Attempted to capture a commit phase error inside a detached tree. This indicates a bug in React. Potential causes include deleting the same fiber more than once, committing an already-finished tree, or an inconsistent return pointer.\n\nError message:\n\n%s", - error$1 - ); + + return null; } - } - function attachPingListener(root, wakeable, lanes) { - var pingCache = root.pingCache; - if (null === pingCache) { - pingCache = root.pingCache = new PossiblyWeakMap(); - var threadIDs = new Set(); - pingCache.set(wakeable, threadIDs); - } else - (threadIDs = pingCache.get(wakeable)), - void 0 === threadIDs && - ((threadIDs = new Set()), pingCache.set(wakeable, threadIDs)); - threadIDs.has(lanes) || - ((workInProgressRootDidAttachPingListener = !0), - threadIDs.add(lanes), - (pingCache = pingSuspendedRoot.bind(null, root, wakeable, lanes)), - isDevToolsPresent && restorePendingUpdaters(root, lanes), - wakeable.then(pingCache, pingCache)); - } - function pingSuspendedRoot(root, wakeable, pingedLanes) { - var pingCache = root.pingCache; - null !== pingCache && pingCache.delete(wakeable); - root.pingedLanes |= root.suspendedLanes & pingedLanes; - executionContext & RenderContext - ? (workInProgressRootDidIncludeRecursiveRenderUpdate = !0) - : executionContext & CommitContext && - (didIncludeCommitPhaseUpdate = !0); - throwIfInfiniteUpdateLoopDetected(); - 0 !== root.tag && - isConcurrentActEnvironment() && - null === ReactSharedInternals.actQueue && - error$jscomp$0( - "A suspended resource finished loading inside a test, but the event was not wrapped in act(...).\n\nWhen testing, code that resolves suspended data should be wrapped into act(...):\n\nact(() => {\n /* finish loading suspended data */\n});\n/* assert on the output */\n\nThis ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act" - ); - workInProgressRoot === root && - (workInProgressRootRenderLanes & pingedLanes) === pingedLanes && - (workInProgressRootExitStatus === RootSuspendedWithDelay || - (workInProgressRootExitStatus === RootSuspended && - (workInProgressRootRenderLanes & RetryLanes) === - workInProgressRootRenderLanes && - now$1() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) - ? (executionContext & RenderContext) === NoContext && - prepareFreshStack(root, 0) - : (workInProgressRootPingedLanes |= pingedLanes)); - ensureRootIsScheduled(root); - } - function retryTimedOutBoundary(boundaryFiber, retryLane) { - 0 === retryLane && - (retryLane = - 0 === (boundaryFiber.mode & 1) ? SyncLane : claimNextRetryLane()); - boundaryFiber = enqueueConcurrentRenderForLane(boundaryFiber, retryLane); - null !== boundaryFiber && - (markRootUpdated(boundaryFiber, retryLane), - ensureRootIsScheduled(boundaryFiber)); - } - function retryDehydratedSuspenseBoundary(boundaryFiber) { - var suspenseState = boundaryFiber.memoizedState, - retryLane = 0; - null !== suspenseState && (retryLane = suspenseState.retryLane); - retryTimedOutBoundary(boundaryFiber, retryLane); - } - function resolveRetryWakeable(boundaryFiber, wakeable) { - var retryLane = 0; - switch (boundaryFiber.tag) { - case 13: - var retryCache = boundaryFiber.stateNode; - var suspenseState = boundaryFiber.memoizedState; - null !== suspenseState && (retryLane = suspenseState.retryLane); - break; - case 19: - retryCache = boundaryFiber.stateNode; - break; - case 22: - retryCache = boundaryFiber.stateNode._retryCache; - break; - default: - throw Error( - "Pinged unknown suspense boundary type. This is probably a bug in React." - ); - } - null !== retryCache && retryCache.delete(wakeable); - retryTimedOutBoundary(boundaryFiber, retryLane); - } - function throwIfInfiniteUpdateLoopDetected() { - if (nestedUpdateCount > NESTED_UPDATE_LIMIT) - throw ( - ((nestedPassiveUpdateCount = nestedUpdateCount = 0), - (rootWithPassiveNestedUpdates = rootWithNestedUpdates = null), - executionContext & RenderContext && - null !== workInProgressRoot && - (workInProgressRoot.errorRecoveryDisabledLanes |= - workInProgressRootRenderLanes), - Error( - "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." - )) - ); - nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT && - ((nestedPassiveUpdateCount = 0), - (rootWithPassiveNestedUpdates = null), - error$jscomp$0( - "Maximum update depth exceeded. This can happen when a component calls setState inside useEffect, but useEffect either doesn't have a dependency array, or one of the dependencies changes on every render." - )); - } - function recursivelyTraverseAndDoubleInvokeEffectsInDEV( - root$jscomp$0, - parentFiber, - isInStrictMode - ) { - if (0 !== (parentFiber.subtreeFlags & 33562624)) - for (parentFiber = parentFiber.child; null !== parentFiber; ) { - var root = root$jscomp$0, - fiber = parentFiber, - isStrictModeFiber = fiber.type === REACT_STRICT_MODE_TYPE; - isStrictModeFiber = isInStrictMode || isStrictModeFiber; - 22 !== fiber.tag - ? fiber.flags & 33554432 - ? isStrictModeFiber && - runWithFiberInDEV( - fiber, - doubleInvokeEffectsOnFiber, - root, - fiber, - 0 === (fiber.mode & 64) - ) - : recursivelyTraverseAndDoubleInvokeEffectsInDEV( - root, - fiber, - isStrictModeFiber - ) - : null === fiber.memoizedState && - (isStrictModeFiber && fiber.flags & 8192 - ? runWithFiberInDEV( - fiber, - doubleInvokeEffectsOnFiber, - root, - fiber - ) - : fiber.subtreeFlags & 33554432 && - runWithFiberInDEV( - fiber, - recursivelyTraverseAndDoubleInvokeEffectsInDEV, - root, - fiber, - isStrictModeFiber - )); - parentFiber = parentFiber.sibling; - } - } - function doubleInvokeEffectsOnFiber(root, fiber) { - var shouldDoubleInvokePassiveEffects = - 2 < arguments.length && void 0 !== arguments[2] ? arguments[2] : !0; - setIsStrictModeForDevtools(!0); - disappearLayoutEffects(fiber); - shouldDoubleInvokePassiveEffects && disconnectPassiveEffect(fiber); - reappearLayoutEffects(root, fiber.alternate, fiber, !1); - shouldDoubleInvokePassiveEffects && - reconnectPassiveEffects(root, fiber, 0, null, !1); - setIsStrictModeForDevtools(!1); - } - function commitDoubleInvokeEffectsInDEV(root, hasPassiveEffects) { - 0 !== root.tag - ? ((hasPassiveEffects = !0), - 1 !== root.tag || root.current.mode & 24 || (hasPassiveEffects = !1), - recursivelyTraverseAndDoubleInvokeEffectsInDEV( - root, - root.current, - hasPassiveEffects - )) - : runWithFiberInDEV( - root.current, - legacyCommitDoubleInvokeEffectsInDEV, - root.current, - hasPassiveEffects - ); - } - function legacyCommitDoubleInvokeEffectsInDEV(fiber, hasPassiveEffects) { - invokeEffectsInDev(fiber, 67108864, invokeLayoutEffectUnmountInDEV); - hasPassiveEffects && - invokeEffectsInDev(fiber, 134217728, invokePassiveEffectUnmountInDEV); - invokeEffectsInDev(fiber, 67108864, invokeLayoutEffectMountInDEV); - hasPassiveEffects && - invokeEffectsInDev(fiber, 134217728, invokePassiveEffectMountInDEV); - } - function invokeEffectsInDev(firstChild, fiberFlags, invokeEffectFn) { - for (var subtreeRoot = null; null != firstChild; ) { - var primarySubtreeFlag = firstChild.subtreeFlags & fiberFlags; - firstChild !== subtreeRoot && - null != firstChild.child && - 0 !== primarySubtreeFlag - ? (firstChild = firstChild.child) - : (0 !== (firstChild.flags & fiberFlags) && - invokeEffectFn(firstChild), - (firstChild = - null !== firstChild.sibling - ? firstChild.sibling - : (subtreeRoot = firstChild.return))); - } - } - function warnAboutUpdateOnNotYetMountedFiberInDEV(fiber) { - if ((executionContext & RenderContext) === NoContext && fiber.mode & 1) { - var tag = fiber.tag; + + function updateFromMap( + existingChildren, + returnFiber, + newIdx, + newChild, + lanes, + debugInfo + ) { if ( - 3 === tag || - 1 === tag || - 0 === tag || - 11 === tag || - 14 === tag || - 15 === tag + (typeof newChild === "string" && newChild !== "") || + typeof newChild === "number" || + enableBigIntSupport ) { - tag = getComponentNameFromFiber(fiber) || "ReactComponent"; - if (null !== didWarnStateUpdateForNotYetMountedComponent) { - if (didWarnStateUpdateForNotYetMountedComponent.has(tag)) return; - didWarnStateUpdateForNotYetMountedComponent.add(tag); - } else didWarnStateUpdateForNotYetMountedComponent = new Set([tag]); - runWithFiberInDEV(fiber, function () { - error$jscomp$0( - "Can't perform a React state update on a component that hasn't mounted yet. This indicates that you have a side-effect in your render function that asynchronously later calls tries to update the component. Move this work to useEffect instead." - ); - }); - } - } - } - function restorePendingUpdaters(root, lanes) { - isDevToolsPresent && - root.memoizedUpdaters.forEach(function (schedulingFiber) { - addFiberToLanesMap(root, schedulingFiber, lanes); - }); - } - function scheduleCallback(priorityLevel, callback) { - var actQueue = ReactSharedInternals.actQueue; - return null !== actQueue - ? (actQueue.push(callback), fakeActCallbackNode) - : scheduleCallback$3(priorityLevel, callback); - } - function warnIfUpdatesNotWrappedWithActDEV(fiber) { - if (fiber.mode & 1) { - if (!isConcurrentActEnvironment()) return; - } else if ( - !isLegacyActEnvironment() || - executionContext !== NoContext || - (0 !== fiber.tag && 11 !== fiber.tag && 15 !== fiber.tag) - ) - return; - null === ReactSharedInternals.actQueue && - runWithFiberInDEV(fiber, function () { - error$jscomp$0( - "An update to %s inside a test was not wrapped in act(...).\n\nWhen testing, code that causes React state updates should be wrapped into act(...):\n\nact(() => {\n /* fire events that update state */\n});\n/* assert on the output */\n\nThis ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act", - getComponentNameFromFiber(fiber) + // Text nodes don't have keys, so we neither have to check the old nor + // new node for the key. If both are text nodes, they match. + var matchedFiber = existingChildren.get(newIdx) || null; + return updateTextNode( + returnFiber, + matchedFiber, // $FlowFixMe[unsafe-addition] Flow doesn't want us to use `+` operator with string and bigint + "" + newChild, + lanes, + debugInfo ); - }); - } - function resolveFunctionForHotReloading(type) { - if (null === resolveFamily) return type; - var family = resolveFamily(type); - return void 0 === family ? type : family.current; - } - function resolveForwardRefForHotReloading(type) { - if (null === resolveFamily) return type; - var family = resolveFamily(type); - return void 0 === family - ? null !== type && - void 0 !== type && - "function" === typeof type.render && - ((family = resolveFunctionForHotReloading(type.render)), - type.render !== family) - ? ((family = { $$typeof: REACT_FORWARD_REF_TYPE, render: family }), - void 0 !== type.displayName && - (family.displayName = type.displayName), - family) - : type - : family.current; - } - function isCompatibleFamilyForHotReloading(fiber, element) { - if (null === resolveFamily) return !1; - var prevType = fiber.elementType; - element = element.type; - var needsCompareFamilies = !1, - $$typeofNextType = - "object" === typeof element && null !== element - ? element.$$typeof - : null; - switch (fiber.tag) { - case 1: - "function" === typeof element && (needsCompareFamilies = !0); - break; - case 0: - "function" === typeof element - ? (needsCompareFamilies = !0) - : $$typeofNextType === REACT_LAZY_TYPE && - (needsCompareFamilies = !0); - break; - case 11: - $$typeofNextType === REACT_FORWARD_REF_TYPE - ? (needsCompareFamilies = !0) - : $$typeofNextType === REACT_LAZY_TYPE && - (needsCompareFamilies = !0); - break; - case 14: - case 15: - $$typeofNextType === REACT_MEMO_TYPE - ? (needsCompareFamilies = !0) - : $$typeofNextType === REACT_LAZY_TYPE && - (needsCompareFamilies = !0); - break; - default: - return !1; - } - return needsCompareFamilies && - ((fiber = resolveFamily(prevType)), - void 0 !== fiber && fiber === resolveFamily(element)) - ? !0 - : !1; - } - function markFailedErrorBoundaryForHotReloading(fiber) { - null !== resolveFamily && - "function" === typeof WeakSet && - (null === failedBoundaries && (failedBoundaries = new WeakSet()), - failedBoundaries.add(fiber)); - } - function scheduleFibersWithFamiliesRecursively( - fiber, - updatedFamilies, - staleFamilies - ) { - var alternate = fiber.alternate, - child = fiber.child, - sibling = fiber.sibling, - tag = fiber.tag, - type = fiber.type, - candidateType = null; - switch (tag) { - case 0: - case 15: - case 1: - candidateType = type; - break; - case 11: - candidateType = type.render; - } - if (null === resolveFamily) - throw Error("Expected resolveFamily to be set during hot reload."); - var needsRender = !1; - type = !1; - null !== candidateType && - ((candidateType = resolveFamily(candidateType)), - void 0 !== candidateType && - (staleFamilies.has(candidateType) - ? (type = !0) - : updatedFamilies.has(candidateType) && - (1 === tag ? (type = !0) : (needsRender = !0)))); - null !== failedBoundaries && - (failedBoundaries.has(fiber) || - (null !== alternate && failedBoundaries.has(alternate))) && - (type = !0); - type && (fiber._debugNeedsRemount = !0); - if (type || needsRender) - (alternate = enqueueConcurrentRenderForLane(fiber, SyncLane)), - null !== alternate && - scheduleUpdateOnFiber(alternate, fiber, SyncLane); - null === child || - type || - scheduleFibersWithFamiliesRecursively( - child, - updatedFamilies, - staleFamilies - ); - null !== sibling && - scheduleFibersWithFamiliesRecursively( - sibling, - updatedFamilies, - staleFamilies - ); - } - function findHostInstancesForMatchingFibersRecursively( - fiber, - types, - hostInstances - ) { - var child = fiber.child, - sibling = fiber.sibling, - type = fiber.type, - candidateType = null; - switch (fiber.tag) { - case 0: - case 15: - case 1: - candidateType = type; - break; - case 11: - candidateType = type.render; - } - type = !1; - null !== candidateType && types.has(candidateType) && (type = !0); - if (type) - a: { - b: for (child = fiber, candidateType = !1; ; ) { - if (5 === child.tag || 26 === child.tag) - (candidateType = !0), hostInstances.add(child.stateNode); - else if (null !== child.child) { - child.child.return = child; - child = child.child; - continue; - } - if (child === fiber) { - child = candidateType; - break b; + } + + if (typeof newChild === "object" && newChild !== null) { + switch (newChild.$$typeof) { + case REACT_ELEMENT_TYPE: { + var _matchedFiber = + existingChildren.get( + newChild.key === null ? newIdx : newChild.key + ) || null; + + return updateElement( + returnFiber, + _matchedFiber, + newChild, + lanes, + mergeDebugInfo(debugInfo, newChild._debugInfo) + ); } - for (; null === child.sibling; ) { - if (null === child.return || child.return === fiber) { - child = candidateType; - break b; - } - child = child.return; + + case REACT_PORTAL_TYPE: { + var _matchedFiber2 = + existingChildren.get( + newChild.key === null ? newIdx : newChild.key + ) || null; + + return updatePortal( + returnFiber, + _matchedFiber2, + newChild, + lanes, + debugInfo + ); } - child.sibling.return = child.return; - child = child.sibling; + + case REACT_LAZY_TYPE: + var payload = newChild._payload; + var init = newChild._init; + return updateFromMap( + existingChildren, + returnFiber, + newIdx, + init(payload), + lanes, + mergeDebugInfo(debugInfo, newChild._debugInfo) + ); } - if (!child) - for (;;) { - switch (fiber.tag) { - case 27: - case 5: - hostInstances.add(fiber.stateNode); - break a; - case 4: - hostInstances.add(fiber.stateNode.containerInfo); - break a; - case 3: - hostInstances.add(fiber.stateNode.containerInfo); - break a; - } - if (null === fiber.return) - throw Error("Expected to reach root first."); - fiber = fiber.return; - } - } - else - null !== child && - findHostInstancesForMatchingFibersRecursively( - child, - types, - hostInstances - ); - null !== sibling && - findHostInstancesForMatchingFibersRecursively( - sibling, - types, - hostInstances - ); - } - function FiberNode(tag, pendingProps, key, mode) { - this.tag = tag; - this.key = key; - this.sibling = - this.child = - this.return = - this.stateNode = - this.type = - this.elementType = - null; - this.index = 0; - this.refCleanup = this.ref = null; - this.pendingProps = pendingProps; - this.dependencies = - this.memoizedState = - this.updateQueue = - this.memoizedProps = - null; - this.mode = mode; - this.subtreeFlags = this.flags = 0; - this.deletions = null; - this.childLanes = this.lanes = 0; - this.alternate = null; - this.actualDuration = 0; - this.actualStartTime = -1; - this.treeBaseDuration = this.selfBaseDuration = 0; - this._debugTask = - this._debugStack = - this._debugOwner = - this._debugInfo = - null; - this._debugNeedsRemount = !1; - this._debugHookTypes = null; - hasBadMapPolyfill || - "function" !== typeof Object.preventExtensions || - Object.preventExtensions(this); - } - function createFiber(tag, pendingProps, key, mode) { - return new FiberNode(tag, pendingProps, key, mode); - } - function shouldConstruct(Component) { - Component = Component.prototype; - return !(!Component || !Component.isReactComponent); - } - function createWorkInProgress(current, pendingProps) { - var workInProgress = current.alternate; - null === workInProgress - ? ((workInProgress = createFiber( - current.tag, - pendingProps, - current.key, - current.mode - )), - (workInProgress.elementType = current.elementType), - (workInProgress.type = current.type), - (workInProgress.stateNode = current.stateNode), - (workInProgress._debugOwner = current._debugOwner), - (workInProgress._debugStack = current._debugStack), - (workInProgress._debugTask = current._debugTask), - (workInProgress._debugHookTypes = current._debugHookTypes), - (workInProgress.alternate = current), - (current.alternate = workInProgress)) - : ((workInProgress.pendingProps = pendingProps), - (workInProgress.type = current.type), - (workInProgress.flags = 0), - (workInProgress.subtreeFlags = 0), - (workInProgress.deletions = null), - (workInProgress.actualDuration = 0), - (workInProgress.actualStartTime = -1)); - workInProgress.flags = current.flags & 31457280; - workInProgress.childLanes = current.childLanes; - workInProgress.lanes = current.lanes; - workInProgress.child = current.child; - workInProgress.memoizedProps = current.memoizedProps; - workInProgress.memoizedState = current.memoizedState; - workInProgress.updateQueue = current.updateQueue; - pendingProps = current.dependencies; - workInProgress.dependencies = - null === pendingProps - ? null - : { - lanes: pendingProps.lanes, - firstContext: pendingProps.firstContext - }; - workInProgress.sibling = current.sibling; - workInProgress.index = current.index; - workInProgress.ref = current.ref; - workInProgress.refCleanup = current.refCleanup; - workInProgress.selfBaseDuration = current.selfBaseDuration; - workInProgress.treeBaseDuration = current.treeBaseDuration; - workInProgress._debugInfo = current._debugInfo; - workInProgress._debugNeedsRemount = current._debugNeedsRemount; - switch (workInProgress.tag) { - case 0: - case 15: - workInProgress.type = resolveFunctionForHotReloading(current.type); - break; - case 1: - workInProgress.type = resolveFunctionForHotReloading(current.type); - break; - case 11: - workInProgress.type = resolveForwardRefForHotReloading(current.type); - } - return workInProgress; - } - function resetWorkInProgress(workInProgress, renderLanes) { - workInProgress.flags &= 31457282; - var current = workInProgress.alternate; - null === current - ? ((workInProgress.childLanes = 0), - (workInProgress.lanes = renderLanes), - (workInProgress.child = null), - (workInProgress.subtreeFlags = 0), - (workInProgress.memoizedProps = null), - (workInProgress.memoizedState = null), - (workInProgress.updateQueue = null), - (workInProgress.dependencies = null), - (workInProgress.stateNode = null), - (workInProgress.selfBaseDuration = 0), - (workInProgress.treeBaseDuration = 0)) - : ((workInProgress.childLanes = current.childLanes), - (workInProgress.lanes = current.lanes), - (workInProgress.child = current.child), - (workInProgress.subtreeFlags = 0), - (workInProgress.deletions = null), - (workInProgress.memoizedProps = current.memoizedProps), - (workInProgress.memoizedState = current.memoizedState), - (workInProgress.updateQueue = current.updateQueue), - (workInProgress.type = current.type), - (renderLanes = current.dependencies), - (workInProgress.dependencies = - null === renderLanes - ? null - : { - lanes: renderLanes.lanes, - firstContext: renderLanes.firstContext - }), - (workInProgress.selfBaseDuration = current.selfBaseDuration), - (workInProgress.treeBaseDuration = current.treeBaseDuration)); - return workInProgress; - } - function createFiberFromTypeAndProps( - type, - key, - pendingProps, - owner, - mode, - lanes - ) { - var fiberTag = 0, - resolvedType = type; - if ("function" === typeof type) - shouldConstruct(type) && (fiberTag = 1), - (resolvedType = resolveFunctionForHotReloading(resolvedType)); - else if ("string" === typeof type) fiberTag = 5; - else - a: switch (type) { - case REACT_FRAGMENT_TYPE: - return createFiberFromFragment( - pendingProps.children, - mode, + + if (isArray(newChild) || getIteratorFn(newChild)) { + var _matchedFiber3 = existingChildren.get(newIdx) || null; + + return updateFragment( + returnFiber, + _matchedFiber3, + newChild, lanes, - key - ); - case REACT_STRICT_MODE_TYPE: - fiberTag = 8; - mode |= 8; - 0 !== (mode & 1) && (mode |= 16); - break; - case REACT_PROFILER_TYPE: - return ( - (owner = mode), - "string" !== typeof pendingProps.id && - error$jscomp$0( - 'Profiler must specify an "id" of type `string` as a prop. Received the type `%s` instead.', - typeof pendingProps.id - ), - (owner = createFiber(12, pendingProps, key, owner | 2)), - (owner.elementType = REACT_PROFILER_TYPE), - (owner.lanes = lanes), - (owner.stateNode = { - effectDuration: 0, - passiveEffectDuration: 0 - }), - owner - ); - case REACT_SUSPENSE_TYPE: - return ( - (owner = createFiber(13, pendingProps, key, mode)), - (owner.elementType = REACT_SUSPENSE_TYPE), - (owner.lanes = lanes), - owner - ); - case REACT_SUSPENSE_LIST_TYPE: - return ( - (owner = createFiber(19, pendingProps, key, mode)), - (owner.elementType = REACT_SUSPENSE_LIST_TYPE), - (owner.lanes = lanes), - owner - ); - case REACT_OFFSCREEN_TYPE: - return createFiberFromOffscreen(pendingProps, mode, lanes, key); - default: - if ("object" === typeof type && null !== type) - switch (type.$$typeof) { - case REACT_PROVIDER_TYPE: - case REACT_CONTEXT_TYPE: - fiberTag = 10; - break a; - case REACT_CONSUMER_TYPE: - fiberTag = 9; - break a; - case REACT_FORWARD_REF_TYPE: - fiberTag = 11; - resolvedType = resolveForwardRefForHotReloading(resolvedType); - break a; - case REACT_MEMO_TYPE: - fiberTag = 14; - break a; - case REACT_LAZY_TYPE: - fiberTag = 16; - resolvedType = null; - break a; - } - lanes = ""; - if ( - void 0 === type || - ("object" === typeof type && - null !== type && - 0 === Object.keys(type).length) - ) - lanes += - " You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports."; - null === type - ? (type = "null") - : isArrayImpl(type) - ? (type = "array") - : void 0 !== type && type.$$typeof === REACT_ELEMENT_TYPE - ? ((type = - "<" + - (getComponentNameFromType(type.type) || "Unknown") + - " />"), - (lanes = - " Did you accidentally export a JSX literal instead of a component?")) - : (type = typeof type); - owner = owner - ? "number" === typeof owner.tag - ? getComponentNameFromFiber(owner) - : "string" === typeof owner.name - ? owner.name - : null - : null; - owner && - (lanes += "\n\nCheck the render method of `" + owner + "`."); - throw Error( - "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + - (type + "." + lanes) + null, + mergeDebugInfo(debugInfo, newChild._debugInfo) ); - } - key = createFiber(fiberTag, pendingProps, key, mode); - key.elementType = type; - key.type = resolvedType; - key.lanes = lanes; - key._debugOwner = owner; - return key; - } - function createFiberFromElement(element, mode, lanes) { - mode = createFiberFromTypeAndProps( - element.type, - element.key, - element.props, - element._owner, - mode, - lanes - ); - mode._debugOwner = element._owner; - mode._debugStack = element._debugStack; - mode._debugTask = element._debugTask; - return mode; - } - function createFiberFromFragment(elements, mode, lanes, key) { - elements = createFiber(7, elements, key, mode); - elements.lanes = lanes; - return elements; - } - function createFiberFromOffscreen(pendingProps, mode, lanes, key) { - pendingProps = createFiber(22, pendingProps, key, mode); - pendingProps.elementType = REACT_OFFSCREEN_TYPE; - pendingProps.lanes = lanes; - var primaryChildInstance = { - _visibility: 1, - _pendingVisibility: 1, - _pendingMarkers: null, - _retryCache: null, - _transitions: null, - _current: null, - detach: function () { - var instance = primaryChildInstance, - fiber = instance._current; - if (null === fiber) - throw Error( - "Calling Offscreen.detach before instance handle has been set." + } // Usable node types + // + // Unwrap the inner value and recursively call this function again. + + if (typeof newChild.then === "function") { + var thenable = newChild; + return updateFromMap( + existingChildren, + returnFiber, + newIdx, + unwrapThenable(thenable), + lanes, + debugInfo ); - if (0 === (instance._pendingVisibility & 2)) { - var root = enqueueConcurrentRenderForLane(fiber, SyncLane); - null !== root && - ((instance._pendingVisibility |= 2), - scheduleUpdateOnFiber(root, fiber, SyncLane)); } - }, - attach: function () { - var instance = primaryChildInstance, - fiber = instance._current; - if (null === fiber) - throw Error( - "Calling Offscreen.detach before instance handle has been set." + + if (newChild.$$typeof === REACT_CONTEXT_TYPE) { + var context = newChild; + return updateFromMap( + existingChildren, + returnFiber, + newIdx, + readContextDuringReconciliation(returnFiber, context, lanes), + lanes, + debugInfo ); - if (0 !== (instance._pendingVisibility & 2)) { - var root = enqueueConcurrentRenderForLane(fiber, SyncLane); - null !== root && - ((instance._pendingVisibility &= -3), - scheduleUpdateOnFiber(root, fiber, SyncLane)); } + + throwOnInvalidObjectType(returnFiber, newChild); } + + { + if (typeof newChild === "function") { + warnOnFunctionType(returnFiber, newChild); + } + + if (typeof newChild === "symbol") { + warnOnSymbolType(returnFiber, newChild); + } + } + + return null; + } + /** + * Warns if there is a duplicate or missing key + */ + + function warnOnInvalidKey(child, knownKeys, returnFiber) { + { + if (typeof child !== "object" || child === null) { + return knownKeys; + } + + switch (child.$$typeof) { + case REACT_ELEMENT_TYPE: + case REACT_PORTAL_TYPE: + warnForMissingKey(child, returnFiber); + var key = child.key; + + if (typeof key !== "string") { + break; + } + + if (knownKeys === null) { + knownKeys = new Set(); + knownKeys.add(key); + break; + } + + if (!knownKeys.has(key)) { + knownKeys.add(key); + break; + } + + error( + "Encountered two children with the same key, `%s`. " + + "Keys should be unique so that components maintain their identity " + + "across updates. Non-unique keys may cause children to be " + + "duplicated and/or omitted — the behavior is unsupported and " + + "could change in a future version.", + key + ); + + break; + + case REACT_LAZY_TYPE: + var payload = child._payload; + var init = child._init; + warnOnInvalidKey(init(payload), knownKeys, returnFiber); + break; + } + } + + return knownKeys; + } + + function reconcileChildrenArray( + returnFiber, + currentFirstChild, + newChildren, + lanes, + debugInfo + ) { + // This algorithm can't optimize by searching from both ends since we + // don't have backpointers on fibers. I'm trying to see how far we can get + // with that model. If it ends up not being worth the tradeoffs, we can + // add it later. + // Even with a two ended optimization, we'd want to optimize for the case + // where there are few changes and brute force the comparison instead of + // going for the Map. It'd like to explore hitting that path first in + // forward-only mode and only go for the Map once we notice that we need + // lots of look ahead. This doesn't handle reversal as well as two ended + // search but that's unusual. Besides, for the two ended optimization to + // work on Iterables, we'd need to copy the whole set. + // In this first iteration, we'll just live with hitting the bad case + // (adding everything to a Map) in for every insert/move. + // If you change this code, also update reconcileChildrenIterator() which + // uses the same algorithm. + { + // First, validate keys. + var knownKeys = null; + + for (var i = 0; i < newChildren.length; i++) { + var child = newChildren[i]; + knownKeys = warnOnInvalidKey(child, knownKeys, returnFiber); + } + } + + var resultingFirstChild = null; + var previousNewFiber = null; + var oldFiber = currentFirstChild; + var lastPlacedIndex = 0; + var newIdx = 0; + var nextOldFiber = null; + + for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) { + if (oldFiber.index > newIdx) { + nextOldFiber = oldFiber; + oldFiber = null; + } else { + nextOldFiber = oldFiber.sibling; + } + + var newFiber = updateSlot( + returnFiber, + oldFiber, + newChildren[newIdx], + lanes, + debugInfo + ); + + if (newFiber === null) { + // TODO: This breaks on empty slots like null children. That's + // unfortunate because it triggers the slow path all the time. We need + // a better way to communicate whether this was a miss or null, + // boolean, undefined, etc. + if (oldFiber === null) { + oldFiber = nextOldFiber; + } + + break; + } + + if (shouldTrackSideEffects) { + if (oldFiber && newFiber.alternate === null) { + // We matched the slot, but we didn't reuse the existing fiber, so we + // need to delete the existing child. + deleteChild(returnFiber, oldFiber); + } + } + + lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx); + + if (previousNewFiber === null) { + // TODO: Move out of the loop. This only happens for the first run. + resultingFirstChild = newFiber; + } else { + // TODO: Defer siblings if we're not at the right index for this slot. + // I.e. if we had null values before, then we want to defer this + // for each null value. However, we also don't want to call updateSlot + // with the previous one. + previousNewFiber.sibling = newFiber; + } + + previousNewFiber = newFiber; + oldFiber = nextOldFiber; + } + + if (newIdx === newChildren.length) { + // We've reached the end of the new children. We can delete the rest. + deleteRemainingChildren(returnFiber, oldFiber); + + return resultingFirstChild; + } + + if (oldFiber === null) { + // If we don't have any more existing children we can choose a fast path + // since the rest will all be insertions. + for (; newIdx < newChildren.length; newIdx++) { + var _newFiber = createChild( + returnFiber, + newChildren[newIdx], + lanes, + debugInfo + ); + + if (_newFiber === null) { + continue; + } + + lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx); + + if (previousNewFiber === null) { + // TODO: Move out of the loop. This only happens for the first run. + resultingFirstChild = _newFiber; + } else { + previousNewFiber.sibling = _newFiber; + } + + previousNewFiber = _newFiber; + } + + return resultingFirstChild; + } // Add all children to a key map for quick lookups. + + var existingChildren = mapRemainingChildren(oldFiber); // Keep scanning and use the map to restore deleted items as moves. + + for (; newIdx < newChildren.length; newIdx++) { + var _newFiber2 = updateFromMap( + existingChildren, + returnFiber, + newIdx, + newChildren[newIdx], + lanes, + debugInfo + ); + + if (_newFiber2 !== null) { + if (shouldTrackSideEffects) { + if (_newFiber2.alternate !== null) { + // The new fiber is a work in progress, but if there exists a + // current, that means that we reused the fiber. We need to delete + // it from the child list so that we don't add it to the deletion + // list. + existingChildren.delete( + _newFiber2.key === null ? newIdx : _newFiber2.key + ); + } + } + + lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx); + + if (previousNewFiber === null) { + resultingFirstChild = _newFiber2; + } else { + previousNewFiber.sibling = _newFiber2; + } + + previousNewFiber = _newFiber2; + } + } + + if (shouldTrackSideEffects) { + // Any existing children that weren't consumed above were deleted. We need + // to add them to the deletion list. + existingChildren.forEach(function (child) { + return deleteChild(returnFiber, child); + }); + } + + return resultingFirstChild; + } + + function reconcileChildrenIterator( + returnFiber, + currentFirstChild, + newChildrenIterable, + lanes, + debugInfo + ) { + // This is the same implementation as reconcileChildrenArray(), + // but using the iterator instead. + var iteratorFn = getIteratorFn(newChildrenIterable); + + if (typeof iteratorFn !== "function") { + throw new Error( + "An object is not an iterable. This error is likely caused by a bug in " + + "React. Please file an issue." + ); + } + + { + // We don't support rendering Generators because it's a mutation. + // See https://github.com/facebook/react/issues/12995 + if ( + typeof Symbol === "function" && // $FlowFixMe[prop-missing] Flow doesn't know about toStringTag + newChildrenIterable[Symbol.toStringTag] === "Generator" + ) { + if (!didWarnAboutGenerators) { + error( + "Using Generators as children is unsupported and will likely yield " + + "unexpected results because enumerating a generator mutates it. " + + "You may convert it to an array with `Array.from()` or the " + + "`[...spread]` operator before rendering. Keep in mind " + + "you might need to polyfill these features for older browsers." + ); + } + + didWarnAboutGenerators = true; + } // Warn about using Maps as children + + if (newChildrenIterable.entries === iteratorFn) { + if (!didWarnAboutMaps) { + error( + "Using Maps as children is not supported. " + + "Use an array of keyed ReactElements instead." + ); + } + + didWarnAboutMaps = true; + } // First, validate keys. + // We'll get a different iterator later for the main pass. + + var _newChildren = iteratorFn.call(newChildrenIterable); + + if (_newChildren) { + var knownKeys = null; + + var _step = _newChildren.next(); + + for (; !_step.done; _step = _newChildren.next()) { + var child = _step.value; + knownKeys = warnOnInvalidKey(child, knownKeys, returnFiber); + } + } + } + + var newChildren = iteratorFn.call(newChildrenIterable); + + if (newChildren == null) { + throw new Error("An iterable object provided no iterator."); + } + + var resultingFirstChild = null; + var previousNewFiber = null; + var oldFiber = currentFirstChild; + var lastPlacedIndex = 0; + var newIdx = 0; + var nextOldFiber = null; + var step = newChildren.next(); + + for ( + ; + oldFiber !== null && !step.done; + newIdx++, step = newChildren.next() + ) { + if (oldFiber.index > newIdx) { + nextOldFiber = oldFiber; + oldFiber = null; + } else { + nextOldFiber = oldFiber.sibling; + } + + var newFiber = updateSlot( + returnFiber, + oldFiber, + step.value, + lanes, + debugInfo + ); + + if (newFiber === null) { + // TODO: This breaks on empty slots like null children. That's + // unfortunate because it triggers the slow path all the time. We need + // a better way to communicate whether this was a miss or null, + // boolean, undefined, etc. + if (oldFiber === null) { + oldFiber = nextOldFiber; + } + + break; + } + + if (shouldTrackSideEffects) { + if (oldFiber && newFiber.alternate === null) { + // We matched the slot, but we didn't reuse the existing fiber, so we + // need to delete the existing child. + deleteChild(returnFiber, oldFiber); + } + } + + lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx); + + if (previousNewFiber === null) { + // TODO: Move out of the loop. This only happens for the first run. + resultingFirstChild = newFiber; + } else { + // TODO: Defer siblings if we're not at the right index for this slot. + // I.e. if we had null values before, then we want to defer this + // for each null value. However, we also don't want to call updateSlot + // with the previous one. + previousNewFiber.sibling = newFiber; + } + + previousNewFiber = newFiber; + oldFiber = nextOldFiber; + } + + if (step.done) { + // We've reached the end of the new children. We can delete the rest. + deleteRemainingChildren(returnFiber, oldFiber); + + return resultingFirstChild; + } + + if (oldFiber === null) { + // If we don't have any more existing children we can choose a fast path + // since the rest will all be insertions. + for (; !step.done; newIdx++, step = newChildren.next()) { + var _newFiber3 = createChild( + returnFiber, + step.value, + lanes, + debugInfo + ); + + if (_newFiber3 === null) { + continue; + } + + lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx); + + if (previousNewFiber === null) { + // TODO: Move out of the loop. This only happens for the first run. + resultingFirstChild = _newFiber3; + } else { + previousNewFiber.sibling = _newFiber3; + } + + previousNewFiber = _newFiber3; + } + + return resultingFirstChild; + } // Add all children to a key map for quick lookups. + + var existingChildren = mapRemainingChildren(oldFiber); // Keep scanning and use the map to restore deleted items as moves. + + for (; !step.done; newIdx++, step = newChildren.next()) { + var _newFiber4 = updateFromMap( + existingChildren, + returnFiber, + newIdx, + step.value, + lanes, + debugInfo + ); + + if (_newFiber4 !== null) { + if (shouldTrackSideEffects) { + if (_newFiber4.alternate !== null) { + // The new fiber is a work in progress, but if there exists a + // current, that means that we reused the fiber. We need to delete + // it from the child list so that we don't add it to the deletion + // list. + existingChildren.delete( + _newFiber4.key === null ? newIdx : _newFiber4.key + ); + } + } + + lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx); + + if (previousNewFiber === null) { + resultingFirstChild = _newFiber4; + } else { + previousNewFiber.sibling = _newFiber4; + } + + previousNewFiber = _newFiber4; + } + } + + if (shouldTrackSideEffects) { + // Any existing children that weren't consumed above were deleted. We need + // to add them to the deletion list. + existingChildren.forEach(function (child) { + return deleteChild(returnFiber, child); + }); + } + + return resultingFirstChild; + } + + function reconcileSingleTextNode( + returnFiber, + currentFirstChild, + textContent, + lanes + ) { + // There's no need to check for keys on text nodes since we don't have a + // way to define them. + if (currentFirstChild !== null && currentFirstChild.tag === HostText) { + // We already have an existing node so let's just update it and delete + // the rest. + deleteRemainingChildren(returnFiber, currentFirstChild.sibling); + var existing = useFiber(currentFirstChild, textContent); + existing.return = returnFiber; + return existing; + } // The existing first child is not a text node so we need to create one + // and delete the existing ones. + + deleteRemainingChildren(returnFiber, currentFirstChild); + var created = createFiberFromText(textContent, returnFiber.mode, lanes); + created.return = returnFiber; + return created; + } + + function reconcileSingleElement( + returnFiber, + currentFirstChild, + element, + lanes, + debugInfo + ) { + var key = element.key; + var child = currentFirstChild; + + while (child !== null) { + // TODO: If key === null and child.key === null, then this only applies to + // the first item in the list. + if (child.key === key) { + var elementType = element.type; + + if (elementType === REACT_FRAGMENT_TYPE) { + if (child.tag === Fragment) { + deleteRemainingChildren(returnFiber, child.sibling); + var existing = useFiber(child, element.props.children); + existing.return = returnFiber; + + { + existing._debugOwner = element._owner; + existing._debugInfo = debugInfo; + } + + 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. + (typeof elementType === "object" && + elementType !== null && + elementType.$$typeof === REACT_LAZY_TYPE && + resolveLazy(elementType) === child.type) + ) { + deleteRemainingChildren(returnFiber, child.sibling); + + var _existing = useFiber(child, element.props); + + coerceRef(returnFiber, child, _existing, element); + _existing.return = returnFiber; + + { + _existing._debugOwner = element._owner; + _existing._debugInfo = debugInfo; + } + + return _existing; + } + } // Didn't match. + + deleteRemainingChildren(returnFiber, child); + break; + } else { + deleteChild(returnFiber, child); + } + + child = child.sibling; + } + + if (element.type === REACT_FRAGMENT_TYPE) { + var created = createFiberFromFragment( + element.props.children, + returnFiber.mode, + lanes, + element.key + ); + created.return = returnFiber; + + { + created._debugInfo = debugInfo; + } + + return created; + } else { + var _created4 = createFiberFromElement( + element, + returnFiber.mode, + lanes + ); + + coerceRef(returnFiber, currentFirstChild, _created4, element); + _created4.return = returnFiber; + + { + _created4._debugInfo = debugInfo; + } + + return _created4; + } + } + + function reconcileSinglePortal( + returnFiber, + currentFirstChild, + portal, + lanes, + debugInfo + ) { + var key = portal.key; + var child = currentFirstChild; + + while (child !== null) { + // TODO: If key === null and child.key === null, then this only applies to + // the first item in the list. + if (child.key === key) { + if ( + child.tag === HostPortal && + child.stateNode.containerInfo === portal.containerInfo && + child.stateNode.implementation === portal.implementation + ) { + deleteRemainingChildren(returnFiber, child.sibling); + var existing = useFiber(child, portal.children || []); + existing.return = returnFiber; + return existing; + } else { + deleteRemainingChildren(returnFiber, child); + break; + } + } else { + deleteChild(returnFiber, child); + } + + child = child.sibling; + } + + var created = createFiberFromPortal(portal, returnFiber.mode, lanes); + created.return = returnFiber; + return created; + } // This API will tag the children with the side-effect of the reconciliation + // itself. They will be added to the side-effect list as we pass through the + // children and the parent. + + function reconcileChildFibersImpl( + returnFiber, + currentFirstChild, + newChild, + lanes, + debugInfo + ) { + // This function is not recursive. + // If the top level item is an array, we treat it as a set of children, + // not as a fragment. Nested arrays on the other hand will be treated as + // fragment nodes. Recursion happens at the normal flow. + // Handle top level unkeyed fragments as if they were arrays. + // This leads to an ambiguity between <>{[...]} and <>.... + // We treat the ambiguous cases above the same. + // TODO: Let's use recursion like we do for Usable nodes? + var isUnkeyedTopLevelFragment = + typeof newChild === "object" && + newChild !== null && + newChild.type === REACT_FRAGMENT_TYPE && + newChild.key === null; + + if (isUnkeyedTopLevelFragment) { + newChild = newChild.props.children; + } // Handle object types + + if (typeof newChild === "object" && newChild !== null) { + switch (newChild.$$typeof) { + case REACT_ELEMENT_TYPE: + return placeSingleChild( + reconcileSingleElement( + returnFiber, + currentFirstChild, + newChild, + lanes, + mergeDebugInfo(debugInfo, newChild._debugInfo) + ) + ); + + case REACT_PORTAL_TYPE: + return placeSingleChild( + reconcileSinglePortal( + returnFiber, + currentFirstChild, + newChild, + lanes + ) + ); + + case REACT_LAZY_TYPE: + var payload = newChild._payload; + var init = newChild._init; + return reconcileChildFibersImpl( + returnFiber, + currentFirstChild, + init(payload), + lanes, + mergeDebugInfo(debugInfo, newChild._debugInfo) + ); + } + + if (isArray(newChild)) { + return reconcileChildrenArray( + returnFiber, + currentFirstChild, + newChild, + lanes, + mergeDebugInfo(debugInfo, newChild._debugInfo) + ); + } + + if (getIteratorFn(newChild)) { + return reconcileChildrenIterator( + returnFiber, + currentFirstChild, + newChild, + lanes, + mergeDebugInfo(debugInfo, newChild._debugInfo) + ); + } // Usables are a valid React node type. When React encounters a Usable in + // a child position, it unwraps it using the same algorithm as `use`. For + // example, for promises, React will throw an exception to unwind the + // stack, then replay the component once the promise resolves. + // + // A difference from `use` is that React will keep unwrapping the value + // until it reaches a non-Usable type. + // + // e.g. Usable>> should resolve to T + // + // The structure is a bit unfortunate. Ideally, we shouldn't need to + // replay the entire begin phase of the parent fiber in order to reconcile + // the children again. This would require a somewhat significant refactor, + // because reconcilation happens deep within the begin phase, and + // depending on the type of work, not always at the end. We should + // consider as an future improvement. + + if (typeof newChild.then === "function") { + var thenable = newChild; + return reconcileChildFibersImpl( + returnFiber, + currentFirstChild, + unwrapThenable(thenable), + lanes, + mergeDebugInfo(debugInfo, thenable._debugInfo) + ); + } + + if (newChild.$$typeof === REACT_CONTEXT_TYPE) { + var context = newChild; + return reconcileChildFibersImpl( + returnFiber, + currentFirstChild, + readContextDuringReconciliation(returnFiber, context, lanes), + lanes, + debugInfo + ); + } + + throwOnInvalidObjectType(returnFiber, newChild); + } + + if ( + (typeof newChild === "string" && newChild !== "") || + typeof newChild === "number" || + enableBigIntSupport + ) { + return placeSingleChild( + reconcileSingleTextNode( + returnFiber, + currentFirstChild, // $FlowFixMe[unsafe-addition] Flow doesn't want us to use `+` operator with string and bigint + "" + newChild, + lanes + ) + ); + } + + { + if (typeof newChild === "function") { + warnOnFunctionType(returnFiber, newChild); + } + + if (typeof newChild === "symbol") { + warnOnSymbolType(returnFiber, newChild); + } + } // Remaining cases are all treated as empty. + + return deleteRemainingChildren(returnFiber, currentFirstChild); + } + + function reconcileChildFibers( + returnFiber, + currentFirstChild, + newChild, + lanes + ) { + // This indirection only exists so we can reset `thenableState` at the end. + // It should get inlined by Closure. + thenableIndexCounter$1 = 0; + var firstChildFiber = reconcileChildFibersImpl( + returnFiber, + currentFirstChild, + newChild, + lanes, + null // debugInfo + ); + thenableState$1 = null; // Don't bother to reset `thenableIndexCounter` to 0 because it always gets + // set at the beginning. + + return firstChildFiber; + } + + return reconcileChildFibers; + } + + var reconcileChildFibers = createChildReconciler(true); + var mountChildFibers = createChildReconciler(false); + function resetChildReconcilerOnUnwind() { + // On unwind, clear any pending thenables that were used. + thenableState$1 = null; + thenableIndexCounter$1 = 0; + } + function cloneChildFibers(current, workInProgress) { + if (current !== null && workInProgress.child !== current.child) { + throw new Error("Resuming work not yet implemented."); + } + + if (workInProgress.child === null) { + return; + } + + var currentChild = workInProgress.child; + var newChild = createWorkInProgress( + currentChild, + currentChild.pendingProps + ); + workInProgress.child = newChild; + newChild.return = workInProgress; + + while (currentChild.sibling !== null) { + currentChild = currentChild.sibling; + newChild = newChild.sibling = createWorkInProgress( + currentChild, + currentChild.pendingProps + ); + newChild.return = workInProgress; + } + + newChild.sibling = null; + } // Reset a workInProgress child set to prepare it for a second pass. + + function resetChildFibers(workInProgress, lanes) { + var child = workInProgress.child; + + while (child !== null) { + resetWorkInProgress(child, lanes); + child = child.sibling; + } + } + + // TODO: This isn't being used yet, but it's intended to replace the + // InvisibleParentContext that is currently managed by SuspenseContext. + + var currentTreeHiddenStackCursor = createCursor(null); + var prevEntangledRenderLanesCursor = createCursor(NoLanes); + function pushHiddenContext(fiber, context) { + var prevEntangledRenderLanes = getEntangledRenderLanes(); + push(prevEntangledRenderLanesCursor, prevEntangledRenderLanes, fiber); + push(currentTreeHiddenStackCursor, context, fiber); // When rendering a subtree that's currently hidden, we must include all + // lanes that would have rendered if the hidden subtree hadn't been deferred. + // That is, in order to reveal content from hidden -> visible, we must commit + // all the updates that we skipped when we originally hid the tree. + + setEntangledRenderLanes( + mergeLanes(prevEntangledRenderLanes, context.baseLanes) + ); + } + function reuseHiddenContextOnStack(fiber) { + // This subtree is not currently hidden, so we don't need to add any lanes + // to the render lanes. But we still need to push something to avoid a + // context mismatch. Reuse the existing context on the stack. + push(prevEntangledRenderLanesCursor, getEntangledRenderLanes(), fiber); + push( + currentTreeHiddenStackCursor, + currentTreeHiddenStackCursor.current, + fiber + ); + } + function popHiddenContext(fiber) { + // Restore the previous render lanes from the stack + setEntangledRenderLanes(prevEntangledRenderLanesCursor.current); + pop(currentTreeHiddenStackCursor, fiber); + pop(prevEntangledRenderLanesCursor, fiber); + } + function isCurrentTreeHidden() { + return currentTreeHiddenStackCursor.current !== null; + } + + // suspends, i.e. it's the nearest `catch` block on the stack. + + var suspenseHandlerStackCursor = createCursor(null); // Represents the outermost boundary that is not visible in the current tree. + // Everything above this is the "shell". When this is null, it means we're + // rendering in the shell of the app. If it's non-null, it means we're rendering + // deeper than the shell, inside a new tree that wasn't already visible. + // + // The main way we use this concept is to determine whether showing a fallback + // would result in a desirable or undesirable loading state. Activing a fallback + // in the shell is considered an undersirable loading state, because it would + // mean hiding visible (albeit stale) content in the current tree — we prefer to + // show the stale content, rather than switch to a fallback. But showing a + // fallback in a new tree is fine, because there's no stale content to + // prefer instead. + + var shellBoundary = null; + function getShellBoundary() { + return shellBoundary; + } + function pushPrimaryTreeSuspenseHandler(handler) { + // TODO: Pass as argument + var current = handler.alternate; + // propagated a single level. For example, when ForceSuspenseFallback is set, + // it should only force the nearest Suspense boundary into fallback mode. + + pushSuspenseListContext( + handler, + setDefaultShallowSuspenseListContext(suspenseStackCursor.current) + ); // Experimental feature: Some Suspense boundaries are marked as having an + // to push a nested Suspense handler, because it will get replaced by the + // outer fallback, anyway. Consider this as a future optimization. + + push(suspenseHandlerStackCursor, handler, handler); + + if (shellBoundary === null) { + if (current === null || isCurrentTreeHidden()) { + // This boundary is not visible in the current UI. + shellBoundary = handler; + } else { + var prevState = current.memoizedState; + + if (prevState !== null) { + // This boundary is showing a fallback in the current UI. + shellBoundary = handler; + } + } + } + } + function pushFallbackTreeSuspenseHandler(fiber) { + // We're about to render the fallback. If something in the fallback suspends, + // it's akin to throwing inside of a `catch` block. This boundary should not + // capture. Reuse the existing handler on the stack. + reuseSuspenseHandlerOnStack(fiber); + } + function pushOffscreenSuspenseHandler(fiber) { + if (fiber.tag === OffscreenComponent) { + // A SuspenseList context is only pushed here to avoid a push/pop mismatch. + // Reuse the current value on the stack. + // TODO: We can avoid needing to push here by by forking popSuspenseHandler + // into separate functions for Suspense and Offscreen. + pushSuspenseListContext(fiber, suspenseStackCursor.current); + push(suspenseHandlerStackCursor, fiber, fiber); + + if (shellBoundary !== null); + else { + var current = fiber.alternate; + + if (current !== null) { + var prevState = current.memoizedState; + + if (prevState !== null) { + // This is the first boundary in the stack that's already showing + // a fallback. So everything outside is considered the shell. + shellBoundary = fiber; + } + } + } + } else { + // This is a LegacyHidden component. + reuseSuspenseHandlerOnStack(fiber); + } + } + function reuseSuspenseHandlerOnStack(fiber) { + pushSuspenseListContext(fiber, suspenseStackCursor.current); + push(suspenseHandlerStackCursor, getSuspenseHandler(), fiber); + } + function getSuspenseHandler() { + return suspenseHandlerStackCursor.current; + } + function popSuspenseHandler(fiber) { + pop(suspenseHandlerStackCursor, fiber); + + if (shellBoundary === fiber) { + // Popping back into the shell. + shellBoundary = null; + } + + popSuspenseListContext(fiber); + } // SuspenseList context + // TODO: Move to a separate module? We may change the SuspenseList + // implementation to hide/show in the commit phase, anyway. + + var DefaultSuspenseContext = 0; + var SubtreeSuspenseContextMask = 1; // ForceSuspenseFallback can be used by SuspenseList to force newly added + // items into their fallback state during one of the render passes. + + var ForceSuspenseFallback = 2; + var suspenseStackCursor = createCursor(DefaultSuspenseContext); + function hasSuspenseListContext(parentContext, flag) { + return (parentContext & flag) !== 0; + } + function setDefaultShallowSuspenseListContext(parentContext) { + return parentContext & SubtreeSuspenseContextMask; + } + function setShallowSuspenseListContext(parentContext, shallowContext) { + return (parentContext & SubtreeSuspenseContextMask) | shallowContext; + } + function pushSuspenseListContext(fiber, newContext) { + push(suspenseStackCursor, newContext, fiber); + } + function popSuspenseListContext(fiber) { + pop(suspenseStackCursor, fiber); + } + + // A non-null SuspenseState means that it is blocked for one reason or another. + // - A non-null dehydrated field means it's blocked pending hydration. + // - A non-null dehydrated field can use isSuspenseInstancePending or + // isSuspenseInstanceFallback to query the reason for being dehydrated. + // - A null dehydrated field means it's blocked by something suspending and + // we're currently showing a fallback instead. + + function findFirstSuspended(row) { + var node = row; + + while (node !== null) { + if (node.tag === SuspenseComponent) { + var state = node.memoizedState; + + if (state !== null) { + var dehydrated = state.dehydrated; + + if ( + dehydrated === null || + isSuspenseInstancePending() || + isSuspenseInstanceFallback() + ) { + return node; + } + } + } else if ( + node.tag === SuspenseListComponent && // revealOrder undefined can't be trusted because it don't + // keep track of whether it suspended or not. + node.memoizedProps.revealOrder !== undefined + ) { + var didSuspend = (node.flags & DidCapture) !== NoFlags$1; + + if (didSuspend) { + return node; + } + } else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; + } + + if (node === row) { + return null; + } + + while (node.sibling === null) { + if (node.return === null || node.return === row) { + return null; + } + + node = node.return; + } + + node.sibling.return = node.return; + node = node.sibling; + } + + return null; + } + + var NoFlags = + /* */ + 0; // Represents whether effect should fire. + + var HasEffect = + /* */ + 1; // Represents the phase in which the effect (not the clean-up) fires. + + var Insertion = + /* */ + 2; + var Layout = + /* */ + 4; + var Passive = + /* */ + 8; + + var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, + ReactCurrentBatchConfig$2 = ReactSharedInternals.ReactCurrentBatchConfig; + var didWarnAboutMismatchedHooksForComponent; + var didWarnUncachedGetSnapshot; + var didWarnAboutUseWrappedInTryCatch; + var didWarnAboutAsyncClientComponent; + + { + didWarnAboutMismatchedHooksForComponent = new Set(); + didWarnAboutUseWrappedInTryCatch = new Set(); + didWarnAboutAsyncClientComponent = new Set(); + } // The effect "instance" is a shared object that remains the same for the entire + // lifetime of an effect. In Rust terms, a RefCell. We use it to store the + // "destroy" function that is returned from an effect, because that is stateful. + // The field is `undefined` if the effect is unmounted, or if the effect ran + // but is not stateful. We don't explicitly track whether the effect is mounted + // or unmounted because that can be inferred by the hiddenness of the fiber in + // the tree, i.e. whether there is a hidden Offscreen fiber above it. + // + // It's unfortunate that this is stored on a separate object, because it adds + // more memory per effect instance, but it's conceptually sound. I think there's + // likely a better data structure we could use for effects; perhaps just one + // array of effect instances per fiber. But I think this is OK for now despite + // the additional memory and we can follow up with performance + // optimizations later. + // These are set right before calling the component. + + var renderLanes = NoLanes; // The work-in-progress fiber. I've named it differently to distinguish it from + // the work-in-progress hook. + + var currentlyRenderingFiber$1 = null; // Hooks are stored as a linked list on the fiber's memoizedState field. The + // current hook list is the list that belongs to the current fiber. The + // work-in-progress hook list is a new list that will be added to the + // work-in-progress fiber. + + var currentHook = null; + var workInProgressHook = null; // Whether an update was scheduled at any point during the render phase. This + // does not get reset if we do another render pass; only when we're completely + // finished evaluating this component. This is an optimization so we know + // whether we need to clear render phase updates after a throw. + + var didScheduleRenderPhaseUpdate = false; // Where an update was scheduled only during the current render pass. This + // gets reset after each attempt. + // TODO: Maybe there's some way to consolidate this with + // `didScheduleRenderPhaseUpdate`. Or with `numberOfReRenders`. + + var didScheduleRenderPhaseUpdateDuringThisPass = false; + var shouldDoubleInvokeUserFnsInHooksDEV = false; // Counts the number of useId hooks in this component. + + var thenableIndexCounter = 0; + var thenableState = null; // Used for ids that are generated completely client-side (i.e. not during + // hydration). This counter is global, so client ids are not stable across + // render attempts. + + var globalClientIdCounter = 0; + var RE_RENDER_LIMIT = 25; // In DEV, this is the name of the currently executing primitive hook + + var currentHookNameInDev = null; // In DEV, this list ensures that hooks are called in the same order between renders. + // The list stores the order of hooks used during the initial render (mount). + // Subsequent renders (updates) reference this list. + + var hookTypesDev = null; + var hookTypesUpdateIndexDev = -1; // In DEV, this tracks whether currently rendering component needs to ignore + // the dependencies for Hooks that need them (e.g. useEffect or useMemo). + // When true, such Hooks will always be "remounted". Only used during hot reload. + + var ignorePreviousDependencies = false; + + function mountHookTypesDev() { + { + var hookName = currentHookNameInDev; + + if (hookTypesDev === null) { + hookTypesDev = [hookName]; + } else { + hookTypesDev.push(hookName); + } + } + } + + function updateHookTypesDev() { + { + var hookName = currentHookNameInDev; + + if (hookTypesDev !== null) { + hookTypesUpdateIndexDev++; + + if (hookTypesDev[hookTypesUpdateIndexDev] !== hookName) { + warnOnHookMismatchInDev(hookName); + } + } + } + } + + function checkDepsAreArrayDev(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( + "%s received a final argument that is not an array (instead, received `%s`). When " + + "specified, the final argument must be an array.", + currentHookNameInDev, + typeof deps + ); + } + } + } + + function warnOnHookMismatchInDev(currentHookName) { + { + var componentName = getComponentNameFromFiber( + currentlyRenderingFiber$1 + ); + + if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) { + didWarnAboutMismatchedHooksForComponent.add(componentName); + + if (hookTypesDev !== null) { + var table = ""; + var secondColumnStart = 30; + + for (var i = 0; i <= hookTypesUpdateIndexDev; i++) { + var oldHookName = hookTypesDev[i]; + var newHookName = + i === hookTypesUpdateIndexDev ? currentHookName : oldHookName; + var row = i + 1 + ". " + oldHookName; // Extra space so second column lines up + // lol @ IE not supporting String#repeat + + while (row.length < secondColumnStart) { + row += " "; + } + + row += newHookName + "\n"; + table += row; + } + + error( + "React has detected a change in the order of Hooks called by %s. " + + "This will lead to bugs and errors if not fixed. " + + "For more information, read the Rules of Hooks: https://react.dev/link/rules-of-hooks\n\n" + + " Previous render Next render\n" + + " ------------------------------------------------------\n" + + "%s" + + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + componentName, + table + ); + } + } + } + } + + function warnIfAsyncClientComponent(Component) { + { + // This dev-only check only works for detecting native async functions, + // not transpiled ones. There's also a prod check that we use to prevent + // async client components from crashing the app; the prod one works even + // for transpiled async functions. Neither mechanism is completely + // bulletproof but together they cover the most common cases. + var isAsyncFunction = // $FlowIgnore[method-unbinding] + Object.prototype.toString.call(Component) === + "[object AsyncFunction]"; + + if (isAsyncFunction) { + // Encountered an async Client Component. This is not yet supported. + var componentName = getComponentNameFromFiber( + currentlyRenderingFiber$1 + ); + + if (!didWarnAboutAsyncClientComponent.has(componentName)) { + didWarnAboutAsyncClientComponent.add(componentName); + + error( + "async/await is not yet supported in Client Components, only " + + "Server Components. This error is often caused by accidentally " + + "adding `'use client'` to a module that was originally written " + + "for the server." + ); + } + } + } + } + + function throwInvalidHookError() { + throw new Error( + "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for" + + " one of the following reasons:\n" + + "1. You might have mismatching versions of React and the renderer (such as React DOM)\n" + + "2. You might be breaking the Rules of Hooks\n" + + "3. You might have more than one copy of React in the same app\n" + + "See https://react.dev/link/invalid-hook-call for tips about how to debug and fix this problem." + ); + } + + function areHookInputsEqual(nextDeps, prevDeps) { + { + if (ignorePreviousDependencies) { + // Only true when this component is being hot reloaded. + return false; + } + } + + if (prevDeps === null) { + { + error( + "%s received a final argument during this render, but not during " + + "the previous render. Even though the final argument is optional, " + + "its type cannot change between renders.", + currentHookNameInDev + ); + } + + return false; + } + + { + // Don't bother comparing lengths in prod because these arrays should be + // passed inline. + if (nextDeps.length !== prevDeps.length) { + error( + "The final argument passed to %s changed size between renders. The " + + "order and size of this array must remain constant.\n\n" + + "Previous: %s\n" + + "Incoming: %s", + currentHookNameInDev, + "[" + prevDeps.join(", ") + "]", + "[" + nextDeps.join(", ") + "]" + ); + } + } // $FlowFixMe[incompatible-use] found when upgrading Flow + + for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) { + // $FlowFixMe[incompatible-use] found when upgrading Flow + if (objectIs(nextDeps[i], prevDeps[i])) { + continue; + } + + return false; + } + + return true; + } + + function renderWithHooks( + current, + workInProgress, + Component, + props, + secondArg, + nextRenderLanes + ) { + renderLanes = nextRenderLanes; + currentlyRenderingFiber$1 = workInProgress; + + { + hookTypesDev = current !== null ? current._debugHookTypes : null; + hookTypesUpdateIndexDev = -1; // Used for hot reloading: + + ignorePreviousDependencies = + current !== null && current.type !== workInProgress.type; + warnIfAsyncClientComponent(Component); + } + + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; + workInProgress.lanes = NoLanes; // The following should have already been reset + // currentHook = null; + // workInProgressHook = null; + // didScheduleRenderPhaseUpdate = false; + // localIdCounter = 0; + // thenableIndexCounter = 0; + // thenableState = null; + // TODO Warn if no hooks are used at all during mount, then some are used during update. + // Currently we will identify the update render as a mount because memoizedState === null. + // This is tricky because it's valid for certain types of components (e.g. React.lazy) + // Using memoizedState to differentiate between mount/update only works if at least one stateful hook is used. + // Non-stateful hooks (e.g. context) don't get added to memoizedState, + // so memoizedState would be null during updates and mounts. + + { + if (current !== null && current.memoizedState !== null) { + ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV; + } else if (hookTypesDev !== null) { + // This dispatcher handles an edge case where a component is updating, + // but no stateful hooks have been used. + // We want to match the production code behavior (which will use HooksDispatcherOnMount), + // but with the extra DEV validation to ensure hooks ordering hasn't changed. + // This dispatcher does that. + ReactCurrentDispatcher$1.current = + HooksDispatcherOnMountWithHookTypesInDEV; + } else { + ReactCurrentDispatcher$1.current = HooksDispatcherOnMountInDEV; + } + } // In Strict Mode, during development, user functions are double invoked to + // help detect side effects. The logic for how this is implemented for in + // hook components is a bit complex so let's break it down. + // + // We will invoke the entire component function twice. However, during the + // second invocation of the component, the hook state from the first + // invocation will be reused. That means things like `useMemo` functions won't + // run again, because the deps will match and the memoized result will + // be reused. + // + // We want memoized functions to run twice, too, so account for this, user + // functions are double invoked during the *first* invocation of the component + // function, and are *not* double invoked during the second incovation: + // + // - First execution of component function: user functions are double invoked + // - Second execution of component function (in Strict Mode, during + // development): user functions are not double invoked. + // + // This is intentional for a few reasons; most importantly, it's because of + // how `use` works when something suspends: it reuses the promise that was + // passed during the first attempt. This is itself a form of memoization. + // We need to be able to memoize the reactive inputs to the `use` call using + // a hook (i.e. `useMemo`), which means, the reactive inputs to `use` must + // come from the same component invocation as the output. + // + // There are plenty of tests to ensure this behavior is correct. + + var shouldDoubleRenderDEV = + (workInProgress.mode & StrictLegacyMode) !== NoMode; + shouldDoubleInvokeUserFnsInHooksDEV = shouldDoubleRenderDEV; + var children = Component(props, secondArg); + shouldDoubleInvokeUserFnsInHooksDEV = false; // Check if there was a render phase update + + if (didScheduleRenderPhaseUpdateDuringThisPass) { + // Keep rendering until the component stabilizes (there are no more render + // phase updates). + children = renderWithHooksAgain( + workInProgress, + Component, + props, + secondArg + ); + } + + if (shouldDoubleRenderDEV) { + // In development, components are invoked twice to help detect side effects. + setIsStrictModeForDevtools(true); + + try { + children = renderWithHooksAgain( + workInProgress, + Component, + props, + secondArg + ); + } finally { + setIsStrictModeForDevtools(false); + } + } + + finishRenderingHooks(current, workInProgress); + return children; + } + + function finishRenderingHooks(current, workInProgress, Component) { + { + workInProgress._debugHookTypes = hookTypesDev; + } // We can assume the previous dispatcher is always this one, since we set it + // at the beginning of the render phase and there's no re-entrance. + + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; // This check uses currentHook so that it works the same in DEV and prod bundles. + // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles. + + var didRenderTooFewHooks = + currentHook !== null && currentHook.next !== null; + renderLanes = NoLanes; + currentlyRenderingFiber$1 = null; + currentHook = null; + workInProgressHook = null; + + { + currentHookNameInDev = null; + hookTypesDev = null; + 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; // This is reset by checkDidRenderIdHook + // localIdCounter = 0; + + thenableIndexCounter = 0; + thenableState = null; + + if (didRenderTooFewHooks) { + throw new Error( + "Rendered fewer hooks than expected. This may be caused by an accidental " + + "early return statement." + ); + } + + { + if (checkIfUseWrappedInTryCatch()) { + var componentName = + getComponentNameFromFiber(workInProgress) || "Unknown"; + + if ( + !didWarnAboutUseWrappedInTryCatch.has(componentName) && // This warning also fires if you suspend with `use` inside an + // async component. Since we warn for that above, we'll silence this + // second warning by checking here. + !didWarnAboutAsyncClientComponent.has(componentName) + ) { + didWarnAboutUseWrappedInTryCatch.add(componentName); + + error( + "`use` was called from inside a try/catch block. This is not allowed " + + "and can lead to unexpected behavior. To handle errors triggered " + + "by `use`, wrap your component in a error boundary." + ); + } + } + } + } + + function replaySuspendedComponentWithHooks( + current, + workInProgress, + Component, + props, + secondArg + ) { + // This function is used to replay a component that previously suspended, + // after its data resolves. + // + // It's a simplified version of renderWithHooks, but it doesn't need to do + // most of the set up work because they weren't reset when we suspended; they + // only get reset when the component either completes (finishRenderingHooks) + // or unwinds (resetHooksOnUnwind). + { + hookTypesUpdateIndexDev = -1; // Used for hot reloading: + + ignorePreviousDependencies = + current !== null && current.type !== workInProgress.type; + } + + var children = renderWithHooksAgain( + workInProgress, + Component, + props, + secondArg + ); + finishRenderingHooks(current, workInProgress); + return children; + } + + function renderWithHooksAgain(workInProgress, Component, props, secondArg) { + // This is used to perform another render pass. It's used when setState is + // called during render, and for double invoking components in Strict Mode + // during development. + // + // The state from the previous pass is reused whenever possible. So, state + // updates that were already processed are not processed again, and memoized + // functions (`useMemo`) are not invoked again. + // + // Keep rendering in a loop for as long as render phase updates continue to + // be scheduled. Use a counter to prevent infinite loops. + currentlyRenderingFiber$1 = workInProgress; + var numberOfReRenders = 0; + var children; + + do { + if (didScheduleRenderPhaseUpdateDuringThisPass) { + // It's possible that a use() value depended on a state that was updated in + // this rerender, so we need to watch for different thenables this time. + thenableState = null; + } + + thenableIndexCounter = 0; + didScheduleRenderPhaseUpdateDuringThisPass = false; + + if (numberOfReRenders >= RE_RENDER_LIMIT) { + throw new Error( + "Too many re-renders. React limits the number of renders to prevent " + + "an infinite loop." + ); + } + + numberOfReRenders += 1; + + { + // Even when hot reloading, allow dependencies to stabilize + // after first render to prevent infinite render phase updates. + ignorePreviousDependencies = false; + } // Start over from the beginning of the list + + currentHook = null; + workInProgressHook = null; + workInProgress.updateQueue = null; + + { + // Also validate hook order for cascading updates. + hookTypesUpdateIndexDev = -1; + } + + ReactCurrentDispatcher$1.current = HooksDispatcherOnRerenderInDEV; + children = Component(props, secondArg); + } while (didScheduleRenderPhaseUpdateDuringThisPass); + + return children; + } + 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$1 | + Update + ); + } else { + workInProgress.flags &= ~(Passive$1 | Update); + } + + current.lanes = removeLanes(current.lanes, lanes); + } + function resetHooksAfterThrow() { + // This is called immediaetly after a throw. It shouldn't reset the entire + // module state, because the work loop might decide to replay the component + // again without rewinding. + // + // It should only reset things like the current dispatcher, to prevent hooks + // from being called outside of a component. + currentlyRenderingFiber$1 = null; // We can assume the previous dispatcher is always this one, since we set it + // at the beginning of the render phase and there's no re-entrance. + + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + } + function resetHooksOnUnwind(workInProgress) { + if (didScheduleRenderPhaseUpdate) { + // There were render phase updates. These are only valid for this render + // phase, which we are now aborting. Remove the updates from the queues so + // they do not persist to the next render. Do not remove updates from hooks + // that weren't processed. + // + // Only reset the updates from the queue if it has a clone. If it does + // not have a clone, that means it wasn't processed, and the updates were + // scheduled before we entered the render phase. + var hook = workInProgress.memoizedState; + + while (hook !== null) { + var queue = hook.queue; + + if (queue !== null) { + queue.pending = null; + } + + hook = hook.next; + } + + didScheduleRenderPhaseUpdate = false; + } + + renderLanes = NoLanes; + currentlyRenderingFiber$1 = null; + currentHook = null; + workInProgressHook = null; + + { + hookTypesDev = null; + hookTypesUpdateIndexDev = -1; + currentHookNameInDev = null; + } + + didScheduleRenderPhaseUpdateDuringThisPass = false; + thenableIndexCounter = 0; + thenableState = null; + } + + function mountWorkInProgressHook() { + var hook = { + memoizedState: null, + baseState: null, + baseQueue: null, + queue: null, + next: null + }; + + if (workInProgressHook === null) { + // This is the first hook in the list + currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook; + } else { + // Append to the end of the list + workInProgressHook = workInProgressHook.next = hook; + } + + return workInProgressHook; + } + + function updateWorkInProgressHook() { + // This function is used both for updates and for re-renders triggered by a + // render phase update. It assumes there is either a current hook we can + // clone, or a work-in-progress hook from a previous render pass that we can + // use as a base. + var nextCurrentHook; + + if (currentHook === null) { + var current = currentlyRenderingFiber$1.alternate; + + if (current !== null) { + nextCurrentHook = current.memoizedState; + } else { + nextCurrentHook = null; + } + } else { + nextCurrentHook = currentHook.next; + } + + var nextWorkInProgressHook; + + if (workInProgressHook === null) { + nextWorkInProgressHook = currentlyRenderingFiber$1.memoizedState; + } else { + nextWorkInProgressHook = workInProgressHook.next; + } + + if (nextWorkInProgressHook !== null) { + // There's already a work-in-progress. Reuse it. + workInProgressHook = nextWorkInProgressHook; + nextWorkInProgressHook = workInProgressHook.next; + currentHook = nextCurrentHook; + } else { + // Clone from the current hook. + if (nextCurrentHook === null) { + var currentFiber = currentlyRenderingFiber$1.alternate; + + if (currentFiber === null) { + // This is the initial render. This branch is reached when the component + // suspends, resumes, then renders an additional hook. + // Should never be reached because we should switch to the mount dispatcher first. + throw new Error( + "Update hook called on initial render. This is likely a bug in React. Please file an issue." + ); + } else { + // This is an update. We should always have a current hook. + throw new Error( + "Rendered more hooks than during the previous render." + ); + } + } + + currentHook = nextCurrentHook; + var newHook = { + memoizedState: currentHook.memoizedState, + baseState: currentHook.baseState, + baseQueue: currentHook.baseQueue, + queue: currentHook.queue, + next: null + }; + + if (workInProgressHook === null) { + // This is the first hook in the list. + currentlyRenderingFiber$1.memoizedState = workInProgressHook = + newHook; + } else { + // Append to the end of the list. + workInProgressHook = workInProgressHook.next = newHook; + } + } + + return workInProgressHook; + } // NOTE: defining two versions of this function to avoid size impact when this feature is disabled. + // Previously this function was inlined, the additional `memoCache` property makes it not inlined. + + var createFunctionComponentUpdateQueue; + + { + createFunctionComponentUpdateQueue = function () { + return { + lastEffect: null, + events: null, + stores: null + }; + }; + } + + function useThenable(thenable) { + // Track the position of the thenable within this fiber. + var index = thenableIndexCounter; + thenableIndexCounter += 1; + + if (thenableState === null) { + thenableState = createThenableState(); + } + + var result = trackUsedThenable(thenableState, thenable, index); + + if ( + currentlyRenderingFiber$1.alternate === null && + (workInProgressHook === null + ? currentlyRenderingFiber$1.memoizedState === null + : workInProgressHook.next === null) + ) { + // Initial render, and either this is the first time the component is + // called, or there were no Hooks called after this use() the previous + // time (perhaps because it threw). Subsequent Hook calls should use the + // mount dispatcher. + { + ReactCurrentDispatcher$1.current = HooksDispatcherOnMountInDEV; + } + } + + return result; + } + + function use(usable) { + if (usable !== null && typeof usable === "object") { + // $FlowFixMe[method-unbinding] + if (typeof usable.then === "function") { + // This is a thenable. + var thenable = usable; + return useThenable(thenable); + } else if (usable.$$typeof === REACT_CONTEXT_TYPE) { + var context = usable; + return readContext(context); + } + } // eslint-disable-next-line react-internal/safe-string-coercion + + throw new Error( + "An unsupported type was passed to use(): " + String(usable) + ); + } + + function basicStateReducer(state, action) { + // $FlowFixMe[incompatible-use]: Flow doesn't like mixed types + return typeof action === "function" ? action(state) : action; + } + + function mountReducer(reducer, initialArg, init) { + var hook = mountWorkInProgressHook(); + var initialState; + + if (init !== undefined) { + initialState = init(initialArg); + + if (shouldDoubleInvokeUserFnsInHooksDEV) { + setIsStrictModeForDevtools(true); + init(initialArg); + setIsStrictModeForDevtools(false); + } + } else { + initialState = initialArg; + } + + hook.memoizedState = hook.baseState = initialState; + var queue = { + pending: null, + lanes: NoLanes, + dispatch: null, + lastRenderedReducer: reducer, + lastRenderedState: initialState + }; + hook.queue = queue; + var dispatch = (queue.dispatch = dispatchReducerAction.bind( + null, + currentlyRenderingFiber$1, + queue + )); + return [hook.memoizedState, dispatch]; + } + + function updateReducer(reducer, initialArg, init) { + var hook = updateWorkInProgressHook(); + return updateReducerImpl(hook, currentHook, reducer); + } + + function updateReducerImpl(hook, current, reducer) { + var queue = hook.queue; + + if (queue === null) { + throw new Error( + "Should have a queue. This is likely a bug in React. Please file an issue." + ); + } + + queue.lastRenderedReducer = reducer; // The last rebase update that is NOT part of the base state. + + var baseQueue = hook.baseQueue; // The last pending update that hasn't been processed yet. + + var pendingQueue = queue.pending; + + if (pendingQueue !== null) { + // We have new updates that haven't been processed yet. + // We'll add them to the base queue. + if (baseQueue !== null) { + // Merge the pending queue and the base queue. + var baseFirst = baseQueue.next; + var pendingFirst = pendingQueue.next; + baseQueue.next = pendingFirst; + pendingQueue.next = baseFirst; + } + + { + if (current.baseQueue !== baseQueue) { + // Internal invariant that should never happen, but feasibly could in + // the future if we implement resuming, or some form of that. + error( + "Internal error: Expected work-in-progress queue to be a clone. " + + "This is a bug in React." + ); + } + } + + current.baseQueue = baseQueue = pendingQueue; + queue.pending = null; + } + + var baseState = hook.baseState; + + if (baseQueue === null) { + // If there are no pending updates, then the memoized state should be the + // same as the base state. Currently these only diverge in the case of + // useOptimistic, because useOptimistic accepts a new baseState on + // every render. + hook.memoizedState = baseState; // We don't need to call markWorkInProgressReceivedUpdate because + // baseState is derived from other reactive values. + } else { + // We have a queue to process. + var first = baseQueue.next; + var newState = baseState; + var newBaseState = null; + var newBaseQueueFirst = null; + var newBaseQueueLast = null; + var update = first; + var didReadFromEntangledAsyncAction = false; + + do { + // An extra OffscreenLane bit is added to updates that were made to + // a hidden tree, so that we can distinguish them from updates that were + // already there when the tree was hidden. + var updateLane = removeLanes(update.lane, OffscreenLane); + var isHiddenUpdate = updateLane !== update.lane; // Check if this update was made while the tree was hidden. If so, then + // it's not a "base" update and we should disregard the extra base lanes + // that were added to renderLanes when we entered the Offscreen tree. + + var shouldSkipUpdate = isHiddenUpdate + ? !isSubsetOfLanes(getWorkInProgressRootRenderLanes(), updateLane) + : !isSubsetOfLanes(renderLanes, updateLane); + + if (shouldSkipUpdate) { + // Priority is insufficient. Skip this update. If this is the first + // skipped update, the previous update/state is the new base + // update/state. + var clone = { + lane: updateLane, + revertLane: update.revertLane, + action: update.action, + hasEagerState: update.hasEagerState, + eagerState: update.eagerState, + next: null + }; + + if (newBaseQueueLast === null) { + newBaseQueueFirst = newBaseQueueLast = clone; + newBaseState = newState; + } else { + newBaseQueueLast = newBaseQueueLast.next = clone; + } // Update the remaining priority in the queue. + // TODO: Don't need to accumulate this. Instead, we can remove + // renderLanes from the original lanes. + + currentlyRenderingFiber$1.lanes = mergeLanes( + currentlyRenderingFiber$1.lanes, + updateLane + ); + markSkippedUpdateLanes(updateLane); + } else { + { + // This is not an optimistic update, and we're going to apply it now. + // But, if there were earlier updates that were skipped, we need to + // leave this update in the queue so it can be rebased later. + if (newBaseQueueLast !== null) { + var _clone = { + // This update is going to be committed so we never want uncommit + // it. Using NoLane works because 0 is a subset of all bitmasks, so + // this will never be skipped by the check above. + lane: NoLane, + revertLane: NoLane, + action: update.action, + hasEagerState: update.hasEagerState, + eagerState: update.eagerState, + next: null + }; + newBaseQueueLast = newBaseQueueLast.next = _clone; + } // Check if this update is part of a pending async action. If so, + // we'll need to suspend until the action has finished, so that it's + // batched together with future updates in the same action. + + if (updateLane === peekEntangledActionLane()) { + didReadFromEntangledAsyncAction = true; + } + } // Process this update. + + var action = update.action; + + if (shouldDoubleInvokeUserFnsInHooksDEV) { + reducer(newState, action); + } + + if (update.hasEagerState) { + // If this update is a state update (not a reducer) and was processed eagerly, + // we can use the eagerly computed state + newState = update.eagerState; + } else { + newState = reducer(newState, action); + } + } + + update = update.next; + } while (update !== null && update !== first); + + if (newBaseQueueLast === null) { + newBaseState = newState; + } else { + newBaseQueueLast.next = newBaseQueueFirst; + } // Mark that the fiber performed work, but only if the new state is + // different from the current state. + + if (!objectIs(newState, hook.memoizedState)) { + markWorkInProgressReceivedUpdate(); // Check if this update is part of a pending async action. If so, we'll + // need to suspend until the action has finished, so that it's batched + // together with future updates in the same action. + // TODO: Once we support hooks inside useMemo (or an equivalent + // memoization boundary like Forget), hoist this logic so that it only + // suspends if the memo boundary produces a new value. + + if (didReadFromEntangledAsyncAction) { + var entangledActionThenable = peekEntangledActionThenable(); + + if (entangledActionThenable !== null) { + // TODO: Instead of the throwing the thenable directly, throw a + // special object like `use` does so we can detect if it's captured + // by userspace. + throw entangledActionThenable; + } + } + } + + hook.memoizedState = newState; + hook.baseState = newBaseState; + hook.baseQueue = newBaseQueueLast; + queue.lastRenderedState = newState; + } + + 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; + return [hook.memoizedState, dispatch]; + } + + function rerenderReducer(reducer, initialArg, init) { + var hook = updateWorkInProgressHook(); + var queue = hook.queue; + + if (queue === null) { + throw new Error( + "Should have a queue. This is likely a bug in React. Please file an issue." + ); + } + + queue.lastRenderedReducer = reducer; // This is a re-render. Apply the new render phase updates to the previous + // work-in-progress hook. + + var dispatch = queue.dispatch; + var lastRenderPhaseUpdate = queue.pending; + var newState = hook.memoizedState; + + if (lastRenderPhaseUpdate !== null) { + // The queue doesn't persist past this render pass. + queue.pending = null; + var firstRenderPhaseUpdate = lastRenderPhaseUpdate.next; + var update = firstRenderPhaseUpdate; + + do { + // Process this render phase update. We don't have to check the + // priority because it will always be the same as the current + // render's. + var action = update.action; + newState = reducer(newState, action); + update = update.next; + } while (update !== firstRenderPhaseUpdate); // Mark that the fiber performed work, but only if the new state is + // different from the current state. + + if (!objectIs(newState, hook.memoizedState)) { + markWorkInProgressReceivedUpdate(); + } + + hook.memoizedState = newState; // Don't persist the state accumulated from the render phase updates to + // the base state unless the queue is empty. + // TODO: Not sure if this is the desired semantics, but it's what we + // do for gDSFP. I can't remember why. + + if (hook.baseQueue === null) { + hook.baseState = newState; + } + + queue.lastRenderedState = newState; + } + + return [newState, dispatch]; + } + + function mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) { + var fiber = currentlyRenderingFiber$1; + var hook = mountWorkInProgressHook(); + var nextSnapshot; + + { + nextSnapshot = getSnapshot(); + + { + if (!didWarnUncachedGetSnapshot) { + var cachedSnapshot = getSnapshot(); + + if (!objectIs(nextSnapshot, cachedSnapshot)) { + error( + "The result of getSnapshot should be cached to avoid an infinite loop" + ); + + didWarnUncachedGetSnapshot = true; + } + } + } // Unless we're rendering a blocking lane, schedule a consistency check. + // Right before committing, we will walk the tree and check if any of the + // stores were mutated. + // + // We won't do this if we're hydrating server-rendered content, because if + // the content is stale, it's already visible anyway. Instead we'll patch + // it up in a passive effect. + + var root = getWorkInProgressRoot(); + + if (root === null) { + throw new Error( + "Expected a work-in-progress root. This is a bug in React. Please file an issue." + ); + } + + var rootRenderLanes = getWorkInProgressRootRenderLanes(); + + if (!includesBlockingLane(root, rootRenderLanes)) { + pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot); + } + } // Read the current snapshot from the store on every render. This breaks the + // normal rules of React, and only works because store updates are + // always synchronous. + + hook.memoizedState = nextSnapshot; + var inst = { + value: nextSnapshot, + getSnapshot: getSnapshot + }; + hook.queue = inst; // Schedule an effect to subscribe to the store. + + mountEffect(subscribeToStore.bind(null, fiber, inst, subscribe), [ + subscribe + ]); // Schedule an effect to update the mutable instance fields. We will update + // this whenever subscribe, getSnapshot, or value changes. Because there's no + // clean-up function, and we track the deps correctly, we can call pushEffect + // directly, without storing any additional state. For the same reason, we + // don't need to set a static flag, either. + + fiber.flags |= Passive$1; + pushEffect( + HasEffect | Passive, + updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot), + createEffectInstance(), + null + ); + return nextSnapshot; + } + + function updateSyncExternalStore( + subscribe, + getSnapshot, + getServerSnapshot + ) { + var fiber = currentlyRenderingFiber$1; + var hook = updateWorkInProgressHook(); // Read the current snapshot from the store on every render. This breaks the + // normal rules of React, and only works because store updates are + // always synchronous. + + var nextSnapshot; + + { + nextSnapshot = getSnapshot(); + + { + if (!didWarnUncachedGetSnapshot) { + var cachedSnapshot = getSnapshot(); + + if (!objectIs(nextSnapshot, cachedSnapshot)) { + error( + "The result of getSnapshot should be cached to avoid an infinite loop" + ); + + didWarnUncachedGetSnapshot = true; + } + } + } + } + + var prevSnapshot = (currentHook || hook).memoizedState; + var snapshotChanged = !objectIs(prevSnapshot, nextSnapshot); + + if (snapshotChanged) { + hook.memoizedState = nextSnapshot; + markWorkInProgressReceivedUpdate(); + } + + var inst = hook.queue; + updateEffect(subscribeToStore.bind(null, fiber, inst, subscribe), [ + subscribe + ]); // Whenever getSnapshot or subscribe changes, we need to check in the + // commit phase if there was an interleaved mutation. In concurrent mode + // this can happen all the time, but even in synchronous mode, an earlier + // effect may have mutated the store. + + if ( + inst.getSnapshot !== getSnapshot || + snapshotChanged || // Check if the subscribe function changed. We can save some memory by + // checking whether we scheduled a subscription effect above. + (workInProgressHook !== null && + workInProgressHook.memoizedState.tag & HasEffect) + ) { + fiber.flags |= Passive$1; + pushEffect( + HasEffect | Passive, + updateStoreInstance.bind( + null, + fiber, + inst, + nextSnapshot, + getSnapshot + ), + createEffectInstance(), + null + ); // Unless we're rendering a blocking lane, schedule a consistency check. + // Right before committing, we will walk the tree and check if any of the + // stores were mutated. + + var root = getWorkInProgressRoot(); + + if (root === null) { + throw new Error( + "Expected a work-in-progress root. This is a bug in React. Please file an issue." + ); + } + + if (!includesBlockingLane(root, renderLanes)) { + pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot); + } + } + + return nextSnapshot; + } + + function pushStoreConsistencyCheck(fiber, getSnapshot, renderedSnapshot) { + fiber.flags |= StoreConsistency; + var check = { + getSnapshot: getSnapshot, + value: renderedSnapshot + }; + var componentUpdateQueue = currentlyRenderingFiber$1.updateQueue; + + if (componentUpdateQueue === null) { + componentUpdateQueue = createFunctionComponentUpdateQueue(); + currentlyRenderingFiber$1.updateQueue = componentUpdateQueue; + componentUpdateQueue.stores = [check]; + } else { + var stores = componentUpdateQueue.stores; + + if (stores === null) { + componentUpdateQueue.stores = [check]; + } else { + stores.push(check); + } + } + } + + function updateStoreInstance(fiber, inst, nextSnapshot, getSnapshot) { + // These are updated in the passive phase + inst.value = nextSnapshot; + inst.getSnapshot = getSnapshot; // Something may have been mutated in between render and commit. This could + // have been in an event that fired before the passive effects, or it could + // have been in a layout effect. In that case, we would have used the old + // snapsho and getSnapshot values to bail out. We need to check one more time. + + if (checkIfSnapshotChanged(inst)) { + // Force a re-render. + forceStoreRerender(fiber); + } + } + + function subscribeToStore(fiber, inst, subscribe) { + var handleStoreChange = function () { + // The store changed. Check if the snapshot changed since the last time we + // read from the store. + if (checkIfSnapshotChanged(inst)) { + // Force a re-render. + forceStoreRerender(fiber); + } + }; // Subscribe to the store and return a clean-up function. + + return subscribe(handleStoreChange); + } + + function checkIfSnapshotChanged(inst) { + var latestGetSnapshot = inst.getSnapshot; + var prevValue = inst.value; + + try { + var nextValue = latestGetSnapshot(); + return !objectIs(prevValue, nextValue); + } catch (error) { + return true; + } + } + + function forceStoreRerender(fiber) { + var root = enqueueConcurrentRenderForLane(fiber, SyncLane); + + if (root !== null) { + scheduleUpdateOnFiber(root, fiber, SyncLane); + } + } + + function mountStateImpl(initialState) { + var hook = mountWorkInProgressHook(); + + if (typeof initialState === "function") { + var initialStateInitializer = initialState; // $FlowFixMe[incompatible-use]: Flow doesn't like mixed types + + initialState = initialStateInitializer(); + + if (shouldDoubleInvokeUserFnsInHooksDEV) { + setIsStrictModeForDevtools(true); // $FlowFixMe[incompatible-use]: Flow doesn't like mixed types + + initialStateInitializer(); + setIsStrictModeForDevtools(false); + } + } + + hook.memoizedState = hook.baseState = initialState; + var queue = { + pending: null, + lanes: NoLanes, + dispatch: null, + lastRenderedReducer: basicStateReducer, + lastRenderedState: initialState + }; + hook.queue = queue; + return hook; + } + + function mountState(initialState) { + var hook = mountStateImpl(initialState); + var queue = hook.queue; + var dispatch = dispatchSetState.bind( + null, + currentlyRenderingFiber$1, + queue + ); + queue.dispatch = dispatch; + return [hook.memoizedState, dispatch]; + } + + function updateState(initialState) { + return updateReducer(basicStateReducer); + } + + function rerenderState(initialState) { + return rerenderReducer(basicStateReducer); + } + + function pushEffect(tag, create, inst, deps) { + var effect = { + tag: tag, + create: create, + inst: inst, + deps: deps, + // Circular + next: null + }; + var componentUpdateQueue = currentlyRenderingFiber$1.updateQueue; + + if (componentUpdateQueue === null) { + componentUpdateQueue = createFunctionComponentUpdateQueue(); + currentlyRenderingFiber$1.updateQueue = componentUpdateQueue; + componentUpdateQueue.lastEffect = effect.next = effect; + } else { + var lastEffect = componentUpdateQueue.lastEffect; + + if (lastEffect === null) { + componentUpdateQueue.lastEffect = effect.next = effect; + } else { + var firstEffect = lastEffect.next; + lastEffect.next = effect; + effect.next = firstEffect; + componentUpdateQueue.lastEffect = effect; + } + } + + return effect; + } + + function createEffectInstance() { + return { + destroy: undefined + }; + } + + function mountRef(initialValue) { + var hook = mountWorkInProgressHook(); + + { + var _ref2 = { + current: initialValue + }; + hook.memoizedState = _ref2; + return _ref2; + } + } + + function updateRef(initialValue) { + var hook = updateWorkInProgressHook(); + return hook.memoizedState; + } + + function mountEffectImpl(fiberFlags, hookFlags, create, deps) { + var hook = mountWorkInProgressHook(); + var nextDeps = deps === undefined ? null : deps; + currentlyRenderingFiber$1.flags |= fiberFlags; + hook.memoizedState = pushEffect( + HasEffect | hookFlags, + create, + createEffectInstance(), + nextDeps + ); + } + + function updateEffectImpl(fiberFlags, hookFlags, create, deps) { + var hook = updateWorkInProgressHook(); + var nextDeps = deps === undefined ? null : deps; + var effect = hook.memoizedState; + var inst = effect.inst; // currentHook is null on initial mount when rerendering after a render phase + // state update or for strict mode. + + if (currentHook !== null) { + if (nextDeps !== null) { + var prevEffect = currentHook.memoizedState; + var prevDeps = prevEffect.deps; + + if (areHookInputsEqual(nextDeps, prevDeps)) { + hook.memoizedState = pushEffect(hookFlags, create, inst, nextDeps); + return; + } + } + } + + currentlyRenderingFiber$1.flags |= fiberFlags; + hook.memoizedState = pushEffect( + HasEffect | hookFlags, + create, + inst, + nextDeps + ); + } + + function mountEffect(create, deps) { + if ( + (currentlyRenderingFiber$1.mode & StrictEffectsMode) !== NoMode && + (currentlyRenderingFiber$1.mode & NoStrictPassiveEffectsMode) === NoMode + ) { + mountEffectImpl( + MountPassiveDev | Passive$1 | PassiveStatic, + Passive, + create, + deps + ); + } else { + mountEffectImpl(Passive$1 | PassiveStatic, Passive, create, deps); + } + } + + function updateEffect(create, deps) { + updateEffectImpl(Passive$1, Passive, create, deps); + } + + function mountInsertionEffect(create, deps) { + mountEffectImpl(Update, Insertion, create, deps); + } + + function updateInsertionEffect(create, deps) { + return updateEffectImpl(Update, Insertion, create, deps); + } + + function mountLayoutEffect(create, deps) { + var fiberFlags = Update | LayoutStatic; + + if ((currentlyRenderingFiber$1.mode & StrictEffectsMode) !== NoMode) { + fiberFlags |= MountLayoutDev; + } + + return mountEffectImpl(fiberFlags, Layout, create, deps); + } + + function updateLayoutEffect(create, deps) { + return updateEffectImpl(Update, Layout, create, deps); + } + + function imperativeHandleEffect(create, ref) { + if (typeof ref === "function") { + var refCallback = ref; + var inst = create(); + refCallback(inst); + return function () { + refCallback(null); + }; + } else if (ref !== null && ref !== undefined) { + var refObject = ref; + + { + if (!refObject.hasOwnProperty("current")) { + error( + "Expected useImperativeHandle() first argument to either be a " + + "ref callback or React.createRef() object. Instead received: %s.", + "an object with keys {" + Object.keys(refObject).join(", ") + "}" + ); + } + } + + var _inst = create(); + + refObject.current = _inst; + return function () { + refObject.current = null; + }; + } + } + + function mountImperativeHandle(ref, create, deps) { + { + if (typeof create !== "function") { + error( + "Expected useImperativeHandle() second argument to be a function " + + "that creates a handle. Instead received: %s.", + create !== null ? typeof create : "null" + ); + } + } // TODO: If deps are provided, should we skip comparing the ref itself? + + var effectDeps = + deps !== null && deps !== undefined ? deps.concat([ref]) : null; + var fiberFlags = Update | LayoutStatic; + + if ((currentlyRenderingFiber$1.mode & StrictEffectsMode) !== NoMode) { + fiberFlags |= MountLayoutDev; + } + + mountEffectImpl( + fiberFlags, + Layout, + imperativeHandleEffect.bind(null, create, ref), + effectDeps + ); + } + + function updateImperativeHandle(ref, create, deps) { + { + if (typeof create !== "function") { + error( + "Expected useImperativeHandle() second argument to be a function " + + "that creates a handle. Instead received: %s.", + create !== null ? typeof create : "null" + ); + } + } // TODO: If deps are provided, should we skip comparing the ref itself? + + var effectDeps = + deps !== null && deps !== undefined ? deps.concat([ref]) : null; + updateEffectImpl( + Update, + Layout, + imperativeHandleEffect.bind(null, create, ref), + effectDeps + ); + } + + function mountDebugValue(value, formatterFn) { + // This hook is normally a no-op. + // The react-debug-hooks package injects its own implementation + // so that e.g. DevTools can display custom hook values. + } + + var updateDebugValue = mountDebugValue; + + function mountCallback(callback, deps) { + var hook = mountWorkInProgressHook(); + var nextDeps = deps === undefined ? null : deps; + hook.memoizedState = [callback, nextDeps]; + return callback; + } + + function updateCallback(callback, deps) { + var hook = updateWorkInProgressHook(); + var nextDeps = deps === undefined ? null : deps; + var prevState = hook.memoizedState; + + if (nextDeps !== null) { + var prevDeps = prevState[1]; + + if (areHookInputsEqual(nextDeps, prevDeps)) { + return prevState[0]; + } + } + + hook.memoizedState = [callback, nextDeps]; + return callback; + } + + function mountMemo(nextCreate, deps) { + var hook = mountWorkInProgressHook(); + var nextDeps = deps === undefined ? null : deps; + var nextValue = nextCreate(); + + if (shouldDoubleInvokeUserFnsInHooksDEV) { + setIsStrictModeForDevtools(true); + nextCreate(); + setIsStrictModeForDevtools(false); + } + + hook.memoizedState = [nextValue, nextDeps]; + return nextValue; + } + + function updateMemo(nextCreate, deps) { + var hook = updateWorkInProgressHook(); + var nextDeps = deps === undefined ? null : deps; + var prevState = hook.memoizedState; // Assume these are defined. If they're not, areHookInputsEqual will warn. + + if (nextDeps !== null) { + var prevDeps = prevState[1]; + + if (areHookInputsEqual(nextDeps, prevDeps)) { + return prevState[0]; + } + } + + var nextValue = nextCreate(); + + if (shouldDoubleInvokeUserFnsInHooksDEV) { + setIsStrictModeForDevtools(true); + nextCreate(); + setIsStrictModeForDevtools(false); + } + + hook.memoizedState = [nextValue, nextDeps]; + return nextValue; + } + + function mountDeferredValue(value, initialValue) { + var hook = mountWorkInProgressHook(); + return mountDeferredValueImpl(hook, value, initialValue); + } + + function updateDeferredValue(value, initialValue) { + var hook = updateWorkInProgressHook(); + var resolvedCurrentHook = currentHook; + var prevValue = resolvedCurrentHook.memoizedState; + return updateDeferredValueImpl(hook, prevValue, value, initialValue); + } + + function rerenderDeferredValue(value, initialValue) { + var hook = updateWorkInProgressHook(); + + if (currentHook === null) { + // This is a rerender during a mount. + return mountDeferredValueImpl(hook, value, initialValue); + } else { + // This is a rerender during an update. + var prevValue = currentHook.memoizedState; + return updateDeferredValueImpl(hook, prevValue, value, initialValue); + } + } + + function mountDeferredValueImpl(hook, value, initialValue) { + if ( + // When `initialValue` is provided, we defer the initial render even if the + // current render is not synchronous. + initialValue !== undefined && // However, to avoid waterfalls, we do not defer if this render + // was itself spawned by an earlier useDeferredValue. Check if DeferredLane + // is part of the render lanes. + !includesSomeLane(renderLanes, DeferredLane) + ) { + // Render with the initial value + hook.memoizedState = initialValue; // Schedule a deferred render to switch to the final value. + + var deferredLane = requestDeferredLane(); + currentlyRenderingFiber$1.lanes = mergeLanes( + currentlyRenderingFiber$1.lanes, + deferredLane + ); + markSkippedUpdateLanes(deferredLane); + return initialValue; + } else { + hook.memoizedState = value; + return value; + } + } + + function updateDeferredValueImpl(hook, prevValue, value, initialValue) { + if (objectIs(value, prevValue)) { + // The incoming value is referentially identical to the currently rendered + // value, so we can bail out quickly. + return value; + } else { + // Received a new value that's different from the current value. + // Check if we're inside a hidden tree + if (isCurrentTreeHidden()) { + // Revealing a prerendered tree is considered the same as mounting new + // one, so we reuse the "mount" path in this case. + var resultValue = mountDeferredValueImpl(hook, value, initialValue); // Unlike during an actual mount, we need to mark this as an update if + // the value changed. + + if (!objectIs(resultValue, prevValue)) { + markWorkInProgressReceivedUpdate(); + } + + return resultValue; + } + + var shouldDeferValue = !includesOnlyNonUrgentLanes(renderLanes); + + if (shouldDeferValue) { + // This is an urgent update. Since the value has changed, keep using the + // previous value and spawn a deferred render to update it later. + // Schedule a deferred render + var deferredLane = requestDeferredLane(); + currentlyRenderingFiber$1.lanes = mergeLanes( + currentlyRenderingFiber$1.lanes, + deferredLane + ); + markSkippedUpdateLanes(deferredLane); // Reuse the previous value. We do not need to mark this as an update, + // because we did not render a new value. + + return prevValue; + } else { + // This is not an urgent update, so we can use the latest value regardless + // of what it is. No need to defer it. + // Mark this as an update to prevent the fiber from bailing out. + markWorkInProgressReceivedUpdate(); + hook.memoizedState = value; + return value; + } + } + } + + function startTransition( + fiber, + queue, + pendingState, + finishedState, + callback, + options + ) { + var previousPriority = getCurrentUpdatePriority(); + setCurrentUpdatePriority( + higherEventPriority(previousPriority, ContinuousEventPriority) + ); + var prevTransition = ReactCurrentBatchConfig$2.transition; + var currentTransition = { + _callbacks: new Set() + }; + + { + ReactCurrentBatchConfig$2.transition = null; + dispatchSetState(fiber, queue, pendingState); + ReactCurrentBatchConfig$2.transition = currentTransition; + } + + { + ReactCurrentBatchConfig$2.transition._updatedFibers = new Set(); + } + + try { + var returnValue, thenable, thenableForFinishedState; + if (enableAsyncActions); + else { + // Async actions are not enabled. + dispatchSetState(fiber, queue, finishedState); + callback(); + } + } catch (error) { + { + // The error rethrowing behavior is only enabled when the async actions + // feature is on, even for sync actions. + throw error; + } + } finally { + setCurrentUpdatePriority(previousPriority); + ReactCurrentBatchConfig$2.transition = prevTransition; + + { + if (prevTransition === null && currentTransition._updatedFibers) { + var updatedFibersCount = currentTransition._updatedFibers.size; + + currentTransition._updatedFibers.clear(); + + if (updatedFibersCount > 10) { + warn( + "Detected a large number of updates inside startTransition. " + + "If this is due to a subscription please re-write it to use React provided hooks. " + + "Otherwise concurrent mode guarantees are off the table." + ); + } + } + } + } + } + + function mountTransition() { + var stateHook = mountStateImpl(false); // The `start` method never changes. + + var start = startTransition.bind( + null, + currentlyRenderingFiber$1, + stateHook.queue, + true, + false + ); + var hook = mountWorkInProgressHook(); + hook.memoizedState = start; + return [false, start]; + } + + function updateTransition() { + var _updateState2 = updateState(), + booleanOrThenable = _updateState2[0]; + + var hook = updateWorkInProgressHook(); + var start = hook.memoizedState; + var isPending = + typeof booleanOrThenable === "boolean" + ? booleanOrThenable // This will suspend until the async action scope has finished. + : useThenable(booleanOrThenable); + return [isPending, start]; + } + + function rerenderTransition() { + var _rerenderState = rerenderState(), + booleanOrThenable = _rerenderState[0]; + + var hook = updateWorkInProgressHook(); + var start = hook.memoizedState; + var isPending = + typeof booleanOrThenable === "boolean" + ? booleanOrThenable // This will suspend until the async action scope has finished. + : useThenable(booleanOrThenable); + return [isPending, start]; + } + + function mountId() { + var hook = mountWorkInProgressHook(); + var root = getWorkInProgressRoot(); // TODO: In Fizz, id generation is specific to each server config. Maybe we + // should do this in Fiber, too? Deferring this decision for now because + // there's no other place to store the prefix except for an internal field on + // the public createRoot object, which the fiber tree does not currently have + // a reference to. + + var identifierPrefix = root.identifierPrefix; + var id; + + { + // Use a lowercase r prefix for client-generated ids. + var globalClientId = globalClientIdCounter++; + id = ":" + identifierPrefix + "r" + globalClientId.toString(32) + ":"; + } + + hook.memoizedState = id; + return id; + } + + function updateId() { + var hook = updateWorkInProgressHook(); + var id = hook.memoizedState; + return id; + } + + function dispatchReducerAction(fiber, queue, action) { + { + if (typeof arguments[3] === "function") { + error( + "State updates from the useState() and useReducer() Hooks don't support the " + + "second callback argument. To execute a side effect after " + + "rendering, declare it in the component body with useEffect()." + ); + } + } + + var lane = requestUpdateLane(fiber); + var update = { + lane: lane, + revertLane: NoLane, + action: action, + hasEagerState: false, + eagerState: null, + next: null + }; + + if (isRenderPhaseUpdate(fiber)) { + enqueueRenderPhaseUpdate(queue, update); + } else { + var root = enqueueConcurrentHookUpdate(fiber, queue, update, lane); + + if (root !== null) { + scheduleUpdateOnFiber(root, fiber, lane); + entangleTransitionUpdate(root, queue, lane); + } + } + } + + function dispatchSetState(fiber, queue, action) { + { + if (typeof arguments[3] === "function") { + error( + "State updates from the useState() and useReducer() Hooks don't support the " + + "second callback argument. To execute a side effect after " + + "rendering, declare it in the component body with useEffect()." + ); + } + } + + var lane = requestUpdateLane(fiber); + var update = { + lane: lane, + revertLane: NoLane, + action: action, + hasEagerState: false, + eagerState: null, + next: null + }; + + if (isRenderPhaseUpdate(fiber)) { + enqueueRenderPhaseUpdate(queue, update); + } else { + var alternate = fiber.alternate; + + if ( + fiber.lanes === NoLanes && + (alternate === null || alternate.lanes === NoLanes) + ) { + // The queue is currently empty, which means we can eagerly compute the + // next state before entering the render phase. If the new state is the + // same as the current state, we may be able to bail out entirely. + var lastRenderedReducer = queue.lastRenderedReducer; + + if (lastRenderedReducer !== null) { + var prevDispatcher; + + { + prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = + InvalidNestedHooksDispatcherOnUpdateInDEV; + } + + try { + var currentState = queue.lastRenderedState; + var eagerState = lastRenderedReducer(currentState, action); // Stash the eagerly computed state, and the reducer used to compute + // it, on the update object. If the reducer hasn't changed by the + // time we enter the render phase, then the eager state can be used + // without calling the reducer again. + + update.hasEagerState = true; + update.eagerState = eagerState; + + if (objectIs(eagerState, currentState)) { + // Fast path. We can bail out without scheduling React to re-render. + // It's still possible that we'll need to rebase this update later, + // if the component re-renders for a different reason and by that + // time the reducer has changed. + // TODO: Do we still need to entangle transitions in this case? + enqueueConcurrentHookUpdateAndEagerlyBailout( + fiber, + queue, + update + ); + return; + } + } catch (error) { + // Suppress the error. It will throw again in the render phase. + } finally { + { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + } + } + } + + var root = enqueueConcurrentHookUpdate(fiber, queue, update, lane); + + if (root !== null) { + scheduleUpdateOnFiber(root, fiber, lane); + entangleTransitionUpdate(root, queue, lane); + } + } + } + + function isRenderPhaseUpdate(fiber) { + var alternate = fiber.alternate; + return ( + fiber === currentlyRenderingFiber$1 || + (alternate !== null && alternate === currentlyRenderingFiber$1) + ); + } + + function enqueueRenderPhaseUpdate(queue, update) { + // This is a render phase update. Stash it in a lazily-created map of + // 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; + } // TODO: Move to ReactFiberConcurrentUpdates? + + function entangleTransitionUpdate(root, queue, lane) { + if (isTransitionLane(lane)) { + 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); + } + } + + var ContextOnlyDispatcher = { + readContext: readContext, + use: use, + useCallback: throwInvalidHookError, + useContext: throwInvalidHookError, + useEffect: throwInvalidHookError, + useImperativeHandle: throwInvalidHookError, + useInsertionEffect: throwInvalidHookError, + useLayoutEffect: throwInvalidHookError, + useMemo: throwInvalidHookError, + useReducer: throwInvalidHookError, + useRef: throwInvalidHookError, + useState: throwInvalidHookError, + useDebugValue: throwInvalidHookError, + useDeferredValue: throwInvalidHookError, + useTransition: throwInvalidHookError, + useSyncExternalStore: throwInvalidHookError, + useId: throwInvalidHookError + }; + + var HooksDispatcherOnMountInDEV = null; + var HooksDispatcherOnMountWithHookTypesInDEV = null; + var HooksDispatcherOnUpdateInDEV = null; + var HooksDispatcherOnRerenderInDEV = null; + var InvalidNestedHooksDispatcherOnMountInDEV = null; + var InvalidNestedHooksDispatcherOnUpdateInDEV = null; + var InvalidNestedHooksDispatcherOnRerenderInDEV = null; + + { + var warnInvalidContextAccess = function () { + 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()." + ); + }; + + var warnInvalidHookAccess = function () { + error( + "Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. " + + "You can only call Hooks at the top level of your React function. " + + "For more information, see " + + "https://react.dev/link/rules-of-hooks" + ); + }; + + HooksDispatcherOnMountInDEV = { + readContext: function (context) { + return readContext(context); + }, + use: use, + useCallback: function (callback, deps) { + currentHookNameInDev = "useCallback"; + mountHookTypesDev(); + checkDepsAreArrayDev(deps); + return mountCallback(callback, deps); + }, + useContext: function (context) { + currentHookNameInDev = "useContext"; + mountHookTypesDev(); + return readContext(context); + }, + useEffect: function (create, deps) { + currentHookNameInDev = "useEffect"; + mountHookTypesDev(); + checkDepsAreArrayDev(deps); + return mountEffect(create, deps); + }, + useImperativeHandle: function (ref, create, deps) { + currentHookNameInDev = "useImperativeHandle"; + mountHookTypesDev(); + checkDepsAreArrayDev(deps); + return mountImperativeHandle(ref, create, deps); + }, + useInsertionEffect: function (create, deps) { + currentHookNameInDev = "useInsertionEffect"; + mountHookTypesDev(); + checkDepsAreArrayDev(deps); + return mountInsertionEffect(create, deps); + }, + useLayoutEffect: function (create, deps) { + currentHookNameInDev = "useLayoutEffect"; + mountHookTypesDev(); + checkDepsAreArrayDev(deps); + return mountLayoutEffect(create, deps); + }, + useMemo: function (create, deps) { + currentHookNameInDev = "useMemo"; + mountHookTypesDev(); + checkDepsAreArrayDev(deps); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = + InvalidNestedHooksDispatcherOnMountInDEV; + + try { + return mountMemo(create, deps); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useReducer: function (reducer, initialArg, init) { + currentHookNameInDev = "useReducer"; + mountHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = + InvalidNestedHooksDispatcherOnMountInDEV; + + try { + return mountReducer(reducer, initialArg, init); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useRef: function (initialValue) { + currentHookNameInDev = "useRef"; + mountHookTypesDev(); + return mountRef(initialValue); + }, + useState: function (initialState) { + currentHookNameInDev = "useState"; + mountHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = + InvalidNestedHooksDispatcherOnMountInDEV; + + try { + return mountState(initialState); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useDebugValue: function (value, formatterFn) { + currentHookNameInDev = "useDebugValue"; + mountHookTypesDev(); + return mountDebugValue(); + }, + useDeferredValue: function (value, initialValue) { + currentHookNameInDev = "useDeferredValue"; + mountHookTypesDev(); + return mountDeferredValue(value, initialValue); + }, + useTransition: function () { + currentHookNameInDev = "useTransition"; + mountHookTypesDev(); + return mountTransition(); + }, + useSyncExternalStore: function ( + subscribe, + getSnapshot, + getServerSnapshot + ) { + currentHookNameInDev = "useSyncExternalStore"; + mountHookTypesDev(); + return mountSyncExternalStore(subscribe, getSnapshot); + }, + useId: function () { + currentHookNameInDev = "useId"; + mountHookTypesDev(); + return mountId(); + } + }; + + HooksDispatcherOnMountWithHookTypesInDEV = { + readContext: function (context) { + return readContext(context); + }, + use: use, + useCallback: function (callback, deps) { + currentHookNameInDev = "useCallback"; + updateHookTypesDev(); + return mountCallback(callback, deps); + }, + useContext: function (context) { + currentHookNameInDev = "useContext"; + updateHookTypesDev(); + return readContext(context); + }, + useEffect: function (create, deps) { + currentHookNameInDev = "useEffect"; + updateHookTypesDev(); + return mountEffect(create, deps); + }, + useImperativeHandle: function (ref, create, deps) { + currentHookNameInDev = "useImperativeHandle"; + updateHookTypesDev(); + return mountImperativeHandle(ref, create, deps); + }, + useInsertionEffect: function (create, deps) { + currentHookNameInDev = "useInsertionEffect"; + updateHookTypesDev(); + return mountInsertionEffect(create, deps); + }, + useLayoutEffect: function (create, deps) { + currentHookNameInDev = "useLayoutEffect"; + updateHookTypesDev(); + return mountLayoutEffect(create, deps); + }, + useMemo: function (create, deps) { + currentHookNameInDev = "useMemo"; + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = + InvalidNestedHooksDispatcherOnMountInDEV; + + try { + return mountMemo(create, deps); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useReducer: function (reducer, initialArg, init) { + currentHookNameInDev = "useReducer"; + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = + InvalidNestedHooksDispatcherOnMountInDEV; + + try { + return mountReducer(reducer, initialArg, init); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useRef: function (initialValue) { + currentHookNameInDev = "useRef"; + updateHookTypesDev(); + return mountRef(initialValue); + }, + useState: function (initialState) { + currentHookNameInDev = "useState"; + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = + InvalidNestedHooksDispatcherOnMountInDEV; + + try { + return mountState(initialState); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useDebugValue: function (value, formatterFn) { + currentHookNameInDev = "useDebugValue"; + updateHookTypesDev(); + return mountDebugValue(); + }, + useDeferredValue: function (value, initialValue) { + currentHookNameInDev = "useDeferredValue"; + updateHookTypesDev(); + return mountDeferredValue(value, initialValue); + }, + useTransition: function () { + currentHookNameInDev = "useTransition"; + updateHookTypesDev(); + return mountTransition(); + }, + useSyncExternalStore: function ( + subscribe, + getSnapshot, + getServerSnapshot + ) { + currentHookNameInDev = "useSyncExternalStore"; + updateHookTypesDev(); + return mountSyncExternalStore(subscribe, getSnapshot); + }, + useId: function () { + currentHookNameInDev = "useId"; + updateHookTypesDev(); + return mountId(); + } + }; + + HooksDispatcherOnUpdateInDEV = { + readContext: function (context) { + return readContext(context); + }, + use: use, + useCallback: function (callback, deps) { + currentHookNameInDev = "useCallback"; + updateHookTypesDev(); + return updateCallback(callback, deps); + }, + useContext: function (context) { + currentHookNameInDev = "useContext"; + updateHookTypesDev(); + return readContext(context); + }, + useEffect: function (create, deps) { + currentHookNameInDev = "useEffect"; + updateHookTypesDev(); + return updateEffect(create, deps); + }, + useImperativeHandle: function (ref, create, deps) { + currentHookNameInDev = "useImperativeHandle"; + updateHookTypesDev(); + return updateImperativeHandle(ref, create, deps); + }, + useInsertionEffect: function (create, deps) { + currentHookNameInDev = "useInsertionEffect"; + updateHookTypesDev(); + return updateInsertionEffect(create, deps); + }, + useLayoutEffect: function (create, deps) { + currentHookNameInDev = "useLayoutEffect"; + updateHookTypesDev(); + return updateLayoutEffect(create, deps); + }, + useMemo: function (create, deps) { + currentHookNameInDev = "useMemo"; + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = + InvalidNestedHooksDispatcherOnUpdateInDEV; + + try { + return updateMemo(create, deps); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useReducer: function (reducer, initialArg, init) { + currentHookNameInDev = "useReducer"; + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = + InvalidNestedHooksDispatcherOnUpdateInDEV; + + try { + return updateReducer(reducer, initialArg, init); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useRef: function (initialValue) { + currentHookNameInDev = "useRef"; + updateHookTypesDev(); + return updateRef(); + }, + useState: function (initialState) { + currentHookNameInDev = "useState"; + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = + InvalidNestedHooksDispatcherOnUpdateInDEV; + + try { + return updateState(initialState); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useDebugValue: function (value, formatterFn) { + currentHookNameInDev = "useDebugValue"; + updateHookTypesDev(); + return updateDebugValue(); + }, + useDeferredValue: function (value, initialValue) { + currentHookNameInDev = "useDeferredValue"; + updateHookTypesDev(); + return updateDeferredValue(value, initialValue); + }, + useTransition: function () { + currentHookNameInDev = "useTransition"; + updateHookTypesDev(); + return updateTransition(); + }, + useSyncExternalStore: function ( + subscribe, + getSnapshot, + getServerSnapshot + ) { + currentHookNameInDev = "useSyncExternalStore"; + updateHookTypesDev(); + return updateSyncExternalStore(subscribe, getSnapshot); + }, + useId: function () { + currentHookNameInDev = "useId"; + updateHookTypesDev(); + return updateId(); + } + }; + + HooksDispatcherOnRerenderInDEV = { + readContext: function (context) { + return readContext(context); + }, + use: use, + useCallback: function (callback, deps) { + currentHookNameInDev = "useCallback"; + updateHookTypesDev(); + return updateCallback(callback, deps); + }, + useContext: function (context) { + currentHookNameInDev = "useContext"; + updateHookTypesDev(); + return readContext(context); + }, + useEffect: function (create, deps) { + currentHookNameInDev = "useEffect"; + updateHookTypesDev(); + return updateEffect(create, deps); + }, + useImperativeHandle: function (ref, create, deps) { + currentHookNameInDev = "useImperativeHandle"; + updateHookTypesDev(); + return updateImperativeHandle(ref, create, deps); + }, + useInsertionEffect: function (create, deps) { + currentHookNameInDev = "useInsertionEffect"; + updateHookTypesDev(); + return updateInsertionEffect(create, deps); + }, + useLayoutEffect: function (create, deps) { + currentHookNameInDev = "useLayoutEffect"; + updateHookTypesDev(); + return updateLayoutEffect(create, deps); + }, + useMemo: function (create, deps) { + currentHookNameInDev = "useMemo"; + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = + InvalidNestedHooksDispatcherOnRerenderInDEV; + + try { + return updateMemo(create, deps); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useReducer: function (reducer, initialArg, init) { + currentHookNameInDev = "useReducer"; + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = + InvalidNestedHooksDispatcherOnRerenderInDEV; + + try { + return rerenderReducer(reducer, initialArg, init); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useRef: function (initialValue) { + currentHookNameInDev = "useRef"; + updateHookTypesDev(); + return updateRef(); + }, + useState: function (initialState) { + currentHookNameInDev = "useState"; + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = + InvalidNestedHooksDispatcherOnRerenderInDEV; + + try { + return rerenderState(initialState); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useDebugValue: function (value, formatterFn) { + currentHookNameInDev = "useDebugValue"; + updateHookTypesDev(); + return updateDebugValue(); + }, + useDeferredValue: function (value, initialValue) { + currentHookNameInDev = "useDeferredValue"; + updateHookTypesDev(); + return rerenderDeferredValue(value, initialValue); + }, + useTransition: function () { + currentHookNameInDev = "useTransition"; + updateHookTypesDev(); + return rerenderTransition(); + }, + useSyncExternalStore: function ( + subscribe, + getSnapshot, + getServerSnapshot + ) { + currentHookNameInDev = "useSyncExternalStore"; + updateHookTypesDev(); + return updateSyncExternalStore(subscribe, getSnapshot); + }, + useId: function () { + currentHookNameInDev = "useId"; + updateHookTypesDev(); + return updateId(); + } + }; + + InvalidNestedHooksDispatcherOnMountInDEV = { + readContext: function (context) { + warnInvalidContextAccess(); + return readContext(context); + }, + use: function (usable) { + warnInvalidHookAccess(); + return use(usable); + }, + useCallback: function (callback, deps) { + currentHookNameInDev = "useCallback"; + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountCallback(callback, deps); + }, + useContext: function (context) { + currentHookNameInDev = "useContext"; + warnInvalidHookAccess(); + mountHookTypesDev(); + return readContext(context); + }, + useEffect: function (create, deps) { + currentHookNameInDev = "useEffect"; + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountEffect(create, deps); + }, + useImperativeHandle: function (ref, create, deps) { + currentHookNameInDev = "useImperativeHandle"; + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountImperativeHandle(ref, create, deps); + }, + useInsertionEffect: function (create, deps) { + currentHookNameInDev = "useInsertionEffect"; + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountInsertionEffect(create, deps); + }, + useLayoutEffect: function (create, deps) { + currentHookNameInDev = "useLayoutEffect"; + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountLayoutEffect(create, deps); + }, + useMemo: function (create, deps) { + currentHookNameInDev = "useMemo"; + warnInvalidHookAccess(); + mountHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = + InvalidNestedHooksDispatcherOnMountInDEV; + + try { + return mountMemo(create, deps); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useReducer: function (reducer, initialArg, init) { + currentHookNameInDev = "useReducer"; + warnInvalidHookAccess(); + mountHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = + InvalidNestedHooksDispatcherOnMountInDEV; + + try { + return mountReducer(reducer, initialArg, init); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useRef: function (initialValue) { + currentHookNameInDev = "useRef"; + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountRef(initialValue); + }, + useState: function (initialState) { + currentHookNameInDev = "useState"; + warnInvalidHookAccess(); + mountHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = + InvalidNestedHooksDispatcherOnMountInDEV; + + try { + return mountState(initialState); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useDebugValue: function (value, formatterFn) { + currentHookNameInDev = "useDebugValue"; + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountDebugValue(); + }, + useDeferredValue: function (value, initialValue) { + currentHookNameInDev = "useDeferredValue"; + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountDeferredValue(value, initialValue); + }, + useTransition: function () { + currentHookNameInDev = "useTransition"; + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountTransition(); + }, + useSyncExternalStore: function ( + subscribe, + getSnapshot, + getServerSnapshot + ) { + currentHookNameInDev = "useSyncExternalStore"; + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountSyncExternalStore(subscribe, getSnapshot); + }, + useId: function () { + currentHookNameInDev = "useId"; + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountId(); + } + }; + + InvalidNestedHooksDispatcherOnUpdateInDEV = { + readContext: function (context) { + warnInvalidContextAccess(); + return readContext(context); + }, + use: function (usable) { + warnInvalidHookAccess(); + return use(usable); + }, + useCallback: function (callback, deps) { + currentHookNameInDev = "useCallback"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateCallback(callback, deps); + }, + useContext: function (context) { + currentHookNameInDev = "useContext"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return readContext(context); + }, + useEffect: function (create, deps) { + currentHookNameInDev = "useEffect"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateEffect(create, deps); + }, + useImperativeHandle: function (ref, create, deps) { + currentHookNameInDev = "useImperativeHandle"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateImperativeHandle(ref, create, deps); + }, + useInsertionEffect: function (create, deps) { + currentHookNameInDev = "useInsertionEffect"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateInsertionEffect(create, deps); + }, + useLayoutEffect: function (create, deps) { + currentHookNameInDev = "useLayoutEffect"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateLayoutEffect(create, deps); + }, + useMemo: function (create, deps) { + currentHookNameInDev = "useMemo"; + warnInvalidHookAccess(); + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = + InvalidNestedHooksDispatcherOnUpdateInDEV; + + try { + return updateMemo(create, deps); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useReducer: function (reducer, initialArg, init) { + currentHookNameInDev = "useReducer"; + warnInvalidHookAccess(); + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = + InvalidNestedHooksDispatcherOnUpdateInDEV; + + try { + return updateReducer(reducer, initialArg, init); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useRef: function (initialValue) { + currentHookNameInDev = "useRef"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateRef(); + }, + useState: function (initialState) { + currentHookNameInDev = "useState"; + warnInvalidHookAccess(); + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = + InvalidNestedHooksDispatcherOnUpdateInDEV; + + try { + return updateState(initialState); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useDebugValue: function (value, formatterFn) { + currentHookNameInDev = "useDebugValue"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateDebugValue(); + }, + useDeferredValue: function (value, initialValue) { + currentHookNameInDev = "useDeferredValue"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateDeferredValue(value, initialValue); + }, + useTransition: function () { + currentHookNameInDev = "useTransition"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateTransition(); + }, + useSyncExternalStore: function ( + subscribe, + getSnapshot, + getServerSnapshot + ) { + currentHookNameInDev = "useSyncExternalStore"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateSyncExternalStore(subscribe, getSnapshot); + }, + useId: function () { + currentHookNameInDev = "useId"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateId(); + } + }; + + InvalidNestedHooksDispatcherOnRerenderInDEV = { + readContext: function (context) { + warnInvalidContextAccess(); + return readContext(context); + }, + use: function (usable) { + warnInvalidHookAccess(); + return use(usable); + }, + useCallback: function (callback, deps) { + currentHookNameInDev = "useCallback"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateCallback(callback, deps); + }, + useContext: function (context) { + currentHookNameInDev = "useContext"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return readContext(context); + }, + useEffect: function (create, deps) { + currentHookNameInDev = "useEffect"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateEffect(create, deps); + }, + useImperativeHandle: function (ref, create, deps) { + currentHookNameInDev = "useImperativeHandle"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateImperativeHandle(ref, create, deps); + }, + useInsertionEffect: function (create, deps) { + currentHookNameInDev = "useInsertionEffect"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateInsertionEffect(create, deps); + }, + useLayoutEffect: function (create, deps) { + currentHookNameInDev = "useLayoutEffect"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateLayoutEffect(create, deps); + }, + useMemo: function (create, deps) { + currentHookNameInDev = "useMemo"; + warnInvalidHookAccess(); + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = + InvalidNestedHooksDispatcherOnUpdateInDEV; + + try { + return updateMemo(create, deps); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useReducer: function (reducer, initialArg, init) { + currentHookNameInDev = "useReducer"; + warnInvalidHookAccess(); + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = + InvalidNestedHooksDispatcherOnUpdateInDEV; + + try { + return rerenderReducer(reducer, initialArg, init); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useRef: function (initialValue) { + currentHookNameInDev = "useRef"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateRef(); + }, + useState: function (initialState) { + currentHookNameInDev = "useState"; + warnInvalidHookAccess(); + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = + InvalidNestedHooksDispatcherOnUpdateInDEV; + + try { + return rerenderState(initialState); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useDebugValue: function (value, formatterFn) { + currentHookNameInDev = "useDebugValue"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateDebugValue(); + }, + useDeferredValue: function (value, initialValue) { + currentHookNameInDev = "useDeferredValue"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return rerenderDeferredValue(value, initialValue); + }, + useTransition: function () { + currentHookNameInDev = "useTransition"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return rerenderTransition(); + }, + useSyncExternalStore: function ( + subscribe, + getSnapshot, + getServerSnapshot + ) { + currentHookNameInDev = "useSyncExternalStore"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateSyncExternalStore(subscribe, getSnapshot); + }, + useId: function () { + currentHookNameInDev = "useId"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateId(); + } + }; + } + + var now = Scheduler.unstable_now; + var commitTime = 0; + var layoutEffectStartTime = -1; + var profilerStartTime = -1; + var passiveEffectStartTime = -1; + /** + * Tracks whether the current update was a nested/cascading update (scheduled from a layout effect). + * + * The overall sequence is: + * 1. render + * 2. commit (and call `onRender`, `onCommit`) + * 3. check for nested updates + * 4. flush passive effects (and call `onPostCommit`) + * + * Nested updates are identified in step 3 above, + * but step 4 still applies to the work that was just committed. + * We use two flags to track nested updates then: + * one tracks whether the upcoming update is a nested update, + * and the other tracks whether the current update was a nested update. + * The first value gets synced to the second at the start of the render phase. + */ + + var currentUpdateIsNested = false; + var nestedUpdateScheduled = false; + + function isCurrentUpdateNested() { + return currentUpdateIsNested; + } + + function markNestedUpdateScheduled() { + { + nestedUpdateScheduled = true; + } + } + + function resetNestedUpdateFlag() { + { + currentUpdateIsNested = false; + nestedUpdateScheduled = false; + } + } + + function syncNestedUpdateFlag() { + { + currentUpdateIsNested = nestedUpdateScheduled; + nestedUpdateScheduled = false; + } + } + + function getCommitTime() { + return commitTime; + } + + function recordCommitTime() { + commitTime = now(); + } + + function startProfilerTimer(fiber) { + profilerStartTime = now(); + + if (fiber.actualStartTime < 0) { + fiber.actualStartTime = now(); + } + } + + function stopProfilerTimerIfRunning(fiber) { + profilerStartTime = -1; + } + + function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) { + if (profilerStartTime >= 0) { + var elapsedTime = now() - profilerStartTime; + fiber.actualDuration += elapsedTime; + + if (overrideBaseTime) { + fiber.selfBaseDuration = elapsedTime; + } + + profilerStartTime = -1; + } + } + + function recordLayoutEffectDuration(fiber) { + if (layoutEffectStartTime >= 0) { + var elapsedTime = now() - layoutEffectStartTime; + layoutEffectStartTime = -1; // Store duration on the next nearest Profiler ancestor + // Or the root (for the DevTools Profiler to read) + + var parentFiber = fiber.return; + + while (parentFiber !== null) { + switch (parentFiber.tag) { + case HostRoot: + var root = parentFiber.stateNode; + root.effectDuration += elapsedTime; + return; + + case Profiler: + var parentStateNode = parentFiber.stateNode; + parentStateNode.effectDuration += elapsedTime; + return; + } + + parentFiber = parentFiber.return; + } + } + } + + function recordPassiveEffectDuration(fiber) { + if (passiveEffectStartTime >= 0) { + var elapsedTime = now() - passiveEffectStartTime; + passiveEffectStartTime = -1; // Store duration on the next nearest Profiler ancestor + // Or the root (for the DevTools Profiler to read) + + var parentFiber = fiber.return; + + while (parentFiber !== null) { + switch (parentFiber.tag) { + case HostRoot: + var root = parentFiber.stateNode; + + if (root !== null) { + root.passiveEffectDuration += elapsedTime; + } + + return; + + case Profiler: + var parentStateNode = parentFiber.stateNode; + + if (parentStateNode !== null) { + // Detached fibers have their state node cleared out. + // In this case, the return pointer is also cleared out, + // so we won't be able to report the time spent in this Profiler's subtree. + parentStateNode.passiveEffectDuration += elapsedTime; + } + + return; + } + + parentFiber = parentFiber.return; + } + } + } + + function startLayoutEffectTimer() { + layoutEffectStartTime = now(); + } + + function startPassiveEffectTimer() { + passiveEffectStartTime = now(); + } + + 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) { + // $FlowFixMe[unsafe-addition] addition with possible null/undefined value + fiber.actualDuration += child.actualDuration; + child = child.sibling; + } + } + + function resolveDefaultProps(Component, baseProps) { + if (Component && Component.defaultProps) { + // Resolve default props. Taken from ReactElement + var props = assign({}, baseProps); + var defaultProps = Component.defaultProps; + + for (var propName in defaultProps) { + if (props[propName] === undefined) { + props[propName] = defaultProps[propName]; + } + } + + return props; + } + + return baseProps; + } + + var fakeInternalInstance = {}; + var didWarnAboutStateAssignmentForComponent; + var didWarnAboutUninitializedState; + var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate; + var didWarnAboutLegacyLifecyclesAndDerivedState; + var didWarnAboutUndefinedDerivedState; + var didWarnAboutDirectlyAssigningPropsToState; + var didWarnAboutInvalidateContextType; + var didWarnOnInvalidCallback; + + { + didWarnAboutStateAssignmentForComponent = new Set(); + didWarnAboutUninitializedState = new Set(); + didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set(); + didWarnAboutLegacyLifecyclesAndDerivedState = new Set(); + didWarnAboutDirectlyAssigningPropsToState = new Set(); + didWarnAboutUndefinedDerivedState = new Set(); + didWarnAboutInvalidateContextType = new Set(); + didWarnOnInvalidCallback = new Set(); // This is so gross but it's at least non-critical and can be removed if + // it causes problems. This is meant to give a nicer error message for + // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component, + // ...)) which otherwise throws a "_processChildContext is not a function" + // exception. + + Object.defineProperty(fakeInternalInstance, "_processChildContext", { + enumerable: false, + value: function () { + throw new Error( + "_processChildContext is not available in React 16+. This likely " + + "means you have multiple copies of React and are attempting to nest " + + "a React 15 tree inside a React 16 tree using " + + "unstable_renderSubtreeIntoContainer, which isn't supported. Try " + + "to make sure you have only one copy of React (and ideally, switch " + + "to ReactDOM.createPortal)." + ); + } + }); + Object.freeze(fakeInternalInstance); + } + + function warnOnInvalidCallback(callback) { + { + if (callback === null || typeof callback === "function") { + return; + } // eslint-disable-next-line react-internal/safe-string-coercion + + var key = String(callback); + + if (!didWarnOnInvalidCallback.has(key)) { + didWarnOnInvalidCallback.add(key); + + error( + "Expected the last optional `callback` argument to be a " + + "function. Instead received: %s.", + callback + ); + } + } + } + + function warnOnUndefinedDerivedState(type, partialState) { + { + if (partialState === undefined) { + var componentName = getComponentNameFromType(type) || "Component"; + + if (!didWarnAboutUndefinedDerivedState.has(componentName)) { + didWarnAboutUndefinedDerivedState.add(componentName); + + error( + "%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. " + + "You have returned undefined.", + componentName + ); + } + } + } + } + + function applyDerivedStateFromProps( + workInProgress, + ctor, + getDerivedStateFromProps, + nextProps + ) { + var prevState = workInProgress.memoizedState; + var partialState = getDerivedStateFromProps(nextProps, prevState); + + { + if (workInProgress.mode & StrictLegacyMode) { + setIsStrictModeForDevtools(true); + + try { + // Invoke the function an extra time to help detect side-effects. + partialState = getDerivedStateFromProps(nextProps, prevState); + } finally { + setIsStrictModeForDevtools(false); + } + } + + warnOnUndefinedDerivedState(ctor, partialState); + } // Merge the partial state and the previous state. + + var memoizedState = + partialState === null || partialState === undefined + ? prevState + : assign({}, prevState, partialState); + workInProgress.memoizedState = memoizedState; // Once the update queue is empty, persist the derived state onto the + // base state. + + if (workInProgress.lanes === NoLanes) { + // Queue is always non-null for classes + var updateQueue = workInProgress.updateQueue; + updateQueue.baseState = memoizedState; + } + } + + var classComponentUpdater = { + isMounted: isMounted, + // $FlowFixMe[missing-local-annot] + enqueueSetState: function (inst, payload, callback) { + var fiber = get(inst); + var lane = requestUpdateLane(fiber); + var update = createUpdate(lane); + update.payload = payload; + + if (callback !== undefined && callback !== null) { + { + warnOnInvalidCallback(callback); + } + + update.callback = callback; + } + + var root = enqueueUpdate(fiber, update, lane); + + if (root !== null) { + scheduleUpdateOnFiber(root, fiber, lane); + entangleTransitions(root, fiber, lane); + } + }, + enqueueReplaceState: function (inst, payload, callback) { + var fiber = get(inst); + var lane = requestUpdateLane(fiber); + var update = createUpdate(lane); + update.tag = ReplaceState; + update.payload = payload; + + if (callback !== undefined && callback !== null) { + { + warnOnInvalidCallback(callback); + } + + update.callback = callback; + } + + var root = enqueueUpdate(fiber, update, lane); + + if (root !== null) { + scheduleUpdateOnFiber(root, fiber, lane); + entangleTransitions(root, fiber, lane); + } + }, + // $FlowFixMe[missing-local-annot] + enqueueForceUpdate: function (inst, callback) { + var fiber = get(inst); + var lane = requestUpdateLane(fiber); + var update = createUpdate(lane); + update.tag = ForceUpdate; + + if (callback !== undefined && callback !== null) { + { + warnOnInvalidCallback(callback); + } + + update.callback = callback; + } + + var root = enqueueUpdate(fiber, update, lane); + + if (root !== null) { + scheduleUpdateOnFiber(root, fiber, lane); + entangleTransitions(root, fiber, lane); + } + } + }; + + function checkShouldComponentUpdate( + workInProgress, + ctor, + oldProps, + newProps, + oldState, + newState, + nextContext + ) { + var instance = workInProgress.stateNode; + + if (typeof instance.shouldComponentUpdate === "function") { + var shouldUpdate = instance.shouldComponentUpdate( + newProps, + newState, + nextContext + ); + + { + if (workInProgress.mode & StrictLegacyMode) { + setIsStrictModeForDevtools(true); + + try { + // Invoke the function an extra time to help detect side-effects. + shouldUpdate = instance.shouldComponentUpdate( + newProps, + newState, + nextContext + ); + } finally { + setIsStrictModeForDevtools(false); + } + } + + if (shouldUpdate === undefined) { + error( + "%s.shouldComponentUpdate(): Returned undefined instead of a " + + "boolean value. Make sure to return true or false.", + getComponentNameFromType(ctor) || "Component" + ); + } + } + + return shouldUpdate; + } + + if (ctor.prototype && ctor.prototype.isPureReactComponent) { + return ( + !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState) + ); + } + + return true; + } + + function checkClassInstance(workInProgress, ctor, newProps) { + var instance = workInProgress.stateNode; + + { + var name = getComponentNameFromType(ctor) || "Component"; + var renderPresent = instance.render; + + if (!renderPresent) { + if (ctor.prototype && typeof ctor.prototype.render === "function") { + error( + "No `render` method found on the %s " + + "instance: did you accidentally return an object from the constructor?", + name + ); + } else { + error( + "No `render` method found on the %s " + + "instance: you may have forgotten to define `render`.", + name + ); + } + } + + if ( + instance.getInitialState && + !instance.getInitialState.isReactClassApproved && + !instance.state + ) { + error( + "getInitialState was defined on %s, a plain JavaScript class. " + + "This is only supported for classes created using React.createClass. " + + "Did you mean to define a state property instead?", + name + ); + } + + if ( + instance.getDefaultProps && + !instance.getDefaultProps.isReactClassApproved + ) { + error( + "getDefaultProps was defined on %s, a plain JavaScript class. " + + "This is only supported for classes created using React.createClass. " + + "Use a static property to define defaultProps instead.", + name + ); + } + + if (instance.propTypes) { + error( + "propTypes was defined as an instance property on %s. Use a static " + + "property to define propTypes instead.", + name + ); + } + + if (instance.contextType) { + error( + "contextType was defined as an instance property on %s. Use a static " + + "property to define contextType instead.", + name + ); + } + + { + if (ctor.childContextTypes) { + error( + "%s uses the legacy childContextTypes API which is no longer supported. " + + "Use React.createContext() instead.", + name + ); + } + + if (ctor.contextTypes) { + error( + "%s uses the legacy contextTypes API which is no longer supported. " + + "Use React.createContext() with static contextType instead.", + name + ); + } + } + + if (typeof instance.componentShouldUpdate === "function") { + error( + "%s has a method called " + + "componentShouldUpdate(). Did you mean shouldComponentUpdate()? " + + "The name is phrased as a question because the function is " + + "expected to return a value.", + name + ); + } + + if ( + ctor.prototype && + ctor.prototype.isPureReactComponent && + typeof instance.shouldComponentUpdate !== "undefined" + ) { + error( + "%s has a method called shouldComponentUpdate(). " + + "shouldComponentUpdate should not be used when extending React.PureComponent. " + + "Please extend React.Component if shouldComponentUpdate is used.", + getComponentNameFromType(ctor) || "A pure component" + ); + } + + if (typeof instance.componentDidUnmount === "function") { + error( + "%s has a method called " + + "componentDidUnmount(). But there is no such lifecycle method. " + + "Did you mean componentWillUnmount()?", + name + ); + } + + if (typeof instance.componentDidReceiveProps === "function") { + error( + "%s has a method called " + + "componentDidReceiveProps(). But there is no such lifecycle method. " + + "If you meant to update the state in response to changing props, " + + "use componentWillReceiveProps(). If you meant to fetch data or " + + "run side-effects or mutations after React has updated the UI, use componentDidUpdate().", + name + ); + } + + if (typeof instance.componentWillRecieveProps === "function") { + error( + "%s has a method called " + + "componentWillRecieveProps(). Did you mean componentWillReceiveProps()?", + name + ); + } + + if (typeof instance.UNSAFE_componentWillRecieveProps === "function") { + error( + "%s has a method called " + + "UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?", + name + ); + } + + var hasMutatedProps = instance.props !== newProps; + + if (instance.props !== undefined && hasMutatedProps) { + error( + "When calling super() in `%s`, make sure to pass " + + "up the same props that your component's constructor was passed.", + name + ); + } + + if (instance.defaultProps) { + error( + "Setting defaultProps as an instance property on %s is not supported and will be ignored." + + " Instead, define defaultProps as a static property on %s.", + name, + name + ); + } + + if ( + typeof instance.getSnapshotBeforeUpdate === "function" && + typeof instance.componentDidUpdate !== "function" && + !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor) + ) { + didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor); + + error( + "%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). " + + "This component defines getSnapshotBeforeUpdate() only.", + getComponentNameFromType(ctor) + ); + } + + if (typeof instance.getDerivedStateFromProps === "function") { + error( + "%s: getDerivedStateFromProps() is defined as an instance method " + + "and will be ignored. Instead, declare it as a static method.", + name + ); + } + + if (typeof instance.getDerivedStateFromError === "function") { + error( + "%s: getDerivedStateFromError() is defined as an instance method " + + "and will be ignored. Instead, declare it as a static method.", + name + ); + } + + if (typeof ctor.getSnapshotBeforeUpdate === "function") { + error( + "%s: getSnapshotBeforeUpdate() is defined as a static method " + + "and will be ignored. Instead, declare it as an instance method.", + name + ); + } + + var state = instance.state; + + if (state && (typeof state !== "object" || isArray(state))) { + error("%s.state: must be set to an object or null", name); + } + + if ( + typeof instance.getChildContext === "function" && + typeof ctor.childContextTypes !== "object" + ) { + error( + "%s.getChildContext(): childContextTypes must be defined in order to " + + "use getChildContext().", + name + ); + } + } + } + + function adoptClassInstance(workInProgress, instance) { + instance.updater = classComponentUpdater; + workInProgress.stateNode = instance; // The instance needs access to the fiber so that it can schedule updates + + set(instance, workInProgress); + + { + instance._reactInternalInstance = fakeInternalInstance; + } + } + + function constructClassInstance(workInProgress, ctor, props) { + var context = emptyContextObject; + var contextType = ctor.contextType; + + { + if ("contextType" in ctor) { + var isValid = // Allow null for conditional declaration + contextType === null || + (contextType !== undefined && + contextType.$$typeof === REACT_CONTEXT_TYPE); + + if (!isValid && !didWarnAboutInvalidateContextType.has(ctor)) { + didWarnAboutInvalidateContextType.add(ctor); + var addendum = ""; + + if (contextType === undefined) { + addendum = + " However, it is set to undefined. " + + "This can be caused by a typo or by mixing up named and default imports. " + + "This can also happen due to a circular dependency, so " + + "try moving the createContext() call to a separate file."; + } else if (typeof contextType !== "object") { + addendum = " However, it is set to a " + typeof contextType + "."; + } else if (contextType.$$typeof === REACT_CONSUMER_TYPE) { + addendum = + " Did you accidentally pass the Context.Consumer instead?"; + } else { + addendum = + " However, it is set to an object with keys {" + + Object.keys(contextType).join(", ") + + "}."; + } + + error( + "%s defines an invalid contextType. " + + "contextType should point to the Context object returned by React.createContext().%s", + getComponentNameFromType(ctor) || "Component", + addendum + ); + } + } + } + + if (typeof contextType === "object" && contextType !== null) { + context = readContext(contextType); + } + + var instance = new ctor(props, context); // Instantiate twice to help detect side-effects. + + { + if (workInProgress.mode & StrictLegacyMode) { + setIsStrictModeForDevtools(true); + + try { + instance = new ctor(props, context); // eslint-disable-line no-new + } finally { + setIsStrictModeForDevtools(false); + } + } + } + + var state = (workInProgress.memoizedState = + instance.state !== null && instance.state !== undefined + ? instance.state + : null); + adoptClassInstance(workInProgress, instance); + + { + if ( + typeof ctor.getDerivedStateFromProps === "function" && + state === null + ) { + var componentName = getComponentNameFromType(ctor) || "Component"; + + if (!didWarnAboutUninitializedState.has(componentName)) { + didWarnAboutUninitializedState.add(componentName); + + error( + "`%s` uses `getDerivedStateFromProps` but its initial state is " + + "%s. This is not recommended. Instead, define the initial state by " + + "assigning an object to `this.state` in the constructor of `%s`. " + + "This ensures that `getDerivedStateFromProps` arguments have a consistent shape.", + componentName, + instance.state === null ? "null" : "undefined", + componentName + ); + } + } // If new component APIs are defined, "unsafe" lifecycles won't be called. + // Warn about these lifecycles if they are present. + // Don't warn about react-lifecycles-compat polyfilled methods though. + + if ( + typeof ctor.getDerivedStateFromProps === "function" || + typeof instance.getSnapshotBeforeUpdate === "function" + ) { + var foundWillMountName = null; + var foundWillReceivePropsName = null; + var foundWillUpdateName = null; + + if ( + typeof instance.componentWillMount === "function" && + instance.componentWillMount.__suppressDeprecationWarning !== true + ) { + foundWillMountName = "componentWillMount"; + } else if (typeof instance.UNSAFE_componentWillMount === "function") { + foundWillMountName = "UNSAFE_componentWillMount"; + } + + if ( + typeof instance.componentWillReceiveProps === "function" && + instance.componentWillReceiveProps.__suppressDeprecationWarning !== + true + ) { + foundWillReceivePropsName = "componentWillReceiveProps"; + } else if ( + typeof instance.UNSAFE_componentWillReceiveProps === "function" + ) { + foundWillReceivePropsName = "UNSAFE_componentWillReceiveProps"; + } + + if ( + typeof instance.componentWillUpdate === "function" && + instance.componentWillUpdate.__suppressDeprecationWarning !== true + ) { + foundWillUpdateName = "componentWillUpdate"; + } else if ( + typeof instance.UNSAFE_componentWillUpdate === "function" + ) { + foundWillUpdateName = "UNSAFE_componentWillUpdate"; + } + + if ( + foundWillMountName !== null || + foundWillReceivePropsName !== null || + foundWillUpdateName !== null + ) { + var _componentName = getComponentNameFromType(ctor) || "Component"; + + var newApiName = + typeof ctor.getDerivedStateFromProps === "function" + ? "getDerivedStateFromProps()" + : "getSnapshotBeforeUpdate()"; + + if ( + !didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName) + ) { + didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName); + + error( + "Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n" + + "%s uses %s but also contains the following legacy lifecycles:%s%s%s\n\n" + + "The above lifecycles should be removed. Learn more about this warning here:\n" + + "https://react.dev/link/unsafe-component-lifecycles", + _componentName, + newApiName, + foundWillMountName !== null ? "\n " + foundWillMountName : "", + foundWillReceivePropsName !== null + ? "\n " + foundWillReceivePropsName + : "", + foundWillUpdateName !== null ? "\n " + foundWillUpdateName : "" + ); + } + } + } + } // Cache unmasked context so we can avoid recreating masked context unless necessary. + + return instance; + } + + function callComponentWillMount(workInProgress, instance) { + var oldState = instance.state; + + if (typeof instance.componentWillMount === "function") { + instance.componentWillMount(); + } + + if (typeof instance.UNSAFE_componentWillMount === "function") { + instance.UNSAFE_componentWillMount(); + } + + if (oldState !== instance.state) { + { + error( + "%s.componentWillMount(): Assigning directly to this.state is " + + "deprecated (except inside a component's " + + "constructor). Use setState instead.", + getComponentNameFromFiber(workInProgress) || "Component" + ); + } + + classComponentUpdater.enqueueReplaceState( + instance, + instance.state, + null + ); + } + } + + function callComponentWillReceiveProps( + workInProgress, + instance, + newProps, + nextContext + ) { + var oldState = instance.state; + + if (typeof instance.componentWillReceiveProps === "function") { + instance.componentWillReceiveProps(newProps, nextContext); + } + + if (typeof instance.UNSAFE_componentWillReceiveProps === "function") { + instance.UNSAFE_componentWillReceiveProps(newProps, nextContext); + } + + if (instance.state !== oldState) { + { + var componentName = + getComponentNameFromFiber(workInProgress) || "Component"; + + if (!didWarnAboutStateAssignmentForComponent.has(componentName)) { + didWarnAboutStateAssignmentForComponent.add(componentName); + + error( + "%s.componentWillReceiveProps(): Assigning directly to " + + "this.state is deprecated (except inside a component's " + + "constructor). Use setState instead.", + componentName + ); + } + } + + classComponentUpdater.enqueueReplaceState( + instance, + instance.state, + null + ); + } + } // Invokes the mount life-cycles on a previously never rendered instance. + + function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { + { + checkClassInstance(workInProgress, ctor, newProps); + } + + var instance = workInProgress.stateNode; + instance.props = newProps; + instance.state = workInProgress.memoizedState; + instance.refs = {}; + initializeUpdateQueue(workInProgress); + var contextType = ctor.contextType; + + if (typeof contextType === "object" && contextType !== null) { + instance.context = readContext(contextType); + } else { + instance.context = emptyContextObject; + } + + { + if (instance.state === newProps) { + var componentName = getComponentNameFromType(ctor) || "Component"; + + if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) { + didWarnAboutDirectlyAssigningPropsToState.add(componentName); + + error( + "%s: It is not recommended to assign props directly to state " + + "because updates to props won't be reflected in state. " + + "In most cases, it is better to use props directly.", + componentName + ); + } + } + + if (workInProgress.mode & StrictLegacyMode) { + ReactStrictModeWarnings.recordLegacyContextWarning( + workInProgress, + instance + ); + } + + ReactStrictModeWarnings.recordUnsafeLifecycleWarnings( + workInProgress, + instance + ); + } + + instance.state = workInProgress.memoizedState; + var getDerivedStateFromProps = ctor.getDerivedStateFromProps; + + if (typeof getDerivedStateFromProps === "function") { + applyDerivedStateFromProps( + workInProgress, + ctor, + getDerivedStateFromProps, + newProps + ); + instance.state = workInProgress.memoizedState; + } // In order to support react-lifecycles-compat polyfilled components, + // Unsafe lifecycles should not be invoked for components using the new APIs. + + if ( + typeof ctor.getDerivedStateFromProps !== "function" && + typeof instance.getSnapshotBeforeUpdate !== "function" && + (typeof instance.UNSAFE_componentWillMount === "function" || + typeof instance.componentWillMount === "function") + ) { + callComponentWillMount(workInProgress, instance); // If we had additional state updates during this life-cycle, let's + // process them now. + + processUpdateQueue(workInProgress, newProps, instance, renderLanes); + suspendIfUpdateReadFromEntangledAsyncAction(); + instance.state = workInProgress.memoizedState; + } + + if (typeof instance.componentDidMount === "function") { + workInProgress.flags |= Update | LayoutStatic; + } + + if ((workInProgress.mode & StrictEffectsMode) !== NoMode) { + workInProgress.flags |= MountLayoutDev; + } + } + + function resumeMountClassInstance( + workInProgress, + ctor, + newProps, + renderLanes + ) { + var instance = workInProgress.stateNode; + var oldProps = workInProgress.memoizedProps; + instance.props = oldProps; + var oldContext = instance.context; + var contextType = ctor.contextType; + var nextContext = emptyContextObject; + + if (typeof contextType === "object" && contextType !== null) { + nextContext = readContext(contextType); + } + + var getDerivedStateFromProps = ctor.getDerivedStateFromProps; + var hasNewLifecycles = + typeof getDerivedStateFromProps === "function" || + typeof instance.getSnapshotBeforeUpdate === "function"; // Note: During these life-cycles, instance.props/instance.state are what + // ever the previously attempted to render - not the "current". However, + // during componentDidUpdate we pass the "current" props. + // In order to support react-lifecycles-compat polyfilled components, + // Unsafe lifecycles should not be invoked for components using the new APIs. + + if ( + !hasNewLifecycles && + (typeof instance.UNSAFE_componentWillReceiveProps === "function" || + typeof instance.componentWillReceiveProps === "function") + ) { + if (oldProps !== newProps || oldContext !== nextContext) { + callComponentWillReceiveProps( + workInProgress, + instance, + newProps, + nextContext + ); + } + } + + resetHasForceUpdateBeforeProcessing(); + var oldState = workInProgress.memoizedState; + var newState = (instance.state = oldState); + processUpdateQueue(workInProgress, newProps, instance, renderLanes); + suspendIfUpdateReadFromEntangledAsyncAction(); + newState = workInProgress.memoizedState; + + if ( + oldProps === newProps && + oldState === newState && + !hasContextChanged() && + !checkHasForceUpdateAfterProcessing() + ) { + // 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 | LayoutStatic; + } + + if ((workInProgress.mode & StrictEffectsMode) !== NoMode) { + workInProgress.flags |= MountLayoutDev; + } + + return false; + } + + if (typeof getDerivedStateFromProps === "function") { + applyDerivedStateFromProps( + workInProgress, + ctor, + getDerivedStateFromProps, + newProps + ); + newState = workInProgress.memoizedState; + } + + var shouldUpdate = + checkHasForceUpdateAfterProcessing() || + checkShouldComponentUpdate( + workInProgress, + ctor, + oldProps, + newProps, + oldState, + newState, + nextContext + ); + + if (shouldUpdate) { + // In order to support react-lifecycles-compat polyfilled components, + // Unsafe lifecycles should not be invoked for components using the new APIs. + if ( + !hasNewLifecycles && + (typeof instance.UNSAFE_componentWillMount === "function" || + typeof instance.componentWillMount === "function") + ) { + if (typeof instance.componentWillMount === "function") { + instance.componentWillMount(); + } + + if (typeof instance.UNSAFE_componentWillMount === "function") { + instance.UNSAFE_componentWillMount(); + } + } + + if (typeof instance.componentDidMount === "function") { + workInProgress.flags |= Update | LayoutStatic; + } + + if ((workInProgress.mode & StrictEffectsMode) !== NoMode) { + workInProgress.flags |= MountLayoutDev; + } + } 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 | LayoutStatic; + } + + if ((workInProgress.mode & StrictEffectsMode) !== NoMode) { + workInProgress.flags |= MountLayoutDev; + } // If shouldComponentUpdate returned false, we should still update the + // memoized state to indicate that this work can be reused. + + workInProgress.memoizedProps = newProps; + workInProgress.memoizedState = newState; + } // Update the existing instance's state, props, and context pointers even + // if shouldComponentUpdate returns false. + + instance.props = newProps; + instance.state = newState; + instance.context = nextContext; + return shouldUpdate; + } // Invokes the update life-cycles and returns false if it shouldn't rerender. + + function updateClassInstance( + current, + workInProgress, + ctor, + newProps, + renderLanes + ) { + var instance = workInProgress.stateNode; + cloneUpdateQueue(current, workInProgress); + var unresolvedOldProps = workInProgress.memoizedProps; + var oldProps = + workInProgress.type === workInProgress.elementType + ? unresolvedOldProps + : resolveDefaultProps(workInProgress.type, unresolvedOldProps); + instance.props = oldProps; + var unresolvedNewProps = workInProgress.pendingProps; + var oldContext = instance.context; + var contextType = ctor.contextType; + var nextContext = emptyContextObject; + + if (typeof contextType === "object" && contextType !== null) { + nextContext = readContext(contextType); + } + + var getDerivedStateFromProps = ctor.getDerivedStateFromProps; + var hasNewLifecycles = + typeof getDerivedStateFromProps === "function" || + typeof instance.getSnapshotBeforeUpdate === "function"; // Note: During these life-cycles, instance.props/instance.state are what + // ever the previously attempted to render - not the "current". However, + // during componentDidUpdate we pass the "current" props. + // In order to support react-lifecycles-compat polyfilled components, + // Unsafe lifecycles should not be invoked for components using the new APIs. + + if ( + !hasNewLifecycles && + (typeof instance.UNSAFE_componentWillReceiveProps === "function" || + typeof instance.componentWillReceiveProps === "function") + ) { + if ( + unresolvedOldProps !== unresolvedNewProps || + oldContext !== nextContext + ) { + callComponentWillReceiveProps( + workInProgress, + instance, + newProps, + nextContext + ); + } + } + + resetHasForceUpdateBeforeProcessing(); + var oldState = workInProgress.memoizedState; + var newState = (instance.state = oldState); + processUpdateQueue(workInProgress, newProps, instance, renderLanes); + suspendIfUpdateReadFromEntangledAsyncAction(); + newState = workInProgress.memoizedState; + + if ( + unresolvedOldProps === unresolvedNewProps && + oldState === newState && + !hasContextChanged() && + !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. + if (typeof instance.componentDidUpdate === "function") { + if ( + unresolvedOldProps !== current.memoizedProps || + oldState !== current.memoizedState + ) { + workInProgress.flags |= Update; + } + } + + if (typeof instance.getSnapshotBeforeUpdate === "function") { + if ( + unresolvedOldProps !== current.memoizedProps || + oldState !== current.memoizedState + ) { + workInProgress.flags |= Snapshot; + } + } + + return false; + } + + if (typeof getDerivedStateFromProps === "function") { + applyDerivedStateFromProps( + workInProgress, + ctor, + getDerivedStateFromProps, + newProps + ); + newState = workInProgress.memoizedState; + } + + var shouldUpdate = + checkHasForceUpdateAfterProcessing() || + checkShouldComponentUpdate( + workInProgress, + ctor, + oldProps, + newProps, + 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, + // Unsafe lifecycles should not be invoked for components using the new APIs. + if ( + !hasNewLifecycles && + (typeof instance.UNSAFE_componentWillUpdate === "function" || + typeof instance.componentWillUpdate === "function") + ) { + if (typeof instance.componentWillUpdate === "function") { + instance.componentWillUpdate(newProps, newState, nextContext); + } + + if (typeof instance.UNSAFE_componentWillUpdate === "function") { + instance.UNSAFE_componentWillUpdate( + newProps, + newState, + nextContext + ); + } + } + + if (typeof instance.componentDidUpdate === "function") { + workInProgress.flags |= Update; + } + + if (typeof instance.getSnapshotBeforeUpdate === "function") { + workInProgress.flags |= Snapshot; + } + } 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.componentDidUpdate === "function") { + if ( + unresolvedOldProps !== current.memoizedProps || + oldState !== current.memoizedState + ) { + workInProgress.flags |= Update; + } + } + + if (typeof instance.getSnapshotBeforeUpdate === "function") { + if ( + unresolvedOldProps !== current.memoizedProps || + oldState !== current.memoizedState + ) { + workInProgress.flags |= Snapshot; + } + } // If shouldComponentUpdate returned false, we should still update the + // memoized props/state to indicate that this work can be reused. + + workInProgress.memoizedProps = newProps; + workInProgress.memoizedState = newState; + } // Update the existing instance's state, props, and context pointers even + // if shouldComponentUpdate returns false. + + instance.props = newProps; + instance.state = newState; + instance.context = nextContext; + return shouldUpdate; + } + + var CapturedStacks = new WeakMap(); + function createCapturedValueAtFiber(value, source) { + // If the value is an error, call this function immediately after it is thrown + // so the stack is accurate. + var stack; + + if (typeof value === "object" && value !== null) { + var capturedStack = CapturedStacks.get(value); + + if (typeof capturedStack === "string") { + stack = capturedStack; + } else { + stack = getStackByFiberInDevAndProd(source); + CapturedStacks.set(value, stack); + } + } else { + stack = getStackByFiberInDevAndProd(source); + } + + return { + value: value, + source: source, + stack: stack, + digest: null + }; + } + function createCapturedValueFromError(value, digest, stack) { + if (typeof stack === "string") { + CapturedStacks.set(value, stack); + } + + return { + value: value, + source: null, + stack: stack != null ? stack : null, + digest: digest != null ? digest : null + }; + } + + if ( + typeof ReactNativePrivateInterface.ReactFiberErrorDialog + .showErrorDialog !== "function" + ) { + throw new Error( + "Expected ReactFiberErrorDialog.showErrorDialog to be a function." + ); + } + + 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 + ); + } + + 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 (logError === false) { + return; + } + + var error = errorInfo.value; + + if (true) { + var source = errorInfo.source; + var stack = errorInfo.stack; + var componentStack = stack !== null ? stack : ""; // TODO: There's no longer a way to silence these warnings e.g. for tests. + // See https://github.com/facebook/react/pull/13384 + + 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://react.dev/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 + + "."); + } // In development, we provide our own message which includes the component stack + // in addition to the error. + + console["error"]( + // Don't transform to our wrapper + "%o\n\n%s\n%s\n\n%s", + error, + componentNameMessage, + componentStack, + errorBoundaryMessage + ); + } + } 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; + }); + } + } + + function createRootErrorUpdate(fiber, errorInfo, lane) { + var update = createUpdate(lane); // Unmount the root by rendering null. + + update.tag = CaptureUpdate; // Caution: React DevTools currently depends on this property + // being called "element". + + update.payload = { + element: null + }; + var error = errorInfo.value; + + update.callback = function () { + onUncaughtError(error); + logCapturedError(fiber, errorInfo); + }; + + return update; + } + + function createClassErrorUpdate(fiber, errorInfo, lane) { + var update = createUpdate(lane); + update.tag = CaptureUpdate; + var getDerivedStateFromError = fiber.type.getDerivedStateFromError; + + if (typeof getDerivedStateFromError === "function") { + var error$1 = errorInfo.value; + + update.payload = function () { + return getDerivedStateFromError(error$1); + }; + + update.callback = function () { + { + markFailedErrorBoundaryForHotReloading(fiber); + } + + logCapturedError(fiber, errorInfo); + }; + } + + var inst = fiber.stateNode; + + if (inst !== null && typeof inst.componentDidCatch === "function") { + // $FlowFixMe[missing-this-annot] + update.callback = function callback() { + { + markFailedErrorBoundaryForHotReloading(fiber); + } + + logCapturedError(fiber, errorInfo); + + 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); + } + + var error$1 = errorInfo.value; + var stack = errorInfo.stack; + this.componentDidCatch(error$1, { + componentStack: stack !== null ? stack : "" + }); + + { + 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" + ); + } + } + } + }; + } + + return update; + } + + function resetSuspendedComponent(sourceFiber, rootRenderLanes) { + // A legacy mode Suspense quirk, only relevant to hook components. + + var tag = sourceFiber.tag; + + if ( + (sourceFiber.mode & ConcurrentMode) === NoMode && + (tag === FunctionComponent || + tag === ForwardRef || + tag === SimpleMemoComponent) + ) { + var currentSource = sourceFiber.alternate; + + if (currentSource) { + sourceFiber.updateQueue = currentSource.updateQueue; + sourceFiber.memoizedState = currentSource.memoizedState; + sourceFiber.lanes = currentSource.lanes; + } else { + sourceFiber.updateQueue = null; + sourceFiber.memoizedState = null; + } + } + } + + function markSuspenseBoundaryShouldCapture( + suspenseBoundary, + returnFiber, + sourceFiber, + root, + rootRenderLanes + ) { + // This marks a Suspense boundary so that when we're unwinding the stack, + // it captures the suspended "exception" and does a second (fallback) pass. + if ((suspenseBoundary.mode & ConcurrentMode) === NoMode) { + // Legacy Mode Suspense + // + // If the boundary is in legacy mode, we should *not* + // suspend the commit. Pretend as if the suspended component rendered + // null and keep rendering. When the Suspense boundary completes, + // we'll do a second pass to render the fallback. + if (suspenseBoundary === returnFiber) { + // Special case where we suspended while reconciling the children of + // a Suspense boundary's inner Offscreen wrapper fiber. This happens + // when a React.lazy component is a direct child of a + // Suspense boundary. + // + // Suspense boundaries are implemented as multiple fibers, but they + // are a single conceptual unit. The legacy mode behavior where we + // pretend the suspended fiber committed as `null` won't work, + // because in this case the "suspended" fiber is the inner + // Offscreen wrapper. + // + // Because the contents of the boundary haven't started rendering + // yet (i.e. nothing in the tree has partially rendered) we can + // switch to the regular, concurrent mode behavior: mark the + // boundary with ShouldCapture and enter the unwind phase. + suspenseBoundary.flags |= ShouldCapture; + } else { + suspenseBoundary.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. + + sourceFiber.flags &= ~(LifecycleEffectMask | Incomplete); + + 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(SyncLane); + update.tag = ForceUpdate; + enqueueUpdate(sourceFiber, update, SyncLane); + } + } // 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); + } + + return suspenseBoundary; + } // 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. + + suspenseBoundary.flags |= ShouldCapture; // TODO: I think we can remove this, since we now use `DidCapture` in + // the begin phase to prevent an early bailout. + + suspenseBoundary.lanes = rootRenderLanes; + return suspenseBoundary; + } + + function throwException( + root, + returnFiber, + sourceFiber, + value, + rootRenderLanes + ) { + // The source fiber did not complete. + sourceFiber.flags |= Incomplete; + + { + if (isDevToolsPresent) { + // If we have pending work still, restore the original updaters + restorePendingUpdaters(root, rootRenderLanes); + } + } + + if (value !== null && typeof value === "object") { + if (typeof value.then === "function") { + // This is a wakeable. The component suspended. + var wakeable = value; + resetSuspendedComponent(sourceFiber); + + var suspenseBoundary = getSuspenseHandler(); + + if (suspenseBoundary !== null) { + switch (suspenseBoundary.tag) { + case SuspenseComponent: { + // If this suspense boundary is not already showing a fallback, mark + // the in-progress render as suspended. We try to perform this logic + // as soon as soon as possible during the render phase, so the work + // loop can know things like whether it's OK to switch to other tasks, + // or whether it can wait for data to resolve before continuing. + // TODO: Most of these checks are already performed when entering a + // Suspense boundary. We should track the information on the stack so + // we don't have to recompute it on demand. This would also allow us + // to unify with `use` which needs to perform this logic even sooner, + // before `throwException` is called. + if (sourceFiber.mode & ConcurrentMode) { + if (getShellBoundary() === null) { + // Suspended in the "shell" of the app. This is an undesirable + // loading state. We should avoid committing this tree. + renderDidSuspendDelayIfPossible(); + } else { + // If we suspended deeper than the shell, we don't need to delay + // the commmit. However, we still call renderDidSuspend if this is + // a new boundary, to tell the work loop that a new fallback has + // appeared during this render. + // TODO: Theoretically we should be able to delete this branch. + // It's currently used for two things: 1) to throttle the + // appearance of successive loading states, and 2) in + // SuspenseList, to determine whether the children include any + // pending fallbacks. For 1, we should apply throttling to all + // retries, not just ones that render an additional fallback. For + // 2, we should check subtreeFlags instead. Then we can delete + // this branch. + var current = suspenseBoundary.alternate; + + if (current === null) { + renderDidSuspend(); + } + } + } + + suspenseBoundary.flags &= ~ForceClientRender; + markSuspenseBoundaryShouldCapture( + suspenseBoundary, + returnFiber, + sourceFiber, + root, + rootRenderLanes + ); // Retry listener + // + // If the fallback does commit, we need to attach a different type of + // listener. This one schedules an update on the Suspense boundary to + // turn the fallback state off. + // + // Stash the wakeable on the boundary fiber so we can access it in the + // commit phase. + // + // When the wakeable resolves, we'll attempt to render the boundary + // again ("retry"). + // Check if this is a Suspensey resource. We do not attach retry + // listeners to these, because we don't actually need them for + // rendering. Only for committing. Instead, if a fallback commits + // and the only thing that suspended was a Suspensey resource, we + // retry immediately. + // TODO: Refactor throwException so that we don't have to do this type + // check. The caller already knows what the cause was. + + var isSuspenseyResource = + wakeable === noopSuspenseyCommitThenable; + + if (isSuspenseyResource) { + suspenseBoundary.flags |= ScheduleRetry; + } else { + var retryQueue = suspenseBoundary.updateQueue; + + if (retryQueue === null) { + suspenseBoundary.updateQueue = new Set([wakeable]); + } else { + retryQueue.add(wakeable); + } // We only attach ping listeners in concurrent mode. Legacy + // Suspense always commits fallbacks synchronously, so there are + // no pings. + + if (suspenseBoundary.mode & ConcurrentMode) { + attachPingListener(root, wakeable, rootRenderLanes); + } + } + + return false; + } + + case OffscreenComponent: { + if (suspenseBoundary.mode & ConcurrentMode) { + suspenseBoundary.flags |= ShouldCapture; + + var _isSuspenseyResource = + wakeable === noopSuspenseyCommitThenable; + + if (_isSuspenseyResource) { + suspenseBoundary.flags |= ScheduleRetry; + } else { + var offscreenQueue = suspenseBoundary.updateQueue; + + if (offscreenQueue === null) { + var newOffscreenQueue = { + transitions: null, + markerInstances: null, + retryQueue: new Set([wakeable]) + }; + suspenseBoundary.updateQueue = newOffscreenQueue; + } else { + var _retryQueue = offscreenQueue.retryQueue; + + if (_retryQueue === null) { + offscreenQueue.retryQueue = new Set([wakeable]); + } else { + _retryQueue.add(wakeable); + } + } + + attachPingListener(root, wakeable, rootRenderLanes); + } + + return false; + } + } + } + + throw new Error( + "Unexpected Suspense handler tag (" + + suspenseBoundary.tag + + "). This " + + "is a bug in React." + ); + } else { + // No boundary was found. Unless this is a sync update, this is OK. + // We can suspend and wait for more data to arrive. + if (root.tag === ConcurrentRoot) { + // In a concurrent root, suspending without a Suspense boundary is + // allowed. It will suspend indefinitely without committing. + // + // TODO: Should we have different behavior for discrete updates? What + // about flushSync? Maybe it should put the tree into an inert state, + // and potentially log a warning. Revisit this for a future release. + attachPingListener(root, wakeable, rootRenderLanes); + renderDidSuspendDelayIfPossible(); + return false; + } else { + // In a legacy root, suspending without a boundary is always an error. + var uncaughtSuspenseError = new Error( + "A component suspended while responding to synchronous input. This " + + "will cause the UI to be replaced with a loading indicator. To " + + "fix, updates that suspend should be wrapped " + + "with startTransition." + ); + value = uncaughtSuspenseError; + } + } + } + } // This is a regular error, not a Suspense wakeable. + + value = createCapturedValueAtFiber(value, sourceFiber); + renderDidError(value); // 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. + + if (returnFiber === null) { + // There's no return fiber, which means the root errored. This should never + // happen. Return `true` to trigger a fatal error (panic). + return true; + } + + var workInProgress = returnFiber; + + do { + switch (workInProgress.tag) { + case HostRoot: { + var _errorInfo = value; + workInProgress.flags |= ShouldCapture; + var lane = pickArbitraryLane(rootRenderLanes); + workInProgress.lanes = mergeLanes(workInProgress.lanes, lane); + var update = createRootErrorUpdate( + workInProgress, + _errorInfo, + lane + ); + enqueueCapturedUpdate(workInProgress, update); + return false; + } + + case ClassComponent: + // Capture and retry + var errorInfo = value; + var ctor = workInProgress.type; + var instance = workInProgress.stateNode; + + if ( + (workInProgress.flags & DidCapture) === NoFlags$1 && + (typeof ctor.getDerivedStateFromError === "function" || + (instance !== null && + typeof instance.componentDidCatch === "function" && + !isAlreadyFailedLegacyErrorBoundary(instance))) + ) { + workInProgress.flags |= ShouldCapture; + + var _lane = pickArbitraryLane(rootRenderLanes); + + workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane); // Schedule the error boundary to re-render using updated state + + var _update = createClassErrorUpdate( + workInProgress, + errorInfo, + _lane + ); + + enqueueCapturedUpdate(workInProgress, _update); + return false; + } + + break; + } // $FlowFixMe[incompatible-type] we bail out when we get a null + + workInProgress = workInProgress.return; + } while (workInProgress !== null); + + return false; + } + + var ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner; // A special exception that's used to unwind the stack when an update flows + // into a dehydrated boundary. + + var SelectiveHydrationException = new Error( + "This is not a real error. It's an implementation detail of React's " + + "selective hydration feature. If this leaks into userspace, it's a bug in " + + "React. Please file an issue." + ); + var didReceiveUpdate = false; + var didWarnAboutBadClass; + var didWarnAboutModulePatternComponent; + var didWarnAboutContextTypeOnFunctionComponent; + var didWarnAboutGetDerivedStateOnFunctionComponent; + var didWarnAboutFunctionRefs; + var didWarnAboutReassigningProps; + var didWarnAboutRevealOrder; + var didWarnAboutTailOptions; + var didWarnAboutDefaultPropsOnFunctionComponent; + + { + didWarnAboutBadClass = {}; + didWarnAboutModulePatternComponent = {}; + didWarnAboutContextTypeOnFunctionComponent = {}; + didWarnAboutGetDerivedStateOnFunctionComponent = {}; + didWarnAboutFunctionRefs = {}; + didWarnAboutReassigningProps = false; + didWarnAboutRevealOrder = {}; + didWarnAboutTailOptions = {}; + didWarnAboutDefaultPropsOnFunctionComponent = {}; + } + + 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. + var render = Component.render; + var ref = workInProgress.ref; + var propsWithoutRef; + + { + propsWithoutRef = nextProps; + } // The rest is a fork of updateFunctionComponent + + var nextChildren; + prepareToReadContext(workInProgress, renderLanes); + + { + ReactCurrentOwner$2.current = workInProgress; + setIsRendering(true); + nextChildren = renderWithHooks( + current, + workInProgress, + render, + propsWithoutRef, + ref, + renderLanes + ); + setIsRendering(false); + } + + if (current !== null && !didReceiveUpdate) { + bailoutHooks(current, workInProgress, renderLanes); + return bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderLanes + ); + } + + workInProgress.flags |= PerformedWork; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; + } + + function updateMemoComponent( + current, + workInProgress, + Component, + nextProps, + 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, + renderLanes + ); + } + + { + if (Component.defaultProps !== undefined) { + var componentName = getComponentNameFromType(type) || "Unknown"; + + if (!didWarnAboutDefaultPropsOnFunctionComponent[componentName]) { + error( + "%s: Support for defaultProps will be removed from memo components " + + "in a future major release. Use JavaScript default parameters instead.", + componentName + ); + + didWarnAboutDefaultPropsOnFunctionComponent[componentName] = true; + } + } + } + + var child = createFiberFromTypeAndProps( + Component.type, + null, + nextProps, + workInProgress, + workInProgress.mode, + renderLanes + ); + child.ref = workInProgress.ref; + child.return = workInProgress; + workInProgress.child = child; + return child; + } + + var currentChild = current.child; // This is always exactly one child + + var hasScheduledUpdateOrContext = checkScheduledUpdateOrContext( + current, + renderLanes + ); + + if (!hasScheduledUpdateOrContext) { + // 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, + 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 (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; // The props are shallowly equal. Reuse the previous props object, like we + // would during a normal fiber bailout. + // + // We don't have strong guarantees that the props object is referentially + // equal during updates where we can't bail out anyway — like if the props + // are shallowly equal, but there's a local state or context update in the + // same batch. + // + // However, as a principle, we should aim to make the behavior consistent + // across different ways of memoizing a component. For example, React.memo + // has a different internal Fiber layout if you pass a normal function + // component (SimpleMemoComponent) versus if you pass a different type + // like forwardRef (MemoComponent). But this is an implementation detail. + // Wrapping a component in forwardRef (or React.lazy, etc) shouldn't + // affect whether the props object is reused during a bailout. + + workInProgress.pendingProps = nextProps = prevProps; + + if (!checkScheduledUpdateOrContext(current, renderLanes)) { + // The pending lanes were cleared at the beginning of beginWork. We're + // 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 accumulated 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$1 + ) { + // 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 nextIsDetached = + (workInProgress.stateNode._pendingVisibility & OffscreenDetached) !== 0; + var prevState = current !== null ? current.memoizedState : null; + markRef(current, workInProgress); + + if (nextProps.mode === "hidden" || enableLegacyHidden || nextIsDetached) { + // Rendering a hidden tree. + var didSuspend = (workInProgress.flags & DidCapture) !== NoFlags$1; + + if (didSuspend) { + // Something suspended inside a hidden tree + // Include the base lanes from the last render + var nextBaseLanes = + prevState !== null + ? mergeLanes(prevState.baseLanes, renderLanes) + : renderLanes; + + if (current !== null) { + // Reset to the current children + var currentChild = (workInProgress.child = current.child); // The current render suspended, but there may be other lanes with + // pending work. We can't read `childLanes` from the current Offscreen + // fiber because we reset it when it was deferred; however, we can read + // the pending lanes from the child fibers. + + var currentChildLanes = NoLanes; + + while (currentChild !== null) { + currentChildLanes = mergeLanes( + mergeLanes(currentChildLanes, currentChild.lanes), + currentChild.childLanes + ); + currentChild = currentChild.sibling; + } + + var lanesWeJustAttempted = nextBaseLanes; + var remainingChildLanes = removeLanes( + currentChildLanes, + lanesWeJustAttempted + ); + workInProgress.childLanes = remainingChildLanes; + } else { + workInProgress.childLanes = NoLanes; + workInProgress.child = null; + } + + return deferHiddenOffscreenComponent( + current, + workInProgress, + nextBaseLanes + ); + } + + if ((workInProgress.mode & ConcurrentMode) === NoMode) { + // In legacy sync mode, don't defer the subtree. Render it now. + // TODO: Consider how Offscreen should work with transitions in the future + var nextState = { + baseLanes: NoLanes, + cachePool: null + }; + workInProgress.memoizedState = nextState; + + reuseHiddenContextOnStack(workInProgress); + pushOffscreenSuspenseHandler(workInProgress); + } else if (!includesSomeLane(renderLanes, OffscreenLane)) { + // We're hidden, and we're not rendering at Offscreen. We will bail out + // and resume this tree later. + // Schedule this fiber to re-render at Offscreen priority + workInProgress.lanes = workInProgress.childLanes = + laneToLanes(OffscreenLane); // Include the base lanes from the last render + + var _nextBaseLanes = + prevState !== null + ? mergeLanes(prevState.baseLanes, renderLanes) + : renderLanes; + + return deferHiddenOffscreenComponent( + current, + workInProgress, + _nextBaseLanes + ); + } else { + // This is the second render. The surrounding visible content has already + // committed. Now we resume rendering the hidden tree. + // Rendering at offscreen, so we can clear the base lanes. + var _nextState = { + baseLanes: NoLanes, + cachePool: null + }; + workInProgress.memoizedState = _nextState; + + if (prevState !== null) { + pushHiddenContext(workInProgress, prevState); + } else { + reuseHiddenContextOnStack(workInProgress); + } + + pushOffscreenSuspenseHandler(workInProgress); + } + } else { + // Rendering a visible tree. + if (prevState !== null) { + pushHiddenContext(workInProgress, prevState); + reuseSuspenseHandlerOnStack(workInProgress); // Since we're not hidden anymore, reset the state + + workInProgress.memoizedState = null; + } else { + // to avoid a push/pop misalignment. + + reuseHiddenContextOnStack(workInProgress); + reuseSuspenseHandlerOnStack(workInProgress); + } + } + + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; + } + + function deferHiddenOffscreenComponent( + current, + workInProgress, + nextBaseLanes, + renderLanes + ) { + var nextState = { + baseLanes: nextBaseLanes, + // Save the cache pool so we can resume later. + cachePool: null + }; + workInProgress.memoizedState = nextState; + // to avoid a push/pop misalignment. + + reuseHiddenContextOnStack(workInProgress); + pushOffscreenSuspenseHandler(workInProgress); + + return null; + } // Note: These happen to have identical begin phases, for now. We shouldn't hold + + function updateFragment(current, workInProgress, renderLanes) { + var nextChildren = workInProgress.pendingProps; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; + } + + function updateMode(current, workInProgress, renderLanes) { + var nextChildren = workInProgress.pendingProps.children; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; + } + + function updateProfiler(current, workInProgress, renderLanes) { + { + workInProgress.flags |= Update; + + { + // Reset effect durations for the next eventual effect phase. + // These are reset during render to allow the DevTools commit hook a chance to read them, + var stateNode = workInProgress.stateNode; + stateNode.effectDuration = 0; + stateNode.passiveEffectDuration = 0; + } + } + + var nextProps = workInProgress.pendingProps; + var nextChildren = nextProps.children; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; + } + + function markRef(current, workInProgress) { + // TODO: Check props.ref instead of fiber.ref when enableRefAsProp is on. + var ref = workInProgress.ref; + + if (ref === null) { + if (current !== null && current.ref !== null) { + // Schedule a Ref effect + workInProgress.flags |= Ref | RefStatic; + } + } else { + if (typeof ref !== "function" && typeof ref !== "object") { + throw new Error( + "Expected ref to be a function, an object returned by React.createRef(), or undefined/null." + ); + } + + if (current === null || current.ref !== ref) { + // Schedule a Ref effect + workInProgress.flags |= Ref | RefStatic; + } + } + } + + function updateFunctionComponent( + current, + workInProgress, + Component, + nextProps, + renderLanes + ) { + var context; + + var nextChildren; + prepareToReadContext(workInProgress, renderLanes); + + { + ReactCurrentOwner$2.current = workInProgress; + setIsRendering(true); + nextChildren = renderWithHooks( + current, + workInProgress, + Component, + nextProps, + context, + renderLanes + ); + setIsRendering(false); + } + + if (current !== null && !didReceiveUpdate) { + bailoutHooks(current, workInProgress, renderLanes); + return bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderLanes + ); + } + + workInProgress.flags |= PerformedWork; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; + } + + function replayFunctionComponent( + current, + workInProgress, + nextProps, + Component, + secondArg, + renderLanes + ) { + // This function is used to replay a component that previously suspended, + // after its data resolves. It's a simplified version of + // updateFunctionComponent that reuses the hooks from the previous attempt. + prepareToReadContext(workInProgress, renderLanes); + + var nextChildren = replaySuspendedComponentWithHooks( + current, + workInProgress, + Component, + nextProps, + secondArg + ); + + if (current !== null && !didReceiveUpdate) { + bailoutHooks(current, workInProgress, renderLanes); + return bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderLanes + ); + } + + workInProgress.flags |= PerformedWork; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; + } + + function updateClassComponent( + current, + workInProgress, + Component, + nextProps, + renderLanes + ) { + { + // This is used by DevTools to force a boundary to error. + switch (shouldError(workInProgress)) { + case false: { + var _instance = workInProgress.stateNode; + var ctor = workInProgress.type; // TODO This way of resetting the error boundary state is a hack. + // Is there a better way to do this? + + var tempInstance = new ctor( + workInProgress.memoizedProps, + _instance.context + ); + var state = tempInstance.state; + + _instance.updater.enqueueSetState(_instance, state, null); + + break; + } + + case true: { + workInProgress.flags |= DidCapture; + workInProgress.flags |= ShouldCapture; // eslint-disable-next-line react-internal/prod-error-codes + + var error$1 = new Error("Simulated error coming from DevTools"); + var lane = pickArbitraryLane(renderLanes); + workInProgress.lanes = mergeLanes(workInProgress.lanes, lane); // Schedule the error boundary to re-render using updated state + + var update = createClassErrorUpdate( + workInProgress, + createCapturedValueAtFiber(error$1, workInProgress), + lane + ); + enqueueCapturedUpdate(workInProgress, update); + break; + } + } + } // Push context providers early to prevent context stack mismatches. + // During mounting we don't know the child context yet as the instance doesn't exist. + // We will invalidate the child context in finishClassComponent() right after rendering. + + var hasContext; + + if (isContextProvider()) { + hasContext = true; + } else { + hasContext = false; + } + + prepareToReadContext(workInProgress, renderLanes); + var instance = workInProgress.stateNode; + var shouldUpdate; + + if (instance === null) { + resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress); // 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, + workInProgress, + Component, + shouldUpdate, + 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.", + getComponentNameFromFiber(workInProgress) || "a component" + ); + } + + didWarnAboutReassigningProps = true; + } + } + + return nextUnitOfWork; + } + + function finishClassComponent( + current, + workInProgress, + Component, + shouldUpdate, + hasContext, + renderLanes + ) { + // Refs should update even if shouldComponentUpdate returns false + markRef(current, workInProgress); + var didCaptureError = (workInProgress.flags & DidCapture) !== NoFlags$1; + + if (!shouldUpdate && !didCaptureError) { + return bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderLanes + ); + } + + var instance = workInProgress.stateNode; // Rerender + + ReactCurrentOwner$2.current = workInProgress; + var nextChildren; + + if ( + didCaptureError && + typeof Component.getDerivedStateFromError !== "function" + ) { + // If we captured an error, but getDerivedStateFromError is not defined, + // unmount all the children. componentDidCatch will schedule an update to + // re-render a fallback. This is temporary until we migrate everyone to + // the new API. + // TODO: Warn in a future release. + nextChildren = null; + + { + stopProfilerTimerIfRunning(); + } + } else { + { + setIsRendering(true); + nextChildren = instance.render(); + + if (workInProgress.mode & StrictLegacyMode) { + setIsStrictModeForDevtools(true); + + try { + instance.render(); + } finally { + setIsStrictModeForDevtools(false); + } + } + + setIsRendering(false); + } + } // React DevTools reads this flag. + + workInProgress.flags |= PerformedWork; + + if (current !== null && didCaptureError) { + // If we're recovering from an error, reconcile without reusing any of + // the existing children. Conceptually, the normal children and the children + // that are shown on error are two different sets, so we shouldn't reuse + // normal children even if their identities match. + forceUnmountCurrentAndReconcile( + current, + workInProgress, + nextChildren, + renderLanes + ); + } else { + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + } // Memoize state using the values we just used to render. + // TODO: Restructure so we never read values from the instance. + + workInProgress.memoizedState = instance.state; // The context might have changed so we need to recalculate it. + + return workInProgress.child; + } + + function pushHostRootContext(workInProgress) { + var root = workInProgress.stateNode; + + pushHostContainer(workInProgress, root.containerInfo); + } + + function updateHostRoot(current, workInProgress, renderLanes) { + pushHostRootContext(workInProgress); + + if (current === null) { + throw new Error("Should have a current fiber. This is a bug in React."); + } + + var nextProps = workInProgress.pendingProps; + var prevState = workInProgress.memoizedState; + var prevChildren = prevState.element; + cloneUpdateQueue(current, workInProgress); + processUpdateQueue(workInProgress, nextProps, null, renderLanes); + var nextState = workInProgress.memoizedState; + // it needs to happen after the `pushCacheProvider` call above to avoid a + // context stack mismatch. A bit unfortunate. + + suspendIfUpdateReadFromEntangledAsyncAction(); // Caution: React DevTools currently depends on this property + // being called "element". + + var nextChildren = nextState.element; + + { + if (nextChildren === prevChildren) { + return bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderLanes + ); + } + + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + } + + return workInProgress.child; + } + + function updateHostComponent$1(current, workInProgress, renderLanes) { + pushHostContext(workInProgress); + var nextProps = workInProgress.pendingProps; + var prevProps = current !== null ? current.memoizedProps : null; + var nextChildren = nextProps.children; + + if (prevProps !== null && shouldSetTextContent()) { + // If we're switching from a direct text child to a normal child, or to + // empty, we need to schedule the text content to be reset. + workInProgress.flags |= ContentReset; + } + + markRef(current, workInProgress); + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; + } + + function updateHostText$1(current, workInProgress) { + // immediately after. + + return null; + } + + function mountLazyComponent( + _current, + workInProgress, + elementType, + renderLanes + ) { + resetSuspendedCurrentOnMountInLegacyMode(_current, workInProgress); + 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; + } + + case ForwardRef: { + { + workInProgress.type = Component = + resolveForwardRefForHotReloading(Component); + } + + child = updateForwardRef( + null, + workInProgress, + Component, + resolvedProps, + renderLanes + ); + return child; + } + + case MemoComponent: { + child = updateMemoComponent( + null, + workInProgress, + Component, + resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too + renderLanes + ); + return child; + } + } + + var hint = ""; + + { + if ( + Component !== null && + typeof Component === "object" && + Component.$$typeof === REACT_LAZY_TYPE + ) { + hint = " Did you wrap a component in React.lazy() more than once?"; + } + } // This message intentionally doesn't mention ForwardRef or MemoComponent + // because the fact that it's a separate type of work is an + // implementation detail. + + throw new Error( + "Element type is invalid. Received a promise that resolves to: " + + Component + + ". " + + ("Lazy element type must resolve to a class or function." + hint) + ); + } + + function mountIncompleteClassComponent( + _current, + workInProgress, + Component, + nextProps, + renderLanes + ) { + resetSuspendedCurrentOnMountInLegacyMode(_current, workInProgress); // Promote the fiber to a class and try rendering again. + + workInProgress.tag = ClassComponent; // The rest of this function is a fork of `updateClassComponent` + // Push context providers early to prevent context stack mismatches. + // During mounting we don't know the child context yet as the instance doesn't exist. + // We will invalidate the child context in finishClassComponent() right after rendering. + + var hasContext; + + if (isContextProvider()) { + hasContext = true; + } else { + hasContext = false; + } + + prepareToReadContext(workInProgress, renderLanes); + constructClassInstance(workInProgress, Component, nextProps); + mountClassInstance(workInProgress, Component, nextProps, renderLanes); + return finishClassComponent( + null, + workInProgress, + Component, + true, + hasContext, + renderLanes + ); + } + + function mountIndeterminateComponent( + _current, + workInProgress, + Component, + renderLanes + ) { + resetSuspendedCurrentOnMountInLegacyMode(_current, workInProgress); + var props = workInProgress.pendingProps; + var context; + + prepareToReadContext(workInProgress, renderLanes); + var value; + + { + if ( + Component.prototype && + typeof Component.prototype.render === "function" + ) { + var componentName = getComponentNameFromType(Component) || "Unknown"; + + if (!didWarnAboutBadClass[componentName]) { + error( + "The <%s /> component appears to have a render method, but doesn't extend React.Component. " + + "This is likely to cause errors. Change %s to extend React.Component instead.", + componentName, + componentName + ); + + didWarnAboutBadClass[componentName] = true; + } + } + + if (workInProgress.mode & StrictLegacyMode) { + ReactStrictModeWarnings.recordLegacyContextWarning( + workInProgress, + null + ); + } + + setIsRendering(true); + ReactCurrentOwner$2.current = workInProgress; + value = renderWithHooks( + null, + workInProgress, + Component, + props, + context, + renderLanes + ); + setIsRendering(false); + } + + workInProgress.flags |= PerformedWork; + + { + // Support for module components is deprecated and is removed behind a flag. + // Whether or not it would crash later, we want to show a good message in DEV first. + if ( + typeof value === "object" && + value !== null && + typeof value.render === "function" && + value.$$typeof === undefined + ) { + var _componentName = 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; + } + } + } + + 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"; + + if (!didWarnAboutModulePatternComponent[_componentName2]) { + error( + "The <%s /> component appears to be a function component that returns a class instance. " + + "Change %s to a class that extends React.Component instead. " + + "If you can't use a class try assigning the prototype on the function as a workaround. " + + "`%s.prototype = React.Component.prototype`. Don't use an arrow function since it " + + "cannot be called with `new` by React.", + _componentName2, + _componentName2, + _componentName2 + ); + + didWarnAboutModulePatternComponent[_componentName2] = true; + } + } // Proceed under the assumption that this is a class instance + + workInProgress.tag = ClassComponent; // Throw out any hooks that were used. + + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; // Push context providers early to prevent context stack mismatches. + // During mounting we don't know the child context yet as the instance doesn't exist. + // We will invalidate the child context in finishClassComponent() right after rendering. + + var hasContext = false; + + if (isContextProvider()) { + hasContext = true; + } 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, + Component, + true, + hasContext, + renderLanes + ); + } else { + // Proceed under the assumption that this is a function component + workInProgress.tag = FunctionComponent; + + { + if (Component.contextTypes) { + error( + "%s uses the legacy contextTypes API which is no longer supported. " + + "Use React.createContext() with React.useContext() instead.", + getComponentNameFromType(Component) || "Unknown" + ); + } + } + + reconcileChildren(null, workInProgress, value, renderLanes); + + { + validateFunctionComponentInDev(workInProgress, Component); + } + + return workInProgress.child; + } + } + + function validateFunctionComponentInDev(workInProgress, Component) { + { + if (Component) { + if (Component.childContextTypes) { + error( + "childContextTypes cannot be defined on a function component.\n" + + " %s.childContextTypes = ...", + Component.displayName || Component.name || "Component" + ); + } + } + + if (workInProgress.ref !== null) { + var info = ""; + var componentName = getComponentNameFromType(Component) || "Unknown"; + var ownerName = getCurrentFiberOwnerNameInDevOrNull(); + + if (ownerName) { + info += "\n\nCheck the render method of `" + ownerName + "`."; + } + + var warningKey = componentName + "|" + (ownerName || ""); + + 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 + ); + } + } + + if (Component.defaultProps !== undefined) { + var _componentName3 = + getComponentNameFromType(Component) || "Unknown"; + + if (!didWarnAboutDefaultPropsOnFunctionComponent[_componentName3]) { + error( + "%s: Support for defaultProps will be removed from function components " + + "in a future major release. Use JavaScript default parameters instead.", + _componentName3 + ); + + didWarnAboutDefaultPropsOnFunctionComponent[_componentName3] = true; + } + } + + if (typeof Component.getDerivedStateFromProps === "function") { + var _componentName4 = + getComponentNameFromType(Component) || "Unknown"; + + if ( + !didWarnAboutGetDerivedStateOnFunctionComponent[_componentName4] + ) { + error( + "%s: Function components do not support getDerivedStateFromProps.", + _componentName4 + ); + + didWarnAboutGetDerivedStateOnFunctionComponent[_componentName4] = + true; + } + } + + if ( + typeof Component.contextType === "object" && + Component.contextType !== null + ) { + var _componentName5 = + getComponentNameFromType(Component) || "Unknown"; + + if (!didWarnAboutContextTypeOnFunctionComponent[_componentName5]) { + error( + "%s: Function components do not support contextType.", + _componentName5 + ); + + didWarnAboutContextTypeOnFunctionComponent[_componentName5] = true; + } + } + } + } + + var SUSPENDED_MARKER = { + dehydrated: null, + treeContext: null, + retryLane: NoLane + }; + + function mountSuspenseOffscreenState(renderLanes) { + return { + baseLanes: renderLanes, + cachePool: getSuspendedCache() + }; + } + + function updateSuspenseOffscreenState(prevOffscreenState, renderLanes) { + var cachePool = null; + + return { + baseLanes: mergeLanes(prevOffscreenState.baseLanes, renderLanes), + cachePool: cachePool + }; + } // TODO: Probably should inline this back + + function shouldRemainOnFallback(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. + // TODO: For compatibility with offscreen prerendering, this should also check + // whether the current fiber (if it exists) was visible in the previous tree. + if (current !== null) { + var suspenseState = current.memoizedState; + + if (suspenseState === null) { + // Currently showing content. Don't hide it, even if ForceSuspenseFallback + // 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 suspenseContext = suspenseStackCursor.current; + return hasSuspenseListContext(suspenseContext, ForceSuspenseFallback); + } + + function getRemainingWorkInPrimaryTree( + current, + primaryTreeDidDefer, + renderLanes + ) { + var remainingLanes = + current !== null + ? removeLanes(current.childLanes, renderLanes) + : NoLanes; + + if (primaryTreeDidDefer) { + // A useDeferredValue hook spawned a deferred task inside the primary tree. + // Ensure that we retry this component at the deferred priority. + // TODO: We could make this a per-subtree value instead of a global one. + // Would need to track it on the context stack somehow, similar to what + // we'd have to do for resumable contexts. + remainingLanes = mergeLanes(remainingLanes, peekDeferredLane()); + } + + return remainingLanes; + } + + 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 showFallback = false; + var didSuspend = (workInProgress.flags & DidCapture) !== NoFlags$1; + + if (didSuspend || shouldRemainOnFallback(current)) { + // Something in this boundary's subtree already suspended. Switch to + // rendering the fallback children. + showFallback = true; + workInProgress.flags &= ~DidCapture; + } // Check if the primary children spawned a deferred task (useDeferredValue) + // during the first pass. + + var didPrimaryChildrenDefer = + (workInProgress.flags & DidDefer) !== NoFlags$1; + workInProgress.flags &= ~DidDefer; // OK, the next part is confusing. We're about to reconcile the Suspense + // boundary's children. This involves some custom reconciliation 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) { + var nextPrimaryChildren = nextProps.children; + var nextFallbackChildren = nextProps.fallback; + + if (showFallback) { + pushFallbackTreeSuspenseHandler(workInProgress); + var fallbackFragment = mountSuspenseFallbackChildren( + workInProgress, + nextPrimaryChildren, + nextFallbackChildren, + renderLanes + ); + var primaryChildFragment = workInProgress.child; + primaryChildFragment.memoizedState = + mountSuspenseOffscreenState(renderLanes); + primaryChildFragment.childLanes = getRemainingWorkInPrimaryTree( + current, + didPrimaryChildrenDefer, + renderLanes + ); + workInProgress.memoizedState = SUSPENDED_MARKER; + + return fallbackFragment; + } else { + pushPrimaryTreeSuspenseHandler(workInProgress); + return mountSuspensePrimaryChildren( + workInProgress, + nextPrimaryChildren + ); + } + } else { + // This is an update. + // Special path for hydration + var prevState = current.memoizedState; + + if (prevState !== null) { + var _dehydrated = prevState.dehydrated; + + if (_dehydrated !== null) { + return updateDehydratedSuspenseComponent( + current, + workInProgress, + didSuspend, + didPrimaryChildrenDefer, + nextProps, + _dehydrated, + prevState, + renderLanes + ); + } + } + + if (showFallback) { + pushFallbackTreeSuspenseHandler(workInProgress); + var _nextFallbackChildren = nextProps.fallback; + var _nextPrimaryChildren = nextProps.children; + var fallbackChildFragment = updateSuspenseFallbackChildren( + current, + workInProgress, + _nextPrimaryChildren, + _nextFallbackChildren, + renderLanes + ); + var _primaryChildFragment2 = workInProgress.child; + var prevOffscreenState = current.child.memoizedState; + _primaryChildFragment2.memoizedState = + prevOffscreenState === null + ? mountSuspenseOffscreenState(renderLanes) + : updateSuspenseOffscreenState(prevOffscreenState, renderLanes); + + _primaryChildFragment2.childLanes = getRemainingWorkInPrimaryTree( + current, + didPrimaryChildrenDefer, + renderLanes + ); + workInProgress.memoizedState = SUSPENDED_MARKER; + return fallbackChildFragment; + } else { + pushPrimaryTreeSuspenseHandler(workInProgress); + var _nextPrimaryChildren2 = nextProps.children; + + var _primaryChildFragment3 = updateSuspensePrimaryChildren( + current, + workInProgress, + _nextPrimaryChildren2, + renderLanes + ); + + workInProgress.memoizedState = null; + return _primaryChildFragment3; + } + } + } + + function mountSuspensePrimaryChildren( + workInProgress, + primaryChildren, + renderLanes + ) { + var mode = workInProgress.mode; + var primaryChildProps = { + mode: "visible", + children: primaryChildren + }; + var primaryChildFragment = mountWorkInProgressOffscreenFiber( + primaryChildProps, + mode + ); + primaryChildFragment.return = workInProgress; + workInProgress.child = primaryChildFragment; + return primaryChildFragment; + } + + 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; + } + + fallbackChildFragment = createFiberFromFragment( + fallbackChildren, + mode, + renderLanes, + null + ); + } else { + primaryChildFragment = mountWorkInProgressOffscreenFiber( + primaryChildProps, + mode + ); + fallbackChildFragment = createFiberFromFragment( + fallbackChildren, + mode, + renderLanes, + null + ); + } + + primaryChildFragment.return = workInProgress; + fallbackChildFragment.return = workInProgress; + primaryChildFragment.sibling = fallbackChildFragment; + workInProgress.child = primaryChildFragment; + return fallbackChildFragment; + } + + function mountWorkInProgressOffscreenFiber( + offscreenProps, + mode, + renderLanes + ) { + // The props argument to `createFiberFromOffscreen` is `any` typed, so we use + // this wrapper function to constrain it. + return createFiberFromOffscreen(offscreenProps, mode, NoLanes, null); + } + + function updateWorkInProgressOffscreenFiber(current, offscreenProps) { + // The props argument to `createWorkInProgress` is `any` typed, so we use this + // wrapper function to constrain it. + return createWorkInProgress(current, offscreenProps); + } + + function updateSuspensePrimaryChildren( + current, + workInProgress, + primaryChildren, + renderLanes + ) { + var currentPrimaryChildFragment = current.child; + var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; + var primaryChildFragment = updateWorkInProgressOffscreenFiber( + currentPrimaryChildFragment, + { + mode: "visible", + children: primaryChildren + } + ); + + if ((workInProgress.mode & ConcurrentMode) === NoMode) { + primaryChildFragment.lanes = renderLanes; + } + + primaryChildFragment.return = workInProgress; + primaryChildFragment.sibling = null; + + if (currentFallbackChildFragment !== null) { + // Delete the fallback child fragment + var deletions = workInProgress.deletions; + + if (deletions === null) { + workInProgress.deletions = [currentFallbackChildFragment]; + workInProgress.flags |= ChildDeletion; + } else { + deletions.push(currentFallbackChildFragment); + } + } + + workInProgress.child = primaryChildFragment; + return primaryChildFragment; + } + + function updateSuspenseFallbackChildren( + current, + workInProgress, + primaryChildren, + fallbackChildren, + renderLanes + ) { + var mode = workInProgress.mode; + var currentPrimaryChildFragment = current.child; + var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; + var primaryChildProps = { + mode: "hidden", + children: primaryChildren + }; + var primaryChildFragment; + + if ( + // In legacy mode, we commit the primary tree as if it successfully + // completed, even though it's in an inconsistent state. + (mode & 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 (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. + + workInProgress.deletions = null; + } else { + primaryChildFragment = updateWorkInProgressOffscreenFiber( + currentPrimaryChildFragment, + primaryChildProps + ); // Since we're reusing a current tree, we need to reuse the flags, too. + // (We don't do this in legacy mode, because in legacy mode we don't re-use + // the current tree; see previous branch.) + + primaryChildFragment.subtreeFlags = + currentPrimaryChildFragment.subtreeFlags & StaticMask; + } + + 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. + + fallbackChildFragment.flags |= Placement; + } + + fallbackChildFragment.return = workInProgress; + primaryChildFragment.return = workInProgress; + primaryChildFragment.sibling = fallbackChildFragment; + workInProgress.child = primaryChildFragment; + return fallbackChildFragment; + } + + function retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + recoverableError + ) { + // Falling back to client rendering. Because this has performance + // implications, it's considered a recoverable error, even though the user + // likely won't observe anything wrong with the UI. + // + // The error is passed in as an argument to enforce that every caller provide + // a custom message, or explicitly opt out (currently the only path that opts + // out is legacy mode; every concurrent path provides an error). + if (recoverableError !== null) { + queueHydrationError(recoverableError); + } // This will add the old fiber to the deletion list + + reconcileChildFibers(workInProgress, current.child, null, renderLanes); // We're now not suspended nor dehydrated. + + var nextProps = workInProgress.pendingProps; + var primaryChildren = nextProps.children; + var primaryChildFragment = mountSuspensePrimaryChildren( + workInProgress, + primaryChildren + ); // Needs a placement effect because the parent (the Suspense boundary) already + // mounted but this is a new fiber. + + primaryChildFragment.flags |= Placement; + workInProgress.memoizedState = null; + return primaryChildFragment; + } + + function mountSuspenseFallbackAfterRetryWithoutHydrating( + current, + workInProgress, + primaryChildren, + fallbackChildren, + renderLanes + ) { + var fiberMode = workInProgress.mode; + var primaryChildProps = { + mode: "visible", + children: primaryChildren }; - pendingProps.stateNode = primaryChildInstance; - return pendingProps; + var primaryChildFragment = mountWorkInProgressOffscreenFiber( + primaryChildProps, + fiberMode + ); + var fallbackChildFragment = createFiberFromFragment( + fallbackChildren, + fiberMode, + renderLanes, + null + ); // Needs a placement effect because the parent (the Suspense + // boundary) already mounted but this is a new fiber. + + fallbackChildFragment.flags |= Placement; + primaryChildFragment.return = workInProgress; + fallbackChildFragment.return = workInProgress; + primaryChildFragment.sibling = fallbackChildFragment; + workInProgress.child = primaryChildFragment; + + if ((workInProgress.mode & ConcurrentMode) !== NoMode) { + // We will have dropped the effect list which contains the + // deletion. We need to reconcile to delete the current child. + reconcileChildFibers(workInProgress, current.child, null, renderLanes); + } + + return fallbackChildFragment; + } + + function updateDehydratedSuspenseComponent( + current, + workInProgress, + didSuspend, + didPrimaryChildrenDefer, + nextProps, + suspenseInstance, + suspenseState, + renderLanes + ) { + if (!didSuspend) { + // This is the first render pass. Attempt to hydrate. + pushPrimaryTreeSuspenseHandler(workInProgress); // We should never be hydrating at this point because it is the first pass, + + if ((workInProgress.mode & ConcurrentMode) === NoMode) { + return retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + null + ); + } + + if (isSuspenseInstanceFallback()) { + // This boundary is in a permanent fallback state. In this case, we'll never + // get an update and we'll never be able to hydrate the final content. Let's just try the + // client side render instead. + var digest; + var message, stack; + + { + var _getSuspenseInstanceF = + getSuspenseInstanceFallbackErrorDetails(); + + digest = _getSuspenseInstanceF.digest; + message = _getSuspenseInstanceF.message; + stack = _getSuspenseInstanceF.stack; + } + + var capturedValue = null; // TODO: Figure out a better signal than encoding a magic digest value. + + { + var error; + + if (message) { + // eslint-disable-next-line react-internal/prod-error-codes + error = new Error(message); + } else { + error = new Error( + "The server could not finish this Suspense boundary, likely " + + "due to an error during server rendering. Switched to " + + "client rendering." + ); + } + + error.digest = digest; + capturedValue = createCapturedValueFromError(error, digest, stack); + } + + return retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + capturedValue + ); + } + // any context has changed, we need to treat is as if the input might have changed. + + var hasContextChanged = includesSomeLane( + renderLanes, + current.childLanes + ); + + if (didReceiveUpdate || hasContextChanged) { + // This boundary has changed since the first render. This means that we are now unable to + // hydrate it. We might still be able to hydrate it using a higher priority lane. + var root = getWorkInProgressRoot(); + + if (root !== null) { + var attemptHydrationAtLane = getBumpedLaneForHydration( + root, + renderLanes + ); + + if ( + attemptHydrationAtLane !== NoLane && + attemptHydrationAtLane !== suspenseState.retryLane + ) { + // Intentionally mutating since this render will get interrupted. This + // is one of the very rare times where we mutate the current tree + // during the render phase. + suspenseState.retryLane = attemptHydrationAtLane; + enqueueConcurrentRenderForLane(current, attemptHydrationAtLane); + scheduleUpdateOnFiber(root, current, attemptHydrationAtLane); // Throw a special object that signals to the work loop that it should + // interrupt the current render. + // + // Because we're inside a React-only execution stack, we don't + // strictly need to throw here — we could instead modify some internal + // work loop state. But using an exception means we don't need to + // check for this case on every iteration of the work loop. So doing + // it this way moves the check out of the fast path. + + throw SelectiveHydrationException; + } + } // If we did not selectively hydrate, we'll continue rendering without + // hydrating. Mark this tree as suspended to prevent it from committing + // outside a transition. + // + // This path should only happen if the hydration lane already suspended. + // Currently, it also happens during sync updates because there is no + // hydration lane for sync updates. + // TODO: We should ideally have a sync hydration lane that we can apply to do + // a pass where we hydrate this subtree in place using the previous Context and then + // reapply the update afterwards. + + if (isSuspenseInstancePending()); + else { + renderDidSuspendDelayIfPossible(); + } + + return retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + null + ); + } else if (isSuspenseInstancePending()) { + // This component is still pending more data from the server, so we can't hydrate its + // content. We treat it as if this component suspended itself. It might seem as if + // we could just try to render it client-side instead. However, this will perform a + // lot of unnecessary work and is unlikely to complete since it often will suspend + // on missing data anyway. Additionally, the server might be able to render more + // than we can on the client yet. In that case we'd end up with more fallback states + // on the client than if we just leave it alone. If the server times out or errors + // these should update this boundary to the permanent Fallback state instead. + // Mark it as having captured (i.e. suspended). + workInProgress.flags |= DidCapture; // Leave the child in place. I.e. the dehydrated fragment. + + workInProgress.child = current.child; // Register a callback to retry this boundary once the server has sent the result. + + retryDehydratedSuspenseBoundary.bind(null, current); + registerSuspenseInstanceRetry(); + return null; + } else { + var primaryChildren = nextProps.children; + var primaryChildFragment = mountSuspensePrimaryChildren( + workInProgress, + primaryChildren + ); // Mark the children as hydrating. This is a fast path to know whether this + // tree is part of a hydrating tree. This is used to determine if a child + // node has fully mounted yet, and for scheduling event replaying. + // Conceptually this is similar to Placement in that a new subtree is + // inserted into the React tree here. It just happens to not need DOM + // mutations because it already exists. + + primaryChildFragment.flags |= Hydrating; + return primaryChildFragment; + } + } else { + // This is the second render pass. We already attempted to hydrated, but + // something either suspended or errored. + if (workInProgress.flags & ForceClientRender) { + // Something errored during hydration. Try again without hydrating. + pushPrimaryTreeSuspenseHandler(workInProgress); + workInProgress.flags &= ~ForceClientRender; + + var _capturedValue = createCapturedValueFromError( + new Error( + "There was an error while hydrating this Suspense boundary. " + + "Switched to client rendering." + ) + ); + + return retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + _capturedValue + ); + } else if (workInProgress.memoizedState !== null) { + // Something suspended and we should still be in dehydrated mode. + // Leave the existing child in place. + // Push to avoid a mismatch + pushFallbackTreeSuspenseHandler(workInProgress); + workInProgress.child = current.child; // The dehydrated completion pass expects this flag to be there + // but the normal suspense pass doesn't. + + workInProgress.flags |= DidCapture; + return null; + } else { + // Suspended but we should no longer be in dehydrated mode. + // Therefore we now have to render the fallback. + pushFallbackTreeSuspenseHandler(workInProgress); + var nextPrimaryChildren = nextProps.children; + var nextFallbackChildren = nextProps.fallback; + var fallbackChildFragment = + mountSuspenseFallbackAfterRetryWithoutHydrating( + current, + workInProgress, + nextPrimaryChildren, + nextFallbackChildren, + renderLanes + ); + var _primaryChildFragment4 = workInProgress.child; + _primaryChildFragment4.memoizedState = + mountSuspenseOffscreenState(renderLanes); + _primaryChildFragment4.childLanes = getRemainingWorkInPrimaryTree( + current, + didPrimaryChildrenDefer, + renderLanes + ); + workInProgress.memoizedState = SUSPENDED_MARKER; + return fallbackChildFragment; + } + } + } + + function scheduleSuspenseWorkOnFiber(fiber, renderLanes, propagationRoot) { + fiber.lanes = mergeLanes(fiber.lanes, renderLanes); + var alternate = fiber.alternate; + + if (alternate !== null) { + alternate.lanes = mergeLanes(alternate.lanes, renderLanes); + } + + scheduleContextWorkOnParentPath( + fiber.return, + renderLanes, + propagationRoot + ); + } + + 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; + + while (node !== null) { + if (node.tag === SuspenseComponent) { + var state = node.memoizedState; + + if (state !== null) { + scheduleSuspenseWorkOnFiber(node, renderLanes, workInProgress); + } + } 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. + scheduleSuspenseWorkOnFiber(node, renderLanes, workInProgress); + } else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; + } + + if (node === workInProgress) { + return; + } // $FlowFixMe[incompatible-use] found when upgrading Flow + + while (node.sibling === null) { + // $FlowFixMe[incompatible-use] found when upgrading Flow + if (node.return === null || node.return === workInProgress) { + return; + } + + node = node.return; + } // $FlowFixMe[incompatible-use] found when upgrading Flow + + node.sibling.return = node.return; + node = node.sibling; + } + } + + function findLastContentRow(firstChild) { + // This is going to find the last row among these children that is already + // showing content on the screen, as opposed to being in fallback state or + // new. If a row has multiple Suspense boundaries, any of them being in the + // fallback state, counts as the whole row being in a fallback state. + // Note that the "rows" will be workInProgress, but any nested children + // will still be current since we haven't rendered them yet. The mounted + // order may not be the same as the new order. We use the new order. + var row = firstChild; + var lastContentRow = null; + + while (row !== null) { + var currentRow = row.alternate; // New rows can't be content rows. + + if (currentRow !== null && findFirstSuspended(currentRow) === null) { + lastContentRow = row; + } + + row = row.sibling; + } + + return lastContentRow; + } + + function validateRevealOrder(revealOrder) { + { + if ( + revealOrder !== undefined && + revealOrder !== "forwards" && + revealOrder !== "backwards" && + revealOrder !== "together" && + !didWarnAboutRevealOrder[revealOrder] + ) { + didWarnAboutRevealOrder[revealOrder] = true; + + if (typeof revealOrder === "string") { + switch (revealOrder.toLowerCase()) { + case "together": + case "forwards": + case "backwards": { + error( + '"%s" is not a valid value for revealOrder on . ' + + 'Use lowercase "%s" instead.', + revealOrder, + revealOrder.toLowerCase() + ); + + break; + } + + case "forward": + case "backward": { + error( + '"%s" is not a valid value for revealOrder on . ' + + 'React uses the -s suffix in the spelling. Use "%ss" instead.', + revealOrder, + revealOrder.toLowerCase() + ); + + break; + } + + default: + error( + '"%s" is not a supported revealOrder on . ' + + 'Did you mean "together", "forwards" or "backwards"?', + revealOrder + ); + + break; + } + } else { + error( + "%s is not a supported value for revealOrder on . " + + 'Did you mean "together", "forwards" or "backwards"?', + revealOrder + ); + } + } + } + } + + function validateTailOptions(tailMode, revealOrder) { + { + if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) { + if (tailMode !== "collapsed" && tailMode !== "hidden") { + didWarnAboutTailOptions[tailMode] = true; + + 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 + ); + } + } + } + } + + function validateSuspenseListNestedChild(childSlot, index) { + { + var isAnArray = isArray(childSlot); + var isIterable = + !isAnArray && typeof getIteratorFn(childSlot) === "function"; + + if (isAnArray || isIterable) { + var type = isAnArray ? "array" : "iterable"; + + error( + "A nested %s was passed to row #%s in . Wrap it in " + + "an additional SuspenseList to configure its revealOrder: " + + " ... " + + "{%s} ... " + + "", + type, + index, + type + ); + + return false; + } + } + + return true; + } + + 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); + + if (typeof iteratorFn === "function") { + var childrenIterator = iteratorFn.call(children); + + if (childrenIterator) { + var step = childrenIterator.next(); + var _i = 0; + + for (; !step.done; step = childrenIterator.next()) { + if (!validateSuspenseListNestedChild(step.value, _i)) { + return; + } + + _i++; + } + } + } else { + error( + 'A single row was passed to a . ' + + "This is not useful since it needs multiple rows. " + + "Did you mean to pass multiple children or an array?", + revealOrder + ); + } + } + } + } + } + + function initSuspenseListRenderState( + workInProgress, + isBackwards, + tail, + lastContentRow, + tailMode + ) { + var renderState = workInProgress.memoizedState; + + if (renderState === null) { + workInProgress.memoizedState = { + isBackwards: isBackwards, + rendering: null, + renderingStartTime: 0, + last: lastContentRow, + tail: tail, + tailMode: tailMode + }; + } else { + // We can reuse the existing object from previous renders. + renderState.isBackwards = isBackwards; + renderState.rendering = null; + renderState.renderingStartTime = 0; + renderState.last = lastContentRow; + renderState.tail = tail; + renderState.tailMode = tailMode; + } + } // This can end up rendering this component multiple passes. + // The first pass splits the children fibers into two sets. A head and tail. + // We first render the head. If anything is in fallback state, we do another + // pass through beginWork to rerender all children (including the tail) with + // the force suspend context. If the first render didn't have anything in + // in fallback state. Then we render each row in the tail one-by-one. + // That happens in the completeWork phase without going back to beginWork. + + 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 = hasSuspenseListContext( + suspenseContext, + ForceSuspenseFallback + ); + + if (shouldForceFallback) { + suspenseContext = setShallowSuspenseListContext( + suspenseContext, + ForceSuspenseFallback + ); + workInProgress.flags |= DidCapture; + } else { + var didSuspendBefore = + current !== null && (current.flags & DidCapture) !== NoFlags$1; + + if (didSuspendBefore) { + // If we previously forced a fallback, we need to schedule work + // on any nested boundaries to let them know to try to render + // again. This is the same as context updating. + propagateSuspenseContextChange( + workInProgress, + workInProgress.child, + renderLanes + ); + } + + suspenseContext = setDefaultShallowSuspenseListContext(suspenseContext); + } + + pushSuspenseListContext(workInProgress, suspenseContext); + + 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 { + switch (revealOrder) { + case "forwards": { + var lastContentRow = findLastContentRow(workInProgress.child); + var tail; + + if (lastContentRow === null) { + // The whole list is part of the tail. + // TODO: We could fast path by just rendering the tail now. + tail = workInProgress.child; + workInProgress.child = null; + } else { + // Disconnect the tail rows after the content row. + // We're going to render them separately later. + tail = lastContentRow.sibling; + lastContentRow.sibling = null; + } + + initSuspenseListRenderState( + workInProgress, + false, // isBackwards + tail, + lastContentRow, + tailMode + ); + break; + } + + case "backwards": { + // We're going to find the first row that has existing content. + // At the same time we're going to reverse the list of everything + // we pass in the meantime. That's going to be our tail in reverse + // order. + var _tail = null; + var row = workInProgress.child; + workInProgress.child = null; + + while (row !== null) { + var currentRow = row.alternate; // New rows can't be content rows. + + if ( + currentRow !== null && + findFirstSuspended(currentRow) === null + ) { + // This is the beginning of the main content. + workInProgress.child = row; + break; + } + + var nextRow = row.sibling; + row.sibling = _tail; + _tail = row; + row = nextRow; + } // TODO: If workInProgress.child is null, we can continue on the tail immediately. + + initSuspenseListRenderState( + workInProgress, + true, // isBackwards + _tail, + null, // last + tailMode + ); + break; + } + + case "together": { + initSuspenseListRenderState( + workInProgress, + false, // isBackwards + null, // tail + null, // last + undefined + ); + break; + } + + default: { + // The default reveal order is the same as not having + // a boundary. + workInProgress.memoizedState = null; + } + } + } + + return workInProgress.child; + } + + function updatePortalComponent(current, workInProgress, renderLanes) { + pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); + var nextChildren = workInProgress.pendingProps; + + if (current === null) { + // Portals are special because we don't append the children during mount + // but at commit. Therefore we need to track insertions which the normal + // flow doesn't do during mount. This doesn't happen at the root because + // the root always starts with a "current" with a null child. + // TODO: Consider unifying this with how the root works. + workInProgress.child = reconcileChildFibers( + workInProgress, + null, + nextChildren, + renderLanes + ); + } else { + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + } + + return workInProgress.child; + } + + var hasWarnedAboutUsingNoValuePropOnContextProvider = false; + + function updateContextProvider(current, workInProgress, renderLanes) { + var context; + + { + context = workInProgress.type._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?" + ); + } + } + } + + 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); + } + } + } + + var newChildren = newProps.children; + reconcileChildren(current, workInProgress, newChildren, renderLanes); + return workInProgress.child; + } + + function updateContextConsumer(current, workInProgress, renderLanes) { + var context; + + { + context = workInProgress.type; + + { + if (context._context !== undefined) { + context = context._context; + } + } + } + + 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." + ); + } + } + + prepareToReadContext(workInProgress, renderLanes); + var newValue = readContext(context); + + var newChildren; + + { + ReactCurrentOwner$2.current = workInProgress; + setIsRendering(true); + newChildren = render(newValue); + setIsRendering(false); + } + + workInProgress.flags |= PerformedWork; + reconcileChildren(current, workInProgress, newChildren, renderLanes); + return workInProgress.child; + } + + function markWorkInProgressReceivedUpdate() { + didReceiveUpdate = true; + } + + function resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress) { + if ((workInProgress.mode & ConcurrentMode) === NoMode) { + if (current !== null) { + // A lazy component only mounts if it suspended inside a non- + // concurrent tree, in an inconsistent state. We want to treat it like + // a new mount, even though an empty version of it already committed. + // Disconnect the alternate pointers. + current.alternate = null; + workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect + + workInProgress.flags |= Placement; + } + } + } + + function bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderLanes + ) { + if (current !== null) { + // Reuse previous dependencies + 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. + { + 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) { + { + var returnFiber = oldWorkInProgress.return; + + if (returnFiber === null) { + // eslint-disable-next-line react-internal/prod-error-codes + throw new Error("Cannot swap the root fiber."); + } // Disconnect from the old current. + // It will get deleted. + + current.alternate = null; + oldWorkInProgress.alternate = null; // Connect to the new tree. + + newWorkInProgress.index = oldWorkInProgress.index; + newWorkInProgress.sibling = oldWorkInProgress.sibling; + newWorkInProgress.return = oldWorkInProgress.return; + newWorkInProgress.ref = oldWorkInProgress.ref; + + { + newWorkInProgress._debugInfo = oldWorkInProgress._debugInfo; + } // Replace the child/sibling pointers above it. + + if (oldWorkInProgress === returnFiber.child) { + returnFiber.child = newWorkInProgress; + } else { + var prevSibling = returnFiber.child; + + if (prevSibling === null) { + // eslint-disable-next-line react-internal/prod-error-codes + throw new Error("Expected parent to have a child."); + } // $FlowFixMe[incompatible-use] found when upgrading Flow + + while (prevSibling.sibling !== oldWorkInProgress) { + // $FlowFixMe[incompatible-use] found when upgrading Flow + prevSibling = prevSibling.sibling; + + if (prevSibling === null) { + // eslint-disable-next-line react-internal/prod-error-codes + throw new Error("Expected to find the previous sibling."); + } + } // $FlowFixMe[incompatible-use] found when upgrading Flow + + prevSibling.sibling = newWorkInProgress; + } // Delete the old fiber and place the new one. + // Since the old fiber is disconnected, we have to schedule it manually. + + var deletions = returnFiber.deletions; + + if (deletions === null) { + returnFiber.deletions = [current]; + returnFiber.flags |= ChildDeletion; + } else { + deletions.push(current); + } + + newWorkInProgress.flags |= Placement; // Restart work from the new fiber. + + return newWorkInProgress; + } + } + + function checkScheduledUpdateOrContext(current, renderLanes) { + // Before performing an early bailout, we must check if there are pending + // updates or context. + var updateLanes = current.lanes; + + if (includesSomeLane(updateLanes, renderLanes)) { + return true; + } // No pending update, but because context is propagated lazily, we need + + return false; + } + + function attemptEarlyBailoutIfNoScheduledUpdate( + current, + workInProgress, + renderLanes + ) { + // This fiber does not have any pending work. Bailout without entering + // the begin phase. There's still some bookkeeping we that needs to be done + // in this optimized path, mostly pushing stuff onto the stack. + switch (workInProgress.tag) { + case HostRoot: + pushHostRootContext(workInProgress); + break; + + case HostSingleton: + case HostComponent: + pushHostContext(workInProgress); + break; + + case ClassComponent: { + break; + } + + case HostPortal: + pushHostContainer( + workInProgress, + workInProgress.stateNode.containerInfo + ); + break; + + case ContextProvider: { + var newValue = workInProgress.memoizedProps.value; + var context; + + { + context = workInProgress.type._context; + } + + pushProvider(workInProgress, context, newValue); + break; + } + + case Profiler: + { + // Profiler should only call onRender when one of its descendants actually rendered. + var hasChildWork = includesSomeLane( + renderLanes, + workInProgress.childLanes + ); + + if (hasChildWork) { + workInProgress.flags |= Update; + } + + { + // Reset effect durations for the next eventual effect phase. + // These are reset during render to allow the DevTools commit hook a chance to read them, + var stateNode = workInProgress.stateNode; + stateNode.effectDuration = 0; + stateNode.passiveEffectDuration = 0; + } + } + + break; + + case SuspenseComponent: { + var state = workInProgress.memoizedState; + + if (state !== null) { + if (state.dehydrated !== null) { + // We're not going to render the children, so this is just to maintain + // push/pop symmetry + pushPrimaryTreeSuspenseHandler(workInProgress); // We know that this component will suspend again because if it has + // been unsuspended it has committed as a resolved Suspense component. + // If it needs to be retried, it should have work scheduled on it. + + workInProgress.flags |= DidCapture; // We should never render the children of a dehydrated boundary until we + // upgrade it. We return null instead of bailoutOnAlreadyFinishedWork. + + return null; + } // If this boundary is currently timed out, we need to decide + // whether to retry the primary children, or to skip over it and + // go straight to the fallback. Check the priority of the primary + // child fragment. + + var primaryChildFragment = workInProgress.child; + var primaryChildLanes = primaryChildFragment.childLanes; + + if (includesSomeLane(renderLanes, primaryChildLanes)) { + // The primary children have pending work. Use the normal path + // to attempt to render the primary children again. + return updateSuspenseComponent( + current, + workInProgress, + renderLanes + ); + } else { + // The primary child fragment does not have pending work marked + // on it + pushPrimaryTreeSuspenseHandler(workInProgress); // The primary children do not have pending work with sufficient + // priority. Bailout. + + var child = bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderLanes + ); + + if (child !== null) { + // The fallback children have pending work. Skip over the + // primary children and work on the fallback. + return child.sibling; + } else { + // 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 { + pushPrimaryTreeSuspenseHandler(workInProgress); + } + + break; + } + + case SuspenseListComponent: { + var didSuspendBefore = (current.flags & DidCapture) !== NoFlags$1; + + var _hasChildWork = includesSomeLane( + renderLanes, + workInProgress.childLanes + ); + + if (didSuspendBefore) { + if (_hasChildWork) { + // If something was in fallback state last time, and we have all the + // same children then we're still in progressive loading state. + // Something might get unblocked by state updates or retries in the + // tree which will affect the tail. So we need to use the normal + // path to compute the correct tail. + return updateSuspenseListComponent( + current, + workInProgress, + renderLanes + ); + } // If none of the children had any work, that means that none of + // them got retried so they'll still be blocked in the same way + // as before. We can fast bail out. + + workInProgress.flags |= DidCapture; + } // If nothing suspended before and we're rendering the same children, + // then the tail doesn't matter. Anything new that suspends will work + // in the "together" mode, so we can continue from the state we had. + + var renderState = workInProgress.memoizedState; + + if (renderState !== null) { + // Reset to the "together" mode in case we've started a different + // update in the past but didn't complete it. + renderState.rendering = null; + renderState.tail = null; + renderState.lastEffect = null; + } + + pushSuspenseListContext(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; + } + } + + 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); + } + } + + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + } + + function beginWork(current, workInProgress, 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 + ) + ); + } + } + + 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 { + // Neither props nor legacy context changes. Check if there's a pending + // update or context change. + var hasScheduledUpdateOrContext = checkScheduledUpdateOrContext( + current, + renderLanes + ); + + if ( + !hasScheduledUpdateOrContext && // If this is the second pass of an error or suspense boundary, there + // may not be work scheduled on `current`, so we check for this flag. + (workInProgress.flags & DidCapture) === NoFlags$1 + ) { + // No pending updates or context. Bail out now. + didReceiveUpdate = false; + return attemptEarlyBailoutIfNoScheduledUpdate( + current, + workInProgress, + renderLanes + ); + } + + if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags$1) { + // 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. + + workInProgress.lanes = NoLanes; + + switch (workInProgress.tag) { + case IndeterminateComponent: { + return mountIndeterminateComponent( + current, + workInProgress, + workInProgress.type, + renderLanes + ); + } + + case LazyComponent: { + var elementType = workInProgress.elementType; + return mountLazyComponent( + current, + workInProgress, + elementType, + renderLanes + ); + } + + 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 ClassComponent: { + var _Component = workInProgress.type; + var _unresolvedProps = workInProgress.pendingProps; + + var _resolvedProps = + workInProgress.elementType === _Component + ? _unresolvedProps + : resolveDefaultProps(_Component, _unresolvedProps); + + return updateClassComponent( + current, + workInProgress, + _Component, + _resolvedProps, + renderLanes + ); + } + + case HostRoot: + return updateHostRoot(current, workInProgress, renderLanes); + + case HostHoistable: + + // Fall through + + case HostSingleton: + + // Fall through + + case HostComponent: + return updateHostComponent$1(current, workInProgress, renderLanes); + + case HostText: + return updateHostText$1(); + + case SuspenseComponent: + return updateSuspenseComponent(current, workInProgress, renderLanes); + + case HostPortal: + return updatePortalComponent(current, workInProgress, renderLanes); + + case ForwardRef: { + var type = workInProgress.type; + var _unresolvedProps2 = workInProgress.pendingProps; + + var _resolvedProps2 = + workInProgress.elementType === type + ? _unresolvedProps2 + : resolveDefaultProps(type, _unresolvedProps2); + + return updateForwardRef( + current, + workInProgress, + type, + _resolvedProps2, + renderLanes + ); + } + + case Fragment: + return updateFragment(current, workInProgress, renderLanes); + + case Mode: + return updateMode(current, workInProgress, renderLanes); + + case Profiler: + return updateProfiler(current, workInProgress, renderLanes); + + case ContextProvider: + return updateContextProvider(current, workInProgress, renderLanes); + + case ContextConsumer: + return updateContextConsumer(current, workInProgress, renderLanes); + + case MemoComponent: { + var _type = workInProgress.type; + var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props. + + var _resolvedProps3 = resolveDefaultProps(_type, _unresolvedProps3); + + _resolvedProps3 = resolveDefaultProps(_type.type, _resolvedProps3); + return updateMemoComponent( + current, + workInProgress, + _type, + _resolvedProps3, + renderLanes + ); + } + + case SimpleMemoComponent: { + return updateSimpleMemoComponent( + current, + workInProgress, + workInProgress.type, + workInProgress.pendingProps, + renderLanes + ); + } + + case IncompleteClassComponent: { + var _Component2 = workInProgress.type; + var _unresolvedProps4 = workInProgress.pendingProps; + + var _resolvedProps4 = + workInProgress.elementType === _Component2 + ? _unresolvedProps4 + : resolveDefaultProps(_Component2, _unresolvedProps4); + + return mountIncompleteClassComponent( + current, + workInProgress, + _Component2, + _resolvedProps4, + renderLanes + ); + } + + case SuspenseListComponent: { + return updateSuspenseListComponent( + current, + workInProgress, + renderLanes + ); + } + + case ScopeComponent: { + break; + } + + case OffscreenComponent: { + return updateOffscreenComponent(current, workInProgress, renderLanes); + } + } + + throw new Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in " + + "React. Please file an issue." + ); + } + + var valueCursor = createCursor(null); + var rendererCursorDEV; + + { + rendererCursorDEV = createCursor(null); + } + + var rendererSigil; + + { + // Use this to detect multiple renderers using the same context + rendererSigil = {}; + } + + var currentlyRenderingFiber = null; + var lastContextDependency = 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; + lastFullyObservedContext = null; + + { + isDisallowedContextReadInDEV = false; + } + } + function enterDisallowedContextReadInDEV() { + { + isDisallowedContextReadInDEV = true; + } + } + function exitDisallowedContextReadInDEV() { + { + isDisallowedContextReadInDEV = false; + } + } + function pushProvider(providerFiber, context, nextValue) { + { + push(valueCursor, context._currentValue, providerFiber); + context._currentValue = nextValue; + + { + push(rendererCursorDEV, context._currentRenderer, providerFiber); + + if ( + context._currentRenderer !== undefined && + context._currentRenderer !== null && + context._currentRenderer !== rendererSigil + ) { + error( + "Detected multiple renderers concurrently rendering the " + + "same context provider. This is currently unsupported." + ); + } + + context._currentRenderer = rendererSigil; + } + } + } + function popProvider(context, providerFiber) { + var currentValue = valueCursor.current; + + { + context._currentValue = currentValue; + + { + var currentRenderer = rendererCursorDEV.current; + pop(rendererCursorDEV, providerFiber); + context._currentRenderer = currentRenderer; + } + } + + pop(valueCursor, providerFiber); + } + function scheduleContextWorkOnParentPath( + parent, + renderLanes, + propagationRoot + ) { + // Update the child lanes of all the ancestors, including the alternates. + var node = parent; + + while (node !== null) { + var alternate = node.alternate; + + if (!isSubsetOfLanes(node.childLanes, renderLanes)) { + node.childLanes = mergeLanes(node.childLanes, renderLanes); + + if (alternate !== null) { + alternate.childLanes = mergeLanes( + alternate.childLanes, + renderLanes + ); + } + } else if ( + alternate !== null && + !isSubsetOfLanes(alternate.childLanes, renderLanes) + ) { + alternate.childLanes = mergeLanes(alternate.childLanes, renderLanes); + } else; + + if (node === propagationRoot) { + break; + } + + node = node.return; + } + + { + if (node !== propagationRoot) { + error( + "Expected to find the propagation root when scheduling context work. " + + "This error is likely caused by a bug in React. Please file an issue." + ); + } + } + } + function propagateContextChange(workInProgress, context, renderLanes) { + { + propagateContextChange_eager(workInProgress, context, renderLanes); + } + } + + function propagateContextChange_eager( + workInProgress, + context, + renderLanes + ) { + var fiber = workInProgress.child; + + if (fiber !== null) { + // Set the return pointer of the child to the work-in-progress fiber. + fiber.return = workInProgress; + } + + while (fiber !== null) { + var nextFiber = void 0; // Visit this fiber. + + var list = fiber.dependencies; + + if (list !== null) { + nextFiber = fiber.child; + var dependency = list.firstContext; + + while (dependency !== null) { + // Check if the context matches. + 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 lane = pickArbitraryLane(renderLanes); + var update = createUpdate(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; + } + + sharedQueue.pending = update; + } + } + + fiber.lanes = mergeLanes(fiber.lanes, renderLanes); + var alternate = fiber.alternate; + + if (alternate !== null) { + alternate.lanes = mergeLanes(alternate.lanes, renderLanes); + } + + scheduleContextWorkOnParentPath( + fiber.return, + renderLanes, + workInProgress + ); // Mark the updated lanes on the list, too. + + list.lanes = mergeLanes(list.lanes, renderLanes); // Since we already found a match, we can stop traversing the + // dependency list. + + break; + } + + dependency = dependency.next; + } + } else if (fiber.tag === ContextProvider) { + // Don't scan deeper if this is a matching provider + nextFiber = fiber.type === workInProgress.type ? null : fiber.child; + } else if (fiber.tag === DehydratedFragment) { + // If a dehydrated suspense boundary is in this subtree, we don't know + // if it will have any context consumers in it. The best we can do is + // mark it as having updates. + var parentSuspense = fiber.return; + + if (parentSuspense === null) { + throw new Error( + "We just came from a parent so we must have had a parent. This is a bug in React." + ); + } + + parentSuspense.lanes = mergeLanes(parentSuspense.lanes, renderLanes); + var _alternate = parentSuspense.alternate; + + if (_alternate !== null) { + _alternate.lanes = mergeLanes(_alternate.lanes, renderLanes); + } // This is intentionally passing this fiber as the parent + // because we want to schedule this fiber as having work + // on its children. We'll use the childLanes on + // this fiber to indicate that a context has changed. + + scheduleContextWorkOnParentPath( + parentSuspense, + renderLanes, + workInProgress + ); + nextFiber = fiber.sibling; + } else { + // Traverse down. + nextFiber = fiber.child; + } + + if (nextFiber !== null) { + // Set the return pointer of the child to the work-in-progress fiber. + nextFiber.return = fiber; + } else { + // No child. Traverse to next sibling. + nextFiber = fiber; + + while (nextFiber !== null) { + if (nextFiber === workInProgress) { + // We're back to the root of this subtree. Exit. + nextFiber = null; + break; + } + + var sibling = nextFiber.sibling; + + if (sibling !== null) { + // Set the return pointer of the sibling to the work-in-progress fiber. + sibling.return = nextFiber.return; + nextFiber = sibling; + break; + } // No more siblings. Traverse up. + + nextFiber = nextFiber.return; + } + } + + fiber = nextFiber; + } + } + function prepareToReadContext(workInProgress, renderLanes) { + currentlyRenderingFiber = workInProgress; + lastContextDependency = null; + lastFullyObservedContext = null; + var dependencies = workInProgress.dependencies; + + if (dependencies !== null) { + { + 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 + + dependencies.firstContext = null; + } + } + } + } + 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. + if (isDisallowedContextReadInDEV) { + 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()." + ); + } + } + + return readContextForConsumer(currentlyRenderingFiber, context); + } + function readContextDuringReconciliation(consumer, context, renderLanes) { + if (currentlyRenderingFiber === null) { + prepareToReadContext(consumer, renderLanes); + } + + return readContextForConsumer(consumer, context); + } + + function readContextForConsumer(consumer, context) { + var value = context._currentValue; + + if (lastFullyObservedContext === context); + else { + var contextItem = { + context: context, + memoizedValue: value, + next: null + }; + + if (lastContextDependency === null) { + if (consumer === null) { + throw new Error( + "Context can only be read while React is rendering. " + + "In classes, you can read it in the render method or getDerivedStateFromProps. " + + "In function components, you can read it directly in the function body, but not " + + "inside Hooks like useReducer() or useMemo()." + ); + } // This is the first dependency for this component. Create a new list. + + lastContextDependency = contextItem; + consumer.dependencies = { + lanes: NoLanes, + firstContext: contextItem + }; + } else { + // Append a new context item. + lastContextDependency = lastContextDependency.next = contextItem; + } + } + + return value; + } + + var ReactCurrentBatchConfig$1 = + ReactSharedInternals.ReactCurrentBatchConfig; + function requestCurrentTransition() { + var transition = ReactCurrentBatchConfig$1.transition; + + if (transition !== null) { + // Whenever a transition update is scheduled, register a callback on the + // transition object so we can get the return value of the scope function. + transition._callbacks.add(handleAsyncAction); + } + + return transition; + } + + function handleAsyncAction(transition, thenable) {} + + function notifyTransitionCallbacks(transition, returnValue) { + var callbacks = transition._callbacks; + callbacks.forEach(function (callback) { + return callback(transition, returnValue); + }); + } // When retrying a Suspense/Offscreen boundary, we restore the cache that was + function getSuspendedCache() { + { + return null; + } // This function is called when a Suspense boundary suspends. It returns the + } + + /** + * Tag the fiber with an update effect. This turns a Placement into + * a PlacementAndUpdate. + */ + + function markUpdate(workInProgress) { + workInProgress.flags |= Update; + } + + function appendAllChildren( + parent, + workInProgress, + needsVisibilityToggle, + isHidden + ) { + { + // We only have the top Fiber that was created but we need recurse down its + // children to find all the terminal nodes. + var node = workInProgress.child; + + while (node !== null) { + if (node.tag === HostComponent || node.tag === HostText) { + appendInitialChild(parent, node.stateNode); + } else if (node.tag === HostPortal || false); + else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; + } + + if (node === workInProgress) { + return; + } // $FlowFixMe[incompatible-use] found when upgrading Flow + + while (node.sibling === null) { + // $FlowFixMe[incompatible-use] found when upgrading Flow + if (node.return === null || node.return === workInProgress) { + return; + } + + node = node.return; + } // $FlowFixMe[incompatible-use] found when upgrading Flow + + node.sibling.return = node.return; + node = node.sibling; + } + } + } // An unfortunate fork of appendAllChildren because we have two different parent types. + + function updateHostComponent( + current, + workInProgress, + type, + newProps, + renderLanes + ) { + { + // 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; + } + + markUpdate(workInProgress); + } + } // This function must be called at the very end of the complete phase, because + // it might throw to suspend, and if the resource immediately loads, the work + // loop will resume rendering as if the work-in-progress completed. So it must + // fully complete. + // TODO: This should ideally move to begin phase, but currently the instance is + // not created until the complete phase. For our existing use cases, host nodes + // that suspend don't have children, so it doesn't matter. But that might not + // always be true in the future. + + function preloadInstanceAndSuspendIfNeeded( + workInProgress, + type, + props, + renderLanes + ) { + { + // If this flag was set previously, we can remove it. The flag + // represents whether this particular set of props might ever need to + // suspend. The safest thing to do is for maySuspendCommit to always + // return true, but if the renderer is reasonably confident that the + // underlying resource won't be evicted, it can return false as a + // performance optimization. + workInProgress.flags &= ~MaySuspendCommit; + return; + } // Mark this fiber with a flag. This gets set on all host instances + } + + function scheduleRetryEffect(workInProgress, retryQueue) { + var wakeables = retryQueue; + + if (wakeables !== null) { + // Schedule an effect to attach a retry listener to the promise. + // TODO: Move to passive phase + workInProgress.flags |= Update; + } else { + // This boundary suspended, but no wakeables were added to the retry + // queue. Check if the renderer suspended commit. If so, this means + // that once the fallback is committed, we can immediately retry + // rendering again, because rendering wasn't actually blocked. Only + // the commit phase. + // TODO: Consider a model where we always schedule an immediate retry, even + // for normal Suspense. That way the retry can partially render up to the + // first thing that suspends. + if (workInProgress.flags & ScheduleRetry) { + var retryLane = // TODO: This check should probably be moved into claimNextRetryLane + // I also suspect that we need some further consolidation of offscreen + // and retry lanes. + workInProgress.tag !== OffscreenComponent + ? claimNextRetryLane() + : OffscreenLane; + workInProgress.lanes = mergeLanes(workInProgress.lanes, retryLane); + } + } + } + + function updateHostText(current, workInProgress, oldText, newText) { + { + // If the text differs, mark it as an update. All the work in done in commitWork. + if (oldText !== newText) { + markUpdate(workInProgress); + } + } + } + + function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { + switch (renderState.tailMode) { + case "hidden": { + // Any insertions at the end of the tail list after this point + // should be invisible. If there are already mounted boundaries + // anything before them are not considered for collapsing. + // Therefore we need to go through the whole tail to find if + // there are any. + var tailNode = renderState.tail; + var lastTailNode = null; + + while (tailNode !== null) { + if (tailNode.alternate !== null) { + lastTailNode = tailNode; + } + + tailNode = tailNode.sibling; + } // Next we're simply going to delete all insertions after the + // last rendered item. + + if (lastTailNode === null) { + // All remaining items in the tail are insertions. + renderState.tail = null; + } else { + // Detach the insertion after the last node that was already + // inserted. + lastTailNode.sibling = null; + } + + break; + } + + case "collapsed": { + // Any insertions at the end of the tail list after this point + // should be invisible. If there are already mounted boundaries + // anything before them are not considered for collapsing. + // Therefore we need to go through the whole tail to find if + // there are any. + var _tailNode = renderState.tail; + var _lastTailNode = null; + + while (_tailNode !== null) { + if (_tailNode.alternate !== null) { + _lastTailNode = _tailNode; + } + + _tailNode = _tailNode.sibling; + } // Next we're simply going to delete all insertions after the + // last rendered item. + + if (_lastTailNode === null) { + // All remaining items in the tail are insertions. + if (!hasRenderedATailFallback && renderState.tail !== null) { + // We suspended during the head. We want to show at least one + // row at the tail. So we'll keep on and cut off the rest. + renderState.tail.sibling = null; + } else { + renderState.tail = null; + } + } else { + // Detach the insertion after the last node that was already + // inserted. + _lastTailNode.sibling = null; + } + + break; + } + } + } + + function bubbleProperties(completedWork) { + var didBailout = + completedWork.alternate !== null && + completedWork.alternate.child === completedWork.child; + var newChildLanes = NoLanes; + var subtreeFlags = NoFlags$1; + + 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. + // $FlowFixMe[unsafe-addition] addition with possible null/undefined value + + actualDuration += child.actualDuration; // $FlowFixMe[unsafe-addition] addition with possible null/undefined value + + 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; // $FlowFixMe[unsafe-addition] addition with possible null/undefined value + + _treeBaseDuration += _child2.treeBaseDuration; + _child2 = _child2.sibling; + } + + completedWork.treeBaseDuration = _treeBaseDuration; + } else { + var _child3 = completedWork.child; + + while (_child3 !== null) { + newChildLanes = mergeLanes( + newChildLanes, + mergeLanes(_child3.lanes, _child3.childLanes) + ); // "Static" flags share the lifetime of the fiber/hook they belong to, + // so we should bubble those up even during a bailout. All the other + // flags have a lifetime only of a single render + commit, so we should + // ignore them. + + subtreeFlags |= _child3.subtreeFlags & StaticMask; + subtreeFlags |= _child3.flags & StaticMask; // Update the return pointer so the tree is consistent. This is a code + // smell because it assumes the commit phase is never concurrent with + // the render phase. Will address during refactor to alternate model. + + _child3.return = completedWork; + _child3 = _child3.sibling; + } + } + + completedWork.subtreeFlags |= subtreeFlags; + } + + completedWork.childLanes = newChildLanes; + return didBailout; + } + + function completeDehydratedSuspenseBoundary( + current, + workInProgress, + nextState + ) { + var wasHydrated = popHydrationState(); + + if (nextState !== null && nextState.dehydrated !== null) { + // We might be inside a hydration state the first time we're picking up this + // Suspense boundary, and also after we've reentered it for further hydration. + if (current === null) { + if (!wasHydrated) { + throw new Error( + "A dehydrated suspense component was completed without a hydrated node. " + + "This is probably a bug in React." + ); + } + + prepareToHydrateHostSuspenseInstance(); + bubbleProperties(workInProgress); + + { + if ((workInProgress.mode & ProfileMode) !== NoMode) { + var isTimedOutSuspense = nextState !== null; + + if (isTimedOutSuspense) { + // Don't count time spent in a timed out Suspense subtree as part of the base duration. + var primaryChildFragment = workInProgress.child; + + if (primaryChildFragment !== null) { + // $FlowFixMe[unsafe-arithmetic] Flow doesn't support type casting in combination with the -= operator + workInProgress.treeBaseDuration -= + primaryChildFragment.treeBaseDuration; + } + } + } + } + + return false; + } else { + if ((workInProgress.flags & DidCapture) === NoFlags$1) { + // This boundary did not suspend so it's now hydrated and unsuspended. + workInProgress.memoizedState = null; + } // If nothing suspended, we need to schedule an effect to mark this boundary + // as having hydrated so events know that they're free to be invoked. + // It's also a signal to replay events and the suspense callback. + // If something suspended, schedule an effect to attach retry listeners. + // So we might as well always mark this. + + workInProgress.flags |= Update; + bubbleProperties(workInProgress); + + { + if ((workInProgress.mode & ProfileMode) !== NoMode) { + var _isTimedOutSuspense = nextState !== null; + + if (_isTimedOutSuspense) { + // Don't count time spent in a timed out Suspense subtree as part of the base duration. + var _primaryChildFragment = workInProgress.child; + + if (_primaryChildFragment !== null) { + // $FlowFixMe[unsafe-arithmetic] Flow doesn't support type casting in combination with the -= operator + workInProgress.treeBaseDuration -= + _primaryChildFragment.treeBaseDuration; + } + } + } + } + + return false; + } + } else { + // Successfully completed this tree. If this was a forced client render, + // there may have been recoverable errors during first hydration + // attempt. If so, add them to a queue so we can log them in the + // commit phase. + upgradeHydrationErrorsToRecoverable(); // Fall through to normal Suspense path + + return true; + } + } + + function completeWork(current, workInProgress, renderLanes) { + var newProps = workInProgress.pendingProps; // Note: This intentionally doesn't check if we're hydrating because comparing + + switch (workInProgress.tag) { + case IndeterminateComponent: + case LazyComponent: + case SimpleMemoComponent: + case FunctionComponent: + case ForwardRef: + case Fragment: + case Mode: + case Profiler: + case ContextConsumer: + case MemoComponent: + bubbleProperties(workInProgress); + return null; + + case ClassComponent: { + bubbleProperties(workInProgress); + return null; + } + + case HostRoot: { + var fiberRoot = workInProgress.stateNode; + popHostContainer(workInProgress); + + if (fiberRoot.pendingContext) { + fiberRoot.context = fiberRoot.pendingContext; + fiberRoot.pendingContext = null; + } + + if (current === null || current.child === null) { + // If we hydrated, pop so that we can delete any remaining children + // that weren't hydrated. + var wasHydrated = popHydrationState(); + + if (wasHydrated) { + // If we hydrated, then we'll need to schedule an update for + // the commit side-effects on the root. + markUpdate(workInProgress); + } else { + if (current !== null) { + var prevState = current.memoizedState; + + if ( + // Check if this is a client root + !prevState.isDehydrated || // Check if we reverted to client rendering (e.g. due to an error) + (workInProgress.flags & ForceClientRender) !== NoFlags$1 + ) { + // Schedule an effect to clear this container at the start of the + // next commit. This handles the case of React rendering into a + // container with previous children. It's also safe to do for + // updates too, because current.child would only be null if the + // previous render was null (so the container would already + // be empty). + workInProgress.flags |= Snapshot; // If this was a forced client render, there may have been + // recoverable errors during first hydration attempt. If so, add + // them to a queue so we can log them in the commit phase. + + upgradeHydrationErrorsToRecoverable(); + } + } + } + } + bubbleProperties(workInProgress); + + return null; + } + + case HostHoistable: + + case HostSingleton: + + case HostComponent: { + popHostContext(workInProgress); + var _type2 = workInProgress.type; + + if (current !== null && workInProgress.stateNode != null) { + updateHostComponent(current, workInProgress, _type2, newProps); + } else { + if (!newProps) { + if (workInProgress.stateNode === null) { + throw new Error( + "We must have new props for new mounts. This error is likely " + + "caused by a bug in React. Please file an issue." + ); + } // This can happen when we abort work. + + bubbleProperties(workInProgress); + return null; + } + + var _currentHostContext = getHostContext(); // TODO: Move createInstance to beginWork and keep it on a context + // "stack" as the parent. Then append children as we go in beginWork + // or completeWork depending on whether we want to add them top->down or + // bottom->up. Top->down is faster in IE11. + + var _wasHydrated2 = popHydrationState(); + + if (_wasHydrated2) { + // TODO: Move this and createInstance step into the beginPhase + // to consolidate. + prepareToHydrateHostInstance(); + } else { + var _rootContainerInstance = getRootHostContainer(); + + var _instance3 = createInstance( + _type2, + newProps, + _rootContainerInstance, + _currentHostContext, + workInProgress + ); // TODO: For persistent renderers, we should pass children as part + // of the initial instance creation + + appendAllChildren(_instance3, workInProgress); + workInProgress.stateNode = _instance3; // Certain renderers require commit-time effects for initial mount. + // (eg DOM renderer supports auto-focus for certain elements). + // Make sure such renderers get scheduled for later work. + + if (finalizeInitialChildren(_instance3)) { + markUpdate(workInProgress); + } + } + } + + bubbleProperties(workInProgress); // This must come at the very end of the complete phase, because it might + // throw to suspend, and if the resource immediately loads, the work loop + // will resume rendering as if the work-in-progress completed. So it must + // fully complete. + + preloadInstanceAndSuspendIfNeeded(workInProgress); + return null; + } + + case HostText: { + var newText = newProps; + + if (current && workInProgress.stateNode != null) { + var oldText = current.memoizedProps; // If we have an alternate, that means this is an update and we need + // to schedule a side-effect to do the updates. + + updateHostText(current, workInProgress, oldText, newText); + } else { + if (typeof newText !== "string") { + if (workInProgress.stateNode === null) { + throw new Error( + "We must have new props for new mounts. This error is likely " + + "caused by a bug in React. Please file an issue." + ); + } // This can happen when we abort work. + } + + var _rootContainerInstance2 = getRootHostContainer(); + + var _currentHostContext2 = getHostContext(); + + var _wasHydrated3 = popHydrationState(); + + if (_wasHydrated3) { + if (prepareToHydrateHostTextInstance()) { + markUpdate(workInProgress); + } + } else { + workInProgress.stateNode = createTextInstance( + newText, + _rootContainerInstance2, + _currentHostContext2, + workInProgress + ); + } + } + + bubbleProperties(workInProgress); + return null; + } + + case SuspenseComponent: { + var nextState = workInProgress.memoizedState; // Special path for dehydrated boundaries. We may eventually move this + // to its own fiber type so that we can add other kinds of hydration + // boundaries that aren't associated with a Suspense tree. In anticipation + // of such a refactor, all the hydration logic is contained in + // this branch. + + if ( + current === null || + (current.memoizedState !== null && + current.memoizedState.dehydrated !== null) + ) { + var fallthroughToNormalSuspensePath = + completeDehydratedSuspenseBoundary( + current, + workInProgress, + nextState + ); + + if (!fallthroughToNormalSuspensePath) { + if (workInProgress.flags & ForceClientRender) { + popSuspenseHandler(workInProgress); // Special case. There were remaining unhydrated nodes. We treat + // this as a mismatch. Revert to client rendering. + + return workInProgress; + } else { + popSuspenseHandler(workInProgress); // Did not finish hydrating, either because this is the initial + // render or because something suspended. + + return null; + } + } // Continue with the normal Suspense path. + } + + popSuspenseHandler(workInProgress); + + if ((workInProgress.flags & DidCapture) !== NoFlags$1) { + // Something suspended. Re-render with the fallback children. + workInProgress.lanes = renderLanes; // Do not reset the effect list. + + if ((workInProgress.mode & ProfileMode) !== NoMode) { + transferActualDuration(workInProgress); + } // Don't bubble properties in this case. + + return workInProgress; + } + + var nextDidTimeout = nextState !== null; + var prevDidTimeout = + current !== null && current.memoizedState !== null; + // a passive effect, which is when we process the transitions + + if (nextDidTimeout !== prevDidTimeout) { + // an effect to toggle the subtree's visibility. When we switch from + // fallback -> primary, the inner Offscreen fiber schedules this effect + // as part of its normal complete phase. But when we switch from + // primary -> fallback, the inner Offscreen fiber does not have a complete + // phase. So we need to schedule its effect here. + // + // We also use this flag to connect/disconnect the effects, but the same + // logic applies: when re-connecting, the Offscreen fiber's complete + // phase will handle scheduling the effect. It's only when the fallback + // is active that we have to do anything special. + + if (nextDidTimeout) { + var _offscreenFiber2 = workInProgress.child; + _offscreenFiber2.flags |= Visibility; + } + } + + var retryQueue = workInProgress.updateQueue; + scheduleRetryEffect(workInProgress, retryQueue); + + bubbleProperties(workInProgress); + + { + if ((workInProgress.mode & ProfileMode) !== NoMode) { + if (nextDidTimeout) { + // Don't count time spent in a timed out Suspense subtree as part of the base duration. + var primaryChildFragment = workInProgress.child; + + if (primaryChildFragment !== null) { + // $FlowFixMe[unsafe-arithmetic] Flow doesn't support type casting in combination with the -= operator + workInProgress.treeBaseDuration -= + primaryChildFragment.treeBaseDuration; + } + } + } + } + + return null; + } + + case HostPortal: + popHostContainer(workInProgress); + + bubbleProperties(workInProgress); + return null; + + case ContextProvider: + // Pop provider fiber + var context; + + { + context = workInProgress.type._context; + } + + popProvider(context, workInProgress); + bubbleProperties(workInProgress); + return null; + + case IncompleteClassComponent: { + bubbleProperties(workInProgress); + return null; + } + + case SuspenseListComponent: { + popSuspenseListContext(workInProgress); + var renderState = workInProgress.memoizedState; + + if (renderState === null) { + // We're running in the default, "independent" mode. + // We don't do anything in this mode. + bubbleProperties(workInProgress); + return null; + } + + var didSuspendAlready = + (workInProgress.flags & DidCapture) !== NoFlags$1; + var renderedTail = renderState.rendering; + + if (renderedTail === null) { + // We just rendered the head. + if (!didSuspendAlready) { + // This is the first pass. We need to figure out if anything is still + // suspended in the rendered set. + // If new content unsuspended, but there's still some content that + // didn't. Then we need to do a second pass that forces everything + // to keep showing their fallbacks. + // We might be suspended if something in this render pass suspended, or + // something in the previous committed pass suspended. Otherwise, + // there's no chance so we can skip the expensive call to + // findFirstSuspended. + var cannotBeSuspended = + renderHasNotSuspendedYet() && + (current === null || + (current.flags & DidCapture) === NoFlags$1); + + if (!cannotBeSuspended) { + var row = workInProgress.child; + + while (row !== null) { + var suspended = findFirstSuspended(row); + + if (suspended !== null) { + didSuspendAlready = true; + workInProgress.flags |= DidCapture; + cutOffTailIfNeeded(renderState, false); // If this is a newly suspended tree, it might not get committed as + // part of the second pass. In that case nothing will subscribe to + // its thenables. Instead, we'll transfer its thenables to the + // SuspenseList so that it can retry if they resolve. + // There might be multiple of these in the list but since we're + // going to wait for all of them anyway, it doesn't really matter + // which ones gets to ping. In theory we could get clever and keep + // track of how many dependencies remain but it gets tricky because + // in the meantime, we can add/remove/change items and dependencies. + // We might bail out of the loop before finding any but that + // doesn't matter since that means that the other boundaries that + // we did find already has their listeners attached. + + var _retryQueue = suspended.updateQueue; + workInProgress.updateQueue = _retryQueue; + scheduleRetryEffect(workInProgress, _retryQueue); // Rerender the whole list, but this time, we'll force fallbacks + // to stay in place. + // Reset the effect flags before doing the second pass since that's now invalid. + // Reset the child fibers to their original state. + + workInProgress.subtreeFlags = NoFlags$1; + resetChildFibers(workInProgress, renderLanes); // Set up the Suspense List Context to force suspense and + // immediately rerender the children. + + pushSuspenseListContext( + workInProgress, + setShallowSuspenseListContext( + suspenseStackCursor.current, + ForceSuspenseFallback + ) + ); // Don't bubble properties in this case. + + return workInProgress.child; + } + + row = row.sibling; + } + } + + if ( + renderState.tail !== null && + now$1() > getRenderTargetTime() + ) { + // We have already passed our CPU deadline but we still have rows + // left in the tail. We'll just give up further attempts to render + // the main content and only render fallbacks. + workInProgress.flags |= DidCapture; + didSuspendAlready = true; + cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this + // to get it started back up to attempt the next item. While in terms + // of priority this work has the same priority as this current render, + // it's not part of the same transition once the transition has + // committed. If it's sync, we still want to yield so that it can be + // painted. Conceptually, this is really the same as pinging. + // We can use any RetryLane even if it's the one currently rendering + // since we're leaving it behind on this node. + + workInProgress.lanes = SomeRetryLane; + } + } else { + cutOffTailIfNeeded(renderState, false); + } // Next we're going to render the tail. + } else { + // Append the rendered row to the child list. + if (!didSuspendAlready) { + var _suspended = findFirstSuspended(renderedTail); + + if (_suspended !== null) { + workInProgress.flags |= DidCapture; + didSuspendAlready = true; // Ensure we transfer the update queue to the parent so that it doesn't + // get lost if this row ends up dropped during a second pass. + + var _retryQueue2 = _suspended.updateQueue; + workInProgress.updateQueue = _retryQueue2; + scheduleRetryEffect(workInProgress, _retryQueue2); + cutOffTailIfNeeded(renderState, true); // This might have been modified. + + if ( + renderState.tail === null && + renderState.tailMode === "hidden" && + !renderedTail.alternate && + !getIsHydrating() // We don't cut it if we're hydrating. + ) { + // We're done. + bubbleProperties(workInProgress); + return null; + } + } else if ( + // The time it took to render last row is greater than the remaining + // time we have to render. So rendering one more row would likely + // exceed it. + now$1() * 2 - renderState.renderingStartTime > + getRenderTargetTime() && + renderLanes !== OffscreenLane + ) { + // We have now passed our CPU deadline and we'll just give up further + // attempts to render the main content and only render fallbacks. + // The assumption is that this is usually faster. + workInProgress.flags |= DidCapture; + didSuspendAlready = true; + cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this + // to get it started back up to attempt the next item. While in terms + // of priority this work has the same priority as this current render, + // it's not part of the same transition once the transition has + // committed. If it's sync, we still want to yield so that it can be + // painted. Conceptually, this is really the same as pinging. + // We can use any RetryLane even if it's the one currently rendering + // since we're leaving it behind on this node. + + workInProgress.lanes = SomeRetryLane; + } + } + + if (renderState.isBackwards) { + // The effect list of the backwards tail will have been added + // to the end. This breaks the guarantee that life-cycles fire in + // sibling order but that isn't a strong guarantee promised by React. + // Especially since these might also just pop in during future commits. + // Append to the beginning of the list. + renderedTail.sibling = workInProgress.child; + workInProgress.child = renderedTail; + } else { + var previousSibling = renderState.last; + + if (previousSibling !== null) { + previousSibling.sibling = renderedTail; + } else { + workInProgress.child = renderedTail; + } + + renderState.last = renderedTail; + } + } + + if (renderState.tail !== null) { + // We still have tail rows to render. + // Pop a row. + var next = renderState.tail; + renderState.rendering = next; + renderState.tail = next.sibling; + renderState.renderingStartTime = now$1(); + next.sibling = null; // Restore the context. + // TODO: We can probably just avoid popping it instead and only + // setting it the first time we go from not suspended to suspended. + + var suspenseContext = suspenseStackCursor.current; + + if (didSuspendAlready) { + suspenseContext = setShallowSuspenseListContext( + suspenseContext, + ForceSuspenseFallback + ); + } else { + suspenseContext = + setDefaultShallowSuspenseListContext(suspenseContext); + } + + pushSuspenseListContext(workInProgress, suspenseContext); // Do a pass over the next row. + // Don't bubble properties in this case. + + return next; + } + + bubbleProperties(workInProgress); + return null; + } + + case ScopeComponent: { + break; + } + + case OffscreenComponent: + case LegacyHiddenComponent: { + popSuspenseHandler(workInProgress); + popHiddenContext(workInProgress); + var _nextState = workInProgress.memoizedState; + var nextIsHidden = _nextState !== null; // Schedule a Visibility effect if the visibility has changed + + { + if (current !== null) { + var _prevState = current.memoizedState; + var prevIsHidden = _prevState !== null; + + if (prevIsHidden !== nextIsHidden) { + workInProgress.flags |= Visibility; + } + } else { + // On initial mount, we only need a Visibility effect if the tree + // is hidden. + if (nextIsHidden) { + workInProgress.flags |= Visibility; + } + } + } + + if ( + !nextIsHidden || + (workInProgress.mode & ConcurrentMode) === NoMode + ) { + bubbleProperties(workInProgress); + } else { + // Don't bubble properties for hidden children unless we're rendering + // at offscreen priority. + if ( + includesSomeLane(renderLanes, OffscreenLane) && // Also don't bubble if the tree suspended + (workInProgress.flags & DidCapture) === NoLanes + ) { + bubbleProperties(workInProgress); // Check if there was an insertion or update in the hidden subtree. + // If so, we need to hide those nodes in the commit phase, so + // schedule a visibility effect. + + if (workInProgress.subtreeFlags & (Placement | Update)) { + workInProgress.flags |= Visibility; + } + } + } + + var offscreenQueue = workInProgress.updateQueue; + + if (offscreenQueue !== null) { + var _retryQueue3 = offscreenQueue.retryQueue; + scheduleRetryEffect(workInProgress, _retryQueue3); + } + return null; + } + + case CacheComponent: { + return null; + } + + case TracingMarkerComponent: { + return null; + } + } + + throw new Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in " + + "React. Please file an issue." + ); + } + + function unwindWork(current, workInProgress, renderLanes) { + switch (workInProgress.tag) { + case ClassComponent: { + var flags = workInProgress.flags; + + if (flags & ShouldCapture) { + workInProgress.flags = (flags & ~ShouldCapture) | DidCapture; + + if ((workInProgress.mode & ProfileMode) !== NoMode) { + transferActualDuration(workInProgress); + } + + return workInProgress; + } + + return null; + } + + case HostRoot: { + popHostContainer(workInProgress); + var _flags = workInProgress.flags; + + if ( + (_flags & ShouldCapture) !== NoFlags$1 && + (_flags & DidCapture) === NoFlags$1 + ) { + // There was an error during render that wasn't captured by a suspense + // boundary. Do a second pass on the root to unmount the children. + workInProgress.flags = (_flags & ~ShouldCapture) | DidCapture; + return workInProgress; + } // We unwound to the root without completing it. Exit. + + return null; + } + + case HostHoistable: + case HostSingleton: + case HostComponent: { + // TODO: popHydrationState + popHostContext(workInProgress); + return null; + } + + case SuspenseComponent: { + popSuspenseHandler(workInProgress); + var suspenseState = workInProgress.memoizedState; + + if (suspenseState !== null && suspenseState.dehydrated !== null) { + if (workInProgress.alternate === null) { + throw new Error( + "Threw in newly mounted dehydrated component. This is likely a bug in " + + "React. Please file an issue." + ); + } + } + + var _flags2 = workInProgress.flags; + + if (_flags2 & ShouldCapture) { + workInProgress.flags = (_flags2 & ~ShouldCapture) | DidCapture; // Captured a suspense effect. Re-render the boundary. + + if ((workInProgress.mode & ProfileMode) !== NoMode) { + transferActualDuration(workInProgress); + } + + return workInProgress; + } + + return null; + } + + case SuspenseListComponent: { + popSuspenseListContext(workInProgress); // SuspenseList doesn't actually catch anything. It should've been + // caught by a nested boundary. If not, it should bubble through. + + return null; + } + + case HostPortal: + popHostContainer(workInProgress); + return null; + + case ContextProvider: + var context; + + { + context = workInProgress.type._context; + } + + popProvider(context, workInProgress); + return null; + + case OffscreenComponent: + case LegacyHiddenComponent: { + popSuspenseHandler(workInProgress); + popHiddenContext(workInProgress); + var _flags3 = workInProgress.flags; + + if (_flags3 & ShouldCapture) { + workInProgress.flags = (_flags3 & ~ShouldCapture) | DidCapture; // Captured a suspense effect. Re-render the boundary. + + if ((workInProgress.mode & ProfileMode) !== NoMode) { + transferActualDuration(workInProgress); + } + + return workInProgress; + } + + return null; + } + + case CacheComponent: + return null; + + case TracingMarkerComponent: + return null; + + default: + return null; + } + } + + function unwindInterruptedWork(current, interruptedWork, renderLanes) { + switch (interruptedWork.tag) { + case ClassComponent: { + break; + } + + case HostRoot: { + popHostContainer(interruptedWork); + break; + } + + case HostHoistable: + case HostSingleton: + case HostComponent: { + popHostContext(interruptedWork); + break; + } + + case HostPortal: + popHostContainer(interruptedWork); + break; + + case SuspenseComponent: + popSuspenseHandler(interruptedWork); + break; + + case SuspenseListComponent: + popSuspenseListContext(interruptedWork); + break; + + case ContextProvider: + var context; + + { + context = interruptedWork.type._context; + } + + popProvider(context, interruptedWork); + break; + + case OffscreenComponent: + case LegacyHiddenComponent: + popSuspenseHandler(interruptedWork); + popHiddenContext(interruptedWork); + break; + } + } + + var didWarnAboutUndefinedSnapshotBeforeUpdate = null; + + { + didWarnAboutUndefinedSnapshotBeforeUpdate = new Set(); + } // Used during the commit phase to track the state of the Offscreen component stack. + // Allows us to avoid traversing the return path to find the nearest Offscreen ancestor. + + var offscreenSubtreeIsHidden = false; + var offscreenSubtreeWasHidden = false; + var PossiblyWeakSet = typeof WeakSet === "function" ? WeakSet : Set; + var nextEffect = null; // Used for Profiling builds to track updaters. + + var inProgressLanes = null; + var inProgressRoot = null; + + function shouldProfile(current) { + return ( + (current.mode & ProfileMode) !== NoMode && + (getExecutionContext() & CommitContext) !== NoContext + ); + } + + function callComponentWillUnmountWithTimer(current, instance) { + instance.props = current.memoizedProps; + instance.state = current.memoizedState; + + if (shouldProfile(current)) { + try { + startLayoutEffectTimer(); + instance.componentWillUnmount(); + } finally { + recordLayoutEffectDuration(current); + } + } else { + instance.componentWillUnmount(); + } + } // Capture errors so they don't interrupt unmounting. + + function safelyCallComponentWillUnmount( + current, + nearestMountedAncestor, + instance + ) { + try { + callComponentWillUnmountWithTimer(current, instance); + } catch (error) { + captureCommitPhaseError(current, nearestMountedAncestor, error); + } + } // Capture errors so they don't interrupt mounting. + + function safelyAttachRef(current, nearestMountedAncestor) { + try { + commitAttachRef(current); + } catch (error) { + captureCommitPhaseError(current, nearestMountedAncestor, error); + } + } + + function safelyDetachRef(current, nearestMountedAncestor) { + var ref = current.ref; + var refCleanup = current.refCleanup; + + if (ref !== null) { + if (typeof refCleanup === "function") { + try { + if (shouldProfile(current)) { + try { + startLayoutEffectTimer(); + refCleanup(); + } finally { + recordLayoutEffectDuration(current); + } + } else { + refCleanup(); + } + } catch (error) { + captureCommitPhaseError(current, nearestMountedAncestor, error); + } finally { + // `refCleanup` has been called. Nullify all references to it to prevent double invocation. + current.refCleanup = null; + var finishedWork = current.alternate; + + if (finishedWork != null) { + finishedWork.refCleanup = null; + } + } + } else if (typeof ref === "function") { + var retVal; + + try { + if (shouldProfile(current)) { + try { + startLayoutEffectTimer(); + retVal = ref(null); + } finally { + recordLayoutEffectDuration(current); + } + } else { + retVal = ref(null); + } + } catch (error) { + captureCommitPhaseError(current, nearestMountedAncestor, error); + } + + { + if (typeof retVal === "function") { + error( + "Unexpected return value from a callback ref in %s. " + + "A callback ref should not return a function.", + getComponentNameFromFiber(current) + ); + } + } + } else { + // $FlowFixMe[incompatible-use] unable to narrow type to RefObject + ref.current = null; + } + } + } + + function safelyCallDestroy(current, nearestMountedAncestor, destroy) { + try { + destroy(); + } catch (error) { + captureCommitPhaseError(current, nearestMountedAncestor, error); + } + } + var shouldFireAfterActiveInstanceBlur = false; + function commitBeforeMutationEffects(root, firstChild) { + nextEffect = firstChild; + commitBeforeMutationEffects_begin(); // We no longer need to track the active instance fiber + + var shouldFire = shouldFireAfterActiveInstanceBlur; + shouldFireAfterActiveInstanceBlur = false; + return shouldFire; + } + + function commitBeforeMutationEffects_begin() { + while (nextEffect !== null) { + var fiber = nextEffect; // This phase is only used for beforeActiveInstanceBlur. + + var child = fiber.child; + + if ( + (fiber.subtreeFlags & BeforeMutationMask) !== NoFlags$1 && + child !== null + ) { + child.return = fiber; + nextEffect = child; + } else { + commitBeforeMutationEffects_complete(); + } + } + } + + function commitBeforeMutationEffects_complete() { + while (nextEffect !== null) { + var fiber = nextEffect; + setCurrentFiber(fiber); + + try { + commitBeforeMutationEffectsOnFiber(fiber); + } catch (error) { + captureCommitPhaseError(fiber, fiber.return, error); + } + + resetCurrentFiber(); + var sibling = fiber.sibling; + + if (sibling !== null) { + sibling.return = fiber.return; + nextEffect = sibling; + return; + } + + nextEffect = fiber.return; + } + } + + function commitBeforeMutationEffectsOnFiber(finishedWork) { + var current = finishedWork.alternate; + var flags = finishedWork.flags; + + if ((flags & Snapshot) !== NoFlags$1) { + setCurrentFiber(finishedWork); + } + + switch (finishedWork.tag) { + case FunctionComponent: { + break; + } + + case ForwardRef: + case SimpleMemoComponent: { + break; + } + + case ClassComponent: { + if ((flags & Snapshot) !== NoFlags$1) { + 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" + ); + } + + 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" + ); + } + } + } + + var snapshot = instance.getSnapshotBeforeUpdate( + finishedWork.elementType === finishedWork.type + ? prevProps + : resolveDefaultProps(finishedWork.type, prevProps), + prevState + ); + + { + var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate; + + if ( + snapshot === undefined && + !didWarnSet.has(finishedWork.type) + ) { + didWarnSet.add(finishedWork.type); + + error( + "%s.getSnapshotBeforeUpdate(): A snapshot value (or null) " + + "must be returned. You have returned undefined.", + getComponentNameFromFiber(finishedWork) + ); + } + } + + instance.__reactInternalSnapshotBeforeUpdate = snapshot; + } + } + + break; + } + + case HostRoot: { + break; + } + + case HostComponent: + case HostHoistable: + case HostSingleton: + case HostText: + case HostPortal: + case IncompleteClassComponent: + // Nothing to do for these component types + break; + + default: { + if ((flags & Snapshot) !== NoFlags$1) { + throw new Error( + "This unit of work tag should not have side-effects. This error is " + + "likely caused by a bug in React. Please file an issue." + ); + } + } + } + + if ((flags & Snapshot) !== NoFlags$1) { + resetCurrentFiber(); + } + } + + function commitHookEffectListUnmount( + flags, + finishedWork, + nearestMountedAncestor + ) { + var updateQueue = finishedWork.updateQueue; + var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; + + if (lastEffect !== null) { + var firstEffect = lastEffect.next; + var effect = firstEffect; + + do { + if ((effect.tag & flags) === flags) { + // Unmount + var inst = effect.inst; + var destroy = inst.destroy; + + if (destroy !== undefined) { + inst.destroy = undefined; + + { + if ((flags & Insertion) !== NoFlags) { + setIsRunningInsertionEffect(true); + } + } + + safelyCallDestroy(finishedWork, nearestMountedAncestor, destroy); + + { + if ((flags & Insertion) !== NoFlags) { + setIsRunningInsertionEffect(false); + } + } + } + } + + effect = effect.next; + } while (effect !== firstEffect); + } + } + + function commitHookEffectListMount(flags, finishedWork) { + var updateQueue = finishedWork.updateQueue; + var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; + + if (lastEffect !== null) { + var firstEffect = lastEffect.next; + var effect = firstEffect; + + do { + if ((effect.tag & flags) === flags) { + var create = effect.create; + + { + if ((flags & Insertion) !== NoFlags) { + setIsRunningInsertionEffect(true); + } + } + + var inst = effect.inst; + var destroy = create(); + inst.destroy = destroy; + + { + if ((flags & Insertion) !== NoFlags) { + setIsRunningInsertionEffect(false); + } + } + + { + if (destroy !== undefined && typeof destroy !== "function") { + var hookName = void 0; + + if ((effect.tag & Layout) !== NoFlags$1) { + hookName = "useLayoutEffect"; + } else if ((effect.tag & Insertion) !== NoFlags$1) { + hookName = "useInsertionEffect"; + } else { + hookName = "useEffect"; + } + + var addendum = void 0; + + 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 " + + hookName + + "(async () => ...) or returned a Promise. " + + "Instead, write the async function inside your effect " + + "and call it immediately:\n\n" + + hookName + + "(() => {\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://react.dev/link/hooks-data-fetching"; + } else { + addendum = " You returned: " + destroy; + } + + error( + "%s must not return anything besides a function, " + + "which is used for clean-up.%s", + hookName, + addendum + ); + } + } + } + + effect = effect.next; + } while (effect !== firstEffect); + } + } + + function commitPassiveEffectDurations(finishedRoot, finishedWork) { + if (getExecutionContext() & CommitContext) { + // Only Profilers with work in their subtree will have an Update effect scheduled. + if ((finishedWork.flags & Update) !== NoFlags$1) { + switch (finishedWork.tag) { + case Profiler: { + var passiveEffectDuration = + finishedWork.stateNode.passiveEffectDuration; + var _finishedWork$memoize = finishedWork.memoizedProps, + id = _finishedWork$memoize.id, + onPostCommit = _finishedWork$memoize.onPostCommit; // This value will still reflect the previous commit phase. + // It does not get reset until the start of the next commit phase. + + var commitTime = getCommitTime(); + var phase = finishedWork.alternate === null ? "mount" : "update"; + + { + if (isCurrentUpdateNested()) { + phase = "nested-update"; + } + } + + if (typeof onPostCommit === "function") { + onPostCommit(id, phase, passiveEffectDuration, commitTime); + } // Bubble times to the next nearest ancestor Profiler. + // After we process that Profiler, we'll bubble further up. + + var parentFiber = finishedWork.return; + + outer: while (parentFiber !== null) { + switch (parentFiber.tag) { + case HostRoot: + var root = parentFiber.stateNode; + root.passiveEffectDuration += passiveEffectDuration; + break outer; + + case Profiler: + var parentStateNode = parentFiber.stateNode; + parentStateNode.passiveEffectDuration += + passiveEffectDuration; + break outer; + } + + parentFiber = parentFiber.return; + } + + break; + } + } + } + } + } + + function commitHookLayoutEffects(finishedWork, hookFlags) { + // 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. + if (shouldProfile(finishedWork)) { + try { + startLayoutEffectTimer(); + commitHookEffectListMount(hookFlags, finishedWork); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + + recordLayoutEffectDuration(finishedWork); + } else { + try { + commitHookEffectListMount(hookFlags, finishedWork); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + } + } + + function commitClassLayoutLifecycles(finishedWork, current) { + var instance = finishedWork.stateNode; + + 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" + ); + } + } + } + + if (shouldProfile(finishedWork)) { + try { + startLayoutEffectTimer(); + instance.componentDidMount(); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + + recordLayoutEffectDuration(finishedWork); + } else { + try { + instance.componentDidMount(); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + } + } 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" + ); + } + } + } + + if (shouldProfile(finishedWork)) { + try { + startLayoutEffectTimer(); + instance.componentDidUpdate( + prevProps, + prevState, + instance.__reactInternalSnapshotBeforeUpdate + ); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + + recordLayoutEffectDuration(finishedWork); + } else { + try { + instance.componentDidUpdate( + prevProps, + prevState, + instance.__reactInternalSnapshotBeforeUpdate + ); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + } + } + } + + function commitClassCallbacks(finishedWork) { + // 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 = finishedWork.stateNode; + + { + 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. + + try { + commitCallbacks(updateQueue, instance); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + } + } + + function commitHostComponentMount(finishedWork) { + var type = finishedWork.type; + var props = finishedWork.memoizedProps; + var instance = finishedWork.stateNode; + + try { + commitMount(instance, type, props, finishedWork); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + } + + function commitProfilerUpdate(finishedWork, current) { + if (getExecutionContext() & CommitContext) { + try { + 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 (enableProfilerNestedUpdatePhase) { + if (isCurrentUpdateNested()) { + phase = "nested-update"; + } + } + + if (typeof onRender === "function") { + onRender( + finishedWork.memoizedProps.id, + phase, + finishedWork.actualDuration, + finishedWork.treeBaseDuration, + finishedWork.actualStartTime, + commitTime + ); + } + + if (enableProfilerCommitHooks) { + if (typeof onCommit === "function") { + onCommit( + finishedWork.memoizedProps.id, + phase, + effectDuration, + commitTime + ); + } // Schedule a passive effect for this Profiler to call onPostCommit hooks. + // This effect should be scheduled even if there is no onPostCommit callback for this Profiler, + // because the effect is also where times bubble to parent Profilers. + + enqueuePendingPassiveProfilerEffect(finishedWork); // Propagate layout effect durations to the next nearest Profiler ancestor. + // Do not reset these values until the next render so DevTools has a chance to read them first. + + var parentFiber = finishedWork.return; + + outer: while (parentFiber !== null) { + switch (parentFiber.tag) { + case HostRoot: + var root = parentFiber.stateNode; + root.effectDuration += effectDuration; + break outer; + + case Profiler: + var parentStateNode = parentFiber.stateNode; + parentStateNode.effectDuration += effectDuration; + break outer; + } + + parentFiber = parentFiber.return; + } + } + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + } + } + + function commitLayoutEffectOnFiber( + finishedRoot, + current, + finishedWork, + committedLanes + ) { + // When updating this function, also update reappearLayoutEffects, which does + // most of the same things when an offscreen tree goes from hidden -> visible. + var flags = finishedWork.flags; + + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + recursivelyTraverseLayoutEffects(finishedRoot, finishedWork); + + if (flags & Update) { + commitHookLayoutEffects(finishedWork, Layout | HasEffect); + } + + break; + } + + case ClassComponent: { + recursivelyTraverseLayoutEffects(finishedRoot, finishedWork); + + if (flags & Update) { + commitClassLayoutLifecycles(finishedWork, current); + } + + if (flags & Callback) { + commitClassCallbacks(finishedWork); + } + + if (flags & Ref) { + safelyAttachRef(finishedWork, finishedWork.return); + } + + break; + } + + case HostRoot: { + recursivelyTraverseLayoutEffects(finishedRoot, finishedWork); + + if (flags & Callback) { + // 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 HostSingleton: + case HostComponent: + instance = getPublicInstance(finishedWork.child.stateNode); + break; + + case ClassComponent: + instance = finishedWork.child.stateNode; + break; + } + } + + try { + commitCallbacks(updateQueue, instance); + } catch (error) { + captureCommitPhaseError( + finishedWork, + finishedWork.return, + error + ); + } + } + } + + break; + } + + case HostHoistable: + + case HostSingleton: + case HostComponent: { + recursivelyTraverseLayoutEffects(finishedRoot, finishedWork); // 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 && flags & Update) { + commitHostComponentMount(finishedWork); + } + + if (flags & Ref) { + safelyAttachRef(finishedWork, finishedWork.return); + } + + break; + } + + case Profiler: { + recursivelyTraverseLayoutEffects(finishedRoot, finishedWork); // TODO: Should this fire inside an offscreen tree? Or should it wait to + // fire when the tree becomes visible again. + + if (flags & Update) { + commitProfilerUpdate(finishedWork, current); + } + + break; + } + + case SuspenseComponent: { + recursivelyTraverseLayoutEffects(finishedRoot, finishedWork); + + break; + } + + case OffscreenComponent: { + var isModernRoot = (finishedWork.mode & ConcurrentMode) !== NoMode; + + if (isModernRoot) { + var isHidden = finishedWork.memoizedState !== null; + var newOffscreenSubtreeIsHidden = + isHidden || offscreenSubtreeIsHidden; + + if (newOffscreenSubtreeIsHidden); + else { + // The Offscreen tree is visible. + var wasHidden = + current !== null && current.memoizedState !== null; + var newOffscreenSubtreeWasHidden = + wasHidden || offscreenSubtreeWasHidden; + var prevOffscreenSubtreeIsHidden = offscreenSubtreeIsHidden; + var prevOffscreenSubtreeWasHidden = offscreenSubtreeWasHidden; + offscreenSubtreeIsHidden = newOffscreenSubtreeIsHidden; + offscreenSubtreeWasHidden = newOffscreenSubtreeWasHidden; + + if (offscreenSubtreeWasHidden && !prevOffscreenSubtreeWasHidden) { + // This is the root of a reappearing boundary. As we continue + // traversing the layout effects, we must also re-mount layout + // effects that were unmounted when the Offscreen subtree was + // hidden. So this is a superset of the normal commitLayoutEffects. + var includeWorkInProgressEffects = + (finishedWork.subtreeFlags & LayoutMask) !== NoFlags$1; + recursivelyTraverseReappearLayoutEffects( + finishedRoot, + finishedWork, + includeWorkInProgressEffects + ); + } else { + recursivelyTraverseLayoutEffects(finishedRoot, finishedWork); + } + + offscreenSubtreeIsHidden = prevOffscreenSubtreeIsHidden; + offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden; + } + } else { + recursivelyTraverseLayoutEffects(finishedRoot, finishedWork); + } + + if (flags & Ref) { + var props = finishedWork.memoizedProps; + + if (props.mode === "manual") { + safelyAttachRef(finishedWork, finishedWork.return); + } else { + safelyDetachRef(finishedWork, finishedWork.return); + } + } + + break; + } + + default: { + recursivelyTraverseLayoutEffects(finishedRoot, finishedWork); + break; + } + } + } + + function hideOrUnhideAllChildren(finishedWork, isHidden) { + // 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. + var node = finishedWork; + + while (true) { + if (node.tag === HostComponent || false || false) { + if (hostSubtreeRoot === null) { + hostSubtreeRoot = node; + + try { + var instance = node.stateNode; + + if (isHidden) { + hideInstance(instance); + } else { + unhideInstance(node.stateNode, node.memoizedProps); + } + } catch (error) { + captureCommitPhaseError( + finishedWork, + finishedWork.return, + error + ); + } + } + } else if (node.tag === HostText) { + if (hostSubtreeRoot === null) { + try { + var _instance = node.stateNode; + + if (isHidden) { + hideTextInstance(_instance); + } else { + unhideTextInstance(_instance, node.memoizedProps); + } + } catch (error) { + captureCommitPhaseError( + finishedWork, + finishedWork.return, + error + ); + } + } + } 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; + } + + while (node.sibling === null) { + if (node.return === null || node.return === finishedWork) { + return; + } + + if (hostSubtreeRoot === node) { + hostSubtreeRoot = null; + } + + node = node.return; + } + + if (hostSubtreeRoot === node) { + hostSubtreeRoot = null; + } + + node.sibling.return = node.return; + node = node.sibling; + } + } + } + + function commitAttachRef(finishedWork) { + var ref = finishedWork.ref; + + if (ref !== null) { + var instance = finishedWork.stateNode; + var instanceToUse; + + switch (finishedWork.tag) { + case HostHoistable: + case HostSingleton: + case HostComponent: + instanceToUse = getPublicInstance(instance); + break; + + default: + instanceToUse = instance; + } // Moved outside to ensure DCE works with this flag + + if (typeof ref === "function") { + if (shouldProfile(finishedWork)) { + try { + startLayoutEffectTimer(); + finishedWork.refCleanup = ref(instanceToUse); + } finally { + recordLayoutEffectDuration(finishedWork); + } + } else { + finishedWork.refCleanup = ref(instanceToUse); + } + } else { + { + // TODO: We should move these warnings to happen during the render + // phase (markRef). + if (!ref.hasOwnProperty("current")) { + error( + "Unexpected ref object provided for %s. " + + "Use either a ref-setter function or React.createRef().", + getComponentNameFromFiber(finishedWork) + ); + } + } // $FlowFixMe[incompatible-use] unable to narrow type to the non-function case + + ref.current = instanceToUse; + } + } + } + + 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 (alternate !== null) { + alternate.return = null; + } + + fiber.return = null; + } + + function detachFiberAfterEffects(fiber) { + var alternate = fiber.alternate; + + if (alternate !== null) { + fiber.alternate = null; + detachFiberAfterEffects(alternate); + } // Clear cyclical Fiber fields. This level alone is designed to roughly + // approximate the planned Fiber refactor. In that world, `setState` will be + // bound to a special "instance" object instead of a Fiber. The Instance + // object will not have any of these fields. It will only be connected to + // the fiber tree via a single link at the root. So if this level alone is + // sufficient to fix memory issues, that bodes well for our plans. + + fiber.child = null; + fiber.deletions = null; + fiber.sibling = null; // The `stateNode` is cyclical because on host nodes it points to the host + + fiber.stateNode = null; + + { + fiber._debugOwner = null; + } // Theoretically, nothing in here should be necessary, because we already + // disconnected the fiber from the tree. So even if something leaks this + // particular fiber, it won't leak anything else. + + fiber.return = null; + fiber.dependencies = null; + fiber.memoizedProps = null; + fiber.memoizedState = null; + fiber.pendingProps = null; + fiber.stateNode = null; // TODO: Move to `commitPassiveUnmountInsideDeletedTreeOnFiber` instead. + + fiber.updateQueue = null; + } + + function getHostParentFiber(fiber) { + var parent = fiber.return; + + while (parent !== null) { + if (isHostParent(parent)) { + return parent; + } + + parent = parent.return; + } + + throw new Error( + "Expected to find a host parent. This error is likely caused by a bug " + + "in React. Please file an issue." + ); + } + + function isHostParent(fiber) { + return ( + fiber.tag === HostComponent || + fiber.tag === HostRoot || + false || + false || + 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; + } // $FlowFixMe[incompatible-type] found when upgrading Flow + + node = node.return; + } + + node.sibling.return = node.return; + node = node.sibling; + + while ( + node.tag !== HostComponent && + node.tag !== HostText && + true && + 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 (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 (!(node.flags & Placement)) { + // Found it! + return node.stateNode; + } + } + } + + function commitPlacement(finishedWork) { + var parentFiber = getHostParentFiber(finishedWork); + + switch (parentFiber.tag) { + case HostSingleton: + + case HostComponent: { + var _parent = parentFiber.stateNode; + + if (parentFiber.flags & ContentReset) { + parentFiber.flags &= ~ContentReset; + } + + 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. + + insertOrAppendPlacementNode(finishedWork, _before, _parent); + break; + } + + case HostRoot: + case HostPortal: { + var _parent2 = parentFiber.stateNode.containerInfo; + + var _before2 = getHostSibling(finishedWork); + + insertOrAppendPlacementNodeIntoContainer( + finishedWork, + _before2, + _parent2 + ); + break; + } + + default: + throw new Error( + "Invalid host parent fiber. This error is likely caused by a bug " + + "in React. Please file an issue." + ); + } + } + + function insertOrAppendPlacementNodeIntoContainer(node, before, parent) { + var tag = node.tag; + var isHost = tag === HostComponent || tag === HostText; + + if (isHost) { + var stateNode = node.stateNode; + + if (before) { + insertInContainerBefore(parent); + } else { + appendChildToContainer(parent, stateNode); + } + } else if (tag === HostPortal || false); + else { + var child = node.child; + + if (child !== null) { + insertOrAppendPlacementNodeIntoContainer(child, before, parent); + var sibling = child.sibling; + + while (sibling !== null) { + insertOrAppendPlacementNodeIntoContainer(sibling, before, parent); + sibling = sibling.sibling; + } + } + } + } + + function insertOrAppendPlacementNode(node, before, parent) { + var tag = node.tag; + var isHost = tag === HostComponent || tag === HostText; + + if (isHost) { + var stateNode = node.stateNode; + + if (before) { + insertBefore(parent, stateNode, before); + } else { + appendChild(parent, stateNode); + } + } else if (tag === HostPortal || false); + else { + var child = node.child; + + if (child !== null) { + insertOrAppendPlacementNode(child, before, parent); + var sibling = child.sibling; + + while (sibling !== null) { + insertOrAppendPlacementNode(sibling, before, parent); + sibling = sibling.sibling; + } + } + } + } // These are tracked on the stack as we recursively traverse a + // deleted subtree. + // TODO: Update these during the whole mutation phase, not just during + // a deletion. + + var hostParent = null; + var hostParentIsContainer = false; + + function commitDeletionEffects(root, returnFiber, deletedFiber) { + { + // We only have the top Fiber that was deleted but we need to recurse down its + // children to find all the terminal nodes. + // Recursively delete all host nodes from the parent, detach refs, clean + // up mounted layout effects, and call componentWillUnmount. + // We only need to remove the topmost host child in each branch. But then we + // still need to keep traversing to unmount effects, refs, and cWU. TODO: We + // could split this into two separate traversals functions, where the second + // one doesn't include any removeChild logic. This is maybe the same + // function as "disappearLayoutEffects" (or whatever that turns into after + // the layout phase is refactored to use recursion). + // Before starting, find the nearest host parent on the stack so we know + // which instance/container to remove the children from. + // TODO: Instead of searching up the fiber return path on every deletion, we + // can track the nearest host component on the JS stack as we traverse the + // tree during the commit phase. This would make insertions faster, too. + var parent = returnFiber; + + findParent: while (parent !== null) { + switch (parent.tag) { + case HostSingleton: + case HostComponent: { + hostParent = parent.stateNode; + hostParentIsContainer = false; + break findParent; + } + + case HostRoot: { + hostParent = parent.stateNode.containerInfo; + hostParentIsContainer = true; + break findParent; + } + + case HostPortal: { + hostParent = parent.stateNode.containerInfo; + hostParentIsContainer = true; + break findParent; + } + } + + parent = parent.return; + } + + if (hostParent === null) { + throw new Error( + "Expected to find a host parent. This error is likely caused by " + + "a bug in React. Please file an issue." + ); + } + + commitDeletionEffectsOnFiber(root, returnFiber, deletedFiber); + hostParent = null; + hostParentIsContainer = false; + } + + detachFiberMutation(deletedFiber); + } + + function recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + parent + ) { + // TODO: Use a static flag to skip trees that don't have unmount effects + var child = parent.child; + + while (child !== null) { + commitDeletionEffectsOnFiber( + finishedRoot, + nearestMountedAncestor, + child + ); + child = child.sibling; + } + } + + function commitDeletionEffectsOnFiber( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ) { + onCommitUnmount(deletedFiber); // The cases in this outer switch modify the stack before they traverse + // into their subtree. There are simpler cases in the inner switch + // that don't modify the stack. + + switch (deletedFiber.tag) { + case HostHoistable: + + case HostSingleton: + + case HostComponent: { + if (!offscreenSubtreeWasHidden) { + safelyDetachRef(deletedFiber, nearestMountedAncestor); + } // Intentional fallthrough to next branch + } + + case HostText: { + // We only need to remove the nearest host child. Set the host parent + // to `null` on the stack to indicate that nested children don't + // need to be removed. + { + var _prevHostParent = hostParent; + var _prevHostParentIsContainer = hostParentIsContainer; + hostParent = null; + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + hostParent = _prevHostParent; + hostParentIsContainer = _prevHostParentIsContainer; + + if (hostParent !== null) { + // Now that all the child effects have unmounted, we can remove the + // node from the tree. + if (hostParentIsContainer) { + removeChildFromContainer(hostParent, deletedFiber.stateNode); + } else { + removeChild(hostParent, deletedFiber.stateNode); + } + } + } + + return; + } + + case DehydratedFragment: { + // Delete the dehydrated suspense boundary and all of its content. + + { + if (hostParent !== null) { + if (hostParentIsContainer) { + clearSuspenseBoundaryFromContainer(); + } else { + clearSuspenseBoundary(); + } + } + } + + return; + } + + case HostPortal: { + { + // When we go into a portal, it becomes the parent to remove from. + var _prevHostParent2 = hostParent; + var _prevHostParentIsContainer2 = hostParentIsContainer; + hostParent = deletedFiber.stateNode.containerInfo; + hostParentIsContainer = true; + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + hostParent = _prevHostParent2; + hostParentIsContainer = _prevHostParentIsContainer2; + } + + return; + } + + case FunctionComponent: + case ForwardRef: + case MemoComponent: + case SimpleMemoComponent: { + if (!offscreenSubtreeWasHidden) { + var updateQueue = deletedFiber.updateQueue; + + if (updateQueue !== null) { + var lastEffect = updateQueue.lastEffect; + + if (lastEffect !== null) { + var firstEffect = lastEffect.next; + var effect = firstEffect; + + do { + var tag = effect.tag; + var inst = effect.inst; + var destroy = inst.destroy; + + if (destroy !== undefined) { + if ((tag & Insertion) !== NoFlags) { + inst.destroy = undefined; + safelyCallDestroy( + deletedFiber, + nearestMountedAncestor, + destroy + ); + } else if ((tag & Layout) !== NoFlags) { + if (shouldProfile(deletedFiber)) { + startLayoutEffectTimer(); + inst.destroy = undefined; + safelyCallDestroy( + deletedFiber, + nearestMountedAncestor, + destroy + ); + recordLayoutEffectDuration(deletedFiber); + } else { + inst.destroy = undefined; + safelyCallDestroy( + deletedFiber, + nearestMountedAncestor, + destroy + ); + } + } + } + + effect = effect.next; + } while (effect !== firstEffect); + } + } + } + + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + return; + } + + case ClassComponent: { + if (!offscreenSubtreeWasHidden) { + safelyDetachRef(deletedFiber, nearestMountedAncestor); + var instance = deletedFiber.stateNode; + + if (typeof instance.componentWillUnmount === "function") { + safelyCallComponentWillUnmount( + deletedFiber, + nearestMountedAncestor, + instance + ); + } + } + + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + return; + } + + case ScopeComponent: { + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + return; + } + + case OffscreenComponent: { + safelyDetachRef(deletedFiber, nearestMountedAncestor); + + if (deletedFiber.mode & ConcurrentMode) { + // If this offscreen component is hidden, we already unmounted it. Before + // deleting the children, track that it's already unmounted so that we + // don't attempt to unmount the effects again. + // TODO: If the tree is hidden, in most cases we should be able to skip + // over the nested children entirely. An exception is we haven't yet found + // the topmost host node to delete, which we already track on the stack. + // But the other case is portals, which need to be detached no matter how + // deeply they are nested. We should use a subtree flag to track whether a + // subtree includes a nested portal. + var prevOffscreenSubtreeWasHidden = offscreenSubtreeWasHidden; + offscreenSubtreeWasHidden = + prevOffscreenSubtreeWasHidden || + deletedFiber.memoizedState !== null; + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden; + } else { + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + } + + break; + } + + default: { + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + return; + } + } + } + + function commitSuspenseCallback(finishedWork) {} + + function getRetryCache(finishedWork) { + // TODO: Unify the interface for the retry cache so we don't have to switch + // on the tag like this. + switch (finishedWork.tag) { + case SuspenseComponent: + case SuspenseListComponent: { + var retryCache = finishedWork.stateNode; + + if (retryCache === null) { + retryCache = finishedWork.stateNode = new PossiblyWeakSet(); + } + + return retryCache; + } + + case OffscreenComponent: { + var instance = finishedWork.stateNode; + var _retryCache = instance._retryCache; + + if (_retryCache === null) { + _retryCache = instance._retryCache = new PossiblyWeakSet(); + } + + return _retryCache; + } + + default: { + throw new Error( + "Unexpected Suspense handler tag (" + + finishedWork.tag + + "). This is a " + + "bug in React." + ); + } + } + } + + function detachOffscreenInstance(instance) { + var fiber = instance._current; + + if (fiber === null) { + throw new Error( + "Calling Offscreen.detach before instance handle has been set." + ); + } + + if ((instance._pendingVisibility & OffscreenDetached) !== NoFlags$1) { + // The instance is already detached, this is a noop. + return; + } // TODO: There is an opportunity to optimise this by not entering commit phase + // and unmounting effects directly. + + var root = enqueueConcurrentRenderForLane(fiber, SyncLane); + + if (root !== null) { + instance._pendingVisibility |= OffscreenDetached; + scheduleUpdateOnFiber(root, fiber, SyncLane); + } + } + function attachOffscreenInstance(instance) { + var fiber = instance._current; + + if (fiber === null) { + throw new Error( + "Calling Offscreen.detach before instance handle has been set." + ); + } + + if ((instance._pendingVisibility & OffscreenDetached) === NoFlags$1) { + // The instance is already attached, this is a noop. + return; + } + + var root = enqueueConcurrentRenderForLane(fiber, SyncLane); + + if (root !== null) { + instance._pendingVisibility &= ~OffscreenDetached; + scheduleUpdateOnFiber(root, fiber, SyncLane); + } + } + + function attachSuspenseRetryListeners(finishedWork, wakeables) { + // 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 retryCache = getRetryCache(finishedWork); + wakeables.forEach(function (wakeable) { + // Memoize using the boundary fiber to prevent redundant listeners. + var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable); + + if (!retryCache.has(wakeable)) { + retryCache.add(wakeable); + + { + if (isDevToolsPresent) { + if (inProgressLanes !== null && inProgressRoot !== null) { + // If we have pending work still, associate the original updaters with it. + restorePendingUpdaters(inProgressRoot, inProgressLanes); + } else { + throw Error( + "Expected finished root and lanes to be set. This is a bug in React." + ); + } + } + } + + wakeable.then(retry, retry); + } + }); + } // This function detects when a Suspense boundary goes from visible to hidden. + function commitMutationEffects(root, finishedWork, committedLanes) { + inProgressLanes = committedLanes; + inProgressRoot = root; + setCurrentFiber(finishedWork); + commitMutationEffectsOnFiber(finishedWork, root); + setCurrentFiber(finishedWork); + inProgressLanes = null; + inProgressRoot = null; + } + + function recursivelyTraverseMutationEffects(root, parentFiber, lanes) { + // Deletions effects can be scheduled on any fiber type. They need to happen + // before the children effects hae fired. + var deletions = parentFiber.deletions; + + if (deletions !== null) { + for (var i = 0; i < deletions.length; i++) { + var childToDelete = deletions[i]; + + try { + commitDeletionEffects(root, parentFiber, childToDelete); + } catch (error) { + captureCommitPhaseError(childToDelete, parentFiber, error); + } + } + } + + var prevDebugFiber = getCurrentFiber(); + + if (parentFiber.subtreeFlags & MutationMask) { + var child = parentFiber.child; + + while (child !== null) { + setCurrentFiber(child); + commitMutationEffectsOnFiber(child, root); + child = child.sibling; + } + } + + setCurrentFiber(prevDebugFiber); + } + + function commitMutationEffectsOnFiber(finishedWork, root, lanes) { + var current = finishedWork.alternate; + var flags = finishedWork.flags; // The effect flag should be checked *after* we refine the type of fiber, + // because the fiber tag is more specific. An exception is any flag related + // to reconciliation, because those can be set on all fiber types. + + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case MemoComponent: + case SimpleMemoComponent: { + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + + if (flags & Update) { + try { + commitHookEffectListUnmount( + Insertion | HasEffect, + finishedWork, + finishedWork.return + ); + commitHookEffectListMount(Insertion | HasEffect, finishedWork); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } // Layout effects are destroyed during the mutation phase so that all + // destroy functions for all fibers are called before any create functions. + // This prevents sibling component effects from interfering with each other, + // e.g. a destroy function in one component should never override a ref set + // by a create function in another component during the same commit. + + if (shouldProfile(finishedWork)) { + try { + startLayoutEffectTimer(); + commitHookEffectListUnmount( + Layout | HasEffect, + finishedWork, + finishedWork.return + ); + } catch (error) { + captureCommitPhaseError( + finishedWork, + finishedWork.return, + error + ); + } + + recordLayoutEffectDuration(finishedWork); + } else { + try { + commitHookEffectListUnmount( + Layout | HasEffect, + finishedWork, + finishedWork.return + ); + } catch (error) { + captureCommitPhaseError( + finishedWork, + finishedWork.return, + error + ); + } + } + } + + return; + } + + case ClassComponent: { + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + + if (flags & Ref) { + if (current !== null) { + safelyDetachRef(current, current.return); + } + } + + if (flags & Callback && offscreenSubtreeIsHidden) { + var updateQueue = finishedWork.updateQueue; + + if (updateQueue !== null) { + deferHiddenCallbacks(updateQueue); + } + } + + return; + } + + case HostHoistable: + + case HostSingleton: + + case HostComponent: { + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + + if (flags & Ref) { + if (current !== null) { + safelyDetachRef(current, current.return); + } + } + + { + // TODO: ContentReset gets cleared by the children during the commit + // phase. This is a refactor hazard because it means we must read + // flags the flags after `commitReconciliationEffects` has already run; + // the order matters. We should refactor so that ContentReset does not + // rely on mutating the flag during commit. Like by setting a flag + // during the render phase instead. + if (finishedWork.flags & ContentReset) { + var instance = finishedWork.stateNode; + + try { + resetTextContent(instance); + } catch (error) { + captureCommitPhaseError( + finishedWork, + finishedWork.return, + error + ); + } + } + + if (flags & Update) { + var _instance2 = finishedWork.stateNode; + + if (_instance2 != 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; + + try { + commitUpdate( + _instance2, + _updatePayload, + type, + oldProps, + newProps, + finishedWork + ); + } catch (error) { + captureCommitPhaseError( + finishedWork, + finishedWork.return, + error + ); + } + } + } + } + + return; + } + + case HostText: { + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + + if (flags & Update) { + { + if (finishedWork.stateNode === null) { + throw new Error( + "This should have a text node initialized. This error is likely " + + "caused by a bug in React. Please file an issue." + ); + } + + var textInstance = finishedWork.stateNode; + var newText = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps + // as the newProps. The updatePayload will contain the real change in + // this case. + + var oldText = current !== null ? current.memoizedProps : newText; + + try { + commitTextUpdate(textInstance, oldText, newText); + } catch (error) { + captureCommitPhaseError( + finishedWork, + finishedWork.return, + error + ); + } + } + } + + return; + } + + case HostRoot: { + { + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + } + + return; + } + + case HostPortal: { + { + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + } + + return; + } + + case SuspenseComponent: { + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); // TODO: We should mark a flag on the Suspense fiber itself, rather than + // relying on the Offscreen fiber having a flag also being marked. The + // reason is that this offscreen fiber might not be part of the work-in- + // progress tree! It could have been reused from a previous render. This + // doesn't lead to incorrect behavior because we don't rely on the flag + // check alone; we also compare the states explicitly below. But for + // modeling purposes, we _should_ be able to rely on the flag check alone. + // So this is a bit fragile. + // + // Also, all this logic could/should move to the passive phase so it + // doesn't block paint. + + var offscreenFiber = finishedWork.child; + + if (offscreenFiber.flags & Visibility) { + // Throttle the appearance and disappearance of Suspense fallbacks. + var isShowingFallback = finishedWork.memoizedState !== null; + var wasShowingFallback = + current !== null && current.memoizedState !== null; + + { + if (isShowingFallback && !wasShowingFallback) { + // Old behavior. Only mark when a fallback appears, not when + // it disappears. + markCommitTimeOfFallback(); + } + } + } + + if (flags & Update) { + try { + commitSuspenseCallback(finishedWork); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + + var retryQueue = finishedWork.updateQueue; + + if (retryQueue !== null) { + finishedWork.updateQueue = null; + attachSuspenseRetryListeners(finishedWork, retryQueue); + } + } + + return; + } + + case OffscreenComponent: { + if (flags & Ref) { + if (current !== null) { + safelyDetachRef(current, current.return); + } + } + + var newState = finishedWork.memoizedState; + var isHidden = newState !== null; + var wasHidden = current !== null && current.memoizedState !== null; + + if (finishedWork.mode & ConcurrentMode) { + // Before committing the children, track on the stack whether this + // offscreen subtree was already hidden, so that we don't unmount the + // effects again. + var prevOffscreenSubtreeIsHidden = offscreenSubtreeIsHidden; + var prevOffscreenSubtreeWasHidden = offscreenSubtreeWasHidden; + offscreenSubtreeIsHidden = prevOffscreenSubtreeIsHidden || isHidden; + offscreenSubtreeWasHidden = + prevOffscreenSubtreeWasHidden || wasHidden; + recursivelyTraverseMutationEffects(root, finishedWork); + offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden; + offscreenSubtreeIsHidden = prevOffscreenSubtreeIsHidden; + } else { + recursivelyTraverseMutationEffects(root, finishedWork); + } + + commitReconciliationEffects(finishedWork); + var offscreenInstance = finishedWork.stateNode; // TODO: Add explicit effect flag to set _current. + + offscreenInstance._current = finishedWork; // Offscreen stores pending changes to visibility in `_pendingVisibility`. This is + // to support batching of `attach` and `detach` calls. + + offscreenInstance._visibility &= ~OffscreenDetached; + offscreenInstance._visibility |= + offscreenInstance._pendingVisibility & OffscreenDetached; + + if (flags & Visibility) { + // Track the current state on the Offscreen instance so we can + // read it during an event + if (isHidden) { + offscreenInstance._visibility &= ~OffscreenVisible; + } else { + offscreenInstance._visibility |= OffscreenVisible; + } + + if (isHidden) { + var isUpdate = current !== null; + var wasHiddenByAncestorOffscreen = + offscreenSubtreeIsHidden || offscreenSubtreeWasHidden; // Only trigger disapper layout effects if: + // - This is an update, not first mount. + // - This Offscreen was not hidden before. + // - Ancestor Offscreen was not hidden in previous commit. + + if (isUpdate && !wasHidden && !wasHiddenByAncestorOffscreen) { + if ((finishedWork.mode & ConcurrentMode) !== NoMode) { + // Disappear the layout effects of all the children + recursivelyTraverseDisappearLayoutEffects(finishedWork); + } + } + } // Offscreen with manual mode manages visibility manually. + + if (!isOffscreenManual(finishedWork)) { + // TODO: This needs to run whenever there's an insertion or update + // inside a hidden Offscreen tree. + hideOrUnhideAllChildren(finishedWork, isHidden); + } + } // TODO: Move to passive phase + + if (flags & Update) { + var offscreenQueue = finishedWork.updateQueue; + + if (offscreenQueue !== null) { + var _retryQueue = offscreenQueue.retryQueue; + + if (_retryQueue !== null) { + offscreenQueue.retryQueue = null; + attachSuspenseRetryListeners(finishedWork, _retryQueue); + } + } + } + + return; + } + + case SuspenseListComponent: { + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + + if (flags & Update) { + var _retryQueue2 = finishedWork.updateQueue; + + if (_retryQueue2 !== null) { + finishedWork.updateQueue = null; + attachSuspenseRetryListeners(finishedWork, _retryQueue2); + } + } + + return; + } + + case ScopeComponent: { + return; + } + + default: { + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + return; + } + } + } + + function commitReconciliationEffects(finishedWork) { + // Placement effects (insertions, reorders) can be scheduled on any fiber + // type. They needs to happen after the children effects have fired, but + // before the effects on this fiber have fired. + var flags = finishedWork.flags; + + if (flags & Placement) { + try { + commitPlacement(finishedWork); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } // Clear the "placement" from effect tag so that we know that this is + // inserted, before any life-cycles like componentDidMount gets called. + // TODO: findDOMNode doesn't rely on this any more but isMounted does + // and isMounted is deprecated anyway so we should be able to kill this. + + finishedWork.flags &= ~Placement; + } + + if (flags & Hydrating) { + finishedWork.flags &= ~Hydrating; + } + } + + function commitLayoutEffects(finishedWork, root, committedLanes) { + inProgressLanes = committedLanes; + inProgressRoot = root; + var current = finishedWork.alternate; + commitLayoutEffectOnFiber(root, current, finishedWork); + inProgressLanes = null; + inProgressRoot = null; + } + + function recursivelyTraverseLayoutEffects(root, parentFiber, lanes) { + var prevDebugFiber = getCurrentFiber(); + + if (parentFiber.subtreeFlags & LayoutMask) { + var child = parentFiber.child; + + while (child !== null) { + setCurrentFiber(child); + var current = child.alternate; + commitLayoutEffectOnFiber(root, current, child); + child = child.sibling; + } + } + + setCurrentFiber(prevDebugFiber); + } + + function disappearLayoutEffects(finishedWork) { + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case MemoComponent: + case SimpleMemoComponent: { + // TODO (Offscreen) Check: flags & LayoutStatic + if (shouldProfile(finishedWork)) { + try { + startLayoutEffectTimer(); + commitHookEffectListUnmount( + Layout, + finishedWork, + finishedWork.return + ); + } finally { + recordLayoutEffectDuration(finishedWork); + } + } else { + commitHookEffectListUnmount( + Layout, + finishedWork, + finishedWork.return + ); + } + + recursivelyTraverseDisappearLayoutEffects(finishedWork); + break; + } + + case ClassComponent: { + // TODO (Offscreen) Check: flags & RefStatic + safelyDetachRef(finishedWork, finishedWork.return); + var instance = finishedWork.stateNode; + + if (typeof instance.componentWillUnmount === "function") { + safelyCallComponentWillUnmount( + finishedWork, + finishedWork.return, + instance + ); + } + + recursivelyTraverseDisappearLayoutEffects(finishedWork); + break; + } + + case HostHoistable: + case HostSingleton: + case HostComponent: { + // TODO (Offscreen) Check: flags & RefStatic + safelyDetachRef(finishedWork, finishedWork.return); + recursivelyTraverseDisappearLayoutEffects(finishedWork); + break; + } + + case OffscreenComponent: { + // TODO (Offscreen) Check: flags & RefStatic + safelyDetachRef(finishedWork, finishedWork.return); + var isHidden = finishedWork.memoizedState !== null; + + if (isHidden); + else { + recursivelyTraverseDisappearLayoutEffects(finishedWork); + } + + break; + } + + default: { + recursivelyTraverseDisappearLayoutEffects(finishedWork); + break; + } + } + } + + function recursivelyTraverseDisappearLayoutEffects(parentFiber) { + // TODO (Offscreen) Check: flags & (RefStatic | LayoutStatic) + var child = parentFiber.child; + + while (child !== null) { + disappearLayoutEffects(child); + child = child.sibling; + } + } + + function reappearLayoutEffects( + finishedRoot, + current, + finishedWork, // This function visits both newly finished work and nodes that were re-used + // from a previously committed tree. We cannot check non-static flags if the + // node was reused. + includeWorkInProgressEffects + ) { + // Turn on layout effects in a tree that previously disappeared. + var flags = finishedWork.flags; + + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + recursivelyTraverseReappearLayoutEffects( + finishedRoot, + finishedWork, + includeWorkInProgressEffects + ); // TODO: Check flags & LayoutStatic + + commitHookLayoutEffects(finishedWork, Layout); + break; + } + + case ClassComponent: { + recursivelyTraverseReappearLayoutEffects( + finishedRoot, + finishedWork, + includeWorkInProgressEffects + ); // TODO: Check for LayoutStatic flag + + var instance = finishedWork.stateNode; + + if (typeof instance.componentDidMount === "function") { + try { + instance.componentDidMount(); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + } // Commit any callbacks that would have fired while the component + // was hidden. + + var updateQueue = finishedWork.updateQueue; + + if (updateQueue !== null) { + commitHiddenCallbacks(updateQueue, instance); + } // If this is newly finished work, check for setState callbacks + + if (includeWorkInProgressEffects && flags & Callback) { + commitClassCallbacks(finishedWork); + } // TODO: Check flags & RefStatic + + safelyAttachRef(finishedWork, finishedWork.return); + break; + } + // Unlike commitLayoutEffectsOnFiber, we don't need to handle HostRoot + // because this function only visits nodes that are inside an + // Offscreen fiber. + // case HostRoot: { + // ... + // } + + case HostHoistable: + case HostSingleton: + case HostComponent: { + recursivelyTraverseReappearLayoutEffects( + finishedRoot, + finishedWork, + includeWorkInProgressEffects + ); // 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 ( + includeWorkInProgressEffects && + current === null && + flags & Update + ) { + commitHostComponentMount(finishedWork); + } // TODO: Check flags & Ref + + safelyAttachRef(finishedWork, finishedWork.return); + break; + } + + case Profiler: { + recursivelyTraverseReappearLayoutEffects( + finishedRoot, + finishedWork, + includeWorkInProgressEffects + ); // TODO: Figure out how Profiler updates should work with Offscreen + + if (includeWorkInProgressEffects && flags & Update) { + commitProfilerUpdate(finishedWork, current); + } + + break; + } + + case SuspenseComponent: { + recursivelyTraverseReappearLayoutEffects( + finishedRoot, + finishedWork, + includeWorkInProgressEffects + ); // TODO: Figure out how Suspense hydration callbacks should work + + break; + } + + case OffscreenComponent: { + var offscreenState = finishedWork.memoizedState; + var isHidden = offscreenState !== null; + + if (isHidden); + else { + recursivelyTraverseReappearLayoutEffects( + finishedRoot, + finishedWork, + includeWorkInProgressEffects + ); + } // TODO: Check flags & Ref + + safelyAttachRef(finishedWork, finishedWork.return); + break; + } + + default: { + recursivelyTraverseReappearLayoutEffects( + finishedRoot, + finishedWork, + includeWorkInProgressEffects + ); + break; + } + } + } + + function recursivelyTraverseReappearLayoutEffects( + finishedRoot, + parentFiber, + includeWorkInProgressEffects + ) { + // This function visits both newly finished work and nodes that were re-used + // from a previously committed tree. We cannot check non-static flags if the + // node was reused. + var childShouldIncludeWorkInProgressEffects = + includeWorkInProgressEffects && + (parentFiber.subtreeFlags & LayoutMask) !== NoFlags$1; // TODO (Offscreen) Check: flags & (RefStatic | LayoutStatic) + + var prevDebugFiber = getCurrentFiber(); + var child = parentFiber.child; + + while (child !== null) { + var current = child.alternate; + reappearLayoutEffects( + finishedRoot, + current, + child, + childShouldIncludeWorkInProgressEffects + ); + child = child.sibling; + } + + setCurrentFiber(prevDebugFiber); + } + + function commitHookPassiveMountEffects(finishedWork, hookFlags) { + if (shouldProfile(finishedWork)) { + startPassiveEffectTimer(); + + try { + commitHookEffectListMount(hookFlags, finishedWork); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + + recordPassiveEffectDuration(finishedWork); + } else { + try { + commitHookEffectListMount(hookFlags, finishedWork); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + } + } + + function commitPassiveMountEffects( + root, + finishedWork, + committedLanes, + committedTransitions + ) { + setCurrentFiber(finishedWork); + commitPassiveMountOnFiber(root, finishedWork); + resetCurrentFiber(); + } + + function recursivelyTraversePassiveMountEffects( + root, + parentFiber, + committedLanes, + committedTransitions + ) { + var prevDebugFiber = getCurrentFiber(); + + if (parentFiber.subtreeFlags & PassiveMask) { + var child = parentFiber.child; + + while (child !== null) { + setCurrentFiber(child); + commitPassiveMountOnFiber(root, child); + child = child.sibling; + } + } + + setCurrentFiber(prevDebugFiber); + } + + function commitPassiveMountOnFiber( + finishedRoot, + finishedWork, + committedLanes, + committedTransitions + ) { + // When updating this function, also update reconnectPassiveEffects, which does + // most of the same things when an offscreen tree goes from hidden -> visible, + // or when toggling effects inside a hidden tree. + var flags = finishedWork.flags; + + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + recursivelyTraversePassiveMountEffects(finishedRoot, finishedWork); + + if (flags & Passive$1) { + commitHookPassiveMountEffects(finishedWork, Passive | HasEffect); + } + + break; + } + + case HostRoot: { + recursivelyTraversePassiveMountEffects(finishedRoot, finishedWork); + + break; + } + + case LegacyHiddenComponent: { + break; + } + + case OffscreenComponent: { + // TODO: Pass `current` as argument to this function + var _instance3 = finishedWork.stateNode; + var nextState = finishedWork.memoizedState; + var isHidden = nextState !== null; + + if (isHidden) { + if (_instance3._visibility & OffscreenPassiveEffectsConnected) { + // The effects are currently connected. Update them. + recursivelyTraversePassiveMountEffects( + finishedRoot, + finishedWork + ); + } else { + if (finishedWork.mode & ConcurrentMode); + else { + // Legacy Mode: Fire the effects even if the tree is hidden. + _instance3._visibility |= OffscreenPassiveEffectsConnected; + recursivelyTraversePassiveMountEffects( + finishedRoot, + finishedWork + ); + } + } + } else { + // Tree is visible + if (_instance3._visibility & OffscreenPassiveEffectsConnected) { + // The effects are currently connected. Update them. + recursivelyTraversePassiveMountEffects( + finishedRoot, + finishedWork + ); + } else { + // The effects are currently disconnected. Reconnect them, while also + // firing effects inside newly mounted trees. This also applies to + // the initial render. + _instance3._visibility |= OffscreenPassiveEffectsConnected; + recursivelyTraverseReconnectPassiveEffects( + finishedRoot, + finishedWork + ); + } + } + + break; + } + + case CacheComponent: { + recursivelyTraversePassiveMountEffects(finishedRoot, finishedWork); + + break; + } + + case TracingMarkerComponent: + + default: { + recursivelyTraversePassiveMountEffects(finishedRoot, finishedWork); + break; + } + } + } + + function recursivelyTraverseReconnectPassiveEffects( + finishedRoot, + parentFiber, + committedLanes, + committedTransitions, + includeWorkInProgressEffects + ) { + var prevDebugFiber = getCurrentFiber(); + var child = parentFiber.child; + + while (child !== null) { + reconnectPassiveEffects(finishedRoot, child); + child = child.sibling; + } + + setCurrentFiber(prevDebugFiber); + } + + function reconnectPassiveEffects( + finishedRoot, + finishedWork, + committedLanes, + committedTransitions, // This function visits both newly finished work and nodes that were re-used + // from a previously committed tree. We cannot check non-static flags if the + // node was reused. + includeWorkInProgressEffects + ) { + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + recursivelyTraverseReconnectPassiveEffects( + finishedRoot, + finishedWork + ); // TODO: Check for PassiveStatic flag + + commitHookPassiveMountEffects(finishedWork, Passive); + break; + } + // Unlike commitPassiveMountOnFiber, we don't need to handle HostRoot + // because this function only visits nodes that are inside an + // Offscreen fiber. + // case HostRoot: { + // ... + // } + + case LegacyHiddenComponent: { + break; + } + + case OffscreenComponent: { + var _instance4 = finishedWork.stateNode; + var nextState = finishedWork.memoizedState; + var isHidden = nextState !== null; + + if (isHidden) { + if (_instance4._visibility & OffscreenPassiveEffectsConnected) { + // The effects are currently connected. Update them. + recursivelyTraverseReconnectPassiveEffects( + finishedRoot, + finishedWork + ); + } else { + if (finishedWork.mode & ConcurrentMode); + else { + // Legacy Mode: Fire the effects even if the tree is hidden. + _instance4._visibility |= OffscreenPassiveEffectsConnected; + recursivelyTraverseReconnectPassiveEffects( + finishedRoot, + finishedWork + ); + } + } + } else { + // Tree is visible + // Since we're already inside a reconnecting tree, it doesn't matter + // whether the effects are currently connected. In either case, we'll + // continue traversing the tree and firing all the effects. + // + // We do need to set the "connected" flag on the instance, though. + _instance4._visibility |= OffscreenPassiveEffectsConnected; + recursivelyTraverseReconnectPassiveEffects( + finishedRoot, + finishedWork + ); + } + + break; + } + + case CacheComponent: { + recursivelyTraverseReconnectPassiveEffects( + finishedRoot, + finishedWork + ); + + break; + } + + case TracingMarkerComponent: + + default: { + recursivelyTraverseReconnectPassiveEffects( + finishedRoot, + finishedWork + ); + break; + } + } + } + + function commitPassiveUnmountEffects(finishedWork) { + setCurrentFiber(finishedWork); + commitPassiveUnmountOnFiber(finishedWork); + resetCurrentFiber(); + } // If we're inside a brand new tree, or a tree that was already visible, then we + // should only suspend host components that have a ShouldSuspendCommit flag. + // Components without it haven't changed since the last commit, so we can skip + // over those. + // + // When we enter a tree that is being revealed (going from hidden -> visible), + // we need to suspend _any_ component that _may_ suspend. Even if they're + // already in the "current" tree. Because their visibility has changed, the + // browser may not have prerendered them yet. So we check the MaySuspendCommit + // flag instead. + + var suspenseyCommitFlag = ShouldSuspendCommit; + function accumulateSuspenseyCommit(finishedWork) { + accumulateSuspenseyCommitOnFiber(finishedWork); + } + + function recursivelyAccumulateSuspenseyCommit(parentFiber) { + if (parentFiber.subtreeFlags & suspenseyCommitFlag) { + var child = parentFiber.child; + + while (child !== null) { + accumulateSuspenseyCommitOnFiber(child); + child = child.sibling; + } + } + } + + function accumulateSuspenseyCommitOnFiber(fiber) { + switch (fiber.tag) { + case HostHoistable: { + recursivelyAccumulateSuspenseyCommit(fiber); + + if (fiber.flags & suspenseyCommitFlag) { + if (fiber.memoizedState !== null) { + suspendResource(); + } + } + + break; + } + + case HostComponent: { + recursivelyAccumulateSuspenseyCommit(fiber); + + break; + } + + case HostRoot: + case HostPortal: { + { + recursivelyAccumulateSuspenseyCommit(fiber); + } + + break; + } + + case OffscreenComponent: { + var isHidden = fiber.memoizedState !== null; + + if (isHidden); + else { + var current = fiber.alternate; + var wasHidden = current !== null && current.memoizedState !== null; + + if (wasHidden) { + // This tree is being revealed. Visit all newly visible suspensey + // instances, even if they're in the current tree. + var prevFlags = suspenseyCommitFlag; + suspenseyCommitFlag = MaySuspendCommit; + recursivelyAccumulateSuspenseyCommit(fiber); + suspenseyCommitFlag = prevFlags; + } else { + recursivelyAccumulateSuspenseyCommit(fiber); + } + } + + break; + } + + default: { + recursivelyAccumulateSuspenseyCommit(fiber); + } + } + } + + function detachAlternateSiblings(parentFiber) { + // 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 = parentFiber.alternate; + + if (previousFiber !== null) { + var detachedChild = previousFiber.child; + + if (detachedChild !== null) { + previousFiber.child = null; + + do { + // $FlowFixMe[incompatible-use] found when upgrading Flow + var detachedSibling = detachedChild.sibling; // $FlowFixMe[incompatible-use] found when upgrading Flow + + detachedChild.sibling = null; + detachedChild = detachedSibling; + } while (detachedChild !== null); + } + } + } + + function commitHookPassiveUnmountEffects( + finishedWork, + nearestMountedAncestor, + hookFlags + ) { + if (shouldProfile(finishedWork)) { + startPassiveEffectTimer(); + commitHookEffectListUnmount( + hookFlags, + finishedWork, + nearestMountedAncestor + ); + recordPassiveEffectDuration(finishedWork); + } else { + commitHookEffectListUnmount( + hookFlags, + finishedWork, + nearestMountedAncestor + ); + } + } + + function recursivelyTraversePassiveUnmountEffects(parentFiber) { + // Deletions effects can be scheduled on any fiber type. They need to happen + // before the children effects have fired. + var deletions = parentFiber.deletions; + + if ((parentFiber.flags & ChildDeletion) !== NoFlags$1) { + if (deletions !== null) { + for (var i = 0; i < deletions.length; i++) { + var childToDelete = deletions[i]; // TODO: Convert this to use recursion + + nextEffect = childToDelete; + commitPassiveUnmountEffectsInsideOfDeletedTree_begin( + childToDelete, + parentFiber + ); + } + } + + detachAlternateSiblings(parentFiber); + } + + var prevDebugFiber = getCurrentFiber(); // TODO: Split PassiveMask into separate masks for mount and unmount? + + if (parentFiber.subtreeFlags & PassiveMask) { + var child = parentFiber.child; + + while (child !== null) { + setCurrentFiber(child); + commitPassiveUnmountOnFiber(child); + child = child.sibling; + } + } + + setCurrentFiber(prevDebugFiber); + } + + function commitPassiveUnmountOnFiber(finishedWork) { + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + recursivelyTraversePassiveUnmountEffects(finishedWork); + + if (finishedWork.flags & Passive$1) { + commitHookPassiveUnmountEffects( + finishedWork, + finishedWork.return, + Passive | HasEffect + ); + } + + break; + } + + case OffscreenComponent: { + var instance = finishedWork.stateNode; + var nextState = finishedWork.memoizedState; + var isHidden = nextState !== null; + + if ( + isHidden && + instance._visibility & OffscreenPassiveEffectsConnected && // For backwards compatibility, don't unmount when a tree suspends. In + // the future we may change this to unmount after a delay. + (finishedWork.return === null || + finishedWork.return.tag !== SuspenseComponent) + ) { + // The effects are currently connected. Disconnect them. + // TODO: Add option or heuristic to delay before disconnecting the + // effects. Then if the tree reappears before the delay has elapsed, we + // can skip toggling the effects entirely. + instance._visibility &= ~OffscreenPassiveEffectsConnected; + recursivelyTraverseDisconnectPassiveEffects(finishedWork); + } else { + recursivelyTraversePassiveUnmountEffects(finishedWork); + } + + break; + } + + default: { + recursivelyTraversePassiveUnmountEffects(finishedWork); + break; + } + } + } + + function recursivelyTraverseDisconnectPassiveEffects(parentFiber) { + // Deletions effects can be scheduled on any fiber type. They need to happen + // before the children effects have fired. + var deletions = parentFiber.deletions; + + if ((parentFiber.flags & ChildDeletion) !== NoFlags$1) { + if (deletions !== null) { + for (var i = 0; i < deletions.length; i++) { + var childToDelete = deletions[i]; // TODO: Convert this to use recursion + + nextEffect = childToDelete; + commitPassiveUnmountEffectsInsideOfDeletedTree_begin( + childToDelete, + parentFiber + ); + } + } + + detachAlternateSiblings(parentFiber); + } + + var prevDebugFiber = getCurrentFiber(); // TODO: Check PassiveStatic flag + + var child = parentFiber.child; + + while (child !== null) { + setCurrentFiber(child); + disconnectPassiveEffect(child); + child = child.sibling; + } + + setCurrentFiber(prevDebugFiber); + } + + function disconnectPassiveEffect(finishedWork) { + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + // TODO: Check PassiveStatic flag + commitHookPassiveUnmountEffects( + finishedWork, + finishedWork.return, + Passive + ); // When disconnecting passive effects, we fire the effects in the same + // order as during a deletiong: parent before child + + recursivelyTraverseDisconnectPassiveEffects(finishedWork); + break; + } + + case OffscreenComponent: { + var instance = finishedWork.stateNode; + + if (instance._visibility & OffscreenPassiveEffectsConnected) { + instance._visibility &= ~OffscreenPassiveEffectsConnected; + recursivelyTraverseDisconnectPassiveEffects(finishedWork); + } + + break; + } + + default: { + recursivelyTraverseDisconnectPassiveEffects(finishedWork); + break; + } + } + } + + 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 + + setCurrentFiber(fiber); + commitPassiveUnmountInsideDeletedTreeOnFiber( + fiber, + nearestMountedAncestor + ); + resetCurrentFiber(); + var child = fiber.child; // TODO: Only traverse subtree if it has a PassiveStatic flag. + + if (child !== null) { + child.return = fiber; + nextEffect = child; + } else { + commitPassiveUnmountEffectsInsideOfDeletedTree_complete( + deletedSubtreeRoot + ); + } + } + } + + function commitPassiveUnmountEffectsInsideOfDeletedTree_complete( + deletedSubtreeRoot + ) { + while (nextEffect !== null) { + var fiber = nextEffect; + var sibling = fiber.sibling; + var returnFiber = fiber.return; // Recursively traverse the entire deleted tree and clean up fiber fields. + // This is more aggressive than ideal, and the long term goal is to only + // have to detach the deleted tree at the root. + + detachFiberAfterEffects(fiber); + + if (fiber === deletedSubtreeRoot) { + nextEffect = null; + return; + } + + if (sibling !== null) { + sibling.return = returnFiber; + nextEffect = sibling; + return; + } + + nextEffect = returnFiber; + } + } + + function commitPassiveUnmountInsideDeletedTreeOnFiber( + current, + nearestMountedAncestor + ) { + switch (current.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + commitHookPassiveUnmountEffects( + current, + nearestMountedAncestor, + Passive + ); + break; + } + } + } + + 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: { + try { + commitHookEffectListMount(Layout | HasEffect, fiber); + } catch (error) { + captureCommitPhaseError(fiber, fiber.return, error); + } + + break; + } + + case ClassComponent: { + var instance = fiber.stateNode; + + if (typeof instance.componentDidMount === "function") { + try { + instance.componentDidMount(); + } catch (error) { + captureCommitPhaseError(fiber, fiber.return, error); + } + } + + 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: { + try { + commitHookEffectListMount(Passive | HasEffect, fiber); + } catch (error) { + captureCommitPhaseError(fiber, fiber.return, error); + } + + 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: { + try { + commitHookEffectListUnmount( + Layout | HasEffect, + fiber, + fiber.return + ); + } catch (error) { + captureCommitPhaseError(fiber, fiber.return, error); + } + + break; + } + + case ClassComponent: { + var instance = fiber.stateNode; + + if (typeof instance.componentWillUnmount === "function") { + safelyCallComponentWillUnmount(fiber, fiber.return, instance); + } + + 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: { + try { + commitHookEffectListUnmount( + Passive | HasEffect, + fiber, + fiber.return + ); + } catch (error) { + captureCommitPhaseError(fiber, fiber.return, error); + } + } + } + } + } + + if (typeof Symbol === "function" && Symbol.for) { + var symbolFor = Symbol.for; + symbolFor("selector.component"); + symbolFor("selector.has_pseudo_class"); + symbolFor("selector.role"); + symbolFor("selector.test_id"); + symbolFor("selector.text"); + } + + var ReactCurrentActQueue$1 = ReactSharedInternals.ReactCurrentActQueue; + function isLegacyActEnvironment(fiber) { + { + // Legacy mode. We preserve the behavior of React 17's act. It assumes an + // act environment whenever `jest` is defined, but you can still turn off + // spurious warnings by setting IS_REACT_ACT_ENVIRONMENT explicitly + // to false. + var isReactActEnvironmentGlobal = // $FlowFixMe[cannot-resolve-name] Flow doesn't know about IS_REACT_ACT_ENVIRONMENT global + typeof IS_REACT_ACT_ENVIRONMENT !== "undefined" // $FlowFixMe[cannot-resolve-name] + ? IS_REACT_ACT_ENVIRONMENT + : undefined; // $FlowFixMe[cannot-resolve-name] - Flow doesn't know about jest + + var jestIsDefined = typeof jest !== "undefined"; + return jestIsDefined && isReactActEnvironmentGlobal !== false; + } + } + function isConcurrentActEnvironment() { + { + var isReactActEnvironmentGlobal = // $FlowFixMe[cannot-resolve-name] Flow doesn't know about IS_REACT_ACT_ENVIRONMENT global + typeof IS_REACT_ACT_ENVIRONMENT !== "undefined" // $FlowFixMe[cannot-resolve-name] + ? IS_REACT_ACT_ENVIRONMENT + : undefined; + + if ( + !isReactActEnvironmentGlobal && + ReactCurrentActQueue$1.current !== null + ) { + // TODO: Include link to relevant documentation page. + error( + "The current testing environment is not configured to support " + + "act(...)" + ); + } + + return isReactActEnvironmentGlobal; + } + } + + var PossiblyWeakMap = typeof WeakMap === "function" ? WeakMap : Map; + var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, + ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner, + ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig, + ReactCurrentActQueue = ReactSharedInternals.ReactCurrentActQueue; + var NoContext = + /* */ + 0; + var BatchedContext = + /* */ + 1; + var RenderContext = + /* */ + 2; + var CommitContext = + /* */ + 4; + var RootInProgress = 0; + var RootFatalErrored = 1; + var RootErrored = 2; + var RootSuspended = 3; + var RootSuspendedWithDelay = 4; + var RootCompleted = 5; + var RootDidNotComplete = 6; // Describes where we are in the React execution stack + + var executionContext = NoContext; // The root we're working on + + var workInProgressRoot = null; // The fiber we're working on + + var workInProgress = null; // The lanes we're rendering + + var workInProgressRootRenderLanes = NoLanes; + var NotSuspended = 0; + var SuspendedOnError = 1; + var SuspendedOnData = 2; + var SuspendedOnImmediate = 3; + var SuspendedOnInstance = 4; + var SuspendedOnInstanceAndReadyToContinue = 5; + var SuspendedOnDeprecatedThrowPromise = 6; + var SuspendedAndReadyToContinue = 7; + var SuspendedOnHydration = 8; // When this is true, the work-in-progress fiber just suspended (or errored) and + // we've yet to unwind the stack. In some cases, we may yield to the main thread + // after this happens. If the fiber is pinged before we resume, we can retry + // immediately instead of unwinding the stack. + + var workInProgressSuspendedReason = NotSuspended; + var workInProgressThrownValue = null; // Whether a ping listener was attached during this render. This is slightly + // different that whether something suspended, because we don't add multiple + // listeners to a promise we've already seen (per root and lane). + + var workInProgressRootDidAttachPingListener = false; // A contextual version of workInProgressRootRenderLanes. It is a superset of + // the lanes that we started working on at the root. When we enter a subtree + // that is currently hidden, we add the lanes that would have committed if + // the hidden tree hadn't been deferred. This is modified by the + // HiddenContext module. + // + // Most things in the work loop should deal with workInProgressRootRenderLanes. + // Most things in begin/complete phases should deal with entangledRenderLanes. + + var entangledRenderLanes = NoLanes; // Whether to root completed, errored, suspended, etc. + + var workInProgressRootExitStatus = RootInProgress; // A fatal error, if one is thrown + + var workInProgressRootFatalError = null; // The work left over by components that were visited during this render. Only + // includes unprocessed updates, not work in bailed out children. + + var workInProgressRootSkippedLanes = NoLanes; // Lanes that were updated (in an interleaved event) during this render. + + var workInProgressRootInterleavedUpdatedLanes = NoLanes; // Lanes that were updated during the render phase (*not* an interleaved event). + + var workInProgressRootPingedLanes = NoLanes; // If this lane scheduled deferred work, this is the lane of the deferred task. + + var workInProgressDeferredLane = NoLane; // Errors that are thrown during the render phase. + + var workInProgressRootConcurrentErrors = null; // These are errors that we recovered from without surfacing them to the UI. + // We will log them once the tree commits. + + var workInProgressRootRecoverableErrors = null; // Tracks when an update occurs during the render phase. + + var workInProgressRootDidIncludeRecursiveRenderUpdate = false; // Thacks when an update occurs during the commit phase. It's a separate + // filled in with the resolved UI. This lets us throttle the appearance of new + // content as it streams in, to minimize jank. + // TODO: Think of a better name for this variable? + + var globalMostRecentFallbackTime = 0; + var FALLBACK_THROTTLE_MS = 300; // The absolute time for when we should start giving up on rendering + // more and prefer CPU suspense heuristics instead. + + var workInProgressRootRenderTargetTime = Infinity; // How long a render is supposed to take before we start following CPU + // suspense heuristics and opt out of rendering more content. + + var RENDER_TIMEOUT_MS = 500; + var workInProgressTransitions = null; + + function resetRenderTimer() { + workInProgressRootRenderTargetTime = now$1() + RENDER_TIMEOUT_MS; + } + + function getRenderTargetTime() { + return workInProgressRootRenderTargetTime; + } + var hasUncaughtError = false; + var firstUncaughtError = null; + var legacyErrorBoundariesThatAlreadyFailed = null; + var rootDoesHavePassiveEffects = false; + var rootWithPendingPassiveEffects = null; + var pendingPassiveEffectsLanes = NoLanes; + var pendingPassiveProfilerEffects = []; + + var NESTED_UPDATE_LIMIT = 50; + var nestedUpdateCount = 0; + var rootWithNestedUpdates = null; + var isFlushingPassiveEffects = false; + var didScheduleUpdateDuringPassiveEffects = false; + var NESTED_PASSIVE_UPDATE_LIMIT = 50; + var nestedPassiveUpdateCount = 0; + var rootWithPassiveNestedUpdates = null; + var isRunningInsertionEffect = false; + function getWorkInProgressRoot() { + return workInProgressRoot; + } + function getWorkInProgressRootRenderLanes() { + return workInProgressRootRenderLanes; + } + function isWorkLoopSuspendedOnData() { + return workInProgressSuspendedReason === SuspendedOnData; + } + function requestUpdateLane(fiber) { + // Special cases + var mode = fiber.mode; + + if ((mode & ConcurrentMode) === NoMode) { + return SyncLane; + } else if ( + (executionContext & RenderContext) !== NoContext && + workInProgressRootRenderLanes !== NoLanes + ) { + // This is a render phase update. These are not officially supported. The + // old behavior is to give this the same "thread" (lanes) as + // whatever is currently rendering. So if you call `setState` on a component + // that happens later in the same render, it will flush. Ideally, we want to + // remove the special case and treat them as if they came from an + // interleaved event. Regardless, this pattern is not officially supported. + // This behavior is only a fallback. The flag only exists until we can roll + // out the setState warning, since existing code might accidentally rely on + // the current behavior. + return pickArbitraryLane(workInProgressRootRenderLanes); + } + + var transition = requestCurrentTransition(); + + if (transition !== null) { + { + var batchConfigTransition = ReactCurrentBatchConfig.transition; + + if (!batchConfigTransition._updatedFibers) { + batchConfigTransition._updatedFibers = new Set(); + } + + batchConfigTransition._updatedFibers.add(fiber); + } + + var actionScopeLane = peekEntangledActionLane(); + return actionScopeLane !== NoLane // We're inside an async action scope. Reuse the same lane. + ? actionScopeLane // We may or may not be inside an async action scope. If we are, this + : // is the first update in that scope. Either way, we need to get a + // fresh transition lane. + requestTransitionLane(); + } // 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. + + var updateLane = getCurrentUpdatePriority(); + + if (updateLane !== NoLane) { + return updateLane; + } // This update originated outside React. Ask the host environment 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. + + var eventLane = getCurrentEventPriority(); + return eventLane; + } + + function requestRetryLane(fiber) { + // This is a fork of `requestUpdateLane` designed specifically for Suspense + // "retries" — a special update that attempts to flip a Suspense boundary + // from its placeholder state to its primary/resolved state. + // Special cases + var mode = fiber.mode; + + if ((mode & ConcurrentMode) === NoMode) { + return SyncLane; + } + + return claimNextRetryLane(); + } + + function requestDeferredLane() { + if (workInProgressDeferredLane === NoLane) { + // If there are multiple useDeferredValue hooks in the same render, the + // tasks that they spawn should all be batched together, so they should all + // receive the same lane. + // Check the priority of the current render to decide the priority of the + // deferred task. + // OffscreenLane is used for prerendering, but we also use OffscreenLane + // for incremental hydration. It's given the lowest priority because the + // initial HTML is the same as the final UI. But useDeferredValue during + // hydration is an exception — we need to upgrade the UI to the final + // value. So if we're currently hydrating, we treat it like a transition. + var isPrerendering = + includesSomeLane(workInProgressRootRenderLanes, OffscreenLane) && + !getIsHydrating(); + + if (isPrerendering) { + // There's only one OffscreenLane, so if it contains deferred work, we + // should just reschedule using the same lane. + workInProgressDeferredLane = OffscreenLane; + } else { + // Everything else is spawned as a transition. + workInProgressDeferredLane = claimNextTransitionLane(); + } + } // Mark the parent Suspense boundary so it knows to spawn the deferred lane. + + var suspenseHandler = getSuspenseHandler(); + + if (suspenseHandler !== null) { + // TODO: As an optimization, we shouldn't entangle the lanes at the root; we + // can entangle them using the baseLanes of the Suspense boundary instead. + // We only need to do something special if there's no Suspense boundary. + suspenseHandler.flags |= DidDefer; + } + + return workInProgressDeferredLane; + } + function peekDeferredLane() { + return workInProgressDeferredLane; + } + function scheduleUpdateOnFiber(root, fiber, lane) { + { + if (isRunningInsertionEffect) { + error("useInsertionEffect must not schedule updates."); + } + } + + { + if (isFlushingPassiveEffects) { + didScheduleUpdateDuringPassiveEffects = true; + } + } // Check if the work loop is currently suspended and waiting for data to + // finish loading. + + if ( + // Suspended render phase + (root === workInProgressRoot && + workInProgressSuspendedReason === SuspendedOnData) || // Suspended commit phase + root.cancelPendingCommit !== null + ) { + // The incoming update might unblock the current render. Interrupt the + // current attempt and restart from the top. + prepareFreshStack(root, NoLanes); + markRootSuspended( + root, + workInProgressRootRenderLanes, + workInProgressDeferredLane + ); + } // Mark that the root has a pending update. + + markRootUpdated(root, lane); + + if ( + (executionContext & RenderContext) !== NoLanes && + root === workInProgressRoot + ) { + // This update was dispatched during the render phase. This is a mistake + // if the update originates from user space (with the exception of local + // hook updates, which are handled differently and don't reach this + // function), but there are some internal React features that use this as + // an implementation detail, like selective hydration. + warnAboutRenderPhaseUpdatesInDEV(fiber); // Track lanes that were updated during the render phase + } else { + // This is a normal update, scheduled from outside the render phase. For + // example, during an input event. + { + if (isDevToolsPresent) { + addFiberToLanesMap(root, fiber, lane); + } + } + + warnIfUpdatesNotWrappedWithActDEV(fiber); + + if (root === workInProgressRoot) { + // Received an update to a tree that's in the middle of rendering. Mark + // that there was an interleaved update work on this root. + if ((executionContext & RenderContext) === NoContext) { + workInProgressRootInterleavedUpdatedLanes = mergeLanes( + workInProgressRootInterleavedUpdatedLanes, + lane + ); + } + + if (workInProgressRootExitStatus === RootSuspendedWithDelay) { + // The root already suspended with a delay, which means this render + // definitely won't finish. Since we have a new update, let's mark it as + // suspended now, right before marking the incoming update. This has the + // effect of interrupting the current render and switching to the update. + // TODO: Make sure this doesn't override pings that happen while we've + // already started rendering. + markRootSuspended( + root, + workInProgressRootRenderLanes, + workInProgressDeferredLane + ); + } + } + + ensureRootIsScheduled(root); + + if ( + lane === SyncLane && + executionContext === NoContext && + (fiber.mode & ConcurrentMode) === NoMode + ) { + if (ReactCurrentActQueue.isBatchingLegacy); + else { + // 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(); + flushSyncWorkOnLegacyRootsOnly(); + } + } + } + } + function isUnsafeClassRenderPhaseUpdate(fiber) { + // Check if this is a render phase update. Only called by class components, + // which special (deprecated) behavior for UNSAFE_componentWillReceive props. + return (executionContext & RenderContext) !== NoContext; + } // This is the entry point for every concurrent task, i.e. anything that + // goes through Scheduler. + + function performConcurrentWorkOnRoot(root, didTimeout) { + { + resetNestedUpdateFlag(); + } + + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) { + throw new Error("Should not already be working."); + } // Flush any pending passive effects before deciding which lanes to work on, + // in case they schedule additional work. + + var originalCallbackNode = root.callbackNode; + var didFlushPassiveEffects = flushPassiveEffects(); + + if (didFlushPassiveEffects) { + // Something in the passive effect phase may have canceled the current task. + // Check if the task node for this root was changed. + if (root.callbackNode !== originalCallbackNode) { + // The current task was canceled. Exit. We don't need to call + // `ensureRootIsScheduled` because the check above implies either that + // there's a new task, or that there's no remaining work on this root. + return null; + } + } // Determine the next lanes to work on, using the fields stored + // on the root. + // TODO: This was already computed in the caller. Pass it as an argument. + + var lanes = getNextLanes( + root, + root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes + ); + + if (lanes === NoLanes) { + // Defensive coding. This is never expected to happen. + return null; + } // 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 shouldTimeSlice = + !includesBlockingLane(root, lanes) && + !includesExpiredLane(root, lanes) && + !didTimeout; + var exitStatus = shouldTimeSlice + ? renderRootConcurrent(root, lanes) + : renderRootSync(root, lanes); + + if (exitStatus !== RootInProgress) { + var renderWasConcurrent = shouldTimeSlice; + + do { + if (exitStatus === RootDidNotComplete) { + // The render unwound without completing the tree. This happens in special + // cases where need to exit the current render without producing a + // consistent tree or committing. + markRootSuspended(root, lanes, NoLane); + } else { + // The render completed. + // Check if this render may have yielded to a concurrent event, and if so, + // confirm that any newly rendered stores are consistent. + // TODO: It's possible that even a concurrent render may never have yielded + // to the main thread, if it was fast enough, or if it expired. We could + // skip the consistency check in that case, too. + var finishedWork = root.current.alternate; + + if ( + renderWasConcurrent && + !isRenderConsistentWithExternalStores(finishedWork) + ) { + // A store was mutated in an interleaved event. Render again, + // synchronously, to block further mutations. + exitStatus = renderRootSync(root, lanes); // We assume the tree is now consistent because we didn't yield to any + // concurrent events. + + renderWasConcurrent = false; // Need to check the exit status again. + + continue; + } // Check if something threw + + if (exitStatus === RootErrored) { + var originallyAttemptedLanes = lanes; + var errorRetryLanes = getLanesToRetrySynchronouslyOnError( + root, + originallyAttemptedLanes + ); + + if (errorRetryLanes !== NoLanes) { + lanes = errorRetryLanes; + exitStatus = recoverFromConcurrentError( + root, + originallyAttemptedLanes, + errorRetryLanes + ); + renderWasConcurrent = false; + } + } + + if (exitStatus === RootFatalErrored) { + var fatalError = workInProgressRootFatalError; + prepareFreshStack(root, NoLanes); + markRootSuspended(root, lanes, NoLane); + ensureRootIsScheduled(root); + throw fatalError; + } // We now have a consistent tree. The next step is either to commit it, + // or, if something suspended, wait to commit it after a timeout. + + root.finishedWork = finishedWork; + root.finishedLanes = lanes; + finishConcurrentRender(root, exitStatus, finishedWork, lanes); + } + + break; + } while (true); + } + + ensureRootIsScheduled(root); + return getContinuationForRoot(root, originalCallbackNode); + } + + function recoverFromConcurrentError( + root, + originallyAttemptedLanes, + errorRetryLanes + ) { + // If an error occurred during hydration, discard server response and fall + // back to client side render. + // Before rendering again, save the errors from the previous attempt. + var errorsFromFirstAttempt = workInProgressRootConcurrentErrors; + var wasRootDehydrated = isRootDehydrated(root); + + if (wasRootDehydrated) { + // The shell failed to hydrate. Set a flag to force a client rendering + // during the next attempt. To do this, we call prepareFreshStack now + // to create the root work-in-progress fiber. This is a bit weird in terms + // of factoring, because it relies on renderRootSync not calling + // prepareFreshStack again in the call below, which happens because the + // root and lanes haven't changed. + // + // TODO: I think what we should do is set ForceClientRender inside + // throwException, like we do for nested Suspense boundaries. The reason + // it's here instead is so we can switch to the synchronous work loop, too. + // Something to consider for a future refactor. + var rootWorkInProgress = prepareFreshStack(root, errorRetryLanes); + rootWorkInProgress.flags |= ForceClientRender; + + { + errorHydratingContainer(); + } + } + + var exitStatus = renderRootSync(root, errorRetryLanes); + + if (exitStatus !== RootErrored) { + // Successfully finished rendering on retry + if (workInProgressRootDidAttachPingListener && !wasRootDehydrated) { + // During the synchronous render, we attached additional ping listeners. + // This is highly suggestive of an uncached promise (though it's not the + // only reason this would happen). If it was an uncached promise, then + // it may have masked a downstream error from ocurring without actually + // fixing it. Example: + // + // use(Promise.resolve('uncached')) + // throw new Error('Oops!') + // + // When this happens, there's a conflict between blocking potential + // concurrent data races and unwrapping uncached promise values. We + // have to choose one or the other. Because the data race recovery is + // a last ditch effort, we'll disable it. + root.errorRecoveryDisabledLanes = mergeLanes( + root.errorRecoveryDisabledLanes, + originallyAttemptedLanes + ); // Mark the current render as suspended and force it to restart. Once + // these lanes finish successfully, we'll re-enable the error recovery + // mechanism for subsequent updates. + + workInProgressRootInterleavedUpdatedLanes |= originallyAttemptedLanes; + return RootSuspendedWithDelay; + } // The errors from the failed first attempt have been recovered. Add + // them to the collection of recoverable errors. We'll log them in the + // commit phase. + + var errorsFromSecondAttempt = workInProgressRootRecoverableErrors; + workInProgressRootRecoverableErrors = errorsFromFirstAttempt; // The errors from the second attempt should be queued after the errors + // from the first attempt, to preserve the causal sequence. + + if (errorsFromSecondAttempt !== null) { + queueRecoverableErrors(errorsFromSecondAttempt); + } + } + + return exitStatus; + } + + function queueRecoverableErrors(errors) { + if (workInProgressRootRecoverableErrors === null) { + workInProgressRootRecoverableErrors = errors; + } else { + // $FlowFixMe[method-unbinding] + workInProgressRootRecoverableErrors.push.apply( + workInProgressRootRecoverableErrors, + errors + ); + } + } + + function finishConcurrentRender(root, exitStatus, finishedWork, lanes) { + // TODO: The fact that most of these branches are identical suggests that some + // of the exit statuses are not best modeled as exit statuses and should be + // tracked orthogonally. + switch (exitStatus) { + case RootInProgress: + case RootFatalErrored: { + throw new Error("Root did not complete. This is a bug in React."); + } + + case RootSuspendedWithDelay: { + if (includesOnlyTransitions(lanes)) { + // This is a transition, so we should exit without committing a + // placeholder and without scheduling a timeout. Delay indefinitely + // until we receive more data. + markRootSuspended(root, lanes, workInProgressDeferredLane); + return; + } // Commit the placeholder. + + break; + } + + case RootErrored: + case RootSuspended: + case RootCompleted: { + break; + } + + default: { + throw new Error("Unknown root exit status."); + } + } + + if (shouldForceFlushFallbacksInDEV()) { + // We're inside an `act` scope. Commit immediately. + commitRoot( + root, + workInProgressRootRecoverableErrors, + workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, + workInProgressDeferredLane + ); + } else { + if (includesOnlyRetries(lanes) && exitStatus === RootSuspended) { + // This render only included retries, no updates. Throttle committing + // retries so that we don't show too many loading states too quickly. + var msUntilTimeout = + globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now$1(); // Don't bother with a very short suspense time. + + if (msUntilTimeout > 10) { + markRootSuspended(root, lanes, workInProgressDeferredLane); + var nextLanes = getNextLanes(root, NoLanes); + + if (nextLanes !== NoLanes) { + // There's additional work we can do on this root. We might as well + // attempt to work on that while we're suspended. + return; + } // The render is suspended, it hasn't timed out, and there's no + // lower priority work to do. Instead of committing the fallback + // immediately, wait for more data to arrive. + // TODO: Combine retry throttling with Suspensey commits. Right now they + // run one after the other. + + root.timeoutHandle = scheduleTimeout( + commitRootWhenReady.bind( + null, + root, + finishedWork, + workInProgressRootRecoverableErrors, + workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, + lanes, + workInProgressDeferredLane + ), + msUntilTimeout + ); + return; + } + } + + commitRootWhenReady( + root, + finishedWork, + workInProgressRootRecoverableErrors, + workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, + lanes, + workInProgressDeferredLane + ); + } + } + + function commitRootWhenReady( + root, + finishedWork, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate, + lanes, + spawnedLane + ) { + // TODO: Combine retry throttling with Suspensey commits. Right now they run + // one after the other. + if (includesOnlyNonUrgentLanes(lanes)) { + // the suspensey resources. The renderer is responsible for accumulating + // all the load events. This all happens in a single synchronous + // transaction, so it track state in its own module scope. + + accumulateSuspenseyCommit(finishedWork); // At the end, ask the renderer if it's ready to commit, or if we should + // suspend. If it's not ready, it will return a callback to subscribe to + // a ready event. + + var schedulePendingCommit = waitForCommitToBeReady(); + + if (schedulePendingCommit !== null) { + // NOTE: waitForCommitToBeReady returns a subscribe function so that we + // only allocate a function if the commit isn't ready yet. The other + // pattern would be to always pass a callback to waitForCommitToBeReady. + // Not yet ready to commit. Delay the commit until the renderer notifies + // us that it's ready. This will be canceled if we start work on the + // root again. + root.cancelPendingCommit = schedulePendingCommit( + commitRoot.bind( + null, + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate + ) + ); + markRootSuspended(root, lanes, spawnedLane); + return; + } + } // Otherwise, commit immediately. + + commitRoot( + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate, + spawnedLane + ); + } + + function isRenderConsistentWithExternalStores(finishedWork) { + // Search the rendered tree for external store reads, and check whether the + // stores were mutated in a concurrent event. Intentionally using an iterative + // loop instead of recursion so we can exit early. + var node = finishedWork; + + while (true) { + if (node.flags & StoreConsistency) { + var updateQueue = node.updateQueue; + + if (updateQueue !== null) { + var checks = updateQueue.stores; + + if (checks !== null) { + for (var i = 0; i < checks.length; i++) { + var check = checks[i]; + var getSnapshot = check.getSnapshot; + var renderedValue = check.value; + + try { + if (!objectIs(getSnapshot(), renderedValue)) { + // Found an inconsistent store. + return false; + } + } catch (error) { + // If `getSnapshot` throws, return `false`. This will schedule + // a re-render, and the error will be rethrown during render. + return false; + } + } + } + } + } + + var child = node.child; + + if (node.subtreeFlags & StoreConsistency && child !== null) { + child.return = node; + node = child; + continue; + } + + if (node === finishedWork) { + return true; + } + + while (node.sibling === null) { + if (node.return === null || node.return === finishedWork) { + return true; + } + + node = node.return; + } + + node.sibling.return = node.return; + node = node.sibling; + } // Flow doesn't know this is unreachable, but eslint does + // eslint-disable-next-line no-unreachable + + return true; + } // The extra indirections around markRootUpdated and markRootSuspended is + // needed to avoid a circular dependency between this module and + // ReactFiberLane. There's probably a better way to split up these modules and + // avoid this problem. Perhaps all the root-marking functions should move into + // the work loop. + + function markRootUpdated(root, updatedLanes) { + markRootUpdated$1(root, updatedLanes); + } + + function markRootPinged(root, pingedLanes) { + markRootPinged$1(root, pingedLanes); + } + + function markRootSuspended(root, suspendedLanes, spawnedLane) { + // When suspending, we should always exclude lanes that were pinged or (more + // rarely, since we try to avoid it) updated during the render phase. + suspendedLanes = removeLanes( + suspendedLanes, + workInProgressRootPingedLanes + ); + suspendedLanes = removeLanes( + suspendedLanes, + workInProgressRootInterleavedUpdatedLanes + ); + + markRootSuspended$1(root, suspendedLanes, spawnedLane); + } // This is the entry point for synchronous tasks that don't go + // through Scheduler + + function performSyncWorkOnRoot(root, lanes) { + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) { + throw new Error("Should not already be working."); + } + + var didFlushPassiveEffects = flushPassiveEffects(); + + if (didFlushPassiveEffects) { + // If passive effects were flushed, exit to the outer work loop in the root + // scheduler, so we can recompute the priority. + // TODO: We don't actually need this `ensureRootIsScheduled` call because + // this path is only reachable if the root is already part of the schedule. + // I'm including it only for consistency with the other exit points from + // this function. Can address in a subsequent refactor. + ensureRootIsScheduled(root); + return null; + } + + { + syncNestedUpdateFlag(); + } + + var exitStatus = renderRootSync(root, lanes); + + if (root.tag !== LegacyRoot && exitStatus === RootErrored) { + // 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. + var originallyAttemptedLanes = lanes; + var errorRetryLanes = getLanesToRetrySynchronouslyOnError( + root, + originallyAttemptedLanes + ); + + if (errorRetryLanes !== NoLanes) { + lanes = errorRetryLanes; + exitStatus = recoverFromConcurrentError( + root, + originallyAttemptedLanes, + errorRetryLanes + ); + } + } + + if (exitStatus === RootFatalErrored) { + var fatalError = workInProgressRootFatalError; + prepareFreshStack(root, NoLanes); + markRootSuspended(root, lanes, NoLane); + ensureRootIsScheduled(root); + throw fatalError; + } + + if (exitStatus === RootDidNotComplete) { + // The render unwound without completing the tree. This happens in special + // cases where need to exit the current render without producing a + // consistent tree or committing. + markRootSuspended(root, lanes, workInProgressDeferredLane); + ensureRootIsScheduled(root); + return null; + } // We now have a consistent tree. Because this is a sync render, we + // will commit it even if something suspended. + + var finishedWork = root.current.alternate; + root.finishedWork = finishedWork; + root.finishedLanes = lanes; + commitRoot( + root, + workInProgressRootRecoverableErrors, + workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, + workInProgressDeferredLane + ); // Before exiting, make sure there's a callback scheduled for the next + // pending level. + + ensureRootIsScheduled(root); + return null; + } + function getExecutionContext() { + return executionContext; + } + function batchedUpdates(fn, a) { + var prevExecutionContext = executionContext; + executionContext |= BatchedContext; + + try { + return fn(a); + } finally { + executionContext = prevExecutionContext; // If there were legacy sync updates, flush them at the end of the outer + // most batchedUpdates-like method. + + if ( + executionContext === NoContext && // Treat `act` as if it's inside `batchedUpdates`, even in legacy mode. + !ReactCurrentActQueue.isBatchingLegacy + ) { + resetRenderTimer(); + flushSyncWorkOnLegacyRootsOnly(); + } + } + } + // Warning, this opts-out of checking the function body. + // eslint-disable-next-line no-unused-vars + // eslint-disable-next-line no-redeclare + // eslint-disable-next-line no-redeclare + + function flushSync(fn) { + // In legacy mode, we flush pending passive effects at the beginning of the + // next event, not at the end of the previous one. + if ( + rootWithPendingPassiveEffects !== null && + rootWithPendingPassiveEffects.tag === LegacyRoot && + (executionContext & (RenderContext | CommitContext)) === NoContext + ) { + flushPassiveEffects(); + } + + var prevExecutionContext = executionContext; + executionContext |= BatchedContext; + var prevTransition = ReactCurrentBatchConfig.transition; + var previousPriority = getCurrentUpdatePriority(); + + try { + ReactCurrentBatchConfig.transition = null; + setCurrentUpdatePriority(DiscreteEventPriority); + + if (fn) { + return fn(); + } else { + return undefined; + } + } finally { + setCurrentUpdatePriority(previousPriority); + ReactCurrentBatchConfig.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 + ) { + flushSyncWorkOnAllRoots(); + } + } + } + // hidden subtree. The stack logic is managed there because that's the only + // place that ever modifies it. Which module it lives in doesn't matter for + // performance because this function will get inlined regardless + + function setEntangledRenderLanes(newEntangledRenderLanes) { + entangledRenderLanes = newEntangledRenderLanes; + } + function getEntangledRenderLanes() { + return entangledRenderLanes; + } + + function resetWorkInProgressStack() { + if (workInProgress === null) return; + var interruptedWork; + + if (workInProgressSuspendedReason === NotSuspended) { + // Normal case. Work-in-progress hasn't started yet. Unwind all + // its parents. + interruptedWork = workInProgress.return; + } else { + // Work-in-progress is in suspended state. Reset the work loop and unwind + // both the suspended fiber and all its parents. + resetSuspendedWorkLoopOnUnwind(workInProgress); + interruptedWork = workInProgress; + } + + while (interruptedWork !== null) { + var current = interruptedWork.alternate; + unwindInterruptedWork(current, interruptedWork); + interruptedWork = interruptedWork.return; + } + + workInProgress = null; + } + + function prepareFreshStack(root, lanes) { + root.finishedWork = null; + root.finishedLanes = NoLanes; + var timeoutHandle = root.timeoutHandle; + + if (timeoutHandle !== noTimeout) { + // The root previous suspended and scheduled a timeout to commit a fallback + // state. Now that we have additional work, cancel the timeout. + root.timeoutHandle = noTimeout; // $FlowFixMe[incompatible-call] Complains noTimeout is not a TimeoutID, despite the check above + + cancelTimeout(timeoutHandle); + } + + var cancelPendingCommit = root.cancelPendingCommit; + + if (cancelPendingCommit !== null) { + root.cancelPendingCommit = null; + cancelPendingCommit(); + } + + resetWorkInProgressStack(); + workInProgressRoot = root; + var rootWorkInProgress = createWorkInProgress(root.current, null); + workInProgress = rootWorkInProgress; + workInProgressRootRenderLanes = lanes; + workInProgressSuspendedReason = NotSuspended; + workInProgressThrownValue = null; + workInProgressRootDidAttachPingListener = false; + workInProgressRootExitStatus = RootInProgress; + workInProgressRootFatalError = null; + workInProgressRootSkippedLanes = NoLanes; + workInProgressRootInterleavedUpdatedLanes = NoLanes; + workInProgressRootPingedLanes = NoLanes; + workInProgressDeferredLane = NoLane; + workInProgressRootConcurrentErrors = null; + workInProgressRootRecoverableErrors = null; + workInProgressRootDidIncludeRecursiveRenderUpdate = false; // Get the lanes that are entangled with whatever we're about to render. We + // track these separately so we can distinguish the priority of the render + // task from the priority of the lanes it is entangled with. For example, a + // transition may not be allowed to finish unless it includes the Sync lane, + // which is currently suspended. We should be able to render the Transition + // and Sync lane in the same batch, but at Transition priority, because the + // Sync lane already suspended. + + entangledRenderLanes = getEntangledLanes(root, lanes); + finishQueueingConcurrentUpdates(); + + { + ReactStrictModeWarnings.discardPendingWarnings(); + } + + return rootWorkInProgress; + } + + function resetSuspendedWorkLoopOnUnwind(fiber) { + // Reset module-level state that was set during the render phase. + resetContextDependencies(); + resetHooksOnUnwind(fiber); + resetChildReconcilerOnUnwind(); + } + + function handleThrow(root, thrownValue) { + // A component threw an exception. Usually this is because it suspended, but + // it also includes regular program errors. + // + // We're either going to unwind the stack to show a Suspense or error + // boundary, or we're going to replay the component again. Like after a + // promise resolves. + // + // Until we decide whether we're going to unwind or replay, we should preserve + // the current state of the work loop without resetting anything. + // + // If we do decide to unwind the stack, module-level variables will be reset + // in resetSuspendedWorkLoopOnUnwind. + // These should be reset immediately because they're only supposed to be set + // when React is executing user code. + resetHooksAfterThrow(); + resetCurrentFiber(); + ReactCurrentOwner$1.current = null; + + if (thrownValue === SuspenseException) { + // This is a special type of exception used for Suspense. For historical + // reasons, the rest of the Suspense implementation expects the thrown value + // to be a thenable, because before `use` existed that was the (unstable) + // API for suspending. This implementation detail can change later, once we + // deprecate the old API in favor of `use`. + thrownValue = getSuspendedThenable(); + workInProgressSuspendedReason = + shouldRemainOnPreviousScreen() && // Check if there are other pending updates that might possibly unblock this + // component from suspending. This mirrors the check in + // renderDidSuspendDelayIfPossible. We should attempt to unify them somehow. + // TODO: Consider unwinding immediately, using the + // SuspendedOnHydration mechanism. + !includesNonIdleWork(workInProgressRootSkippedLanes) && + !includesNonIdleWork(workInProgressRootInterleavedUpdatedLanes) // Suspend work loop until data resolves + ? SuspendedOnData // Don't suspend work loop, except to check if the data has + : // immediately resolved (i.e. in a microtask). Otherwise, trigger the + // nearest Suspense fallback. + SuspendedOnImmediate; + } else if (thrownValue === SuspenseyCommitException) { + thrownValue = getSuspendedThenable(); + workInProgressSuspendedReason = SuspendedOnInstance; + } else if (thrownValue === SelectiveHydrationException) { + // An update flowed into a dehydrated boundary. Before we can apply the + // update, we need to finish hydrating. Interrupt the work-in-progress + // render so we can restart at the hydration lane. + // + // The ideal implementation would be able to switch contexts without + // unwinding the current stack. + // + // We could name this something more general but as of now it's the only + // case where we think this should happen. + workInProgressSuspendedReason = SuspendedOnHydration; + } else { + // This is a regular error. + var isWakeable = + thrownValue !== null && + typeof thrownValue === "object" && + typeof thrownValue.then === "function"; + workInProgressSuspendedReason = isWakeable // A wakeable object was thrown by a legacy Suspense implementation. + ? // This has slightly different behavior than suspending with `use`. + SuspendedOnDeprecatedThrowPromise // This is a regular error. If something earlier in the component already + : // suspended, we must clear the thenable state to unblock the work loop. + SuspendedOnError; + } + + workInProgressThrownValue = thrownValue; + var erroredWork = workInProgress; + + if (erroredWork === null) { + // This is a fatal error + workInProgressRootExitStatus = RootFatalErrored; + workInProgressRootFatalError = thrownValue; + return; + } + + if (erroredWork.mode & ProfileMode) { + // Record the time spent rendering before an error was thrown. This + // avoids inaccurate Profiler durations in the case of a + // suspended render. + stopProfilerTimerIfRunningAndRecordDelta(erroredWork, true); + } + } + + function shouldRemainOnPreviousScreen() { + // This is asking whether it's better to suspend the transition and remain + // on the previous screen, versus showing a fallback as soon as possible. It + // takes into account both the priority of render and also whether showing a + // fallback would produce a desirable user experience. + var handler = getSuspenseHandler(); + + if (handler === null) { + // There's no Suspense boundary that can provide a fallback. We have no + // choice but to remain on the previous screen. + // NOTE: We do this even for sync updates, for lack of any better option. In + // the future, we may change how we handle this, like by putting the whole + // root into a "detached" mode. + return true; + } // TODO: Once `use` has fully replaced the `throw promise` pattern, we should + // be able to remove the equivalent check in finishConcurrentRender, and rely + // just on this one. + + if (includesOnlyTransitions(workInProgressRootRenderLanes)) { + if (getShellBoundary() === null) { + // We're rendering inside the "shell" of the app. Activating the nearest + // fallback would cause visible content to disappear. It's better to + // suspend the transition and remain on the previous screen. + return true; + } else { + // We're rendering content that wasn't part of the previous screen. + // Rather than block the transition, it's better to show a fallback as + // soon as possible. The appearance of any nested fallbacks will be + // throttled to avoid jank. + return false; + } + } + + if ( + includesOnlyRetries(workInProgressRootRenderLanes) || // In this context, an OffscreenLane counts as a Retry + // TODO: It's become increasingly clear that Retries and Offscreen are + // deeply connected. They probably can be unified further. + includesSomeLane(workInProgressRootRenderLanes, OffscreenLane) + ) { + // During a retry, we can suspend rendering if the nearest Suspense boundary + // is the boundary of the "shell", because we're guaranteed not to block + // any new content from appearing. + // + // The reason we must check if this is a retry is because it guarantees + // that suspending the work loop won't block an actual update, because + // retries don't "update" anything; they fill in fallbacks that were left + // behind by a previous transition. + return handler === getShellBoundary(); + } // For all other Lanes besides Transitions and Retries, we should not wait + // for the data to load. + + return false; + } + + function pushDispatcher(container) { + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = ContextOnlyDispatcher; + + if (prevDispatcher === null) { + // The React isomorphic package does not include a default dispatcher. + // Instead the first renderer will lazily attach one, in order to give + // nicer error messages. + return ContextOnlyDispatcher; + } else { + return prevDispatcher; + } + } + + function popDispatcher(prevDispatcher) { + ReactCurrentDispatcher.current = prevDispatcher; + } + + function markCommitTimeOfFallback() { + globalMostRecentFallbackTime = now$1(); + } + function markSkippedUpdateLanes(lane) { + workInProgressRootSkippedLanes = mergeLanes( + lane, + workInProgressRootSkippedLanes + ); + } + function renderDidSuspend() { + if (workInProgressRootExitStatus === RootInProgress) { + workInProgressRootExitStatus = RootSuspended; + } + } + function renderDidSuspendDelayIfPossible() { + workInProgressRootExitStatus = RootSuspendedWithDelay; // Check if there are updates that we skipped tree that might have unblocked + // this render. + + if ( + (includesNonIdleWork(workInProgressRootSkippedLanes) || + includesNonIdleWork(workInProgressRootInterleavedUpdatedLanes)) && + workInProgressRoot !== null + ) { + // Mark the current render as suspended so that we switch to working on + // the updates that were skipped. Usually we only suspend at the end of + // the render phase. + // TODO: We should probably always mark the root as suspended immediately + // (inside this function), since by suspending at the end of the render + // phase introduces a potential mistake where we suspend lanes that were + // pinged or updated while we were rendering. + // TODO: Consider unwinding immediately, using the + // SuspendedOnHydration mechanism. + markRootSuspended( + workInProgressRoot, + workInProgressRootRenderLanes, + workInProgressDeferredLane + ); + } + } + function renderDidError(error) { + if (workInProgressRootExitStatus !== RootSuspendedWithDelay) { + workInProgressRootExitStatus = RootErrored; + } + + if (workInProgressRootConcurrentErrors === null) { + workInProgressRootConcurrentErrors = [error]; + } else { + workInProgressRootConcurrentErrors.push(error); + } + } // Called during render to determine if anything has suspended. + // Returns false if we're not sure. + + function renderHasNotSuspendedYet() { + // If something errored or completed, we can't really be sure, + // so those are false. + return workInProgressRootExitStatus === RootInProgress; + } // TODO: Over time, this function and renderRootConcurrent have become more + // and more similar. Not sure it makes sense to maintain forked paths. Consider + // unifying them again. + + function renderRootSync(root, lanes) { + var prevExecutionContext = executionContext; + executionContext |= RenderContext; + var prevDispatcher = pushDispatcher(); + // and prepare a fresh one. Otherwise we'll continue where we left off. + + if ( + workInProgressRoot !== root || + workInProgressRootRenderLanes !== lanes + ) { + { + if (isDevToolsPresent) { + var memoizedUpdaters = root.memoizedUpdaters; + + if (memoizedUpdaters.size > 0) { + restorePendingUpdaters(root, workInProgressRootRenderLanes); + memoizedUpdaters.clear(); + } // At this point, move Fibers that scheduled the upcoming work from the Map to the Set. + // If we bailout on this work, we'll move them back (like above). + // It's important to move them now in case the work spawns more work at the same priority with different updaters. + // That way we can keep the current update and future updates separate. + + movePendingFibersToMemoized(root, lanes); + } + } + + workInProgressTransitions = getTransitionsForLanes(); + prepareFreshStack(root, lanes); + } + + var didSuspendInShell = false; + + outer: do { + try { + if ( + workInProgressSuspendedReason !== NotSuspended && + workInProgress !== null + ) { + // The work loop is suspended. During a synchronous render, we don't + // yield to the main thread. Immediately unwind the stack. This will + // trigger either a fallback or an error boundary. + // TODO: For discrete and "default" updates (anything that's not + // flushSync), we want to wait for the microtasks the flush before + // unwinding. Will probably implement this using renderRootConcurrent, + // or merge renderRootSync and renderRootConcurrent into the same + // function and fork the behavior some other way. + var unitOfWork = workInProgress; + var thrownValue = workInProgressThrownValue; + + switch (workInProgressSuspendedReason) { + case SuspendedOnHydration: { + // Selective hydration. An update flowed into a dehydrated tree. + // Interrupt the current render so the work loop can switch to the + // hydration lane. + resetWorkInProgressStack(); + workInProgressRootExitStatus = RootDidNotComplete; + break outer; + } + + case SuspendedOnImmediate: + case SuspendedOnData: { + if (!didSuspendInShell && getSuspenseHandler() === null) { + didSuspendInShell = true; + } // Intentional fallthrough + } + + default: { + // Unwind then continue with the normal work loop. + workInProgressSuspendedReason = NotSuspended; + workInProgressThrownValue = null; + throwAndUnwindWorkLoop(root, unitOfWork, thrownValue); + break; + } + } + } + + workLoopSync(); + break; + } catch (thrownValue) { + handleThrow(root, thrownValue); + } + } while (true); // Check if something suspended in the shell. We use this to detect an + // infinite ping loop caused by an uncached promise. + // + // Only increment this counter once per synchronous render attempt across the + // whole tree. Even if there are many sibling components that suspend, this + // counter only gets incremented once. + + if (didSuspendInShell) { + root.shellSuspendCounter++; + } + + resetContextDependencies(); + executionContext = prevExecutionContext; + popDispatcher(prevDispatcher); + + if (workInProgress !== null) { + // This is a sync render, so we should have finished the whole tree. + throw new Error( + "Cannot commit an incomplete root. This error is likely caused by a " + + "bug in React. Please file an issue." + ); + } + + workInProgressRoot = null; + workInProgressRootRenderLanes = NoLanes; // It's safe to process the queue now that the render phase is complete. + + finishQueueingConcurrentUpdates(); + return workInProgressRootExitStatus; + } // The work loop is an extremely hot path. Tell Closure not to inline it. + + /** @noinline */ + + function workLoopSync() { + // Perform work without checking if we need to yield between fiber. + while (workInProgress !== null) { + performUnitOfWork(workInProgress); + } + } + + function renderRootConcurrent(root, lanes) { + var prevExecutionContext = executionContext; + executionContext |= RenderContext; + var prevDispatcher = pushDispatcher(); + // and prepare a fresh one. Otherwise we'll continue where we left off. + + if ( + workInProgressRoot !== root || + workInProgressRootRenderLanes !== lanes + ) { + { + if (isDevToolsPresent) { + var memoizedUpdaters = root.memoizedUpdaters; + + if (memoizedUpdaters.size > 0) { + restorePendingUpdaters(root, workInProgressRootRenderLanes); + memoizedUpdaters.clear(); + } // At this point, move Fibers that scheduled the upcoming work from the Map to the Set. + // If we bailout on this work, we'll move them back (like above). + // It's important to move them now in case the work spawns more work at the same priority with different updaters. + // That way we can keep the current update and future updates separate. + + movePendingFibersToMemoized(root, lanes); + } + } + + workInProgressTransitions = getTransitionsForLanes(); + resetRenderTimer(); + prepareFreshStack(root, lanes); + } + + outer: do { + try { + if ( + workInProgressSuspendedReason !== NotSuspended && + workInProgress !== null + ) { + // The work loop is suspended. We need to either unwind the stack or + // replay the suspended component. + var unitOfWork = workInProgress; + var thrownValue = workInProgressThrownValue; + + resumeOrUnwind: switch (workInProgressSuspendedReason) { + case SuspendedOnError: { + // Unwind then continue with the normal work loop. + workInProgressSuspendedReason = NotSuspended; + workInProgressThrownValue = null; + throwAndUnwindWorkLoop(root, unitOfWork, thrownValue); + break; + } + + case SuspendedOnData: { + var thenable = thrownValue; + + if (isThenableResolved(thenable)) { + // The data resolved. Try rendering the component again. + workInProgressSuspendedReason = NotSuspended; + workInProgressThrownValue = null; + replaySuspendedUnitOfWork(unitOfWork); + break; + } // The work loop is suspended on data. We should wait for it to + // resolve before continuing to render. + // TODO: Handle the case where the promise resolves synchronously. + // Usually this is handled when we instrument the promise to add a + // `status` field, but if the promise already has a status, we won't + // have added a listener until right here. + + var onResolution = function () { + // Check if the root is still suspended on this promise. + if ( + workInProgressSuspendedReason === SuspendedOnData && + workInProgressRoot === root + ) { + // Mark the root as ready to continue rendering. + workInProgressSuspendedReason = SuspendedAndReadyToContinue; + } // Ensure the root is scheduled. We should do this even if we're + // currently working on a different root, so that we resume + // rendering later. + + ensureRootIsScheduled(root); + }; + + thenable.then(onResolution, onResolution); + break outer; + } + + case SuspendedOnImmediate: { + // If this fiber just suspended, it's possible the data is already + // cached. Yield to the main thread to give it a chance to ping. If + // it does, we can retry immediately without unwinding the stack. + workInProgressSuspendedReason = SuspendedAndReadyToContinue; + break outer; + } + + case SuspendedOnInstance: { + workInProgressSuspendedReason = + SuspendedOnInstanceAndReadyToContinue; + break outer; + } + + case SuspendedAndReadyToContinue: { + var _thenable = thrownValue; + + if (isThenableResolved(_thenable)) { + // The data resolved. Try rendering the component again. + workInProgressSuspendedReason = NotSuspended; + workInProgressThrownValue = null; + replaySuspendedUnitOfWork(unitOfWork); + } else { + // Otherwise, unwind then continue with the normal work loop. + workInProgressSuspendedReason = NotSuspended; + workInProgressThrownValue = null; + throwAndUnwindWorkLoop(root, unitOfWork, thrownValue); + } + + break; + } + + case SuspendedOnInstanceAndReadyToContinue: { + switch (workInProgress.tag) { + case HostComponent: + case HostHoistable: + case HostSingleton: { + // Before unwinding the stack, check one more time if the + // instance is ready. It may have loaded when React yielded to + // the main thread. + // Assigning this to a constant so Flow knows the binding won't + // be mutated by `preloadInstance`. + var hostFiber = workInProgress; + var type = hostFiber.type; + var props = hostFiber.pendingProps; + var isReady = preloadInstance(type, props); + + if (isReady) { + // The data resolved. Resume the work loop as if nothing + // suspended. Unlike when a user component suspends, we don't + // have to replay anything because the host fiber + // already completed. + workInProgressSuspendedReason = NotSuspended; + workInProgressThrownValue = null; + var sibling = hostFiber.sibling; + + if (sibling !== null) { + workInProgress = sibling; + } else { + var returnFiber = hostFiber.return; + + if (returnFiber !== null) { + workInProgress = returnFiber; + completeUnitOfWork(returnFiber); + } else { + workInProgress = null; + } + } + + break resumeOrUnwind; + } + + break; + } + + default: { + // This will fail gracefully but it's not correct, so log a + // warning in dev. + if (true) { + error( + "Unexpected type of fiber triggered a suspensey commit. " + + "This is a bug in React." + ); + } + + break; + } + } // Otherwise, unwind then continue with the normal work loop. + + workInProgressSuspendedReason = NotSuspended; + workInProgressThrownValue = null; + throwAndUnwindWorkLoop(root, unitOfWork, thrownValue); + break; + } + + case SuspendedOnDeprecatedThrowPromise: { + // Suspended by an old implementation that uses the `throw promise` + // pattern. The newer replaying behavior can cause subtle issues + // like infinite ping loops. So we maintain the old behavior and + // always unwind. + workInProgressSuspendedReason = NotSuspended; + workInProgressThrownValue = null; + throwAndUnwindWorkLoop(root, unitOfWork, thrownValue); + break; + } + + case SuspendedOnHydration: { + // Selective hydration. An update flowed into a dehydrated tree. + // Interrupt the current render so the work loop can switch to the + // hydration lane. + resetWorkInProgressStack(); + workInProgressRootExitStatus = RootDidNotComplete; + break outer; + } + + default: { + throw new Error( + "Unexpected SuspendedReason. This is a bug in React." + ); + } + } + } + + if (true && ReactCurrentActQueue.current !== null) { + // `act` special case: If we're inside an `act` scope, don't consult + // `shouldYield`. Always keep working until the render is complete. + // This is not just an optimization: in a unit test environment, we + // can't trust the result of `shouldYield`, because the host I/O is + // likely mocked. + workLoopSync(); + } else { + workLoopConcurrent(); + } + + break; + } catch (thrownValue) { + handleThrow(root, thrownValue); + } + } while (true); + + resetContextDependencies(); + popDispatcher(prevDispatcher); + executionContext = prevExecutionContext; + + if (workInProgress !== null) { + return RootInProgress; + } else { + workInProgressRoot = null; + workInProgressRootRenderLanes = NoLanes; // It's safe to process the queue now that the render phase is complete. + + finishQueueingConcurrentUpdates(); // Return the final exit status. + + return workInProgressRootExitStatus; + } + } + /** @noinline */ + + function workLoopConcurrent() { + // Perform work until Scheduler asks us to yield + while (workInProgress !== null && !shouldYield()) { + // $FlowFixMe[incompatible-call] found when upgrading Flow + performUnitOfWork(workInProgress); + } + } + + function performUnitOfWork(unitOfWork) { + // The current, flushed, state of this fiber is the alternate. Ideally + // nothing should rely on this, but relying on it here means that we don't + // need an additional field on the work in progress. + var current = unitOfWork.alternate; + setCurrentFiber(unitOfWork); + var next; + + if ((unitOfWork.mode & ProfileMode) !== NoMode) { + startProfilerTimer(unitOfWork); + next = beginWork(current, unitOfWork, entangledRenderLanes); + stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true); + } else { + next = beginWork(current, unitOfWork, entangledRenderLanes); + } + + resetCurrentFiber(); + unitOfWork.memoizedProps = unitOfWork.pendingProps; + + if (next === null) { + // If this doesn't spawn new work, complete the current work. + completeUnitOfWork(unitOfWork); + } else { + workInProgress = next; + } + + ReactCurrentOwner$1.current = null; + } + + function replaySuspendedUnitOfWork(unitOfWork) { + // This is a fork of performUnitOfWork specifcally for replaying a fiber that + // just suspended. + // + var current = unitOfWork.alternate; + setCurrentFiber(unitOfWork); + var next; + setCurrentFiber(unitOfWork); + var isProfilingMode = (unitOfWork.mode & ProfileMode) !== NoMode; + + if (isProfilingMode) { + startProfilerTimer(unitOfWork); + } + + switch (unitOfWork.tag) { + case IndeterminateComponent: { + // Because it suspended with `use`, we can assume it's a + // function component. + unitOfWork.tag = FunctionComponent; // Fallthrough to the next branch. + } + + case SimpleMemoComponent: + case FunctionComponent: { + // Resolve `defaultProps`. This logic is copied from `beginWork`. + // TODO: Consider moving this switch statement into that module. Also, + // could maybe use this as an opportunity to say `use` doesn't work with + // `defaultProps` :) + var Component = unitOfWork.type; + var unresolvedProps = unitOfWork.pendingProps; + var resolvedProps = + unitOfWork.elementType === Component + ? unresolvedProps + : resolveDefaultProps(Component, unresolvedProps); + var context; + + next = replayFunctionComponent( + current, + unitOfWork, + resolvedProps, + Component, + context, + workInProgressRootRenderLanes + ); + break; + } + + case ForwardRef: { + // Resolve `defaultProps`. This logic is copied from `beginWork`. + // TODO: Consider moving this switch statement into that module. Also, + // could maybe use this as an opportunity to say `use` doesn't work with + // `defaultProps` :) + var _Component = unitOfWork.type.render; + var _unresolvedProps = unitOfWork.pendingProps; + + var _resolvedProps = + unitOfWork.elementType === _Component + ? _unresolvedProps + : resolveDefaultProps(_Component, _unresolvedProps); + + next = replayFunctionComponent( + current, + unitOfWork, + _resolvedProps, + _Component, + unitOfWork.ref, + workInProgressRootRenderLanes + ); + break; + } + + case HostComponent: { + // Some host components are stateful (that's how we implement form + // actions) but we don't bother to reuse the memoized state because it's + // not worth the extra code. The main reason to reuse the previous hooks + // is to reuse uncached promises, but we happen to know that the only + // promises that a host component might suspend on are definitely cached + // because they are controlled by us. So don't bother. + resetHooksOnUnwind(unitOfWork); // Fallthrough to the next branch. + } + + default: { + // Other types besides function components are reset completely before + // being replayed. Currently this only happens when a Usable type is + // reconciled — the reconciler will suspend. + // + // We reset the fiber back to its original state; however, this isn't + // a full "unwind" because we're going to reuse the promises that were + // reconciled previously. So it's intentional that we don't call + // resetSuspendedWorkLoopOnUnwind here. + unwindInterruptedWork(current, unitOfWork); + unitOfWork = workInProgress = resetWorkInProgress( + unitOfWork, + entangledRenderLanes + ); + next = beginWork(current, unitOfWork, entangledRenderLanes); + break; + } + } + + if (isProfilingMode) { + stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true); + } // The begin phase finished successfully without suspending. Return to the + // normal work loop. + + resetCurrentFiber(); + unitOfWork.memoizedProps = unitOfWork.pendingProps; + + if (next === null) { + // If this doesn't spawn new work, complete the current work. + completeUnitOfWork(unitOfWork); + } else { + workInProgress = next; + } + + ReactCurrentOwner$1.current = null; + } + + function throwAndUnwindWorkLoop(root, unitOfWork, thrownValue) { + // This is a fork of performUnitOfWork specifcally for unwinding a fiber + // that threw an exception. + // + // Return to the normal work loop. This will unwind the stack, and potentially + // result in showing a fallback. + resetSuspendedWorkLoopOnUnwind(unitOfWork); + var returnFiber = unitOfWork.return; + + try { + // Find and mark the nearest Suspense or error boundary that can handle + // this "exception". + var didFatal = throwException( + root, + returnFiber, + unitOfWork, + thrownValue, + workInProgressRootRenderLanes + ); + + if (didFatal) { + panicOnRootError(thrownValue); + return; + } + } catch (error) { + // We had trouble processing the error. An example of this happening is + // when accessing the `componentDidCatch` property of an error boundary + // throws an error. A weird edge case. There's a regression test for this. + // To prevent an infinite loop, bubble the error up to the next parent. + if (returnFiber !== null) { + workInProgress = returnFiber; + throw error; + } else { + panicOnRootError(thrownValue); + return; + } + } + + if (unitOfWork.flags & Incomplete) { + // Unwind the stack until we reach the nearest boundary. + unwindUnitOfWork(unitOfWork); + } else { + // Although the fiber suspended, we're intentionally going to commit it in + // an inconsistent state. We can do this safely in cases where we know the + // inconsistent tree will be hidden. + // + // This currently only applies to Legacy Suspense implementation, but we may + // port a version of this to concurrent roots, too, when performing a + // synchronous render. Because that will allow us to mutate the tree as we + // go instead of buffering mutations until the end. Though it's unclear if + // this particular path is how that would be implemented. + completeUnitOfWork(unitOfWork); + } + } + + function panicOnRootError(error) { + // There's no ancestor that can handle this exception. This should never + // happen because the root is supposed to capture all errors that weren't + // caught by an error boundary. This is a fatal error, or panic condition, + // because we've run out of ways to recover. + workInProgressRootExitStatus = RootFatalErrored; + workInProgressRootFatalError = error; // Set `workInProgress` to null. This represents advancing to the next + // sibling, or the parent if there are no siblings. But since the root + // has no siblings nor a parent, we set it to null. Usually this is + // handled by `completeUnitOfWork` or `unwindWork`, but since we're + // intentionally not calling those, we need set it here. + // TODO: Consider calling `unwindWork` to pop the contexts. + + workInProgress = null; + } + + function completeUnitOfWork(unitOfWork) { + // Attempt to complete the current unit of work, then move to the next + // sibling. If there are no more siblings, return to the parent fiber. + var completedWork = unitOfWork; + + do { + { + if ((completedWork.flags & Incomplete) !== NoFlags$1) { + // NOTE: If we re-enable sibling prerendering in some cases, this branch + // is where we would switch to the unwinding path. + error( + "Internal React error: Expected this fiber to be complete, but " + + "it isn't. It should have been unwound. This is a bug in React." + ); + } + } // The current, flushed, state of this fiber is the alternate. Ideally + // nothing should rely on this, but relying on it here means that we don't + // need an additional field on the work in progress. + + var current = completedWork.alternate; + var returnFiber = completedWork.return; + setCurrentFiber(completedWork); + var next = void 0; + + if ((completedWork.mode & ProfileMode) === NoMode) { + next = completeWork(current, completedWork, entangledRenderLanes); + } else { + startProfilerTimer(completedWork); + next = completeWork(current, completedWork, entangledRenderLanes); // Update render duration assuming we didn't error. + + stopProfilerTimerIfRunningAndRecordDelta(completedWork, false); + } + + resetCurrentFiber(); + + if (next !== null) { + // Completing this fiber spawned new work. Work on that next. + workInProgress = next; + return; + } + + var siblingFiber = completedWork.sibling; + + if (siblingFiber !== null) { + // If there is more work to do in this returnFiber, do that next. + workInProgress = siblingFiber; + return; + } // Otherwise, return to the parent + // $FlowFixMe[incompatible-type] we bail out when we get a null + + completedWork = returnFiber; // Update the next thing we're working on in case something throws. + + workInProgress = completedWork; + } while (completedWork !== null); // We've reached the root. + + if (workInProgressRootExitStatus === RootInProgress) { + workInProgressRootExitStatus = RootCompleted; + } + } + + function unwindUnitOfWork(unitOfWork) { + var incompleteWork = unitOfWork; + + do { + // The current, flushed, state of this fiber is the alternate. Ideally + // nothing should rely on this, but relying on it here means that we don't + // need an additional field on the work in progress. + var current = incompleteWork.alternate; // This fiber did not complete because something threw. Pop values off + // the stack without entering the complete phase. If this is a boundary, + // capture values if possible. + + var next = unwindWork(current, incompleteWork); // Because this fiber did not complete, don't reset its lanes. + + if (next !== null) { + // Found a boundary that can handle this exception. Re-renter the + // begin phase. This branch will return us to the normal work loop. + // + // Since we're restarting, remove anything that is not a host effect + // from the effect tag. + next.flags &= HostEffectMask; + workInProgress = next; + return; + } // Keep unwinding until we reach either a boundary or the root. + + if ((incompleteWork.mode & ProfileMode) !== NoMode) { + // Record the render duration for the fiber that errored. + stopProfilerTimerIfRunningAndRecordDelta(incompleteWork, false); // Include the time spent working on failed children before continuing. + + var actualDuration = incompleteWork.actualDuration; + var child = incompleteWork.child; + + while (child !== null) { + // $FlowFixMe[unsafe-addition] addition with possible null/undefined value + actualDuration += child.actualDuration; + child = child.sibling; + } + + incompleteWork.actualDuration = actualDuration; + } // TODO: Once we stop prerendering siblings, instead of resetting the parent + // of the node being unwound, we should be able to reset node itself as we + // unwind the stack. Saves an additional null check. + + var returnFiber = incompleteWork.return; + + if (returnFiber !== null) { + // Mark the parent fiber as incomplete and clear its subtree flags. + // TODO: Once we stop prerendering siblings, we may be able to get rid of + // the Incomplete flag because unwinding to the nearest boundary will + // happen synchronously. + returnFiber.flags |= Incomplete; + returnFiber.subtreeFlags = NoFlags$1; + returnFiber.deletions = null; + } // NOTE: If we re-enable sibling prerendering in some cases, here we + // would switch to the normal completion path: check if a sibling + // exists, and if so, begin work on it. + // Otherwise, return to the parent + // $FlowFixMe[incompatible-type] we bail out when we get a null + + incompleteWork = returnFiber; // Update the next thing we're working on in case something throws. + + workInProgress = incompleteWork; + } while (incompleteWork !== null); // We've unwound all the way to the root. + + workInProgressRootExitStatus = RootDidNotComplete; + workInProgress = null; + } + + function commitRoot( + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate, + spawnedLane + ) { + // 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.transition; + + try { + ReactCurrentBatchConfig.transition = null; + setCurrentUpdatePriority(DiscreteEventPriority); + commitRootImpl( + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate, + previousUpdateLanePriority, + spawnedLane + ); + } finally { + ReactCurrentBatchConfig.transition = prevTransition; + setCurrentUpdatePriority(previousUpdateLanePriority); + } + + return null; + } + + function commitRootImpl( + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate, + renderPriorityLevel, + spawnedLane + ) { + do { + // `flushPassiveEffects` will call `flushSyncUpdateQueue` at the end, which + // means `flushPassiveEffects` will sometimes result in additional + // passive effects. So we need to keep flushing in a loop until there are + // no more pending effects. + // TODO: Might be better if `flushPassiveEffects` did not automatically + // flush synchronous work at the end, to avoid factoring hazards like this. + flushPassiveEffects(); + } while (rootWithPendingPassiveEffects !== null); + + flushRenderPhaseStrictModeWarningsInDEV(); + + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) { + throw new Error("Should not already be working."); + } + + var finishedWork = root.finishedWork; + var lanes = root.finishedLanes; + + 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; + root.finishedLanes = NoLanes; + + if (finishedWork === root.current) { + throw new Error( + "Cannot commit the same tree as before. This error is likely caused by " + + "a bug in React. Please file an issue." + ); + } // 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; + root.callbackPriority = NoLane; + root.cancelPendingCommit = null; // Check which lanes no longer have any work scheduled on them, and mark + // those as finished. + + var remainingLanes = mergeLanes( + finishedWork.lanes, + finishedWork.childLanes + ); // Make sure to account for lanes that were updated by a concurrent event + // during the render phase; don't mark them as finished. + + var concurrentlyUpdatedLanes = getConcurrentlyUpdatedLanes(); + remainingLanes = mergeLanes(remainingLanes, concurrentlyUpdatedLanes); + markRootFinished(root, remainingLanes, spawnedLane); // Reset this before firing side effects so we can detect recursive updates. + + if (root === workInProgressRoot) { + // We can reset these now that they are finished. + workInProgressRoot = null; + workInProgress = null; + workInProgressRootRenderLanes = NoLanes; + } // 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 ( + (finishedWork.subtreeFlags & PassiveMask) !== NoFlags$1 || + (finishedWork.flags & PassiveMask) !== NoFlags$1 + ) { + if (!rootDoesHavePassiveEffects) { + rootDoesHavePassiveEffects = true; + scheduleCallback(NormalPriority, function () { + flushPassiveEffects(); // This render triggered passive effects: release the root cache pool + // *after* passive effects fire to avoid freeing a cache pool that may + // be referenced by a node in the tree (HostRoot, Cache boundary etc) + + 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 satisfy 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$1; + var rootHasEffect = + (finishedWork.flags & + (BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !== + NoFlags$1; + + if (subtreeHasEffects || rootHasEffect) { + var prevTransition = ReactCurrentBatchConfig.transition; + ReactCurrentBatchConfig.transition = null; + var previousPriority = getCurrentUpdatePriority(); + setCurrentUpdatePriority(DiscreteEventPriority); + var prevExecutionContext = executionContext; + executionContext |= CommitContext; // Reset this to null before calling lifecycles + + ReactCurrentOwner$1.current = null; // The commit phase is broken into several sub-phases. We do a separate pass + // of the effect list for each phase: all mutation effects come before all + // layout effects, and so on. + // The first phase a "before mutation" phase. We use this phase to read the + // state of the host tree right before we mutate it. This is where + // getSnapshotBeforeUpdate is called. + + 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. + + commitMutationEffects(root, finishedWork, lanes); + // the mutation phase, so that the previous tree is still current during + // componentWillUnmount, but before the layout phase, so that the finished + // work is current during componentDidMount/Update. + + root.current = finishedWork; // The next phase is the layout phase, where we call effects that read + + commitLayoutEffects(finishedWork, root, lanes); + // opportunity to paint. + + requestPaint(); + executionContext = prevExecutionContext; // Reset the priority to the previous non-sync value. + + setCurrentUpdatePriority(previousPriority); + ReactCurrentBatchConfig.transition = prevTransition; + } else { + // No effects. + root.current = finishedWork; // Measure these anyway so the flamegraph explicitly shows that there were + // no effects. + // TODO: Maybe there's a better way to report this. + + { + recordCommitTime(); + } + } + + 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; + } else { + { + nestedPassiveUpdateCount = 0; + rootWithPassiveNestedUpdates = null; + } + } // Read this again, since an effect might have updated it + + remainingLanes = root.pendingLanes; // Check if there's remaining work on this root + // TODO: This is part of the `componentDidCatch` implementation. Its purpose + // is to detect whether something might have called setState inside + // `componentDidCatch`. The mechanism is known to be flawed because `setState` + // inside `componentDidCatch` is itself flawed — that's why we recommend + // `getDerivedStateFromError` instead. However, it could be improved by + // checking if remainingLanes includes Sync work, instead of whether there's + // any work remaining at all (which would also include stuff like Suspense + // retries or transitions). It's been like this for a while, though, so fixing + // it probably isn't that urgent. + + if (remainingLanes === NoLanes) { + // If there's no remaining work, we can clear the set of already failed + // error boundaries. + legacyErrorBoundariesThatAlreadyFailed = null; + } + + { + if (!rootDidHavePassiveEffects) { + commitDoubleInvokeEffectsInDEV(root, false); + } + } + + onCommitRoot(finishedWork.stateNode, renderPriorityLevel); + + { + if (isDevToolsPresent) { + root.memoizedUpdaters.clear(); + } + } + // additional work on this root is scheduled. + + ensureRootIsScheduled(root); + + if (recoverableErrors !== null) { + // There were errors during this render, but recovered from them without + // needing to surface it to the UI. We log them here. + var onRecoverableError = root.onRecoverableError; + + for (var i = 0; i < recoverableErrors.length; i++) { + var recoverableError = recoverableErrors[i]; + var errorInfo = makeErrorInfo( + recoverableError.digest, + recoverableError.stack + ); + onRecoverableError(recoverableError.value, errorInfo); + } + } + + if (hasUncaughtError) { + hasUncaughtError = false; + var error$1 = firstUncaughtError; + firstUncaughtError = null; + throw error$1; + } // 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 ( + includesSyncLane(pendingPassiveEffectsLanes) && + root.tag !== LegacyRoot + ) { + flushPassiveEffects(); + } // Read this again, since a passive effect might have updated it + + remainingLanes = root.pendingLanes; // Check if this render scheduled a cascading synchronous update. This is a + // heurstic to detect infinite update loops. We are intentionally excluding + // hydration lanes in this check, because render triggered by selective + // hydration is conceptually not an update. + + if ( + // Check if there was a recursive update spawned by this render, in either + // the render phase or the commit phase. We track these explicitly because + // we can't infer from the remaining lanes alone. + // Was the finished render the result of an update (not hydration)? + includesSomeLane(lanes, UpdateLanes) && // Did it schedule a sync update? + includesSomeLane(remainingLanes, SyncUpdateLanes) + ) { + { + markNestedUpdateScheduled(); + } // Count the number of times the root synchronously re-renders without + // finishing. If there are too many, it indicates an infinite update loop. + + if (root === rootWithNestedUpdates) { + nestedUpdateCount++; + } else { + nestedUpdateCount = 0; + rootWithNestedUpdates = root; + } + } else { + nestedUpdateCount = 0; + } // If layout work was scheduled, flush it now. + + flushSyncWorkOnAllRoots(); + + return null; + } + + function makeErrorInfo(digest, componentStack) { + { + var errorInfo = { + componentStack: componentStack, + digest: digest + }; + Object.defineProperty(errorInfo, "digest", { + configurable: false, + enumerable: true, + get: function () { + error( + 'You are accessing "digest" from the errorInfo object passed to onRecoverableError.' + + " This property is deprecated and will be removed in a future version of React." + + " To access the digest of an Error look for this property on the Error instance itself." + ); + + return digest; + } + }); + return errorInfo; + } + } + + function flushPassiveEffects() { + // Returns whether passive effects were flushed. + // 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.transition; + var previousPriority = getCurrentUpdatePriority(); + + try { + ReactCurrentBatchConfig.transition = null; + setCurrentUpdatePriority(priority); + return flushPassiveEffectsImpl(); + } finally { + setCurrentUpdatePriority(previousPriority); + ReactCurrentBatchConfig.transition = prevTransition; // Once passive effects have run for the tree - giving components a + } + } + + return false; + } + function enqueuePendingPassiveProfilerEffect(fiber) { + { + pendingPassiveProfilerEffects.push(fiber); + + if (!rootDoesHavePassiveEffects) { + rootDoesHavePassiveEffects = true; + scheduleCallback(NormalPriority, function () { + flushPassiveEffects(); + return null; + }); + } + } + } + + function flushPassiveEffectsImpl() { + if (rootWithPendingPassiveEffects === null) { + return false; + } // Cache and clear the transitions flag + var root = rootWithPendingPassiveEffects; + 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) { + throw new Error( + "Cannot flush passive effects while already rendering." + ); + } + + { + isFlushingPassiveEffects = true; + didScheduleUpdateDuringPassiveEffects = false; + } + + var prevExecutionContext = executionContext; + executionContext |= CommitContext; + commitPassiveUnmountEffects(root.current); + commitPassiveMountEffects(root, root.current); // TODO: Move to commitPassiveMountEffects + + { + var profilerEffects = pendingPassiveProfilerEffects; + pendingPassiveProfilerEffects = []; + + for (var i = 0; i < profilerEffects.length; i++) { + var fiber = profilerEffects[i]; + commitPassiveEffectDurations(root, fiber); + } + } + + { + commitDoubleInvokeEffectsInDEV(root, true); + } + + executionContext = prevExecutionContext; + flushSyncWorkOnAllRoots(); + + { + // If additional passive effects were scheduled, increment a counter. If this + // exceeds the limit, we'll fire a warning. + if (didScheduleUpdateDuringPassiveEffects) { + if (root === rootWithPassiveNestedUpdates) { + nestedPassiveUpdateCount++; + } else { + nestedPassiveUpdateCount = 0; + rootWithPassiveNestedUpdates = root; + } + } else { + nestedPassiveUpdateCount = 0; + } + + isFlushingPassiveEffects = false; + didScheduleUpdateDuringPassiveEffects = false; + } // TODO: Move to commitPassiveMountEffects + + onPostCommitRoot(root); + + { + var stateNode = root.current.stateNode; + stateNode.effectDuration = 0; + stateNode.passiveEffectDuration = 0; + } + + return true; + } + + function isAlreadyFailedLegacyErrorBoundary(instance) { + return ( + legacyErrorBoundariesThatAlreadyFailed !== null && + legacyErrorBoundariesThatAlreadyFailed.has(instance) + ); + } + function markLegacyErrorBoundaryAsFailed(instance) { + if (legacyErrorBoundariesThatAlreadyFailed === null) { + legacyErrorBoundariesThatAlreadyFailed = new Set([instance]); + } else { + legacyErrorBoundariesThatAlreadyFailed.add(instance); + } + } + + function prepareToThrowUncaughtError(error) { + if (!hasUncaughtError) { + hasUncaughtError = true; + firstUncaughtError = error; + } + } + + var onUncaughtError = prepareToThrowUncaughtError; + + function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { + var errorInfo = createCapturedValueAtFiber(error, sourceFiber); + var update = createRootErrorUpdate(rootFiber, errorInfo, SyncLane); + var root = enqueueUpdate(rootFiber, update, SyncLane); + + if (root !== null) { + markRootUpdated(root, SyncLane); + ensureRootIsScheduled(root); + } + } + + function captureCommitPhaseError( + sourceFiber, + nearestMountedAncestor, + error$1 + ) { + { + setIsRunningInsertionEffect(false); + } + + if (sourceFiber.tag === HostRoot) { + // Error was thrown at the root. There is no parent, so the root + // itself should capture it. + captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error$1); + return; + } + + var fiber = nearestMountedAncestor; + + while (fiber !== null) { + if (fiber.tag === HostRoot) { + captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error$1); + return; + } else if (fiber.tag === ClassComponent) { + var ctor = fiber.type; + var instance = fiber.stateNode; + + if ( + typeof ctor.getDerivedStateFromError === "function" || + (typeof instance.componentDidCatch === "function" && + !isAlreadyFailedLegacyErrorBoundary(instance)) + ) { + var errorInfo = createCapturedValueAtFiber(error$1, sourceFiber); + var update = createClassErrorUpdate(fiber, errorInfo, SyncLane); + var root = enqueueUpdate(fiber, update, SyncLane); + + if (root !== null) { + markRootUpdated(root, SyncLane); + ensureRootIsScheduled(root); + } + + return; + } + } + + fiber = fiber.return; + } + + { + error( + "Internal React error: Attempted to capture a commit phase error " + + "inside a detached tree. This indicates a bug in React. Potential " + + "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 attachPingListener(root, wakeable, lanes) { + // Attach a ping listener + // + // The data might resolve before we have a chance to commit the fallback. Or, + // in the case of a refresh, we'll never commit a fallback. So we need to + // attach a listener now. When it resolves ("pings"), we can decide whether to + // try rendering the tree again. + // + // Only attach a listener if one does not already exist for the lanes + // we're currently rendering (which acts like a "thread ID" here). + // + // We only need to do this in concurrent mode. Legacy Suspense always + // commits fallbacks synchronously, so there are no pings. + var pingCache = root.pingCache; + var threadIDs; + + if (pingCache === null) { + pingCache = root.pingCache = new PossiblyWeakMap(); + 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)) { + workInProgressRootDidAttachPingListener = true; // Memoize using the thread ID to prevent redundant listeners. + + threadIDs.add(lanes); + var ping = pingSuspendedRoot.bind(null, root, wakeable, lanes); + + { + if (isDevToolsPresent) { + // If we have pending work still, restore the original updaters + restorePendingUpdaters(root, lanes); + } + } + + wakeable.then(ping, ping); + } + } + + function pingSuspendedRoot(root, wakeable, pingedLanes) { + var pingCache = root.pingCache; + + if (pingCache !== null) { + // The wakeable resolved, so we no longer need to memoize, because it will + // never be thrown again. + pingCache.delete(wakeable); + } + + markRootPinged(root, pingedLanes); + warnIfSuspenseResolutionNotWrappedWithActDEV(root); + + if ( + workInProgressRoot === root && + isSubsetOfLanes(workInProgressRootRenderLanes, pingedLanes) + ) { + // Received a ping at the same priority level at which we're currently + // rendering. We might want to restart this render. This should mirror + // the logic of whether or not a root suspends once it completes. + // TODO: If we're rendering sync either due to Sync, Batched or expired, + // we should probably never restart. + // If we're suspended with delay, or if it's a retry, we'll always suspend + // so we can always restart. + if ( + workInProgressRootExitStatus === RootSuspendedWithDelay || + (workInProgressRootExitStatus === RootSuspended && + includesOnlyRetries(workInProgressRootRenderLanes) && + now$1() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) + ) { + // Force a restart from the root by unwinding the stack. Unless this is + // being called from the render phase, because that would cause a crash. + if ((executionContext & RenderContext) === NoContext) { + prepareFreshStack(root, NoLanes); + } + } else { + // Even though we can't restart right now, we might get an + // opportunity later. So we mark this render as having a ping. + workInProgressRootPingedLanes = mergeLanes( + workInProgressRootPingedLanes, + pingedLanes + ); + } + } + + ensureRootIsScheduled(root); + } + + function retryTimedOutBoundary(boundaryFiber, retryLane) { + // The boundary fiber (a Suspense component or SuspenseList component) + // previously was rendered in its fallback state. One of the promises that + // suspended it has resolved, which means at least part of the tree was + // likely unblocked. Try rendering again, at a new lanes. + if (retryLane === NoLane) { + // TODO: Assign this to `suspenseState.retryLane`? to avoid + // unnecessary entanglement? + retryLane = requestRetryLane(boundaryFiber); + } // TODO: Special case idle priority? + + var root = enqueueConcurrentRenderForLane(boundaryFiber, retryLane); + + if (root !== null) { + markRootUpdated(root, retryLane); + ensureRootIsScheduled(root); + } + } + + function retryDehydratedSuspenseBoundary(boundaryFiber) { + var suspenseState = boundaryFiber.memoizedState; + var retryLane = NoLane; + + if (suspenseState !== null) { + retryLane = suspenseState.retryLane; + } + + retryTimedOutBoundary(boundaryFiber, retryLane); + } + function resolveRetryWakeable(boundaryFiber, wakeable) { + var retryLane = NoLane; // Default + + var retryCache; + + switch (boundaryFiber.tag) { + case SuspenseComponent: + retryCache = boundaryFiber.stateNode; + var suspenseState = boundaryFiber.memoizedState; + + if (suspenseState !== null) { + retryLane = suspenseState.retryLane; + } + + break; + + case SuspenseListComponent: + retryCache = boundaryFiber.stateNode; + break; + + case OffscreenComponent: { + var instance = boundaryFiber.stateNode; + retryCache = instance._retryCache; + break; + } + + default: + throw new Error( + "Pinged unknown suspense boundary type. " + + "This is probably a bug in React." + ); + } + + if (retryCache !== null) { + // The wakeable resolved, so we no longer need to memoize, because it will + // never be thrown again. + retryCache.delete(wakeable); + } + + retryTimedOutBoundary(boundaryFiber, retryLane); + } + function throwIfInfiniteUpdateLoopDetected() { + if (nestedUpdateCount > NESTED_UPDATE_LIMIT) { + nestedUpdateCount = 0; + nestedPassiveUpdateCount = 0; + rootWithNestedUpdates = null; + rootWithPassiveNestedUpdates = null; + + throw new Error( + "Maximum update depth exceeded. This can happen when a component " + + "repeatedly calls setState inside componentWillUpdate or " + + "componentDidUpdate. React limits the number of nested updates to " + + "prevent infinite loops." + ); + } + + { + if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) { + nestedPassiveUpdateCount = 0; + rootWithPassiveNestedUpdates = null; + + error( + "Maximum update depth exceeded. This can happen when a component " + + "calls setState inside useEffect, but useEffect either doesn't " + + "have a dependency array, or one of the dependencies changes on " + + "every render." + ); + } + } + } + + function flushRenderPhaseStrictModeWarningsInDEV() { + { + ReactStrictModeWarnings.flushLegacyContextWarning(); + ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings(); + } + } + + function commitDoubleInvokeEffectsInDEV(root, hasPassiveEffects) { + { + { + legacyCommitDoubleInvokeEffectsInDEV(root.current, hasPassiveEffects); + } + } + } + + function legacyCommitDoubleInvokeEffectsInDEV(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) { + var current = firstChild; + var subtreeRoot = null; + + while (current != null) { + var primarySubtreeFlag = current.subtreeFlags & fiberFlags; + + if ( + current !== subtreeRoot && + current.child != null && + primarySubtreeFlag !== NoFlags$1 + ) { + current = current.child; + } else { + if ((current.flags & fiberFlags) !== NoFlags$1) { + invokeEffectFn(current); + } + + if (current.sibling !== null) { + current = current.sibling; + } else { + current = subtreeRoot = current.return; + } + } + } + } + + var didWarnStateUpdateForNotYetMountedComponent = null; + function warnAboutUpdateOnNotYetMountedFiberInDEV(fiber) { + { + if ((executionContext & RenderContext) !== NoContext) { + // We let the other warning about render phase updates deal with this one. + return; + } + + if (!(fiber.mode & ConcurrentMode)) { + return; + } + + var tag = fiber.tag; + + if ( + tag !== IndeterminateComponent && + tag !== HostRoot && + tag !== ClassComponent && + tag !== FunctionComponent && + tag !== ForwardRef && + tag !== MemoComponent && + tag !== SimpleMemoComponent + ) { + // Only warn for user-defined components, not internal ones like Suspense. + return; + } // 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 = + getComponentNameFromFiber(fiber) || "ReactComponent"; + + if (didWarnStateUpdateForNotYetMountedComponent !== null) { + if (didWarnStateUpdateForNotYetMountedComponent.has(componentName)) { + return; + } // $FlowFixMe[incompatible-use] found when upgrading Flow + + didWarnStateUpdateForNotYetMountedComponent.add(componentName); + } else { + didWarnStateUpdateForNotYetMountedComponent = new Set([ + componentName + ]); + } + + var previousFiber = current; + + try { + setCurrentFiber(fiber); + + error( + "Can't perform a React state update on a component that hasn't mounted yet. " + + "This indicates that you have a side-effect in your render function that " + + "asynchronously later calls tries to update the component. Move this work to " + + "useEffect instead." + ); + } finally { + if (previousFiber) { + setCurrentFiber(fiber); + } else { + resetCurrentFiber(); + } + } + } + } + var didWarnAboutUpdateInRender = false; + var didWarnAboutUpdateInRenderForAnotherComponent; + + { + didWarnAboutUpdateInRenderForAnotherComponent = new Set(); + } + + function warnAboutRenderPhaseUpdatesInDEV(fiber) { + { + if (isRendering) { + switch (fiber.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + var renderingComponentName = + (workInProgress && getComponentNameFromFiber(workInProgress)) || + "Unknown"; // Dedupe by the rendering component because it's the one that needs to be fixed. + + var dedupeKey = renderingComponentName; + + if ( + !didWarnAboutUpdateInRenderForAnotherComponent.has(dedupeKey) + ) { + didWarnAboutUpdateInRenderForAnotherComponent.add(dedupeKey); + var setStateComponentName = + getComponentNameFromFiber(fiber) || "Unknown"; + + error( + "Cannot update a component (`%s`) while rendering a " + + "different component (`%s`). To locate the bad setState() call inside `%s`, " + + "follow the stack trace as described in https://react.dev/link/setstate-in-render", + setStateComponentName, + renderingComponentName, + renderingComponentName + ); + } + + break; + } + + case ClassComponent: { + if (!didWarnAboutUpdateInRender) { + error( + "Cannot update during an existing state transition (such as " + + "within `render`). Render methods should be a pure " + + "function of props and state." + ); + + didWarnAboutUpdateInRender = true; + } + + break; + } + } + } + } + } + + function restorePendingUpdaters(root, lanes) { + { + if (isDevToolsPresent) { + var memoizedUpdaters = root.memoizedUpdaters; + memoizedUpdaters.forEach(function (schedulingFiber) { + addFiberToLanesMap(root, schedulingFiber, lanes); + }); // This function intentionally does not clear memoized updaters. + // Those may still be relevant to the current commit + // and a future one (e.g. Suspense). + } + } + } + var fakeActCallbackNode = {}; // $FlowFixMe[missing-local-annot] + + function scheduleCallback(priorityLevel, callback) { + { + // If we're currently inside an `act` scope, bypass Scheduler and push to + // the `act` queue instead. + var actQueue = ReactCurrentActQueue.current; + + if (actQueue !== null) { + actQueue.push(callback); + return fakeActCallbackNode; + } else { + return scheduleCallback$2(priorityLevel, callback); + } + } + } + + function shouldForceFlushFallbacksInDEV() { + // Never force flush in production. This function should get stripped out. + return ReactCurrentActQueue.current !== null; + } + + function warnIfUpdatesNotWrappedWithActDEV(fiber) { + { + if (fiber.mode & ConcurrentMode) { + if (!isConcurrentActEnvironment()) { + // Not in an act environment. No need to warn. + return; + } + } else { + // Legacy mode has additional cases where we suppress a warning. + if (!isLegacyActEnvironment()) { + // Not in an act environment. No need to warn. + return; + } + + if (executionContext !== NoContext) { + // Legacy mode doesn't warn if the update is batched, i.e. + // batchedUpdates or flushSync. + return; + } + + if ( + fiber.tag !== FunctionComponent && + fiber.tag !== ForwardRef && + fiber.tag !== SimpleMemoComponent + ) { + // For backwards compatibility with pre-hooks code, legacy mode only + // warns for updates that originate from a hook. + return; + } + } + + if (ReactCurrentActQueue.current === null) { + var previousFiber = current; + + try { + setCurrentFiber(fiber); + + error( + "An update to %s inside a test was not wrapped in act(...).\n\n" + + "When testing, code that causes React state updates should be " + + "wrapped into act(...):\n\n" + + "act(() => {\n" + + " /* fire events that update state */\n" + + "});\n" + + "/* assert on the output */\n\n" + + "This ensures that you're testing the behavior the user would see " + + "in the browser." + + " Learn more at https://react.dev/link/wrap-tests-with-act", + getComponentNameFromFiber(fiber) + ); + } finally { + if (previousFiber) { + setCurrentFiber(fiber); + } else { + resetCurrentFiber(); + } + } + } + } + } + + function warnIfSuspenseResolutionNotWrappedWithActDEV(root) { + { + if ( + root.tag !== LegacyRoot && + isConcurrentActEnvironment() && + ReactCurrentActQueue.current === null + ) { + error( + "A suspended resource finished loading inside a test, but the event " + + "was not wrapped in act(...).\n\n" + + "When testing, code that resolves suspended data should be wrapped " + + "into act(...):\n\n" + + "act(() => {\n" + + " /* finish loading suspended data */\n" + + "});\n" + + "/* assert on the output */\n\n" + + "This ensures that you're testing the behavior the user would see " + + "in the browser." + + " Learn more at https://react.dev/link/wrap-tests-with-act" + ); + } + } + } + + function setIsRunningInsertionEffect(isRunning) { + { + isRunningInsertionEffect = isRunning; + } + } + + /* eslint-disable react-internal/prod-error-codes */ + // Used by React Refresh runtime through DevTools Global Hook. + + var resolveFamily = null; + var failedBoundaries = null; + var setRefreshHandler = function (handler) { + { + resolveFamily = handler; + } + }; + function resolveFunctionForHotReloading(type) { + { + if (resolveFamily === null) { + // Hot reloading is disabled. + return type; + } + + var family = resolveFamily(type); + + if (family === undefined) { + return type; + } // Use the latest known implementation. + + return family.current; + } + } + function resolveClassForHotReloading(type) { + // No implementation differences. + return resolveFunctionForHotReloading(type); + } + function resolveForwardRefForHotReloading(type) { + { + if (resolveFamily === null) { + // Hot reloading is disabled. + return type; + } + + var family = resolveFamily(type); + + if (family === undefined) { + // Check if we're dealing with a real forwardRef. Don't want to crash early. + if ( + type !== null && + type !== undefined && + typeof type.render === "function" + ) { + // ForwardRef is special because its resolved .type is an object, + // but it's possible that we only have its inner render function in the map. + // If that inner render function is different, we'll build a new forwardRef type. + var currentRender = resolveFunctionForHotReloading(type.render); + + if (type.render !== currentRender) { + var syntheticType = { + $$typeof: REACT_FORWARD_REF_TYPE, + render: currentRender + }; + + if (type.displayName !== undefined) { + syntheticType.displayName = type.displayName; + } + + return syntheticType; + } + } + + return type; + } // Use the latest known implementation. + + return family.current; + } + } + function isCompatibleFamilyForHotReloading(fiber, element) { + { + if (resolveFamily === null) { + // Hot reloading is disabled. + return false; + } + + var prevType = fiber.elementType; + var nextType = element.type; // If we got here, we know types aren't === equal. + + var needsCompareFamilies = false; + var $$typeofNextType = + typeof nextType === "object" && nextType !== null + ? nextType.$$typeof + : null; + + switch (fiber.tag) { + case ClassComponent: { + if (typeof nextType === "function") { + needsCompareFamilies = true; + } + + break; + } + + case FunctionComponent: { + if (typeof nextType === "function") { + needsCompareFamilies = true; + } else if ($$typeofNextType === REACT_LAZY_TYPE) { + // We don't know the inner type yet. + // We're going to assume that the lazy inner type is stable, + // and so it is sufficient to avoid reconciling it away. + // We're not going to unwrap or actually use the new lazy type. + needsCompareFamilies = true; + } + + break; + } + + case ForwardRef: { + if ($$typeofNextType === REACT_FORWARD_REF_TYPE) { + needsCompareFamilies = true; + } else if ($$typeofNextType === REACT_LAZY_TYPE) { + needsCompareFamilies = true; + } + + break; + } + + case MemoComponent: + case SimpleMemoComponent: { + if ($$typeofNextType === REACT_MEMO_TYPE) { + // TODO: if it was but can no longer be simple, + // we shouldn't set this. + needsCompareFamilies = true; + } else if ($$typeofNextType === REACT_LAZY_TYPE) { + needsCompareFamilies = true; + } + + break; + } + + default: + return false; + } // Check if both types have a family and it's the same one. + + if (needsCompareFamilies) { + // Note: memo() and forwardRef() we'll compare outer rather than inner type. + // This means both of them need to be registered to preserve state. + // If we unwrapped and compared the inner types for wrappers instead, + // then we would risk falsely saying two separate memo(Foo) + // calls are equivalent because they wrap the same Foo function. + var prevFamily = resolveFamily(prevType); // $FlowFixMe[not-a-function] found when upgrading Flow + + if ( + prevFamily !== undefined && + prevFamily === resolveFamily(nextType) + ) { + return true; + } + } + + return false; + } + } + function markFailedErrorBoundaryForHotReloading(fiber) { + { + if (resolveFamily === null) { + // Hot reloading is disabled. + return; + } + + if (typeof WeakSet !== "function") { + return; + } + + if (failedBoundaries === null) { + failedBoundaries = new WeakSet(); + } + + failedBoundaries.add(fiber); + } + } + var scheduleRefresh = function (root, update) { + { + if (resolveFamily === null) { + // Hot reloading is disabled. + return; + } + + var staleFamilies = update.staleFamilies, + updatedFamilies = update.updatedFamilies; + flushPassiveEffects(); + flushSync(function () { + scheduleFibersWithFamiliesRecursively( + root.current, + updatedFamilies, + staleFamilies + ); + }); + } + }; + var scheduleRoot = function (root, element) { + { + if (root.context !== emptyContextObject) { + // Super edge case: root has a legacy _renderSubtree context + // but we don't know the parentComponent so we can't pass it. + // Just ignore. We'll delete this with _renderSubtree code path later. + return; + } + + flushPassiveEffects(); + flushSync(function () { + updateContainer(element, root, null, null); + }); + } + }; + + function scheduleFibersWithFamiliesRecursively( + fiber, + updatedFamilies, + staleFamilies + ) { + { + var alternate = fiber.alternate, + child = fiber.child, + sibling = fiber.sibling, + tag = fiber.tag, + type = fiber.type; + var candidateType = null; + + switch (tag) { + case FunctionComponent: + case SimpleMemoComponent: + case ClassComponent: + candidateType = type; + break; + + case ForwardRef: + candidateType = type.render; + break; + } + + if (resolveFamily === null) { + throw new Error( + "Expected resolveFamily to be set during hot reload." + ); + } + + var needsRender = false; + var needsRemount = false; + + if (candidateType !== null) { + var family = resolveFamily(candidateType); + + if (family !== undefined) { + if (staleFamilies.has(family)) { + needsRemount = true; + } else if (updatedFamilies.has(family)) { + if (tag === ClassComponent) { + needsRemount = true; + } else { + needsRender = true; + } + } + } + } + + if (failedBoundaries !== null) { + if ( + failedBoundaries.has(fiber) || // $FlowFixMe[incompatible-use] found when upgrading Flow + (alternate !== null && failedBoundaries.has(alternate)) + ) { + needsRemount = true; + } + } + + if (needsRemount) { + fiber._debugNeedsRemount = true; + } + + if (needsRemount || needsRender) { + var root = enqueueConcurrentRenderForLane(fiber, SyncLane); + + if (root !== null) { + scheduleUpdateOnFiber(root, fiber, SyncLane); + } + } + + if (child !== null && !needsRemount) { + scheduleFibersWithFamiliesRecursively( + child, + updatedFamilies, + staleFamilies + ); + } + + if (sibling !== null) { + scheduleFibersWithFamiliesRecursively( + sibling, + updatedFamilies, + staleFamilies + ); + } + } } - function createFiberFromText(content, mode, lanes) { - content = createFiber(6, content, null, mode); - content.lanes = lanes; - return content; + + var findHostInstancesForRefresh = function (root, families) { + { + var hostInstances = new Set(); + var types = new Set( + families.map(function (family) { + return family.current; + }) + ); + findHostInstancesForMatchingFibersRecursively( + root.current, + types, + hostInstances + ); + return hostInstances; + } + }; + + function findHostInstancesForMatchingFibersRecursively( + fiber, + types, + hostInstances + ) { + { + var child = fiber.child, + sibling = fiber.sibling, + tag = fiber.tag, + type = fiber.type; + var candidateType = null; + + switch (tag) { + case FunctionComponent: + case SimpleMemoComponent: + case ClassComponent: + candidateType = type; + break; + + case ForwardRef: + candidateType = type.render; + break; + } + + var didMatch = false; + + if (candidateType !== null) { + if (types.has(candidateType)) { + didMatch = true; + } + } + + if (didMatch) { + // We have a match. This only drills down to the closest host components. + // There's no need to search deeper because for the purpose of giving + // visual feedback, "flashing" outermost parent rectangles is sufficient. + findHostInstancesForFiberShallowly(fiber, hostInstances); + } else { + // If there's no match, maybe there will be one further down in the child tree. + if (child !== null) { + findHostInstancesForMatchingFibersRecursively( + child, + types, + hostInstances + ); + } + } + + if (sibling !== null) { + findHostInstancesForMatchingFibersRecursively( + sibling, + types, + hostInstances + ); + } + } } - function createFiberFromPortal(portal, mode, lanes) { - mode = createFiber( - 4, - null !== portal.children ? portal.children : [], - portal.key, - mode - ); - mode.lanes = lanes; - mode.stateNode = { - containerInfo: portal.containerInfo, - pendingChildren: null, - implementation: portal.implementation - }; - return mode; + + function findHostInstancesForFiberShallowly(fiber, hostInstances) { + { + var foundHostInstances = findChildHostInstancesForFiberShallowly( + fiber, + hostInstances + ); + + if (foundHostInstances) { + return; + } // If we didn't find any host children, fallback to closest host parent. + + var node = fiber; + + while (true) { + switch (node.tag) { + case HostSingleton: + case HostComponent: + hostInstances.add(node.stateNode); + return; + + case HostPortal: + hostInstances.add(node.stateNode.containerInfo); + return; + + case HostRoot: + hostInstances.add(node.stateNode.containerInfo); + return; + } + + if (node.return === null) { + throw new Error("Expected to reach root first."); + } + + node = node.return; + } + } } - function FiberRootNode( - containerInfo, - tag, - hydrate, - identifierPrefix, - onUncaughtError, - onCaughtError, - onRecoverableError, - formState - ) { + + function findChildHostInstancesForFiberShallowly(fiber, hostInstances) { + { + var node = fiber; + var foundHostInstances = false; + + while (true) { + if ( + node.tag === HostComponent || + node.tag === HostHoistable || + false + ) { + // We got a match. + foundHostInstances = true; + hostInstances.add(node.stateNode); // There may still be more, so keep searching. + } else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; + } + + if (node === fiber) { + return foundHostInstances; + } + + while (node.sibling === null) { + if (node.return === null || node.return === fiber) { + return foundHostInstances; + } + + node = node.return; + } + + node.sibling.return = node.return; + node = node.sibling; + } + } + + return false; + } + + var hasBadMapPolyfill; + + { + hasBadMapPolyfill = false; + + try { + var nonExtensibleObject = Object.preventExtensions({}); + /* eslint-disable no-new */ + + new Map([[nonExtensibleObject, null]]); + new Set([nonExtensibleObject]); + /* eslint-enable no-new */ + } catch (e) { + // TODO: Consider warning about bad polyfills + hasBadMapPolyfill = true; + } + } + + function FiberNode(tag, pendingProps, key, mode) { + // Instance this.tag = tag; - this.containerInfo = containerInfo; - this.finishedWork = - this.pingCache = - this.current = - this.pendingChildren = - null; - this.timeoutHandle = -1; - this.callbackNode = - this.next = - this.pendingContext = - this.context = - this.cancelPendingCommit = - null; - this.callbackPriority = 0; - this.expirationTimes = createLaneMap(-1); - this.entangledLanes = - this.shellSuspendCounter = - this.errorRecoveryDisabledLanes = - this.finishedLanes = - this.expiredLanes = - this.pingedLanes = - this.suspendedLanes = - this.pendingLanes = - 0; - this.entanglements = createLaneMap(0); - this.hiddenUpdates = createLaneMap(null); - this.identifierPrefix = identifierPrefix; - this.onUncaughtError = onUncaughtError; - this.onCaughtError = onCaughtError; - this.onRecoverableError = onRecoverableError; - this.pooledCache = null; - this.pooledCacheLanes = 0; - this.formState = formState; - this.incompleteTransitions = new Map(); - this.passiveEffectDuration = this.effectDuration = 0; - this.memoizedUpdaters = new Set(); - containerInfo = this.pendingUpdatersLaneMap = []; - for ( - identifierPrefix = 0; - identifierPrefix < TotalLanes; - identifierPrefix++ - ) - containerInfo.push(new Set()); - switch (tag) { - case 1: - this._debugRootType = hydrate ? "hydrateRoot()" : "createRoot()"; - break; - case 0: - this._debugRootType = hydrate ? "hydrate()" : "render()"; + this.key = key; + this.elementType = null; + this.type = null; + this.stateNode = null; // Fiber + + this.return = null; + this.child = null; + this.sibling = null; + this.index = 0; + this.ref = null; + this.refCleanup = null; + this.pendingProps = pendingProps; + this.memoizedProps = null; + this.updateQueue = null; + this.memoizedState = null; + this.dependencies = null; + this.mode = mode; // Effects + + this.flags = NoFlags$1; + this.subtreeFlags = NoFlags$1; + this.deletions = null; + this.lanes = NoLanes; + this.childLanes = NoLanes; + this.alternate = null; + + { + // Note: The following is done to avoid a v8 performance cliff. + // + // Initializing the fields below to smis and later updating them with + // double values will cause Fibers to end up having separate shapes. + // This behavior/bug has something to do with Object.preventExtension(). + // Fortunately this only impacts DEV builds. + // Unfortunately it makes React unusably slow for some applications. + // To work around this, initialize the fields below with doubles. + // + // Learn more about this here: + // https://github.com/facebook/react/issues/14365 + // https://bugs.chromium.org/p/v8/issues/detail?id=8538 + this.actualDuration = Number.NaN; + this.actualStartTime = Number.NaN; + this.selfBaseDuration = Number.NaN; + this.treeBaseDuration = Number.NaN; // It's okay to replace the initial doubles with smis after initialization. + // This won't trigger the performance cliff mentioned above, + // and it simplifies other profiler code (including DevTools). + + this.actualDuration = 0; + this.actualStartTime = -1; + this.selfBaseDuration = 0; + this.treeBaseDuration = 0; } + + { + // This isn't directly used but is handy for debugging internals: + this._debugInfo = null; + this._debugOwner = null; + this._debugNeedsRemount = false; + this._debugHookTypes = null; + + if ( + !hasBadMapPolyfill && + typeof Object.preventExtensions === "function" + ) { + Object.preventExtensions(this); + } + } + } // This is a constructor function, rather than a POJO constructor, still + // please ensure we do the following: + // 1) Nobody should add any instance methods on this. Instance methods can be + // more difficult to predict when they get optimized and they are almost + // never inlined properly in static compilers. + // 2) Nobody should rely on `instanceof Fiber` for type testing. We should + // always know when it is a fiber. + // 3) We might want to experiment with using numeric keys since they are easier + // to optimize in a non-JIT environment. + // 4) We can easily go from a constructor to a createFiber object literal if that + // is faster. + // 5) It should be easy to port this to a C struct and keep a C implementation + // compatible. + + function createFiber(tag, pendingProps, key, mode) { + // $FlowFixMe[invalid-constructor]: the shapes are exact here but Flow doesn't like constructors + return new FiberNode(tag, pendingProps, key, mode); } - function testStringCoercion(value) { - return "" + value; + + function shouldConstruct(Component) { + var prototype = Component.prototype; + return !!(prototype && prototype.isReactComponent); } - function createPortal$1(children, containerInfo, implementation) { - var key = - 3 < arguments.length && void 0 !== arguments[3] ? arguments[3] : null; - try { - testStringCoercion(key); - var JSCompiler_inline_result = !1; - } catch (e$48) { - JSCompiler_inline_result = !0; - } - JSCompiler_inline_result && - (error$jscomp$0( - "The provided key is an unsupported type %s. This value must be coerced to a string before using it here.", - ("function" === typeof Symbol && - Symbol.toStringTag && - key[Symbol.toStringTag]) || - key.constructor.name || - "Object" - ), - testStringCoercion(key)); - return { - $$typeof: REACT_PORTAL_TYPE, - key: null == key ? null : "" + key, - children: children, - containerInfo: containerInfo, - implementation: implementation - }; + + function isSimpleFunctionComponent(type) { + return ( + typeof type === "function" && + !shouldConstruct(type) && + type.defaultProps === undefined + ); } - function findHostInstanceWithWarning(component, methodName) { - var fiber = component._reactInternals; - if (void 0 === fiber) { - if ("function" === typeof component.render) - throw Error("Unable to find node on an unmounted component."); - component = Object.keys(component).join(","); - throw Error( - "Argument appears to not be a ReactComponent. Keys: " + component + function resolveLazyComponentTag(Component) { + if (typeof Component === "function") { + return shouldConstruct(Component) ? ClassComponent : FunctionComponent; + } else if (Component !== undefined && Component !== null) { + var $$typeof = Component.$$typeof; + + if ($$typeof === REACT_FORWARD_REF_TYPE) { + return ForwardRef; + } + + if ($$typeof === REACT_MEMO_TYPE) { + return MemoComponent; + } + } + + return IndeterminateComponent; + } // This is used to create an alternate fiber to do work on. + + function createWorkInProgress(current, pendingProps) { + var workInProgress = current.alternate; + + if (workInProgress === null) { + // We use a double buffering pooling technique because we know that we'll + // only ever need at most two versions of a tree. We pool the "other" unused + // node that we're free to reuse. This is lazily created to avoid allocating + // extra objects for things that are never updated. It also allow us to + // reclaim the extra memory if needed. + workInProgress = createFiber( + current.tag, + pendingProps, + current.key, + current.mode ); + workInProgress.elementType = current.elementType; + workInProgress.type = current.type; + workInProgress.stateNode = current.stateNode; + + { + // DEV-only fields + workInProgress._debugOwner = current._debugOwner; + workInProgress._debugHookTypes = current._debugHookTypes; + } + + workInProgress.alternate = current; + current.alternate = workInProgress; + } else { + workInProgress.pendingProps = pendingProps; // Needed because Blocks store data on type. + + workInProgress.type = current.type; // We already have an alternate. + // Reset the effect tag. + + workInProgress.flags = NoFlags$1; // The effects are no longer valid. + + workInProgress.subtreeFlags = NoFlags$1; + workInProgress.deletions = null; + + { + // We intentionally reset, rather than copy, actualDuration & actualStartTime. + // This prevents time from endlessly accumulating in new commits. + // This has the downside of resetting values for different priority renders, + // But works for yielding (the common case) and should support resuming. + 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; + workInProgress.memoizedProps = current.memoizedProps; + workInProgress.memoizedState = current.memoizedState; + workInProgress.updateQueue = current.updateQueue; // Clone the dependencies object. This is mutated during the render phase, so + // it cannot be shared with the current fiber. + + var currentDependencies = current.dependencies; + workInProgress.dependencies = + currentDependencies === null + ? null + : { + lanes: currentDependencies.lanes, + firstContext: currentDependencies.firstContext + }; // These will be overridden during the parent's reconciliation + + workInProgress.sibling = current.sibling; + workInProgress.index = current.index; + workInProgress.ref = current.ref; + workInProgress.refCleanup = current.refCleanup; + + { + workInProgress.selfBaseDuration = current.selfBaseDuration; + workInProgress.treeBaseDuration = current.treeBaseDuration; } - component = findCurrentHostFiber(fiber); - if (null === component) return null; - if (component.mode & 8) { - var componentName = getComponentNameFromFiber(fiber) || "Component"; - didWarnAboutFindNodeInStrictMode[componentName] || - ((didWarnAboutFindNodeInStrictMode[componentName] = !0), - runWithFiberInDEV(component, function () { - fiber.mode & 8 - ? error$jscomp$0( - "%s is deprecated in StrictMode. %s was passed an instance of %s which is inside StrictMode. Instead, add a ref directly to the element you want to reference. Learn more about using refs safely here: https://react.dev/link/strict-mode-find-node", - methodName, - methodName, - componentName - ) - : error$jscomp$0( - "%s is deprecated in StrictMode. %s was passed an instance of %s which renders StrictMode children. Instead, add a ref directly to the element you want to reference. Learn more about using refs safely here: https://react.dev/link/strict-mode-find-node", - methodName, - methodName, - componentName - ); - })); + + { + workInProgress._debugInfo = current._debugInfo; + workInProgress._debugNeedsRemount = current._debugNeedsRemount; + + switch (workInProgress.tag) { + case IndeterminateComponent: + case FunctionComponent: + case SimpleMemoComponent: + workInProgress.type = resolveFunctionForHotReloading(current.type); + break; + + case ClassComponent: + workInProgress.type = resolveClassForHotReloading(current.type); + break; + + case ForwardRef: + workInProgress.type = resolveForwardRefForHotReloading( + current.type + ); + break; + } + } + + return workInProgress; + } // Used to reuse a Fiber for a second pass. + + function resetWorkInProgress(workInProgress, renderLanes) { + // This resets the Fiber to what createFiber or createWorkInProgress would + // have set the values to before during the first pass. Ideally this wouldn't + // be necessary but unfortunately many code paths reads from the workInProgress + // when they should be reading from current and writing to workInProgress. + // We assume pendingProps, index, key, ref, return are still untouched to + // avoid doing another reconciliation. + // Reset the effect flags but keep any Placement tags, since that's something + // that child fiber is setting, not the reconciliation. + workInProgress.flags &= StaticMask | Placement; // The effects are no longer valid. + + var current = workInProgress.alternate; + + if (current === null) { + // Reset to createFiber's initial values. + workInProgress.childLanes = NoLanes; + workInProgress.lanes = renderLanes; + workInProgress.child = null; + workInProgress.subtreeFlags = NoFlags$1; + workInProgress.memoizedProps = null; + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; + workInProgress.dependencies = null; + workInProgress.stateNode = null; + + { + // Note: We don't reset the actualTime counts. It's useful to accumulate + // actual time across multiple render passes. + workInProgress.selfBaseDuration = 0; + workInProgress.treeBaseDuration = 0; + } + } else { + // Reset to the cloned values that createWorkInProgress would've. + workInProgress.childLanes = current.childLanes; + workInProgress.lanes = current.lanes; + workInProgress.child = current.child; + workInProgress.subtreeFlags = NoFlags$1; + workInProgress.deletions = null; + workInProgress.memoizedProps = current.memoizedProps; + workInProgress.memoizedState = current.memoizedState; + workInProgress.updateQueue = current.updateQueue; // Needed because Blocks store data on type. + + workInProgress.type = current.type; // Clone the dependencies object. This is mutated during the render phase, so + // it cannot be shared with the current fiber. + + var currentDependencies = current.dependencies; + workInProgress.dependencies = + currentDependencies === null + ? null + : { + lanes: currentDependencies.lanes, + firstContext: currentDependencies.firstContext + }; + + { + // Note: We don't reset the actualTime counts. It's useful to accumulate + // actual time across multiple render passes. + workInProgress.selfBaseDuration = current.selfBaseDuration; + workInProgress.treeBaseDuration = current.treeBaseDuration; + } } - return getPublicInstance(component.stateNode); - } - function updateContainer(element, container, parentComponent, callback) { - var current = container.current, - lane = requestUpdateLane(current); - updateContainerImpl( - current, - lane, - element, - container, - parentComponent, - callback - ); - return lane; + + return workInProgress; } - function updateContainerImpl( - rootFiber, - lane, - element, - container, - parentComponent, - callback + function createHostRootFiber( + tag, + isStrictMode, + concurrentUpdatesByDefaultOverride ) { - if ( - injectedHook && - "function" === typeof injectedHook.onScheduleFiberRoot - ) - try { - injectedHook.onScheduleFiberRoot(rendererID, container, element); - } catch (err) { - hasLoggedError || - ((hasLoggedError = !0), - error$jscomp$0( - "React instrumentation encountered an error: %s", - err - )); - } - null !== injectedProfilingHooks && - "function" === typeof injectedProfilingHooks.markRenderScheduled && - injectedProfilingHooks.markRenderScheduled(lane); - parentComponent = emptyContextObject; - null === container.context - ? (container.context = parentComponent) - : (container.pendingContext = parentComponent); - isRendering && - null !== current && - !didWarnAboutNestedUpdates && - ((didWarnAboutNestedUpdates = !0), - error$jscomp$0( - "Render methods should be a pure function of props and state; triggering nested component updates from render is not allowed. If necessary, trigger nested updates in componentDidUpdate.\n\nCheck the render method of %s.", - getComponentNameFromFiber(current) || "Unknown" - )); - container = createUpdate(lane); - container.payload = { element: element }; - callback = void 0 === callback ? null : callback; - null !== callback && - ("function" !== typeof callback && - error$jscomp$0( - "Expected the last optional `callback` argument to be a function. Instead received: %s.", - callback - ), - (container.callback = callback)); - element = enqueueUpdate(rootFiber, container, lane); - null !== element && - (scheduleUpdateOnFiber(element, rootFiber, lane), - entangleTransitions(element, rootFiber, lane)); - } - function findHostInstanceByFiber(fiber) { - fiber = findCurrentHostFiber(fiber); - return null === fiber ? null : fiber.stateNode; - } - function emptyFindFiberByHostInstance() { - return null; - } - function getCurrentFiberForDevTools() { - return current; - } - function findNodeHandle(componentOrHandle) { - var owner = current; - null !== owner && - isRendering && - null !== owner.stateNode && - (owner.stateNode._warnedAboutRefsInRender || - error$jscomp$0( - "%s is accessing findNodeHandle inside its render(). render() should be a pure function of props and state. It should never access something that requires stale data from the previous render, such as refs. Move this logic to componentDidMount and componentDidUpdate instead.", - getComponentNameFromType(owner.type) || "A component" - ), - (owner.stateNode._warnedAboutRefsInRender = !0)); - if (null == componentOrHandle) return null; - if ("number" === typeof componentOrHandle) return componentOrHandle; - if (componentOrHandle._nativeTag) return componentOrHandle._nativeTag; - if ( - null != componentOrHandle.canonical && - null != componentOrHandle.canonical.nativeTag - ) - return componentOrHandle.canonical.nativeTag; - if ( - (owner = - ReactNativePrivateInterface.getNativeTagFromPublicInstance( - componentOrHandle - )) - ) - return owner; - componentOrHandle = findHostInstanceWithWarning( - componentOrHandle, - "findNodeHandle" - ); - return null == componentOrHandle - ? componentOrHandle - : null != componentOrHandle._nativeTag - ? componentOrHandle._nativeTag - : ReactNativePrivateInterface.getNativeTagFromPublicInstance( - componentOrHandle - ); - } - function createHierarchy(fiberHierarchy) { - return fiberHierarchy.map(function (fiber$jscomp$0) { - return { - name: getComponentNameFromType(fiber$jscomp$0.type), - getInspectorData: function (findNodeHandle) { - return { - props: getHostProps(fiber$jscomp$0), - measure: function (callback) { - var hostFiber = findCurrentHostFiber(fiber$jscomp$0); - if ( - (hostFiber = - null != hostFiber && - null !== hostFiber.stateNode && - hostFiber.stateNode.node) - ) - nativeFabricUIManager.measure(hostFiber, callback); - else { - hostFiber = ReactNativePrivateInterface.UIManager; - var JSCompiler_temp_const = hostFiber.measure, - JSCompiler_inline_result; - a: { - for (var fiber = fiber$jscomp$0; fiber; ) { - null !== fiber.stateNode && - 5 === fiber.tag && - (JSCompiler_inline_result = findNodeHandle( - fiber.stateNode - )); - if (JSCompiler_inline_result) break a; - fiber = fiber.child; - } - JSCompiler_inline_result = null; - } - return JSCompiler_temp_const.call( - hostFiber, - JSCompiler_inline_result, - callback - ); - } - } - }; - } - }; - }); - } - function getHostProps(fiber) { - return (fiber = findCurrentHostFiber(fiber)) - ? fiber.memoizedProps || emptyObject - : emptyObject; - } - function getInspectorDataForInstance(closestInstance) { - if (!closestInstance) - return { - hierarchy: [], - props: emptyObject, - selectedIndex: null, - componentStack: "" - }; - closestInstance = findCurrentFiberUsingSlowPath(closestInstance); - if (null === closestInstance) - return { - hierarchy: [], - props: emptyObject, - selectedIndex: null, - componentStack: "" - }; - var hierarchy = []; - traverseOwnerTreeUp(hierarchy, closestInstance); - var instance; - a: { - for (instance = hierarchy.length - 1; 1 < instance; instance--) { - var instance$jscomp$0 = hierarchy[instance]; - if (5 !== instance$jscomp$0.tag) { - instance = instance$jscomp$0; - break a; - } - } - instance = hierarchy[0]; - } - instance$jscomp$0 = createHierarchy(hierarchy); - var props = getHostProps(instance); - hierarchy = hierarchy.indexOf(instance); - closestInstance = getStackByFiberInDevAndProd(closestInstance); - return { - closestInstance: instance, - hierarchy: instance$jscomp$0, - props: props, - selectedIndex: hierarchy, - componentStack: closestInstance - }; - } - function traverseOwnerTreeUp(hierarchy, instance) { - hierarchy.unshift(instance); - instance = instance._debugOwner; - null != instance && - "number" === typeof instance.tag && - traverseOwnerTreeUp(hierarchy, instance); - } - function nativeOnUncaughtError(error, errorInfo) { - !1 !== - ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog({ - errorBoundary: null, - error: error, - componentStack: - null != errorInfo.componentStack ? errorInfo.componentStack : "" - }) && - (reportGlobalError(error), - warn( - "%s\n\n%s\n", - componentName - ? "An error occurred in the <" + componentName + "> component." - : "An error occurred in one of your React components.", - "Consider adding an error boundary to your tree to customize error handling behavior.\nVisit https://react.dev/link/error-boundaries to learn more about error boundaries." - )); - } - function nativeOnCaughtError(error, errorInfo) { - !1 !== - ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog({ - errorBoundary: errorInfo.errorBoundary, - error: error, - componentStack: - null != errorInfo.componentStack ? errorInfo.componentStack : "" - }) && - error$jscomp$0( - "%o\n\n%s\n\n%s\n", - error, - componentName - ? "The above error occurred in the <" + - componentName + - "> component." - : "The above error occurred in one of your React components.", - "React will try to recreate this component tree from scratch using the error boundary you provided, " + - ((errorBoundaryName || "Anonymous") + ".") - ); - } - function unmountComponentAtNode(containerTag) { - var root = roots.get(containerTag); - root && - updateContainer(null, root, null, function () { - roots.delete(containerTag); - }); - } - "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && - "function" === - typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart && - __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error()); - require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); - var React = require("react"), - ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"), - Scheduler = require("scheduler"), - ReactSharedInternals = - React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, - suppressWarning = !1, - supportsCreateTask = !!console.createTask, - isArrayImpl = Array.isArray, - REACT_LEGACY_ELEMENT_TYPE = Symbol.for("react.element"), - REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"), - REACT_PORTAL_TYPE = Symbol.for("react.portal"), - REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"), - REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"), - REACT_PROFILER_TYPE = Symbol.for("react.profiler"), - REACT_PROVIDER_TYPE = Symbol.for("react.provider"), - REACT_CONSUMER_TYPE = Symbol.for("react.consumer"), - REACT_CONTEXT_TYPE = Symbol.for("react.context"), - REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"), - REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"), - REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"), - REACT_MEMO_TYPE = Symbol.for("react.memo"), - REACT_LAZY_TYPE = Symbol.for("react.lazy"); - Symbol.for("react.scope"); - Symbol.for("react.debug_trace_mode"); - var REACT_OFFSCREEN_TYPE = Symbol.for("react.offscreen"); - Symbol.for("react.legacy_hidden"); - Symbol.for("react.tracing_marker"); - var REACT_MEMO_CACHE_SENTINEL = Symbol.for("react.memo_cache_sentinel"), - MAYBE_ITERATOR_SYMBOL = Symbol.iterator, - assign = Object.assign, - disabledDepth = 0, - prevLog, - prevInfo, - prevWarn, - prevError, - prevGroup, - prevGroupCollapsed, - prevGroupEnd; - disabledLog.__reactDisabledLog = !0; - var prefix, - reentry = !1; - var componentFrameCache = new ( - "function" === typeof WeakMap ? WeakMap : Map - )(); - var externalRegExp = /\/node_modules\/|\(\)/, - callComponentFrame = null, - callIteratorFrame = null, - callLazyInitFrame = null, - REACT_CLIENT_REFERENCE = Symbol.for("react.client.reference"), - current = null, - isRendering = !1, - hasError = !1, - caughtError = null, - getFiberCurrentPropsFromNode$1 = null, - getInstanceFromNode = null, - getNodeFromInstance = null; - assign(SyntheticEvent.prototype, { - preventDefault: function () { - this.defaultPrevented = !0; - var event = this.nativeEvent; - event && - (event.preventDefault - ? event.preventDefault() - : "unknown" !== typeof event.returnValue && - (event.returnValue = !1), - (this.isDefaultPrevented = functionThatReturnsTrue)); - }, - stopPropagation: function () { - var event = this.nativeEvent; - event && - (event.stopPropagation - ? event.stopPropagation() - : "unknown" !== typeof event.cancelBubble && - (event.cancelBubble = !0), - (this.isPropagationStopped = functionThatReturnsTrue)); - }, - persist: function () { - this.isPersistent = functionThatReturnsTrue; - }, - isPersistent: functionThatReturnsFalse, - destructor: function () { - var Interface = this.constructor.Interface, - propName; - for (propName in Interface) - Object.defineProperty( - this, - propName, - getPooledWarningPropertyDefinition(propName, Interface[propName]) - ); - this.nativeEvent = this._targetInst = this.dispatchConfig = null; - this.isPropagationStopped = this.isDefaultPrevented = - functionThatReturnsFalse; - this._dispatchInstances = this._dispatchListeners = null; - Object.defineProperty( - this, - "nativeEvent", - getPooledWarningPropertyDefinition("nativeEvent", null) - ); - Object.defineProperty( - this, - "isDefaultPrevented", - getPooledWarningPropertyDefinition( - "isDefaultPrevented", - functionThatReturnsFalse - ) - ); - Object.defineProperty( - this, - "isPropagationStopped", - getPooledWarningPropertyDefinition( - "isPropagationStopped", - functionThatReturnsFalse - ) - ); - Object.defineProperty( - this, - "preventDefault", - getPooledWarningPropertyDefinition("preventDefault", function () {}) - ); - Object.defineProperty( - this, - "stopPropagation", - getPooledWarningPropertyDefinition("stopPropagation", function () {}) - ); + var mode; + + if (tag === ConcurrentRoot) { + mode = ConcurrentMode; + + if (isStrictMode === true) { + mode |= StrictLegacyMode | StrictEffectsMode; + } + } else { + mode = NoMode; } - }); - SyntheticEvent.Interface = { - type: null, - target: null, - currentTarget: function () { - return null; - }, - eventPhase: null, - bubbles: null, - cancelable: null, - timeStamp: function (event) { - return event.timeStamp || Date.now(); - }, - defaultPrevented: null, - isTrusted: null - }; - SyntheticEvent.extend = function (Interface) { - function E() {} - function Class() { - return Super.apply(this, arguments); + + if (isDevToolsPresent) { + // Always collect profile timings when DevTools are present. + // This enables DevTools to start capturing timing at any point– + // Without some nodes in the tree having empty base times. + mode |= ProfileMode; } - var Super = this; - E.prototype = Super.prototype; - var prototype = new E(); - assign(prototype, Class.prototype); - Class.prototype = prototype; - Class.prototype.constructor = Class; - Class.Interface = assign({}, Super.Interface, Interface); - Class.extend = Super.extend; - addEventPoolingTo(Class); - return Class; - }; - addEventPoolingTo(SyntheticEvent); - var ResponderSyntheticEvent = SyntheticEvent.extend({ - touchHistory: function () { - return null; + + return createFiber(HostRoot, null, null, mode); + } + function createFiberFromTypeAndProps( + type, // React$ElementType + key, + pendingProps, + owner, + mode, + lanes + ) { + var fiberTag = IndeterminateComponent; // The resolved type is set if we know what the final type will be. I.e. it's not lazy. + + var resolvedType = type; + + if (typeof type === "function") { + if (shouldConstruct(type)) { + fiberTag = ClassComponent; + + { + resolvedType = resolveClassForHotReloading(resolvedType); + } + } else { + { + resolvedType = resolveFunctionForHotReloading(resolvedType); + } } - }), - startDependencies = ["topTouchStart"], - moveDependencies = ["topTouchMove"], - endDependencies = ["topTouchCancel", "topTouchEnd"], - touchBank = [], - touchHistory = { - touchBank: touchBank, - numberActiveTouches: 0, - indexOfSingleActiveTouch: -1, - mostRecentTimeStamp: 0 - }, - 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 - ) - 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; - } - topLevelType = touchBank[touchHistory.indexOfSingleActiveTouch]; - (null != topLevelType && topLevelType.touchActive) || - error$jscomp$0("Cannot find single active touch."); - } - }, - touchHistory: touchHistory - }, - responderInst = null, - trackedTouchCount = 0, - eventTypes = { - startShouldSetResponder: { - phasedRegistrationNames: { - bubbled: "onStartShouldSetResponder", - captured: "onStartShouldSetResponderCapture" - }, - dependencies: startDependencies - }, - scrollShouldSetResponder: { - phasedRegistrationNames: { - bubbled: "onScrollShouldSetResponder", - captured: "onScrollShouldSetResponderCapture" - }, - dependencies: ["topScroll"] - }, - selectionChangeShouldSetResponder: { - phasedRegistrationNames: { - bubbled: "onSelectionChangeShouldSetResponder", - captured: "onSelectionChangeShouldSetResponderCapture" - }, - dependencies: ["topSelectionChange"] - }, - moveShouldSetResponder: { - phasedRegistrationNames: { - bubbled: "onMoveShouldSetResponder", - captured: "onMoveShouldSetResponderCapture" - }, - dependencies: moveDependencies - }, - responderStart: { - registrationName: "onResponderStart", - dependencies: startDependencies - }, - responderMove: { - registrationName: "onResponderMove", - dependencies: moveDependencies - }, - responderEnd: { - registrationName: "onResponderEnd", - dependencies: endDependencies - }, - responderRelease: { - registrationName: "onResponderRelease", - dependencies: endDependencies - }, - responderTerminationRequest: { - registrationName: "onResponderTerminationRequest", - dependencies: [] - }, - responderGrant: { - registrationName: "onResponderGrant", - dependencies: [] - }, - responderReject: { - registrationName: "onResponderReject", - dependencies: [] - }, - responderTerminate: { - registrationName: "onResponderTerminate", - dependencies: [] + } else if (typeof type === "string") { + { + fiberTag = HostComponent; } - }, - ResponderEventPlugin = { - _getResponder: function () { - return responderInst; - }, - eventTypes: eventTypes, - extractEvents: function ( - topLevelType, - targetInst, - nativeEvent, - nativeEventTarget - ) { - if (isStartish(topLevelType)) trackedTouchCount += 1; - else if ( - "topTouchEnd" === topLevelType || - "topTouchCancel" === topLevelType - ) - if (0 <= trackedTouchCount) --trackedTouchCount; - else - return ( - warn( - "Ended a touch event which was not counted in `trackedTouchCount`." - ), - null - ); - ResponderTouchHistoryStore.recordTouchTrack( - topLevelType, - nativeEvent - ); - if ( - targetInst && - (("topScroll" === topLevelType && - !nativeEvent.responderIgnoreScroll) || - (0 < trackedTouchCount && - "topSelectionChange" === topLevelType) || - isStartish(topLevelType) || - isMoveish(topLevelType)) - ) { - var shouldSetEventType = isStartish(topLevelType) - ? eventTypes.startShouldSetResponder - : isMoveish(topLevelType) - ? eventTypes.moveShouldSetResponder - : "topSelectionChange" === topLevelType - ? eventTypes.selectionChangeShouldSetResponder - : eventTypes.scrollShouldSetResponder; - if (responderInst) - b: { - var JSCompiler_temp = responderInst; - for ( - var depthA = 0, tempA = JSCompiler_temp; - tempA; - tempA = getParent$1(tempA) - ) - depthA++; - tempA = 0; - for (var tempB = targetInst; tempB; tempB = getParent$1(tempB)) - tempA++; - for (; 0 < depthA - tempA; ) - (JSCompiler_temp = getParent$1(JSCompiler_temp)), depthA--; - for (; 0 < tempA - depthA; ) - (targetInst = getParent$1(targetInst)), tempA--; - for (; depthA--; ) { - if ( - JSCompiler_temp === targetInst || - JSCompiler_temp === targetInst.alternate - ) - break b; - JSCompiler_temp = getParent$1(JSCompiler_temp); - targetInst = getParent$1(targetInst); - } - JSCompiler_temp = null; - } - else JSCompiler_temp = targetInst; - targetInst = JSCompiler_temp === responderInst; - JSCompiler_temp = ResponderSyntheticEvent.getPooled( - shouldSetEventType, - JSCompiler_temp, - nativeEvent, - nativeEventTarget + } else { + getTag: switch (type) { + case REACT_FRAGMENT_TYPE: + return createFiberFromFragment( + pendingProps.children, + mode, + lanes, + key ); - JSCompiler_temp.touchHistory = - ResponderTouchHistoryStore.touchHistory; - targetInst - ? forEachAccumulated( - JSCompiler_temp, - accumulateTwoPhaseDispatchesSingleSkipTarget - ) - : forEachAccumulated( - JSCompiler_temp, - accumulateTwoPhaseDispatchesSingle$1 - ); - b: { - shouldSetEventType = JSCompiler_temp._dispatchListeners; - targetInst = JSCompiler_temp._dispatchInstances; - validateEventDispatches(JSCompiler_temp); - if (isArrayImpl(shouldSetEventType)) - for ( - depthA = 0; - depthA < shouldSetEventType.length && - !JSCompiler_temp.isPropagationStopped(); - depthA++ - ) { - if ( - shouldSetEventType[depthA]( - JSCompiler_temp, - targetInst[depthA] - ) - ) { - shouldSetEventType = targetInst[depthA]; - break b; - } + + case REACT_STRICT_MODE_TYPE: + fiberTag = Mode; + mode |= StrictLegacyMode; + + if ((mode & ConcurrentMode) !== NoMode) { + // Strict effects should never run on legacy roots + mode |= StrictEffectsMode; + } + + break; + + case REACT_PROFILER_TYPE: + return createFiberFromProfiler(pendingProps, mode, lanes, key); + + case REACT_SUSPENSE_TYPE: + return createFiberFromSuspense(pendingProps, mode, lanes, key); + + case REACT_SUSPENSE_LIST_TYPE: + return createFiberFromSuspenseList(pendingProps, mode, lanes, key); + + case REACT_OFFSCREEN_TYPE: + return createFiberFromOffscreen(pendingProps, mode, lanes, key); + + case REACT_LEGACY_HIDDEN_TYPE: + + // Fall through + + case REACT_SCOPE_TYPE: + + // Fall through + + case REACT_CACHE_TYPE: + + // Fall through + + case REACT_TRACING_MARKER_TYPE: + + // Fall through + + case REACT_DEBUG_TRACING_MODE_TYPE: + + // Fall through + + default: { + if (typeof type === "object" && type !== null) { + switch (type.$$typeof) { + case REACT_PROVIDER_TYPE: { + fiberTag = ContextProvider; + break getTag; + } + + // Fall through + + case REACT_CONTEXT_TYPE: { + fiberTag = ContextConsumer; + break getTag; } - else if ( - shouldSetEventType && - shouldSetEventType(JSCompiler_temp, targetInst) + + case REACT_CONSUMER_TYPE: + + // Fall through + + case REACT_FORWARD_REF_TYPE: + fiberTag = ForwardRef; + + { + resolvedType = + resolveForwardRefForHotReloading(resolvedType); + } + + break getTag; + + case REACT_MEMO_TYPE: + fiberTag = MemoComponent; + break getTag; + + case REACT_LAZY_TYPE: + fiberTag = LazyComponent; + resolvedType = null; + break getTag; + } + } + + var info = ""; + + { + if ( + type === undefined || + (typeof type === "object" && + type !== null && + Object.keys(type).length === 0) ) { - shouldSetEventType = targetInst; - break b; + info += + " You likely forgot to export your component from the file " + + "it's defined in, or you might have mixed up default and " + + "named imports."; + } + + var ownerName = owner ? getComponentNameFromFiber(owner) : null; + + if (ownerName) { + info += "\n\nCheck the render method of `" + ownerName + "`."; } - shouldSetEventType = null; - } - JSCompiler_temp._dispatchInstances = null; - JSCompiler_temp._dispatchListeners = null; - JSCompiler_temp.isPersistent() || - JSCompiler_temp.constructor.release(JSCompiler_temp); - if (shouldSetEventType && shouldSetEventType !== responderInst) - if ( - ((JSCompiler_temp = ResponderSyntheticEvent.getPooled( - eventTypes.responderGrant, - shouldSetEventType, - nativeEvent, - nativeEventTarget - )), - (JSCompiler_temp.touchHistory = - ResponderTouchHistoryStore.touchHistory), - forEachAccumulated( - JSCompiler_temp, - accumulateDirectDispatchesSingle$1 - ), - (targetInst = !0 === executeDirectDispatch(JSCompiler_temp)), - responderInst) - ) - if ( - ((depthA = ResponderSyntheticEvent.getPooled( - eventTypes.responderTerminationRequest, - responderInst, - nativeEvent, - nativeEventTarget - )), - (depthA.touchHistory = - ResponderTouchHistoryStore.touchHistory), - forEachAccumulated( - depthA, - accumulateDirectDispatchesSingle$1 - ), - (tempA = - !depthA._dispatchListeners || - executeDirectDispatch(depthA)), - depthA.isPersistent() || depthA.constructor.release(depthA), - tempA) - ) { - depthA = ResponderSyntheticEvent.getPooled( - eventTypes.responderTerminate, - responderInst, - nativeEvent, - nativeEventTarget - ); - depthA.touchHistory = ResponderTouchHistoryStore.touchHistory; - forEachAccumulated( - depthA, - accumulateDirectDispatchesSingle$1 - ); - var JSCompiler_temp$jscomp$0 = accumulate( - JSCompiler_temp$jscomp$0, - [JSCompiler_temp, depthA] - ); - changeResponder(shouldSetEventType, targetInst); - } else - (shouldSetEventType = ResponderSyntheticEvent.getPooled( - eventTypes.responderReject, - shouldSetEventType, - nativeEvent, - nativeEventTarget - )), - (shouldSetEventType.touchHistory = - ResponderTouchHistoryStore.touchHistory), - forEachAccumulated( - shouldSetEventType, - accumulateDirectDispatchesSingle$1 - ), - (JSCompiler_temp$jscomp$0 = accumulate( - JSCompiler_temp$jscomp$0, - shouldSetEventType - )); - else - (JSCompiler_temp$jscomp$0 = accumulate( - JSCompiler_temp$jscomp$0, - JSCompiler_temp - )), - changeResponder(shouldSetEventType, targetInst); - else JSCompiler_temp$jscomp$0 = null; - } else JSCompiler_temp$jscomp$0 = null; - shouldSetEventType = responderInst && isStartish(topLevelType); - JSCompiler_temp = responderInst && isMoveish(topLevelType); - targetInst = - responderInst && - ("topTouchEnd" === topLevelType || - "topTouchCancel" === topLevelType); - if ( - (shouldSetEventType = shouldSetEventType - ? eventTypes.responderStart - : JSCompiler_temp - ? eventTypes.responderMove - : targetInst - ? eventTypes.responderEnd - : null) - ) - (shouldSetEventType = ResponderSyntheticEvent.getPooled( - shouldSetEventType, - responderInst, - nativeEvent, - nativeEventTarget - )), - (shouldSetEventType.touchHistory = - ResponderTouchHistoryStore.touchHistory), - forEachAccumulated( - shouldSetEventType, - accumulateDirectDispatchesSingle$1 - ), - (JSCompiler_temp$jscomp$0 = accumulate( - JSCompiler_temp$jscomp$0, - shouldSetEventType - )); - shouldSetEventType = - responderInst && "topTouchCancel" === topLevelType; - if ( - (topLevelType = - responderInst && - !shouldSetEventType && - ("topTouchEnd" === topLevelType || - "topTouchCancel" === topLevelType)) - ) - a: { - if ( - (topLevelType = nativeEvent.touches) && - 0 !== topLevelType.length - ) - for ( - JSCompiler_temp = 0; - JSCompiler_temp < topLevelType.length; - JSCompiler_temp++ - ) - if ( - ((targetInst = topLevelType[JSCompiler_temp].target), - null !== targetInst && - void 0 !== targetInst && - 0 !== targetInst) - ) { - depthA = getInstanceFromNode(targetInst); - b: { - for (targetInst = responderInst; depthA; ) { - if ( - targetInst === depthA || - targetInst === depthA.alternate - ) { - targetInst = !0; - break b; - } - depthA = getParent$1(depthA); - } - targetInst = !1; - } - if (targetInst) { - topLevelType = !1; - break a; - } - } - topLevelType = !0; } - if ( - (topLevelType = shouldSetEventType - ? eventTypes.responderTerminate - : topLevelType - ? eventTypes.responderRelease - : null) - ) - (nativeEvent = ResponderSyntheticEvent.getPooled( - topLevelType, - responderInst, - nativeEvent, - nativeEventTarget - )), - (nativeEvent.touchHistory = - ResponderTouchHistoryStore.touchHistory), - forEachAccumulated( - nativeEvent, - accumulateDirectDispatchesSingle$1 - ), - (JSCompiler_temp$jscomp$0 = accumulate( - JSCompiler_temp$jscomp$0, - nativeEvent - )), - changeResponder(null); - return JSCompiler_temp$jscomp$0; - }, - GlobalResponderHandler: null, - injection: { - injectGlobalResponderHandler: function (GlobalResponderHandler) { - ResponderEventPlugin.GlobalResponderHandler = - GlobalResponderHandler; + + throw new Error( + "Element type is invalid: expected a string (for built-in " + + "components) or a class/function (for composite components) " + + ("but got: " + (type == null ? type : typeof type) + "." + info) + ); } } - }, - eventPluginOrder = null, - namesToPlugins = {}, - plugins = [], - eventNameDispatchConfigs = {}, - registrationNameModules = {}, - customBubblingEventTypes = - ReactNativePrivateInterface.ReactNativeViewConfigRegistry - .customBubblingEventTypes, - customDirectEventTypes = - ReactNativePrivateInterface.ReactNativeViewConfigRegistry - .customDirectEventTypes; - if (eventPluginOrder) - throw Error( - "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." + } + + var fiber = createFiber(fiberTag, pendingProps, key, mode); + fiber.elementType = type; + fiber.type = resolvedType; + fiber.lanes = lanes; + + { + fiber._debugOwner = owner; + } + + return fiber; + } + function createFiberFromElement(element, mode, lanes) { + var owner = null; + + { + owner = element._owner; + } + + var type = element.type; + var key = element.key; + var pendingProps = element.props; + var fiber = createFiberFromTypeAndProps( + type, + key, + pendingProps, + owner, + mode, + lanes ); - eventPluginOrder = Array.prototype.slice.call([ - "ResponderEventPlugin", - "ReactNativeBridgeEventPlugin" - ]); - recomputePluginOrdering(); - (function (injectedNamesToPlugins) { - var isOrderingDirty = !1, - pluginName; - for (pluginName in injectedNamesToPlugins) - if (injectedNamesToPlugins.hasOwnProperty(pluginName)) { - var pluginModule = injectedNamesToPlugins[pluginName]; - if ( - !namesToPlugins.hasOwnProperty(pluginName) || - namesToPlugins[pluginName] !== pluginModule - ) { - if (namesToPlugins[pluginName]) - throw Error( - "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - (pluginName + "`.") - ); - namesToPlugins[pluginName] = pluginModule; - isOrderingDirty = !0; - } - } - isOrderingDirty && recomputePluginOrdering(); - })({ - ResponderEventPlugin: ResponderEventPlugin, - ReactNativeBridgeEventPlugin: { - eventTypes: {}, - extractEvents: function ( - topLevelType, - targetInst, - nativeEvent, - nativeEventTarget - ) { - if (null == targetInst) return null; - var bubbleDispatchConfig = customBubblingEventTypes[topLevelType], - directDispatchConfig = customDirectEventTypes[topLevelType]; - if (!bubbleDispatchConfig && !directDispatchConfig) - throw Error( - 'Unsupported top level event type "' + - topLevelType + - '" dispatched' - ); - topLevelType = SyntheticEvent.getPooled( - bubbleDispatchConfig || directDispatchConfig, - targetInst, - nativeEvent, - nativeEventTarget + + { + fiber._debugOwner = element._owner; + } + + return fiber; + } + function createFiberFromFragment(elements, mode, lanes, key) { + var fiber = createFiber(Fragment, elements, key, mode); + fiber.lanes = lanes; + return fiber; + } + + function createFiberFromProfiler(pendingProps, mode, lanes, key) { + { + if (typeof pendingProps.id !== "string") { + error( + 'Profiler must specify an "id" of type `string` as a prop. Received the type `%s` instead.', + typeof pendingProps.id ); - if (bubbleDispatchConfig) - null != topLevelType && - null != topLevelType.dispatchConfig.phasedRegistrationNames && - topLevelType.dispatchConfig.phasedRegistrationNames.skipBubbling - ? topLevelType && - topLevelType.dispatchConfig.phasedRegistrationNames && - traverseTwoPhase( - topLevelType._targetInst, - accumulateDirectionalDispatches, - topLevelType, - !0 - ) - : forEachAccumulated( - topLevelType, - accumulateTwoPhaseDispatchesSingle - ); - else if (directDispatchConfig) - forEachAccumulated(topLevelType, accumulateDirectDispatchesSingle); - else return null; - return topLevelType; } } - }); - var instanceCache = new Map(), - instanceProps = new Map(), - isInsideEventHandler = !1, - eventQueue = null, - EMPTY_NATIVE_EVENT = {}; - ReactNativePrivateInterface.RCTEventEmitter.register({ - receiveEvent: function (rootNodeID, topLevelType, nativeEventParam) { - _receiveRootNodeIDEvent(rootNodeID, topLevelType, nativeEventParam); - }, - receiveTouches: function (eventTopLevelType, touches, changedIndices) { - if ( - "topTouchEnd" === eventTopLevelType || - "topTouchCancel" === eventTopLevelType - ) { - var JSCompiler_temp = []; - for (var i = 0; i < changedIndices.length; i++) { - var index = changedIndices[i]; - JSCompiler_temp.push(touches[index]); - touches[index] = null; - } - for (i = changedIndices = 0; i < touches.length; i++) - (index = touches[i]), - null !== index && (touches[changedIndices++] = index); - touches.length = changedIndices; - } else - for (JSCompiler_temp = [], i = 0; i < changedIndices.length; i++) - JSCompiler_temp.push(touches[changedIndices[i]]); - for ( - changedIndices = 0; - changedIndices < JSCompiler_temp.length; - changedIndices++ - ) { - i = JSCompiler_temp[changedIndices]; - i.changedTouches = JSCompiler_temp; - i.touches = touches; - index = null; - var target = i.target; - null !== target && - void 0 !== target && - (1 > target - ? error$jscomp$0( - "A view is reporting that a touch occurred on tag zero." - ) - : (index = target)); - _receiveRootNodeIDEvent(index, eventTopLevelType, i); - } + + var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode); + fiber.elementType = REACT_PROFILER_TYPE; + fiber.lanes = lanes; + + { + fiber.stateNode = { + effectDuration: 0, + passiveEffectDuration: 0 + }; } - }); - (function ( - getFiberCurrentPropsFromNodeImpl, - getInstanceFromNodeImpl, - getNodeFromInstanceImpl + + return fiber; + } + + function createFiberFromSuspense(pendingProps, mode, lanes, key) { + 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); + fiber.elementType = REACT_SUSPENSE_LIST_TYPE; + fiber.lanes = lanes; + return fiber; + } + function createFiberFromOffscreen(pendingProps, mode, lanes, key) { + var fiber = createFiber(OffscreenComponent, pendingProps, key, mode); + fiber.elementType = REACT_OFFSCREEN_TYPE; + fiber.lanes = lanes; + var primaryChildInstance = { + _visibility: OffscreenVisible, + _pendingVisibility: OffscreenVisible, + _pendingMarkers: null, + _retryCache: null, + _transitions: null, + _current: null, + detach: function () { + return detachOffscreenInstance(primaryChildInstance); + }, + attach: function () { + return attachOffscreenInstance(primaryChildInstance); + } + }; + fiber.stateNode = primaryChildInstance; + return fiber; + } + function createFiberFromText(content, mode, lanes) { + var fiber = createFiber(HostText, content, null, mode); + fiber.lanes = lanes; + return fiber; + } + function createFiberFromPortal(portal, mode, lanes) { + var pendingProps = portal.children !== null ? portal.children : []; + var fiber = createFiber(HostPortal, pendingProps, portal.key, mode); + fiber.lanes = lanes; + fiber.stateNode = { + containerInfo: portal.containerInfo, + pendingChildren: null, + // Used by persistent updates + implementation: portal.implementation + }; + return fiber; + } + + function FiberRootNode( + containerInfo, // $FlowFixMe[missing-local-annot] + tag, + hydrate, + identifierPrefix, + onRecoverableError, + formState ) { - getFiberCurrentPropsFromNode$1 = getFiberCurrentPropsFromNodeImpl; - getInstanceFromNode = getInstanceFromNodeImpl; - ((getNodeFromInstance = getNodeFromInstanceImpl) && - getInstanceFromNode) || - error$jscomp$0( - "Injected module is missing getNodeFromInstance or getInstanceFromNode." - ); - })( - function (stateNode) { - return instanceProps.get(stateNode._nativeTag) || null; - }, - getInstanceFromTag, - function (inst) { - inst = inst.stateNode; - var tag = inst._nativeTag; - void 0 === tag && - null != inst.canonical && - ((tag = inst.canonical.nativeTag), - (inst = inst.canonical.publicInstance)); - if (!tag) throw Error("All native instances should have a tag."); - return inst; + this.tag = tag; + this.containerInfo = containerInfo; + this.pendingChildren = null; + this.current = null; + this.pingCache = null; + this.finishedWork = null; + this.timeoutHandle = noTimeout; + this.cancelPendingCommit = null; + this.context = null; + this.pendingContext = null; + this.next = null; + this.callbackNode = null; + this.callbackPriority = NoLane; + this.expirationTimes = createLaneMap(NoTimestamp); + this.pendingLanes = NoLanes; + this.suspendedLanes = NoLanes; + this.pingedLanes = NoLanes; + this.expiredLanes = NoLanes; + this.finishedLanes = NoLanes; + this.errorRecoveryDisabledLanes = NoLanes; + this.shellSuspendCounter = 0; + this.entangledLanes = NoLanes; + this.entanglements = createLaneMap(NoLanes); + this.hiddenUpdates = createLaneMap(null); + this.identifierPrefix = identifierPrefix; + this.onRecoverableError = onRecoverableError; + + this.formState = formState; + this.incompleteTransitions = new Map(); + + { + this.effectDuration = 0; + this.passiveEffectDuration = 0; } - ); - ResponderEventPlugin.injection.injectGlobalResponderHandler({ - onChange: function (from, to, blockNativeResponder) { - null !== to - ? ReactNativePrivateInterface.UIManager.setJSResponder( - to.stateNode._nativeTag, - blockNativeResponder - ) - : ReactNativePrivateInterface.UIManager.clearJSResponder(); + + { + this.memoizedUpdaters = new Set(); + var pendingUpdatersLaneMap = (this.pendingUpdatersLaneMap = []); + + for (var _i = 0; _i < TotalLanes; _i++) { + pendingUpdatersLaneMap.push(new Set()); + } } - }); - var emptyObject$1 = {}, - removedKeys = null, - removedKeyCount = 0, - deepDifferOptions = { unsafelyIgnoreFunctions: !0 }, - ReactNativeFiberHostComponent = (function () { - function ReactNativeFiberHostComponent( - tag, - viewConfig, - internalInstanceHandleDEV - ) { - this.viewConfig = void 0; - this._nativeTag = tag; - this._children = []; - this.viewConfig = viewConfig; - this._internalFiberInstanceHandleDEV = internalInstanceHandleDEV; + + { + switch (tag) { + case ConcurrentRoot: + this._debugRootType = hydrate ? "hydrateRoot()" : "createRoot()"; + break; + + case LegacyRoot: + this._debugRootType = hydrate ? "hydrate()" : "render()"; + break; } - 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 - ? error$jscomp$0( - "ref.measureLayout must be called with a node handle or a ref to a native component." - ) - : ReactNativePrivateInterface.UIManager.measureLayout( - this._nativeTag, - relativeNode, - mountSafeCallback_NOT_REALLY_SAFE(this, onFail), - mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) - ); - }; - _proto.setNativeProps = function (nativeProps) { - var validAttributes = this.viewConfig.validAttributes, - key; - for (key in validAttributes.style) - validAttributes[key] || - void 0 === nativeProps[key] || - error$jscomp$0( - "You are setting the style `{ %s: ... }` as a prop. You should nest it in a style object. E.g. `{ style: { %s: ... } }`", - key, - key - ); - nativeProps = diffProperties( - null, - emptyObject$1, - nativeProps, - this.viewConfig.validAttributes - ); - null != nativeProps && - ReactNativePrivateInterface.UIManager.updateView( - this._nativeTag, - this.viewConfig.uiViewClassName, - nativeProps - ); - }; - return ReactNativeFiberHostComponent; - })(), - scheduleCallback$3 = Scheduler.unstable_scheduleCallback, - cancelCallback$1 = Scheduler.unstable_cancelCallback, - shouldYield = Scheduler.unstable_shouldYield, - requestPaint = Scheduler.unstable_requestPaint, - now$1 = Scheduler.unstable_now, - ImmediatePriority = Scheduler.unstable_ImmediatePriority, - UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, - NormalPriority$1 = Scheduler.unstable_NormalPriority, - IdlePriority = Scheduler.unstable_IdlePriority, - log$1 = Scheduler.log, - unstable_setDisableYieldValue = Scheduler.unstable_setDisableYieldValue, - rendererID = null, - injectedHook = null, - injectedProfilingHooks = null, - hasLoggedError = !1, - isDevToolsPresent = "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__, - clz32 = Math.clz32 ? Math.clz32 : clz32Fallback, - log = Math.log, - LN2 = Math.LN2, - TotalLanes = 31, - SyncHydrationLane = 1, - SyncLane = 2, - InputContinuousHydrationLane = 4, - InputContinuousLane = 8, - DefaultHydrationLane = 16, - DefaultLane = 32, - SyncUpdateLanes = SyncLane | InputContinuousLane | DefaultLane, - TransitionHydrationLane = 64, - TransitionLanes = 4194176, - RetryLanes = 62914560, - SelectiveHydrationLane = 67108864, - IdleHydrationLane = 134217728, - IdleLane = 268435456, - OffscreenLane = 536870912, - DeferredLane = 1073741824, - UpdateLanes = - SyncLane | InputContinuousLane | DefaultLane | TransitionLanes, - nextTransitionLane = 128, - nextRetryLane = 4194304, - DiscreteEventPriority = SyncLane, - ContinuousEventPriority = InputContinuousLane, - DefaultEventPriority = DefaultLane, - IdleEventPriority = IdleLane, - isSuspenseInstancePending = shim$1, - isSuspenseInstanceFallback = shim$1, - getSuspenseInstanceFallbackErrorDetails = shim$1, - registerSuspenseInstanceRetry = shim$1, - clearSuspenseBoundary = shim$1, - clearSuspenseBoundaryFromContainer = shim$1, - preloadResource = shim, - suspendResource = shim, - getViewConfigForType = - ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get, - nextReactTag = 3, - scheduleTimeout = setTimeout, - cancelTimeout = clearTimeout, - currentUpdatePriority = 0, - valueStack = []; - var fiberStack = []; - var index$jscomp$0 = -1, - emptyContextObject = {}; - Object.freeze(emptyContextObject); - var objectIs = "function" === typeof Object.is ? Object.is : is, - CapturedStacks = new WeakMap(), - contextStackCursor = createCursor(null), - contextFiberStackCursor = createCursor(null), - rootInstanceStackCursor = createCursor(null), - hostTransitionProviderCursor = createCursor(null), - HostTransitionContext = { - $$typeof: REACT_CONTEXT_TYPE, - Provider: null, - Consumer: null, - _currentValue: null, - _currentValue2: null, - _threadCount: 0 - }, - needsEscaping = /["'&<>\n\t]/, - hydrationDiffRootDEV = null, - hydrationErrors = null, - concurrentQueues = [], - concurrentQueuesIndex = 0, - concurrentlyUpdatedLanes = 0, - firstScheduledRoot = null, - lastScheduledRoot = null, - didScheduleMicrotask = !1, - didScheduleMicrotask_act = !1, - mightHavePendingSyncWork = !1, - isFlushingWork = !1, - currentEventTransitionLane = 0, - fakeActCallbackNode$1 = {}, - currentEntangledListeners = null, - currentEntangledPendingCount = 0, - currentEntangledLane = 0, - currentEntangledActionThenable = null, - UpdateState = 0, - ReplaceState = 1, - ForceUpdate = 2, - CaptureUpdate = 3, - hasForceUpdate = !1; - var didWarnUpdateInsideUpdate = !1; - var currentlyProcessingQueue = null; - var didReadFromEntangledAsyncAction = !1, - hasOwnProperty = Object.prototype.hasOwnProperty, - ReactStrictModeWarnings = { - recordUnsafeLifecycleWarnings: function () {}, - flushPendingUnsafeLifecycleWarnings: function () {}, - recordLegacyContextWarning: function () {}, - flushLegacyContextWarning: function () {}, - discardPendingWarnings: function () {} - }, - pendingComponentWillMountWarnings = [], - pendingUNSAFE_ComponentWillMountWarnings = [], - pendingComponentWillReceivePropsWarnings = [], - pendingUNSAFE_ComponentWillReceivePropsWarnings = [], - pendingComponentWillUpdateWarnings = [], - pendingUNSAFE_ComponentWillUpdateWarnings = [], - didWarnAboutUnsafeLifecycles = new Set(); - ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function ( - fiber, - instance + } + } + + function createFiberRoot( + containerInfo, + tag, + hydrate, + initialChildren, + hydrationCallbacks, + isStrictMode, + concurrentUpdatesByDefaultOverride, // TODO: We have several of these arguments that are conceptually part of the + // host config, but because they are passed in at runtime, we have to thread + // them through the root constructor. Perhaps we should put them all into a + // single type, like a DynamicHostConfig that is defined by the renderer. + identifierPrefix, + onRecoverableError, + transitionCallbacks, + formState ) { - didWarnAboutUnsafeLifecycles.has(fiber.type) || - ("function" === typeof instance.componentWillMount && - !0 !== instance.componentWillMount.__suppressDeprecationWarning && - pendingComponentWillMountWarnings.push(fiber), - fiber.mode & 8 && - "function" === typeof instance.UNSAFE_componentWillMount && - pendingUNSAFE_ComponentWillMountWarnings.push(fiber), - "function" === typeof instance.componentWillReceiveProps && - !0 !== - instance.componentWillReceiveProps.__suppressDeprecationWarning && - pendingComponentWillReceivePropsWarnings.push(fiber), - fiber.mode & 8 && - "function" === typeof instance.UNSAFE_componentWillReceiveProps && - pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber), - "function" === typeof instance.componentWillUpdate && - !0 !== instance.componentWillUpdate.__suppressDeprecationWarning && - pendingComponentWillUpdateWarnings.push(fiber), - fiber.mode & 8 && - "function" === typeof instance.UNSAFE_componentWillUpdate && - pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber)); - }; - ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function () { - var componentWillMountUniqueNames = new Set(); - 0 < pendingComponentWillMountWarnings.length && - (pendingComponentWillMountWarnings.forEach(function (fiber) { - componentWillMountUniqueNames.add( - getComponentNameFromFiber(fiber) || "Component" - ); - didWarnAboutUnsafeLifecycles.add(fiber.type); - }), - (pendingComponentWillMountWarnings = [])); - var UNSAFE_componentWillMountUniqueNames = new Set(); - 0 < pendingUNSAFE_ComponentWillMountWarnings.length && - (pendingUNSAFE_ComponentWillMountWarnings.forEach(function (fiber) { - UNSAFE_componentWillMountUniqueNames.add( - getComponentNameFromFiber(fiber) || "Component" - ); - didWarnAboutUnsafeLifecycles.add(fiber.type); - }), - (pendingUNSAFE_ComponentWillMountWarnings = [])); - var componentWillReceivePropsUniqueNames = new Set(); - 0 < pendingComponentWillReceivePropsWarnings.length && - (pendingComponentWillReceivePropsWarnings.forEach(function (fiber) { - componentWillReceivePropsUniqueNames.add( - getComponentNameFromFiber(fiber) || "Component" - ); - didWarnAboutUnsafeLifecycles.add(fiber.type); - }), - (pendingComponentWillReceivePropsWarnings = [])); - var UNSAFE_componentWillReceivePropsUniqueNames = new Set(); - 0 < pendingUNSAFE_ComponentWillReceivePropsWarnings.length && - (pendingUNSAFE_ComponentWillReceivePropsWarnings.forEach( - function (fiber) { - UNSAFE_componentWillReceivePropsUniqueNames.add( - getComponentNameFromFiber(fiber) || "Component" - ); - didWarnAboutUnsafeLifecycles.add(fiber.type); - } - ), - (pendingUNSAFE_ComponentWillReceivePropsWarnings = [])); - var componentWillUpdateUniqueNames = new Set(); - 0 < pendingComponentWillUpdateWarnings.length && - (pendingComponentWillUpdateWarnings.forEach(function (fiber) { - componentWillUpdateUniqueNames.add( - getComponentNameFromFiber(fiber) || "Component" - ); - didWarnAboutUnsafeLifecycles.add(fiber.type); - }), - (pendingComponentWillUpdateWarnings = [])); - var UNSAFE_componentWillUpdateUniqueNames = new Set(); - 0 < pendingUNSAFE_ComponentWillUpdateWarnings.length && - (pendingUNSAFE_ComponentWillUpdateWarnings.forEach(function (fiber) { - UNSAFE_componentWillUpdateUniqueNames.add( - getComponentNameFromFiber(fiber) || "Component" - ); - didWarnAboutUnsafeLifecycles.add(fiber.type); - }), - (pendingUNSAFE_ComponentWillUpdateWarnings = [])); - if (0 < UNSAFE_componentWillMountUniqueNames.size) { - var sortedNames = setToSortedString( - UNSAFE_componentWillMountUniqueNames - ); - error$jscomp$0( - "Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. See https://react.dev/link/unsafe-component-lifecycles for details.\n\n* Move code with side effects to componentDidMount, and set initial state in the constructor.\n\nPlease update the following components: %s", - sortedNames - ); + // $FlowFixMe[invalid-constructor] Flow no longer supports calling new on functions + var root = new FiberRootNode( + containerInfo, + tag, + hydrate, + identifierPrefix, + onRecoverableError, + formState + ); + // stateNode is any. + + var uninitializedFiber = createHostRootFiber(tag, isStrictMode); + root.current = uninitializedFiber; + uninitializedFiber.stateNode = root; + + { + var _initialState = { + element: initialChildren, + isDehydrated: hydrate, + cache: null // not enabled yet + }; + uninitializedFiber.memoizedState = _initialState; } - 0 < UNSAFE_componentWillReceivePropsUniqueNames.size && - ((sortedNames = setToSortedString( - UNSAFE_componentWillReceivePropsUniqueNames - )), - error$jscomp$0( - "Using UNSAFE_componentWillReceiveProps in strict mode is not recommended and may indicate bugs in your code. See https://react.dev/link/unsafe-component-lifecycles for details.\n\n* Move data fetching code or side effects to componentDidUpdate.\n* If you're updating state whenever props change, refactor your code to use memoization techniques or move it to static getDerivedStateFromProps. Learn more at: https://react.dev/link/derived-state\n\nPlease update the following components: %s", - sortedNames - )); - 0 < UNSAFE_componentWillUpdateUniqueNames.size && - ((sortedNames = setToSortedString( - UNSAFE_componentWillUpdateUniqueNames - )), - error$jscomp$0( - "Using UNSAFE_componentWillUpdate in strict mode is not recommended and may indicate bugs in your code. See https://react.dev/link/unsafe-component-lifecycles for details.\n\n* Move data fetching code or side effects to componentDidUpdate.\n\nPlease update the following components: %s", - sortedNames - )); - 0 < componentWillMountUniqueNames.size && - ((sortedNames = setToSortedString(componentWillMountUniqueNames)), - warn( - "componentWillMount has been renamed, and is not recommended for use. See https://react.dev/link/unsafe-component-lifecycles for details.\n\n* Move code with side effects to componentDidMount, and set initial state in the constructor.\n* Rename componentWillMount to UNSAFE_componentWillMount to suppress this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\nPlease update the following components: %s", - sortedNames - )); - 0 < componentWillReceivePropsUniqueNames.size && - ((sortedNames = setToSortedString( - componentWillReceivePropsUniqueNames - )), - warn( - "componentWillReceiveProps has been renamed, and is not recommended for use. See https://react.dev/link/unsafe-component-lifecycles for details.\n\n* Move data fetching code or side effects to componentDidUpdate.\n* If you're updating state whenever props change, refactor your code to use memoization techniques or move it to static getDerivedStateFromProps. Learn more at: https://react.dev/link/derived-state\n* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\nPlease update the following components: %s", - sortedNames - )); - 0 < componentWillUpdateUniqueNames.size && - ((sortedNames = setToSortedString(componentWillUpdateUniqueNames)), - warn( - "componentWillUpdate has been renamed, and is not recommended for use. See https://react.dev/link/unsafe-component-lifecycles for details.\n\n* Move data fetching code or side effects to componentDidUpdate.\n* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\nPlease update the following components: %s", - sortedNames - )); - }; - var pendingLegacyContextWarning = new Map(), - didWarnAboutLegacyContext = new Set(); - ReactStrictModeWarnings.recordLegacyContextWarning = function ( - fiber, - instance + + initializeUpdateQueue(uninitializedFiber); + return root; + } + + var ReactVersion = "18.3.0-canary-9372c6311-20240315"; + + function createPortal$1( + children, + containerInfo, // TODO: figure out the API for cross-renderer implementation. + implementation ) { - var strictRoot = null; - for (var node = fiber; null !== node; ) - node.mode & 8 && (strictRoot = node), (node = node.return); - null === strictRoot - ? error$jscomp$0( - "Expected to find a StrictMode component in a strict mode tree. This error is likely caused by a bug in React. Please file an issue." - ) - : !didWarnAboutLegacyContext.has(fiber.type) && - ((node = pendingLegacyContextWarning.get(strictRoot)), - null != fiber.type.contextTypes || - null != fiber.type.childContextTypes || - (null !== instance && - "function" === typeof instance.getChildContext)) && - (void 0 === node && - ((node = []), pendingLegacyContextWarning.set(strictRoot, node)), - node.push(fiber)); - }; - ReactStrictModeWarnings.flushLegacyContextWarning = function () { - pendingLegacyContextWarning.forEach(function (fiberArray) { - if (0 !== fiberArray.length) { - var firstFiber = fiberArray[0], - uniqueNames = new Set(); - fiberArray.forEach(function (fiber) { - uniqueNames.add(getComponentNameFromFiber(fiber) || "Component"); - didWarnAboutLegacyContext.add(fiber.type); - }); - var sortedNames = setToSortedString(uniqueNames); - runWithFiberInDEV(firstFiber, function () { - error$jscomp$0( - "Legacy context API has been detected within a strict-mode tree.\n\nThe old API will be supported in all 16.x releases, but applications using it should migrate to the new version.\n\nPlease update the following components: %s\n\nLearn more about this warning here: https://react.dev/link/legacy-context", - sortedNames + var key = + arguments.length > 3 && arguments[3] !== undefined + ? arguments[3] + : null; + + { + checkKeyStringCoercion(key); + } + + return { + // This tag allow us to uniquely identify this as a React Portal + $$typeof: REACT_PORTAL_TYPE, + key: key == null ? null : "" + key, + children: children, + containerInfo: containerInfo, + implementation: implementation + }; + } + + // Might add PROFILE later. + + var didWarnAboutNestedUpdates; + var didWarnAboutFindNodeInStrictMode; + + { + didWarnAboutNestedUpdates = false; + didWarnAboutFindNodeInStrictMode = {}; + } + + function getContextForSubtree(parentComponent) { + if (!parentComponent) { + return emptyContextObject; + } + + var fiber = get(parentComponent); + var parentContext = findCurrentUnmaskedContext(); + + if (fiber.tag === ClassComponent) { + var Component = fiber.type; + + if (isContextProvider()) { + return processChildContext(fiber, Component, parentContext); + } + } + + return parentContext; + } + + function findHostInstanceWithWarning(component, methodName) { + { + var fiber = get(component); + + if (fiber === undefined) { + if (typeof component.render === "function") { + throw new Error("Unable to find node on an unmounted component."); + } else { + var keys = Object.keys(component).join(","); + throw new Error( + "Argument appears to not be a ReactComponent. Keys: " + keys ); - }); + } } - }); - }; - ReactStrictModeWarnings.discardPendingWarnings = function () { - pendingComponentWillMountWarnings = []; - pendingUNSAFE_ComponentWillMountWarnings = []; - pendingComponentWillReceivePropsWarnings = []; - pendingUNSAFE_ComponentWillReceivePropsWarnings = []; - pendingComponentWillUpdateWarnings = []; - pendingUNSAFE_ComponentWillUpdateWarnings = []; - pendingLegacyContextWarning = new Map(); - }; - var SuspenseException = Error( - "Suspense Exception: This is not a real error! It's an implementation detail of `use` to interrupt the current render. You must either rethrow it immediately, or move the `use` call outside of the `try/catch` block. Capturing without rethrowing will lead to unexpected behavior.\n\nTo handle async errors, wrap your component in an error boundary, or call the promise's `.catch` method and pass the result to `use`" - ), - SuspenseyCommitException = Error( - "Suspense Exception: This is not a real error, and should not leak into userspace. If you're seeing this, it's likely a bug in React." - ), - noopSuspenseyCommitThenable = { - then: function () { - error$jscomp$0( - 'Internal React error: A listener was unexpectedly attached to a "noop" thenable. This is a bug in React. Please file an issue.' - ); + + var hostFiber = findCurrentHostFiber(fiber); + + if (hostFiber === null) { + return null; } - }, - suspendedThenable = null, - needsToResetSuspendedThenableDEV = !1, - thenableState$1 = null, - thenableIndexCounter$1 = 0, - currentDebugInfo = null, - didWarnAboutMaps; - var didWarnAboutGenerators = (didWarnAboutMaps = !1); - var ownerHasKeyUseWarning = {}; - var ownerHasFunctionTypeWarning = {}; - var ownerHasSymbolTypeWarning = {}; - warnForMissingKey = function (returnFiber, workInProgress, child) { - if ( - null !== child && - "object" === typeof child && - child._store && - ((!child._store.validated && null == child.key) || - 2 === child._store.validated) - ) { - if ("object" !== typeof child._store) - throw Error( - "React Component in warnForMissingKey should have a _store. This error is likely caused by a bug in React. Please file an issue." - ); - child._store.validated = 1; - var componentName = getComponentNameFromFiber(returnFiber), - componentKey = componentName || "null"; - if (!ownerHasKeyUseWarning[componentKey]) { - ownerHasKeyUseWarning[componentKey] = !0; - child = child._owner; - returnFiber = returnFiber._debugOwner; - var currentComponentErrorInfo = ""; - returnFiber && - "number" === typeof returnFiber.tag && - (componentKey = getComponentNameFromFiber(returnFiber)) && - (currentComponentErrorInfo = - "\n\nCheck the render method of `" + componentKey + "`."); - currentComponentErrorInfo || - (componentName && - (currentComponentErrorInfo = - "\n\nCheck the top-level render call using <" + - componentName + - ">.")); - var childOwnerAppendix = ""; - null != child && - returnFiber !== child && - ((componentName = null), - "number" === typeof child.tag - ? (componentName = getComponentNameFromFiber(child)) - : "string" === typeof child.name && (componentName = child.name), - componentName && - (childOwnerAppendix = - " It was passed a child from " + componentName + ".")); - runWithFiberInDEV(workInProgress, function () { - error$jscomp$0( - 'Each child in a list should have a unique "key" prop.%s%s See https://react.dev/link/warning-keys for more information.', - currentComponentErrorInfo, - childOwnerAppendix - ); - }); + + if (hostFiber.mode & StrictLegacyMode) { + var componentName = getComponentNameFromFiber(fiber) || "Component"; + + if (!didWarnAboutFindNodeInStrictMode[componentName]) { + didWarnAboutFindNodeInStrictMode[componentName] = true; + var previousFiber = current; + + try { + setCurrentFiber(hostFiber); + + if (fiber.mode & StrictLegacyMode) { + error( + "%s is deprecated in StrictMode. " + + "%s was passed an instance of %s which is inside StrictMode. " + + "Instead, add a ref directly to the element you want to reference. " + + "Learn more about using refs safely here: " + + "https://react.dev/link/strict-mode-find-node", + methodName, + methodName, + componentName + ); + } else { + error( + "%s is deprecated in StrictMode. " + + "%s was passed an instance of %s which renders StrictMode children. " + + "Instead, add a ref directly to the element you want to reference. " + + "Learn more about using refs safely here: " + + "https://react.dev/link/strict-mode-find-node", + methodName, + methodName, + componentName + ); + } + } finally { + // Ideally this should reset to previous but this shouldn't be called in + // render and there's another warning for that anyway. + if (previousFiber) { + setCurrentFiber(previousFiber); + } else { + resetCurrentFiber(); + } + } + } } + + return getPublicInstance(hostFiber.stateNode); } - }; - var reconcileChildFibers = createChildReconciler(!0), - mountChildFibers = createChildReconciler(!1), - currentTreeHiddenStackCursor = createCursor(null), - prevEntangledRenderLanesCursor = createCursor(0), - suspenseHandlerStackCursor = createCursor(null), - shellBoundary = null, - SubtreeSuspenseContextMask = 1, - ForceSuspenseFallback = 2, - suspenseStackCursor = createCursor(0), - NoFlags = 0, - HasEffect = 1, - Insertion = 2, - Layout = 4, - Passive = 8, - didWarnUncachedGetSnapshot; - var didWarnAboutMismatchedHooksForComponent = new Set(); - var didWarnAboutUseWrappedInTryCatch = new Set(); - var didWarnAboutAsyncClientComponent = new Set(); - var didWarnAboutUseFormState = new Set(); - var renderLanes = 0, - currentlyRenderingFiber$1 = null, - currentHook = null, - workInProgressHook = null, - didScheduleRenderPhaseUpdate = !1, - didScheduleRenderPhaseUpdateDuringThisPass = !1, - shouldDoubleInvokeUserFnsInHooksDEV = !1, - thenableIndexCounter = 0, - thenableState = null, - globalClientIdCounter = 0, - RE_RENDER_LIMIT = 25, - currentHookNameInDev = null, - hookTypesDev = null, - hookTypesUpdateIndexDev = -1, - ignorePreviousDependencies = !1; - var createFunctionComponentUpdateQueue = function () { - return { lastEffect: null, events: null, stores: null, memoCache: null }; - }; - var ContextOnlyDispatcher = { - readContext: readContext, - use: use, - useCallback: throwInvalidHookError, - useContext: throwInvalidHookError, - useEffect: throwInvalidHookError, - useImperativeHandle: throwInvalidHookError, - useLayoutEffect: throwInvalidHookError, - useInsertionEffect: throwInvalidHookError, - useMemo: throwInvalidHookError, - useReducer: throwInvalidHookError, - useRef: throwInvalidHookError, - useState: throwInvalidHookError, - useDebugValue: throwInvalidHookError, - useDeferredValue: throwInvalidHookError, - useTransition: throwInvalidHookError, - useSyncExternalStore: throwInvalidHookError, - useId: throwInvalidHookError - }; - ContextOnlyDispatcher.useCacheRefresh = throwInvalidHookError; - ContextOnlyDispatcher.useMemoCache = throwInvalidHookError; - ContextOnlyDispatcher.useHostTransitionStatus = throwInvalidHookError; - ContextOnlyDispatcher.useFormState = throwInvalidHookError; - ContextOnlyDispatcher.useActionState = throwInvalidHookError; - ContextOnlyDispatcher.useOptimistic = throwInvalidHookError; - var HooksDispatcherOnMountInDEV = null, - HooksDispatcherOnMountWithHookTypesInDEV = null, - HooksDispatcherOnUpdateInDEV = null, - HooksDispatcherOnRerenderInDEV = null, - InvalidNestedHooksDispatcherOnMountInDEV = null, - InvalidNestedHooksDispatcherOnUpdateInDEV = null, - InvalidNestedHooksDispatcherOnRerenderInDEV = null; - HooksDispatcherOnMountInDEV = { - readContext: function (context) { - return readContext(context); - }, - use: use, - useCallback: function (callback, deps) { - currentHookNameInDev = "useCallback"; - mountHookTypesDev(); - checkDepsAreArrayDev(deps); - return mountCallback(callback, deps); - }, - useContext: function (context) { - currentHookNameInDev = "useContext"; - mountHookTypesDev(); - return readContext(context); - }, - useEffect: function (create, deps) { - currentHookNameInDev = "useEffect"; - mountHookTypesDev(); - checkDepsAreArrayDev(deps); - return mountEffect(create, deps); - }, - useImperativeHandle: function (ref, create, deps) { - currentHookNameInDev = "useImperativeHandle"; - mountHookTypesDev(); - checkDepsAreArrayDev(deps); - return mountImperativeHandle(ref, create, deps); - }, - useInsertionEffect: function (create, deps) { - currentHookNameInDev = "useInsertionEffect"; - mountHookTypesDev(); - checkDepsAreArrayDev(deps); - mountEffectImpl(4, Insertion, create, deps); - }, - useLayoutEffect: function (create, deps) { - currentHookNameInDev = "useLayoutEffect"; - mountHookTypesDev(); - checkDepsAreArrayDev(deps); - return mountLayoutEffect(create, deps); - }, - useMemo: function (create, deps) { - currentHookNameInDev = "useMemo"; - mountHookTypesDev(); - checkDepsAreArrayDev(deps); - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = InvalidNestedHooksDispatcherOnMountInDEV; - try { - return mountMemo(create, deps); - } finally { - ReactSharedInternals.H = prevDispatcher; - } - }, - useReducer: function (reducer, initialArg, init) { - currentHookNameInDev = "useReducer"; - mountHookTypesDev(); - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = InvalidNestedHooksDispatcherOnMountInDEV; - try { - return mountReducer(reducer, initialArg, init); - } finally { - ReactSharedInternals.H = prevDispatcher; + } + + function createContainer( + containerInfo, + tag, + hydrationCallbacks, + isStrictMode, + concurrentUpdatesByDefaultOverride, + identifierPrefix, + onRecoverableError, + transitionCallbacks + ) { + var hydrate = false; + var initialChildren = null; + return createFiberRoot( + containerInfo, + tag, + hydrate, + initialChildren, + hydrationCallbacks, + isStrictMode, + concurrentUpdatesByDefaultOverride, + identifierPrefix, + onRecoverableError, + transitionCallbacks, + null + ); + } + function updateContainer(element, container, parentComponent, callback) { + { + onScheduleRoot(container, element); + } + + var current$1 = container.current; + var lane = requestUpdateLane(current$1); + + var context = getContextForSubtree(parentComponent); + + if (container.context === null) { + container.context = context; + } else { + container.pendingContext = context; + } + + { + if (isRendering && current !== null && !didWarnAboutNestedUpdates) { + didWarnAboutNestedUpdates = true; + + error( + "Render methods should be a pure function of props and state; " + + "triggering nested component updates from render is not allowed. " + + "If necessary, trigger nested updates in componentDidUpdate.\n\n" + + "Check the render method of %s.", + getComponentNameFromFiber(current) || "Unknown" + ); } - }, - useRef: function (initialValue) { - currentHookNameInDev = "useRef"; - mountHookTypesDev(); - return mountRef(initialValue); - }, - useState: function (initialState) { - currentHookNameInDev = "useState"; - mountHookTypesDev(); - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = InvalidNestedHooksDispatcherOnMountInDEV; - try { - return mountState(initialState); - } finally { - ReactSharedInternals.H = prevDispatcher; + } + + var update = createUpdate(lane); // Caution: React DevTools currently depends on this property + // being called "element". + + update.payload = { + element: element + }; + callback = callback === undefined ? null : callback; + + if (callback !== null) { + { + if (typeof callback !== "function") { + error( + "Expected the last optional `callback` argument to be a " + + "function. Instead received: %s.", + callback + ); + } } - }, - useDebugValue: function () { - currentHookNameInDev = "useDebugValue"; - mountHookTypesDev(); - }, - useDeferredValue: function (value, initialValue) { - currentHookNameInDev = "useDeferredValue"; - mountHookTypesDev(); - return mountDeferredValue(value, initialValue); - }, - useTransition: function () { - currentHookNameInDev = "useTransition"; - mountHookTypesDev(); - return mountTransition(); - }, - useSyncExternalStore: function (subscribe, getSnapshot) { - currentHookNameInDev = "useSyncExternalStore"; - mountHookTypesDev(); - return mountSyncExternalStore(subscribe, getSnapshot); - }, - useId: function () { - currentHookNameInDev = "useId"; - mountHookTypesDev(); - return mountId(); - }, - useCacheRefresh: function () { - currentHookNameInDev = "useCacheRefresh"; - mountHookTypesDev(); - return mountRefresh(); + + update.callback = callback; } + + var root = enqueueUpdate(current$1, update, lane); + + if (root !== null) { + scheduleUpdateOnFiber(root, current$1, lane); + entangleTransitions(root, current$1, lane); + } + + return lane; + } + function getPublicRootInstance(container) { + var containerFiber = container.current; + + if (!containerFiber.child) { + return null; + } + + switch (containerFiber.child.tag) { + case HostSingleton: + case HostComponent: + return getPublicInstance(containerFiber.child.stateNode); + + default: + return containerFiber.child.stateNode; + } + } + + var shouldErrorImpl = function (fiber) { + return null; }; - HooksDispatcherOnMountInDEV.useMemoCache = useMemoCache; - HooksDispatcherOnMountInDEV.useHostTransitionStatus = - useHostTransitionStatus; - HooksDispatcherOnMountInDEV.useFormState = function (action, initialState) { - currentHookNameInDev = "useFormState"; - mountHookTypesDev(); - return mountActionState(action, initialState); - }; - HooksDispatcherOnMountInDEV.useActionState = function ( - action, - initialState - ) { - currentHookNameInDev = "useActionState"; - mountHookTypesDev(); - return mountActionState(action, initialState); - }; - HooksDispatcherOnMountInDEV.useOptimistic = function (passthrough) { - currentHookNameInDev = "useOptimistic"; - mountHookTypesDev(); - return mountOptimistic(passthrough); + + function shouldError(fiber) { + return shouldErrorImpl(fiber); + } + + var shouldSuspendImpl = function (fiber) { + return false; }; - HooksDispatcherOnMountWithHookTypesInDEV = { - readContext: function (context) { - return readContext(context); - }, - use: use, - useCallback: function (callback, deps) { - currentHookNameInDev = "useCallback"; - updateHookTypesDev(); - return mountCallback(callback, deps); - }, - useContext: function (context) { - currentHookNameInDev = "useContext"; - updateHookTypesDev(); - return readContext(context); - }, - useEffect: function (create, deps) { - currentHookNameInDev = "useEffect"; - updateHookTypesDev(); - return mountEffect(create, deps); - }, - useImperativeHandle: function (ref, create, deps) { - currentHookNameInDev = "useImperativeHandle"; - updateHookTypesDev(); - return mountImperativeHandle(ref, create, deps); - }, - useInsertionEffect: function (create, deps) { - currentHookNameInDev = "useInsertionEffect"; - updateHookTypesDev(); - mountEffectImpl(4, Insertion, create, deps); - }, - useLayoutEffect: function (create, deps) { - currentHookNameInDev = "useLayoutEffect"; - updateHookTypesDev(); - return mountLayoutEffect(create, deps); - }, - useMemo: function (create, deps) { - currentHookNameInDev = "useMemo"; - updateHookTypesDev(); - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = InvalidNestedHooksDispatcherOnMountInDEV; - try { - return mountMemo(create, deps); - } finally { - ReactSharedInternals.H = prevDispatcher; + + function shouldSuspend(fiber) { + return shouldSuspendImpl(fiber); + } + var overrideHookState = null; + var overrideHookStateDeletePath = null; + var overrideHookStateRenamePath = null; + var overrideProps = null; + var overridePropsDeletePath = null; + var overridePropsRenamePath = null; + var scheduleUpdate = null; + var setErrorHandler = null; + var setSuspenseHandler = null; + + { + var copyWithDeleteImpl = function (obj, path, index) { + var key = path[index]; + var updated = isArray(obj) ? obj.slice() : assign({}, obj); + + if (index + 1 === path.length) { + if (isArray(updated)) { + updated.splice(key, 1); + } else { + delete updated[key]; + } + + return updated; + } // $FlowFixMe[incompatible-use] number or string is fine here + + updated[key] = copyWithDeleteImpl(obj[key], path, index + 1); + return updated; + }; + + var copyWithDelete = function (obj, path) { + return copyWithDeleteImpl(obj, path, 0); + }; + + var copyWithRenameImpl = function (obj, oldPath, newPath, index) { + var oldKey = oldPath[index]; + var updated = isArray(obj) ? obj.slice() : assign({}, obj); + + if (index + 1 === oldPath.length) { + var newKey = newPath[index]; // $FlowFixMe[incompatible-use] number or string is fine here + + updated[newKey] = updated[oldKey]; + + if (isArray(updated)) { + updated.splice(oldKey, 1); + } else { + delete updated[oldKey]; + } + } else { + // $FlowFixMe[incompatible-use] number or string is fine here + updated[oldKey] = copyWithRenameImpl( + // $FlowFixMe[incompatible-use] number or string is fine here + obj[oldKey], + oldPath, + newPath, + index + 1 + ); } - }, - useReducer: function (reducer, initialArg, init) { - currentHookNameInDev = "useReducer"; - updateHookTypesDev(); - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = InvalidNestedHooksDispatcherOnMountInDEV; - try { - return mountReducer(reducer, initialArg, init); - } finally { - ReactSharedInternals.H = prevDispatcher; + + return updated; + }; + + var copyWithRename = function (obj, oldPath, newPath) { + if (oldPath.length !== newPath.length) { + warn("copyWithRename() expects paths of the same length"); + + return; + } else { + for (var i = 0; i < newPath.length - 1; i++) { + if (oldPath[i] !== newPath[i]) { + warn( + "copyWithRename() expects paths to be the same except for the deepest key" + ); + + return; + } + } } - }, - useRef: function (initialValue) { - currentHookNameInDev = "useRef"; - updateHookTypesDev(); - return mountRef(initialValue); - }, - useState: function (initialState) { - currentHookNameInDev = "useState"; - updateHookTypesDev(); - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = InvalidNestedHooksDispatcherOnMountInDEV; - try { - return mountState(initialState); - } finally { - ReactSharedInternals.H = prevDispatcher; + + return copyWithRenameImpl(obj, oldPath, newPath, 0); + }; + + var copyWithSetImpl = function (obj, path, index, value) { + if (index >= path.length) { + return value; } - }, - useDebugValue: function () { - currentHookNameInDev = "useDebugValue"; - updateHookTypesDev(); - }, - useDeferredValue: function (value, initialValue) { - currentHookNameInDev = "useDeferredValue"; - updateHookTypesDev(); - return mountDeferredValue(value, initialValue); - }, - useTransition: function () { - currentHookNameInDev = "useTransition"; - updateHookTypesDev(); - return mountTransition(); - }, - useSyncExternalStore: function (subscribe, getSnapshot) { - currentHookNameInDev = "useSyncExternalStore"; - updateHookTypesDev(); - return mountSyncExternalStore(subscribe, getSnapshot); - }, - useId: function () { - currentHookNameInDev = "useId"; - updateHookTypesDev(); - return mountId(); - }, - useCacheRefresh: function () { - currentHookNameInDev = "useCacheRefresh"; - updateHookTypesDev(); - return mountRefresh(); - } - }; - HooksDispatcherOnMountWithHookTypesInDEV.useMemoCache = useMemoCache; - HooksDispatcherOnMountWithHookTypesInDEV.useHostTransitionStatus = - useHostTransitionStatus; - HooksDispatcherOnMountWithHookTypesInDEV.useFormState = function ( - action, - initialState - ) { - currentHookNameInDev = "useFormState"; - updateHookTypesDev(); - warnOnUseFormStateInDev(); - return mountActionState(action, initialState); - }; - HooksDispatcherOnMountWithHookTypesInDEV.useActionState = function ( - action, - initialState - ) { - currentHookNameInDev = "useActionState"; - updateHookTypesDev(); - return mountActionState(action, initialState); - }; - HooksDispatcherOnMountWithHookTypesInDEV.useOptimistic = function ( - passthrough - ) { - currentHookNameInDev = "useOptimistic"; - updateHookTypesDev(); - return mountOptimistic(passthrough); - }; - HooksDispatcherOnUpdateInDEV = { - readContext: function (context) { - return readContext(context); - }, - use: use, - useCallback: function (callback, deps) { - currentHookNameInDev = "useCallback"; - updateHookTypesDev(); - return updateCallback(callback, deps); - }, - useContext: function (context) { - currentHookNameInDev = "useContext"; - updateHookTypesDev(); - return readContext(context); - }, - useEffect: function (create, deps) { - currentHookNameInDev = "useEffect"; - updateHookTypesDev(); - updateEffectImpl(2048, Passive, create, deps); - }, - useImperativeHandle: function (ref, create, deps) { - currentHookNameInDev = "useImperativeHandle"; - updateHookTypesDev(); - return updateImperativeHandle(ref, create, deps); - }, - useInsertionEffect: function (create, deps) { - currentHookNameInDev = "useInsertionEffect"; - updateHookTypesDev(); - return updateEffectImpl(4, Insertion, create, deps); - }, - useLayoutEffect: function (create, deps) { - currentHookNameInDev = "useLayoutEffect"; - updateHookTypesDev(); - return updateEffectImpl(4, Layout, create, deps); - }, - useMemo: function (create, deps) { - currentHookNameInDev = "useMemo"; - updateHookTypesDev(); - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = InvalidNestedHooksDispatcherOnUpdateInDEV; - try { - return updateMemo(create, deps); - } finally { - ReactSharedInternals.H = prevDispatcher; + + var key = path[index]; + var updated = isArray(obj) ? obj.slice() : assign({}, obj); // $FlowFixMe[incompatible-use] number or string is fine here + + updated[key] = copyWithSetImpl(obj[key], path, index + 1, value); + return updated; + }; + + var copyWithSet = function (obj, path, value) { + return copyWithSetImpl(obj, path, 0, value); + }; + + var findHook = function (fiber, id) { + // For now, the "id" of stateful hooks is just the stateful hook index. + // This may change in the future with e.g. nested hooks. + var currentHook = fiber.memoizedState; + + while (currentHook !== null && id > 0) { + currentHook = currentHook.next; + id--; } - }, - useReducer: function (reducer, initialArg, init) { - currentHookNameInDev = "useReducer"; - updateHookTypesDev(); - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = InvalidNestedHooksDispatcherOnUpdateInDEV; - try { - return updateReducer(reducer, initialArg, init); - } finally { - ReactSharedInternals.H = prevDispatcher; + + return currentHook; + }; // Support DevTools editable values for useState and useReducer. + + overrideHookState = function (fiber, id, path, value) { + var hook = findHook(fiber, id); + + if (hook !== null) { + var newState = copyWithSet(hook.memoizedState, path, value); + hook.memoizedState = newState; + hook.baseState = newState; // We aren't actually adding an update to the queue, + // because there is no update we can add for useReducer hooks that won't trigger an error. + // (There's no appropriate action type for DevTools overrides.) + // As a result though, React will see the scheduled update as a noop and bailout. + // Shallow cloning props works as a workaround for now to bypass the bailout check. + + fiber.memoizedProps = assign({}, fiber.memoizedProps); + var root = enqueueConcurrentRenderForLane(fiber, SyncLane); + + if (root !== null) { + scheduleUpdateOnFiber(root, fiber, SyncLane); + } } - }, - useRef: function () { - currentHookNameInDev = "useRef"; - updateHookTypesDev(); - return updateWorkInProgressHook().memoizedState; - }, - useState: function () { - currentHookNameInDev = "useState"; - updateHookTypesDev(); - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = InvalidNestedHooksDispatcherOnUpdateInDEV; - try { - return updateReducer(basicStateReducer); - } finally { - ReactSharedInternals.H = prevDispatcher; + }; + + overrideHookStateDeletePath = function (fiber, id, path) { + var hook = findHook(fiber, id); + + if (hook !== null) { + var newState = copyWithDelete(hook.memoizedState, path); + hook.memoizedState = newState; + hook.baseState = newState; // We aren't actually adding an update to the queue, + // because there is no update we can add for useReducer hooks that won't trigger an error. + // (There's no appropriate action type for DevTools overrides.) + // As a result though, React will see the scheduled update as a noop and bailout. + // Shallow cloning props works as a workaround for now to bypass the bailout check. + + fiber.memoizedProps = assign({}, fiber.memoizedProps); + var root = enqueueConcurrentRenderForLane(fiber, SyncLane); + + if (root !== null) { + scheduleUpdateOnFiber(root, fiber, SyncLane); + } } - }, - useDebugValue: function () { - currentHookNameInDev = "useDebugValue"; - updateHookTypesDev(); - }, - useDeferredValue: function (value, initialValue) { - currentHookNameInDev = "useDeferredValue"; - updateHookTypesDev(); - return updateDeferredValue(value, initialValue); - }, - useTransition: function () { - currentHookNameInDev = "useTransition"; - updateHookTypesDev(); - return updateTransition(); - }, - useSyncExternalStore: function (subscribe, getSnapshot) { - currentHookNameInDev = "useSyncExternalStore"; - updateHookTypesDev(); - return updateSyncExternalStore(subscribe, getSnapshot); - }, - useId: function () { - currentHookNameInDev = "useId"; - updateHookTypesDev(); - return updateWorkInProgressHook().memoizedState; - }, - useCacheRefresh: function () { - currentHookNameInDev = "useCacheRefresh"; - updateHookTypesDev(); - return updateWorkInProgressHook().memoizedState; - } - }; - HooksDispatcherOnUpdateInDEV.useMemoCache = useMemoCache; - HooksDispatcherOnUpdateInDEV.useHostTransitionStatus = - useHostTransitionStatus; - HooksDispatcherOnUpdateInDEV.useFormState = function (action) { - currentHookNameInDev = "useFormState"; - updateHookTypesDev(); - warnOnUseFormStateInDev(); - return updateActionState(action); - }; - HooksDispatcherOnUpdateInDEV.useActionState = function (action) { - currentHookNameInDev = "useActionState"; - updateHookTypesDev(); - return updateActionState(action); - }; - HooksDispatcherOnUpdateInDEV.useOptimistic = function ( - passthrough, - reducer - ) { - currentHookNameInDev = "useOptimistic"; - updateHookTypesDev(); - return updateOptimistic(passthrough, reducer); - }; - HooksDispatcherOnRerenderInDEV = { - readContext: function (context) { - return readContext(context); - }, - use: use, - useCallback: function (callback, deps) { - currentHookNameInDev = "useCallback"; - updateHookTypesDev(); - return updateCallback(callback, deps); - }, - useContext: function (context) { - currentHookNameInDev = "useContext"; - updateHookTypesDev(); - return readContext(context); - }, - useEffect: function (create, deps) { - currentHookNameInDev = "useEffect"; - updateHookTypesDev(); - updateEffectImpl(2048, Passive, create, deps); - }, - useImperativeHandle: function (ref, create, deps) { - currentHookNameInDev = "useImperativeHandle"; - updateHookTypesDev(); - return updateImperativeHandle(ref, create, deps); - }, - useInsertionEffect: function (create, deps) { - currentHookNameInDev = "useInsertionEffect"; - updateHookTypesDev(); - return updateEffectImpl(4, Insertion, create, deps); - }, - useLayoutEffect: function (create, deps) { - currentHookNameInDev = "useLayoutEffect"; - updateHookTypesDev(); - return updateEffectImpl(4, Layout, create, deps); - }, - useMemo: function (create, deps) { - currentHookNameInDev = "useMemo"; - updateHookTypesDev(); - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = InvalidNestedHooksDispatcherOnRerenderInDEV; - try { - return updateMemo(create, deps); - } finally { - ReactSharedInternals.H = prevDispatcher; + }; + + overrideHookStateRenamePath = function (fiber, id, oldPath, newPath) { + var hook = findHook(fiber, id); + + if (hook !== null) { + var newState = copyWithRename(hook.memoizedState, oldPath, newPath); + hook.memoizedState = newState; + hook.baseState = newState; // We aren't actually adding an update to the queue, + // because there is no update we can add for useReducer hooks that won't trigger an error. + // (There's no appropriate action type for DevTools overrides.) + // As a result though, React will see the scheduled update as a noop and bailout. + // Shallow cloning props works as a workaround for now to bypass the bailout check. + + fiber.memoizedProps = assign({}, fiber.memoizedProps); + var root = enqueueConcurrentRenderForLane(fiber, SyncLane); + + if (root !== null) { + scheduleUpdateOnFiber(root, fiber, SyncLane); + } } - }, - useReducer: function (reducer, initialArg, init) { - currentHookNameInDev = "useReducer"; - updateHookTypesDev(); - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = InvalidNestedHooksDispatcherOnRerenderInDEV; - try { - return rerenderReducer(reducer, initialArg, init); - } finally { - ReactSharedInternals.H = prevDispatcher; + }; // Support DevTools props for function components, forwardRef, memo, host components, etc. + + overrideProps = function (fiber, path, value) { + fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value); + + if (fiber.alternate) { + fiber.alternate.pendingProps = fiber.pendingProps; } - }, - useRef: function () { - currentHookNameInDev = "useRef"; - updateHookTypesDev(); - return updateWorkInProgressHook().memoizedState; - }, - useState: function () { - currentHookNameInDev = "useState"; - updateHookTypesDev(); - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = InvalidNestedHooksDispatcherOnRerenderInDEV; - try { - return rerenderReducer(basicStateReducer); - } finally { - ReactSharedInternals.H = prevDispatcher; + + var root = enqueueConcurrentRenderForLane(fiber, SyncLane); + + if (root !== null) { + scheduleUpdateOnFiber(root, fiber, SyncLane); } - }, - useDebugValue: function () { - currentHookNameInDev = "useDebugValue"; - updateHookTypesDev(); - }, - useDeferredValue: function (value, initialValue) { - currentHookNameInDev = "useDeferredValue"; - updateHookTypesDev(); - return rerenderDeferredValue(value, initialValue); - }, - useTransition: function () { - currentHookNameInDev = "useTransition"; - updateHookTypesDev(); - return rerenderTransition(); - }, - useSyncExternalStore: function (subscribe, getSnapshot) { - currentHookNameInDev = "useSyncExternalStore"; - updateHookTypesDev(); - return updateSyncExternalStore(subscribe, getSnapshot); - }, - useId: function () { - currentHookNameInDev = "useId"; - updateHookTypesDev(); - return updateWorkInProgressHook().memoizedState; - }, - useCacheRefresh: function () { - currentHookNameInDev = "useCacheRefresh"; - updateHookTypesDev(); - return updateWorkInProgressHook().memoizedState; - } - }; - HooksDispatcherOnRerenderInDEV.useMemoCache = useMemoCache; - HooksDispatcherOnRerenderInDEV.useHostTransitionStatus = - useHostTransitionStatus; - HooksDispatcherOnRerenderInDEV.useFormState = function (action) { - currentHookNameInDev = "useFormState"; - updateHookTypesDev(); - warnOnUseFormStateInDev(); - return rerenderActionState(action); - }; - HooksDispatcherOnRerenderInDEV.useActionState = function (action) { - currentHookNameInDev = "useActionState"; - updateHookTypesDev(); - return rerenderActionState(action); - }; - HooksDispatcherOnRerenderInDEV.useOptimistic = function ( - passthrough, - reducer - ) { - currentHookNameInDev = "useOptimistic"; - updateHookTypesDev(); - return rerenderOptimistic(passthrough, reducer); - }; - InvalidNestedHooksDispatcherOnMountInDEV = { - readContext: function (context) { - warnInvalidContextAccess(); - return readContext(context); - }, - use: function (usable) { - warnInvalidHookAccess(); - return use(usable); - }, - useCallback: function (callback, deps) { - currentHookNameInDev = "useCallback"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountCallback(callback, deps); - }, - useContext: function (context) { - currentHookNameInDev = "useContext"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return readContext(context); - }, - useEffect: function (create, deps) { - currentHookNameInDev = "useEffect"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountEffect(create, deps); - }, - useImperativeHandle: function (ref, create, deps) { - currentHookNameInDev = "useImperativeHandle"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountImperativeHandle(ref, create, deps); - }, - useInsertionEffect: function (create, deps) { - currentHookNameInDev = "useInsertionEffect"; - warnInvalidHookAccess(); - mountHookTypesDev(); - mountEffectImpl(4, Insertion, create, deps); - }, - useLayoutEffect: function (create, deps) { - currentHookNameInDev = "useLayoutEffect"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountLayoutEffect(create, deps); - }, - useMemo: function (create, deps) { - currentHookNameInDev = "useMemo"; - warnInvalidHookAccess(); - mountHookTypesDev(); - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = InvalidNestedHooksDispatcherOnMountInDEV; - try { - return mountMemo(create, deps); - } finally { - ReactSharedInternals.H = prevDispatcher; + }; + + overridePropsDeletePath = function (fiber, path) { + fiber.pendingProps = copyWithDelete(fiber.memoizedProps, path); + + if (fiber.alternate) { + fiber.alternate.pendingProps = fiber.pendingProps; } - }, - useReducer: function (reducer, initialArg, init) { - currentHookNameInDev = "useReducer"; - warnInvalidHookAccess(); - mountHookTypesDev(); - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = InvalidNestedHooksDispatcherOnMountInDEV; - try { - return mountReducer(reducer, initialArg, init); - } finally { - ReactSharedInternals.H = prevDispatcher; + + var root = enqueueConcurrentRenderForLane(fiber, SyncLane); + + if (root !== null) { + scheduleUpdateOnFiber(root, fiber, SyncLane); } - }, - useRef: function (initialValue) { - currentHookNameInDev = "useRef"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountRef(initialValue); - }, - useState: function (initialState) { - currentHookNameInDev = "useState"; - warnInvalidHookAccess(); - mountHookTypesDev(); - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = InvalidNestedHooksDispatcherOnMountInDEV; - try { - return mountState(initialState); - } finally { - ReactSharedInternals.H = prevDispatcher; + }; + + overridePropsRenamePath = function (fiber, oldPath, newPath) { + fiber.pendingProps = copyWithRename( + fiber.memoizedProps, + oldPath, + newPath + ); + + if (fiber.alternate) { + fiber.alternate.pendingProps = fiber.pendingProps; } - }, - useDebugValue: function () { - currentHookNameInDev = "useDebugValue"; - warnInvalidHookAccess(); - mountHookTypesDev(); - }, - useDeferredValue: function (value, initialValue) { - currentHookNameInDev = "useDeferredValue"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountDeferredValue(value, initialValue); - }, - useTransition: function () { - currentHookNameInDev = "useTransition"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountTransition(); - }, - useSyncExternalStore: function (subscribe, getSnapshot) { - currentHookNameInDev = "useSyncExternalStore"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountSyncExternalStore(subscribe, getSnapshot); - }, - useId: function () { - currentHookNameInDev = "useId"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountId(); - }, - useCacheRefresh: function () { - currentHookNameInDev = "useCacheRefresh"; - mountHookTypesDev(); - return mountRefresh(); - }, - useMemoCache: function (size) { - warnInvalidHookAccess(); - return useMemoCache(size); + + var root = enqueueConcurrentRenderForLane(fiber, SyncLane); + + if (root !== null) { + scheduleUpdateOnFiber(root, fiber, SyncLane); + } + }; + + scheduleUpdate = function (fiber) { + var root = enqueueConcurrentRenderForLane(fiber, SyncLane); + + if (root !== null) { + scheduleUpdateOnFiber(root, fiber, SyncLane); + } + }; + + setErrorHandler = function (newShouldErrorImpl) { + shouldErrorImpl = newShouldErrorImpl; + }; + + setSuspenseHandler = function (newShouldSuspendImpl) { + shouldSuspendImpl = newShouldSuspendImpl; + }; + } + + function findHostInstanceByFiber(fiber) { + var hostFiber = findCurrentHostFiber(fiber); + + if (hostFiber === null) { + return null; } - }; - InvalidNestedHooksDispatcherOnMountInDEV.useHostTransitionStatus = - useHostTransitionStatus; - InvalidNestedHooksDispatcherOnMountInDEV.useFormState = function ( - action, - initialState - ) { - currentHookNameInDev = "useFormState"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountActionState(action, initialState); - }; - InvalidNestedHooksDispatcherOnMountInDEV.useActionState = function ( - action, - initialState - ) { - currentHookNameInDev = "useActionState"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountActionState(action, initialState); - }; - InvalidNestedHooksDispatcherOnMountInDEV.useOptimistic = function ( - passthrough - ) { - currentHookNameInDev = "useOptimistic"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountOptimistic(passthrough); - }; - InvalidNestedHooksDispatcherOnUpdateInDEV = { - readContext: function (context) { - warnInvalidContextAccess(); - return readContext(context); - }, - use: function (usable) { - warnInvalidHookAccess(); - return use(usable); - }, - useCallback: function (callback, deps) { - currentHookNameInDev = "useCallback"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateCallback(callback, deps); - }, - useContext: function (context) { - currentHookNameInDev = "useContext"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return readContext(context); - }, - useEffect: function (create, deps) { - currentHookNameInDev = "useEffect"; - warnInvalidHookAccess(); - updateHookTypesDev(); - updateEffectImpl(2048, Passive, create, deps); - }, - useImperativeHandle: function (ref, create, deps) { - currentHookNameInDev = "useImperativeHandle"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateImperativeHandle(ref, create, deps); - }, - useInsertionEffect: function (create, deps) { - currentHookNameInDev = "useInsertionEffect"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateEffectImpl(4, Insertion, create, deps); - }, - useLayoutEffect: function (create, deps) { - currentHookNameInDev = "useLayoutEffect"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateEffectImpl(4, Layout, create, deps); - }, - useMemo: function (create, deps) { - currentHookNameInDev = "useMemo"; - warnInvalidHookAccess(); - updateHookTypesDev(); - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = InvalidNestedHooksDispatcherOnUpdateInDEV; - try { - return updateMemo(create, deps); - } finally { - ReactSharedInternals.H = prevDispatcher; + + return hostFiber.stateNode; + } + + function emptyFindFiberByHostInstance(instance) { + return null; + } + + function getCurrentFiberForDevTools() { + return current; + } + + function injectIntoDevTools(devToolsConfig) { + var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance; + var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; + return injectInternals({ + bundleType: devToolsConfig.bundleType, + version: devToolsConfig.version, + rendererPackageName: devToolsConfig.rendererPackageName, + rendererConfig: devToolsConfig.rendererConfig, + overrideHookState: overrideHookState, + overrideHookStateDeletePath: overrideHookStateDeletePath, + overrideHookStateRenamePath: overrideHookStateRenamePath, + overrideProps: overrideProps, + overridePropsDeletePath: overridePropsDeletePath, + overridePropsRenamePath: overridePropsRenamePath, + setErrorHandler: setErrorHandler, + setSuspenseHandler: setSuspenseHandler, + scheduleUpdate: scheduleUpdate, + currentDispatcherRef: ReactCurrentDispatcher, + findHostInstanceByFiber: findHostInstanceByFiber, + findFiberByHostInstance: + findFiberByHostInstance || emptyFindFiberByHostInstance, + // React Refresh + findHostInstancesForRefresh: findHostInstancesForRefresh, + scheduleRefresh: scheduleRefresh, + scheduleRoot: scheduleRoot, + setRefreshHandler: setRefreshHandler, + // Enables DevTools to append owner stacks to error messages in DEV mode. + getCurrentFiber: getCurrentFiberForDevTools, + // Enables DevTools to detect reconciler version rather than renderer version + // which may not match for third party renderers. + reconcilerVersion: ReactVersion + }); + } + + var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner; + function findHostInstance_DEPRECATED(componentOrHandle) { + { + var owner = ReactCurrentOwner.current; + + if (owner !== null && owner.stateNode !== null) { + if (!owner.stateNode._warnedAboutRefsInRender) { + error( + "%s is accessing findNodeHandle inside its render(). " + + "render() should be a pure function of props and state. It should " + + "never access something that requires stale data from the previous " + + "render, such as refs. Move this logic to componentDidMount and " + + "componentDidUpdate instead.", + getComponentNameFromType(owner.type) || "A component" + ); + } + + owner.stateNode._warnedAboutRefsInRender = true; } - }, - useReducer: function (reducer, initialArg, init) { - currentHookNameInDev = "useReducer"; - warnInvalidHookAccess(); - updateHookTypesDev(); - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = InvalidNestedHooksDispatcherOnUpdateInDEV; - try { - return updateReducer(reducer, initialArg, init); - } finally { - ReactSharedInternals.H = prevDispatcher; + } + + if (componentOrHandle == null) { + return null; + } // For compatibility with Fabric instances + + if ( + componentOrHandle.canonical && + componentOrHandle.canonical.publicInstance + ) { + // $FlowExpectedError[incompatible-return] Can't refine componentOrHandle as a Fabric instance + return componentOrHandle.canonical.publicInstance; + } // For compatibility with legacy renderer instances + + if (componentOrHandle._nativeTag) { + // $FlowFixMe[incompatible-exact] Necessary when running Flow on Fabric + // $FlowFixMe[incompatible-return] + return componentOrHandle; + } + + var hostInstance; + + { + hostInstance = findHostInstanceWithWarning( + componentOrHandle, + "findHostInstance_DEPRECATED" + ); + } // findHostInstance handles legacy vs. Fabric differences correctly + // $FlowFixMe[incompatible-exact] we need to fix the definition of `HostComponent` to use NativeMethods as an interface, not as a type. + // $FlowFixMe[incompatible-return] + + return hostInstance; + } + function findNodeHandle(componentOrHandle) { + { + var owner = ReactCurrentOwner.current; + + if (owner !== null && owner.stateNode !== null) { + if (!owner.stateNode._warnedAboutRefsInRender) { + error( + "%s is accessing findNodeHandle inside its render(). " + + "render() should be a pure function of props and state. It should " + + "never access something that requires stale data from the previous " + + "render, such as refs. Move this logic to componentDidMount and " + + "componentDidUpdate instead.", + getComponentNameFromType(owner.type) || "A component" + ); + } + + owner.stateNode._warnedAboutRefsInRender = true; } - }, - useRef: function () { - currentHookNameInDev = "useRef"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateWorkInProgressHook().memoizedState; - }, - useState: function () { - currentHookNameInDev = "useState"; - warnInvalidHookAccess(); - updateHookTypesDev(); - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = InvalidNestedHooksDispatcherOnUpdateInDEV; - try { - return updateReducer(basicStateReducer); - } finally { - ReactSharedInternals.H = prevDispatcher; + } + + if (componentOrHandle == null) { + return null; + } + + if (typeof componentOrHandle === "number") { + // Already a node handle + return componentOrHandle; + } // For compatibility with legacy renderer instances + + if (componentOrHandle._nativeTag) { + return componentOrHandle._nativeTag; + } // For compatibility with Fabric instances + + if ( + componentOrHandle.canonical != null && + componentOrHandle.canonical.nativeTag != null + ) { + return componentOrHandle.canonical.nativeTag; + } // For compatibility with Fabric public instances + + var nativeTag = + ReactNativePrivateInterface.getNativeTagFromPublicInstance( + componentOrHandle + ); + + if (nativeTag) { + return nativeTag; + } + + var hostInstance; + + { + hostInstance = findHostInstanceWithWarning( + componentOrHandle, + "findNodeHandle" + ); + } + + if (hostInstance == null) { + // $FlowFixMe[incompatible-return] Flow limitation in refining an opaque type + return hostInstance; + } + + if (hostInstance._nativeTag != null) { + // $FlowFixMe[incompatible-return] For compatibility with legacy renderer instances + return hostInstance._nativeTag; + } // $FlowFixMe[incompatible-call] Necessary when running Flow on the legacy renderer + + return ReactNativePrivateInterface.getNativeTagFromPublicInstance( + hostInstance + ); + } + function dispatchCommand(handle, command, args) { + var nativeTag = + handle._nativeTag != null + ? handle._nativeTag + : ReactNativePrivateInterface.getNativeTagFromPublicInstance(handle); + + if (nativeTag == null) { + { + error( + "dispatchCommand was called with a ref that isn't a " + + "native component. Use React.forwardRef to get access to the underlying native component" + ); } - }, - useDebugValue: function () { - currentHookNameInDev = "useDebugValue"; - warnInvalidHookAccess(); - updateHookTypesDev(); - }, - useDeferredValue: function (value, initialValue) { - currentHookNameInDev = "useDeferredValue"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateDeferredValue(value, initialValue); - }, - useTransition: function () { - currentHookNameInDev = "useTransition"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateTransition(); - }, - useSyncExternalStore: function (subscribe, getSnapshot) { - currentHookNameInDev = "useSyncExternalStore"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateSyncExternalStore(subscribe, getSnapshot); - }, - useId: function () { - currentHookNameInDev = "useId"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateWorkInProgressHook().memoizedState; - }, - useCacheRefresh: function () { - currentHookNameInDev = "useCacheRefresh"; - updateHookTypesDev(); - return updateWorkInProgressHook().memoizedState; - }, - useMemoCache: function (size) { - warnInvalidHookAccess(); - return useMemoCache(size); + + return; } - }; - InvalidNestedHooksDispatcherOnUpdateInDEV.useHostTransitionStatus = - useHostTransitionStatus; - InvalidNestedHooksDispatcherOnUpdateInDEV.useFormState = function (action) { - currentHookNameInDev = "useFormState"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateActionState(action); - }; - InvalidNestedHooksDispatcherOnUpdateInDEV.useActionState = function ( - action - ) { - currentHookNameInDev = "useActionState"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateActionState(action); - }; - InvalidNestedHooksDispatcherOnUpdateInDEV.useOptimistic = function ( - passthrough, - reducer - ) { - currentHookNameInDev = "useOptimistic"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateOptimistic(passthrough, reducer); - }; - InvalidNestedHooksDispatcherOnRerenderInDEV = { - readContext: function (context) { - warnInvalidContextAccess(); - return readContext(context); - }, - use: function (usable) { - warnInvalidHookAccess(); - return use(usable); - }, - useCallback: function (callback, deps) { - currentHookNameInDev = "useCallback"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateCallback(callback, deps); - }, - useContext: function (context) { - currentHookNameInDev = "useContext"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return readContext(context); - }, - useEffect: function (create, deps) { - currentHookNameInDev = "useEffect"; - warnInvalidHookAccess(); - updateHookTypesDev(); - updateEffectImpl(2048, Passive, create, deps); - }, - useImperativeHandle: function (ref, create, deps) { - currentHookNameInDev = "useImperativeHandle"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateImperativeHandle(ref, create, deps); - }, - useInsertionEffect: function (create, deps) { - currentHookNameInDev = "useInsertionEffect"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateEffectImpl(4, Insertion, create, deps); - }, - useLayoutEffect: function (create, deps) { - currentHookNameInDev = "useLayoutEffect"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateEffectImpl(4, Layout, create, deps); - }, - useMemo: function (create, deps) { - currentHookNameInDev = "useMemo"; - warnInvalidHookAccess(); - updateHookTypesDev(); - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = InvalidNestedHooksDispatcherOnUpdateInDEV; - try { - return updateMemo(create, deps); - } finally { - ReactSharedInternals.H = prevDispatcher; + + var node = ReactNativePrivateInterface.getNodeFromPublicInstance(handle); + + if (node != null) { + nativeFabricUIManager.dispatchCommand(node, command, args); + } else { + ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( + nativeTag, + command, + args + ); + } + } + function sendAccessibilityEvent(handle, eventType) { + var nativeTag = + handle._nativeTag != null + ? handle._nativeTag + : ReactNativePrivateInterface.getNativeTagFromPublicInstance(handle); + + if (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" + ); } - }, - useReducer: function (reducer, initialArg, init) { - currentHookNameInDev = "useReducer"; - warnInvalidHookAccess(); - updateHookTypesDev(); - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = InvalidNestedHooksDispatcherOnUpdateInDEV; - try { - return rerenderReducer(reducer, initialArg, init); - } finally { - ReactSharedInternals.H = prevDispatcher; + + return; + } + + var node = ReactNativePrivateInterface.getNodeFromPublicInstance(handle); + + if (node != null) { + nativeFabricUIManager.sendAccessibilityEvent(node, eventType); + } else { + ReactNativePrivateInterface.legacySendAccessibilityEvent( + nativeTag, + eventType + ); + } + } + function getNodeFromInternalInstanceHandle(internalInstanceHandle) { + return ( + // $FlowExpectedError[incompatible-return] internalInstanceHandle is opaque but we need to make an exception here. + internalInstanceHandle && // $FlowExpectedError[incompatible-return] + internalInstanceHandle.stateNode && // $FlowExpectedError[incompatible-use] + internalInstanceHandle.stateNode.node + ); + } // Should have been PublicInstance from ReactFiberConfigFabric + // Should have been PublicInstance from ReactFiberConfigNative + // Remove this once Paper is no longer supported and DOM Node API are enabled by default in RN. + + function isChildPublicInstance(parentInstance, childInstance) { + { + // Paper + if ( + // $FlowExpectedError[incompatible-type] + // $FlowExpectedError[prop-missing] Don't check via `instanceof ReactNativeFiberHostComponent`, so it won't be leaked to Fabric. + parentInstance._internalFiberInstanceHandleDEV && // $FlowExpectedError[incompatible-type] + // $FlowExpectedError[prop-missing] Don't check via `instanceof ReactNativeFiberHostComponent`, so it won't be leaked to Fabric. + childInstance._internalFiberInstanceHandleDEV + ) { + return doesFiberContain( + // $FlowExpectedError[incompatible-call] + parentInstance._internalFiberInstanceHandleDEV, // $FlowExpectedError[incompatible-call] + childInstance._internalFiberInstanceHandleDEV + ); + } + + var parentInternalInstanceHandle = // $FlowExpectedError[incompatible-call] Type for parentInstance should have been PublicInstance from ReactFiberConfigFabric. + ReactNativePrivateInterface.getInternalInstanceHandleFromPublicInstance( + parentInstance + ); + var childInternalInstanceHandle = // $FlowExpectedError[incompatible-call] Type for childInstance should have been PublicInstance from ReactFiberConfigFabric. + ReactNativePrivateInterface.getInternalInstanceHandleFromPublicInstance( + childInstance + ); // Fabric + + if ( + parentInternalInstanceHandle != null && + childInternalInstanceHandle != null + ) { + return doesFiberContain( + parentInternalInstanceHandle, + childInternalInstanceHandle + ); + } // Means that one instance is from Fabric and other is from Paper. + + return false; + } + } + + var emptyObject = {}; + + { + Object.freeze(emptyObject); + } // $FlowFixMe[missing-local-annot] + + function createHierarchy(fiberHierarchy) { + return fiberHierarchy.map(function (fiber) { + return { + name: getComponentNameFromType(fiber.type), + getInspectorData: function (findNodeHandle) { + return { + props: getHostProps(fiber), + measure: function (callback) { + // If this is Fabric, we'll find a shadow node and use that to measure. + var hostFiber = findCurrentHostFiber(fiber); + var node = + hostFiber != null && + hostFiber.stateNode !== null && + hostFiber.stateNode.node; + + if (node) { + nativeFabricUIManager.measure(node, callback); + } else { + return ReactNativePrivateInterface.UIManager.measure( + getHostNode(fiber, findNodeHandle), + callback + ); + } + } + }; + } + }; + }); + } // $FlowFixMe[missing-local-annot] + + function getHostNode(fiber, findNodeHandle) { + { + var hostNode; // look for children first for the hostNode + // as composite fibers do not have a hostNode + + while (fiber) { + if (fiber.stateNode !== null && fiber.tag === HostComponent) { + hostNode = findNodeHandle(fiber.stateNode); + } + + if (hostNode) { + return hostNode; + } + + fiber = fiber.child; } - }, - useRef: function () { - currentHookNameInDev = "useRef"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateWorkInProgressHook().memoizedState; - }, - useState: function () { - currentHookNameInDev = "useState"; - warnInvalidHookAccess(); - updateHookTypesDev(); - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = InvalidNestedHooksDispatcherOnUpdateInDEV; - try { - return rerenderReducer(basicStateReducer); - } finally { - ReactSharedInternals.H = prevDispatcher; + + return null; + } + } // $FlowFixMe[missing-local-annot] + + function getHostProps(fiber) { + var host = findCurrentHostFiber(fiber); + + if (host) { + return host.memoizedProps || emptyObject; + } + + return emptyObject; + } + + function getInspectorDataForInstance(closestInstance) { + { + // Handle case where user clicks outside of ReactNative + if (!closestInstance) { + return { + hierarchy: [], + props: emptyObject, + selectedIndex: null, + componentStack: "" + }; } - }, - useDebugValue: function () { - currentHookNameInDev = "useDebugValue"; - warnInvalidHookAccess(); - updateHookTypesDev(); - }, - useDeferredValue: function (value, initialValue) { - currentHookNameInDev = "useDeferredValue"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return rerenderDeferredValue(value, initialValue); - }, - useTransition: function () { - currentHookNameInDev = "useTransition"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return rerenderTransition(); - }, - useSyncExternalStore: function (subscribe, getSnapshot) { - currentHookNameInDev = "useSyncExternalStore"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateSyncExternalStore(subscribe, getSnapshot); - }, - useId: function () { - currentHookNameInDev = "useId"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateWorkInProgressHook().memoizedState; - }, - useCacheRefresh: function () { - currentHookNameInDev = "useCacheRefresh"; - updateHookTypesDev(); - return updateWorkInProgressHook().memoizedState; - }, - useMemoCache: function (size) { - warnInvalidHookAccess(); - return useMemoCache(size); + + var fiber = findCurrentFiberUsingSlowPath(closestInstance); + var fiberHierarchy = getOwnerHierarchy(fiber); + var instance = lastNonHostInstance(fiberHierarchy); + var hierarchy = createHierarchy(fiberHierarchy); + var props = getHostProps(instance); + var selectedIndex = fiberHierarchy.indexOf(instance); + var componentStack = + fiber !== null ? getStackByFiberInDevAndProd(fiber) : ""; + return { + closestInstance: instance, + hierarchy: hierarchy, + props: props, + selectedIndex: selectedIndex, + componentStack: componentStack + }; } - }; - InvalidNestedHooksDispatcherOnRerenderInDEV.useHostTransitionStatus = - useHostTransitionStatus; - InvalidNestedHooksDispatcherOnRerenderInDEV.useFormState = function ( - action - ) { - currentHookNameInDev = "useFormState"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return rerenderActionState(action); - }; - InvalidNestedHooksDispatcherOnRerenderInDEV.useActionState = function ( - action - ) { - currentHookNameInDev = "useActionState"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return rerenderActionState(action); - }; - InvalidNestedHooksDispatcherOnRerenderInDEV.useOptimistic = function ( - passthrough, - reducer - ) { - currentHookNameInDev = "useOptimistic"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return rerenderOptimistic(passthrough, reducer); - }; - var now = Scheduler.unstable_now, - commitTime = 0, - layoutEffectStartTime = -1, - profilerStartTime = -1, - passiveEffectStartTime = -1, - currentUpdateIsNested = !1, - nestedUpdateScheduled = !1, - fakeInternalInstance = {}; - var didWarnAboutStateAssignmentForComponent = new Set(); - var didWarnAboutUninitializedState = new Set(); - var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set(); - var didWarnAboutLegacyLifecyclesAndDerivedState = new Set(); - var didWarnAboutDirectlyAssigningPropsToState = new Set(); - var didWarnAboutUndefinedDerivedState = new Set(); - var didWarnAboutInvalidateContextType = new Set(); - var didWarnOnInvalidCallback = new Set(); - Object.freeze(fakeInternalInstance); - var classComponentUpdater = { - isMounted: function (component) { - var owner = current; - if (null !== owner && isRendering && 1 === owner.tag) { - var instance = owner.stateNode; - instance._warnedAboutRefsInRender || - error$jscomp$0( - "%s is accessing isMounted inside its render() function. render() should be a pure function of props and state. It should never access something that requires stale data from the previous render, such as refs. Move this logic to componentDidMount and componentDidUpdate instead.", - getComponentNameFromFiber(owner) || "A component" - ); - instance._warnedAboutRefsInRender = !0; - } - return (component = component._reactInternals) - ? getNearestMountedFiber(component) === component - : !1; - }, - enqueueSetState: function (inst, payload, callback) { - inst = inst._reactInternals; - var lane = requestUpdateLane(inst), - update = createUpdate(lane); - update.payload = payload; - void 0 !== callback && - null !== callback && - (warnOnInvalidCallback(callback), (update.callback = callback)); - payload = enqueueUpdate(inst, update, lane); - null !== payload && - (scheduleUpdateOnFiber(payload, inst, lane), - entangleTransitions(payload, inst, lane)); - markStateUpdateScheduled(inst, lane); - }, - enqueueReplaceState: function (inst, payload, callback) { - inst = inst._reactInternals; - var lane = requestUpdateLane(inst), - update = createUpdate(lane); - update.tag = ReplaceState; - update.payload = payload; - void 0 !== callback && - null !== callback && - (warnOnInvalidCallback(callback), (update.callback = callback)); - payload = enqueueUpdate(inst, update, lane); - null !== payload && - (scheduleUpdateOnFiber(payload, inst, lane), - entangleTransitions(payload, inst, lane)); - markStateUpdateScheduled(inst, lane); - }, - enqueueForceUpdate: function (inst, callback) { - inst = inst._reactInternals; - var lane = requestUpdateLane(inst), - update = createUpdate(lane); - update.tag = ForceUpdate; - void 0 !== callback && - null !== callback && - (warnOnInvalidCallback(callback), (update.callback = callback)); - callback = enqueueUpdate(inst, update, lane); - null !== callback && - (scheduleUpdateOnFiber(callback, inst, lane), - entangleTransitions(callback, inst, lane)); - null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markForceUpdateScheduled && - injectedProfilingHooks.markForceUpdateScheduled(inst, lane); + } + + function getOwnerHierarchy(instance) { + var hierarchy = []; + traverseOwnerTreeUp(hierarchy, instance); + return hierarchy; + } // $FlowFixMe[missing-local-annot] + + function lastNonHostInstance(hierarchy) { + for (var i = hierarchy.length - 1; i > 1; i--) { + var instance = hierarchy[i]; + + if (instance.tag !== HostComponent) { + return instance; } - }, - reportGlobalError = - "function" === typeof reportError - ? reportError - : function (error) { - if ( - "object" === typeof window && - "function" === typeof window.ErrorEvent - ) { - var event = new window.ErrorEvent("error", { - bubbles: !0, - cancelable: !0, - message: - "object" === typeof error && - null !== error && - "string" === typeof error.message - ? String(error.message) - : String(error), - error: error - }); - if (!window.dispatchEvent(event)) return; - } else if ( - "object" === typeof process && - "function" === typeof process.emit - ) { - process.emit("uncaughtException", error); - return; - } - console.error(error); - }, - componentName = null, - errorBoundaryName = null, - SelectiveHydrationException = Error( - "This is not a real error. It's an implementation detail of React's selective hydration feature. If this leaks into userspace, it's a bug in React. Please file an issue." - ), - didReceiveUpdate = !1; - var didWarnAboutBadClass = {}; - var didWarnAboutContextTypeOnFunctionComponent = {}; - var didWarnAboutGetDerivedStateOnFunctionComponent = {}; - var didWarnAboutReassigningProps = !1; - var didWarnAboutRevealOrder = {}; - var didWarnAboutTailOptions = {}; - var SUSPENDED_MARKER = { - dehydrated: null, - treeContext: null, - retryLane: 0 - }, - hasWarnedAboutUsingNoValuePropOnContextProvider = !1, - valueCursor = createCursor(null); - var rendererCursorDEV = createCursor(null); - var rendererSigil = {}; - var currentlyRenderingFiber = null, - lastContextDependency = null, - lastFullyObservedContext = null, - isDisallowedContextReadInDEV = !1, - AbortControllerLocal = - "undefined" !== typeof AbortController - ? AbortController - : function () { - var listeners = [], - signal = (this.signal = { - aborted: !1, - addEventListener: function (type, listener) { - listeners.push(listener); - } - }); - this.abort = function () { - signal.aborted = !0; - listeners.forEach(function (listener) { - return listener(); - }); - }; - }, - scheduleCallback$1 = Scheduler.unstable_scheduleCallback, - NormalPriority = Scheduler.unstable_NormalPriority, - CacheContext = { - $$typeof: REACT_CONTEXT_TYPE, - Consumer: null, - Provider: null, - _currentValue: null, - _currentValue2: null, - _threadCount: 0, - _currentRenderer: null, - _currentRenderer2: null - }, - prevOnStartTransitionFinish = ReactSharedInternals.S; - ReactSharedInternals.S = function (transition, returnValue) { - "object" === typeof returnValue && - null !== returnValue && - "function" === typeof returnValue.then && - entangleAsyncAction(transition, returnValue); - null !== prevOnStartTransitionFinish && - prevOnStartTransitionFinish(transition, returnValue); - }; - var resumedCache = createCursor(null), - didWarnAboutUndefinedSnapshotBeforeUpdate = null; - didWarnAboutUndefinedSnapshotBeforeUpdate = new Set(); - var offscreenSubtreeIsHidden = !1, - offscreenSubtreeWasHidden = !1, - PossiblyWeakSet = "function" === typeof WeakSet ? WeakSet : Set, - nextEffect = null, - inProgressLanes = null, - inProgressRoot = null, - shouldFireAfterActiveInstanceBlur = !1, - hostParent = null, - hostParentIsContainer = !1, - suspenseyCommitFlag = 8192, - DefaultAsyncDispatcher = { - getCacheForType: function (resourceType) { - var cache = readContext(CacheContext), - cacheForType = cache.data.get(resourceType); - void 0 === cacheForType && - ((cacheForType = resourceType()), - cache.data.set(resourceType, cacheForType)); - return cacheForType; - }, - getOwner: function () { - return current; + } + + return hierarchy[0]; + } // $FlowFixMe[missing-local-annot] + + function traverseOwnerTreeUp(hierarchy, instance) { + { + if (instance) { + hierarchy.unshift(instance); + traverseOwnerTreeUp(hierarchy, instance._debugOwner); } - }; - if ("function" === typeof Symbol && Symbol.for) { - var symbolFor = Symbol.for; - symbolFor("selector.component"); - symbolFor("selector.has_pseudo_class"); - symbolFor("selector.role"); - symbolFor("selector.test_id"); - symbolFor("selector.text"); + } } - var PossiblyWeakMap = "function" === typeof WeakMap ? WeakMap : Map, - NoContext = 0, - RenderContext = 2, - CommitContext = 4, - RootInProgress = 0, - RootFatalErrored = 1, - RootErrored = 2, - RootSuspended = 3, - RootSuspendedWithDelay = 4, - RootCompleted = 5, - RootDidNotComplete = 6, - executionContext = NoContext, - workInProgressRoot = null, - workInProgress = null, - workInProgressRootRenderLanes = 0, - NotSuspended = 0, - SuspendedOnError = 1, - SuspendedOnData = 2, - SuspendedOnImmediate = 3, - SuspendedOnInstance = 4, - SuspendedOnInstanceAndReadyToContinue = 5, - SuspendedOnDeprecatedThrowPromise = 6, - SuspendedAndReadyToContinue = 7, - SuspendedOnHydration = 8, - workInProgressSuspendedReason = NotSuspended, - workInProgressThrownValue = null, - workInProgressRootDidAttachPingListener = !1, - entangledRenderLanes = 0, - workInProgressRootExitStatus = RootInProgress, - workInProgressRootSkippedLanes = 0, - workInProgressRootInterleavedUpdatedLanes = 0, - workInProgressRootPingedLanes = 0, - workInProgressDeferredLane = 0, - workInProgressRootConcurrentErrors = null, - workInProgressRootRecoverableErrors = null, - workInProgressRootDidIncludeRecursiveRenderUpdate = !1, - didIncludeCommitPhaseUpdate = !1, - globalMostRecentFallbackTime = 0, - FALLBACK_THROTTLE_MS = 300, - workInProgressRootRenderTargetTime = Infinity, - RENDER_TIMEOUT_MS = 500, - workInProgressTransitions = null, - legacyErrorBoundariesThatAlreadyFailed = null, - rootDoesHavePassiveEffects = !1, - rootWithPendingPassiveEffects = null, - pendingPassiveEffectsLanes = 0, - pendingPassiveProfilerEffects = [], - pendingPassiveEffectsRemainingLanes = 0, - pendingPassiveTransitions = null, - NESTED_UPDATE_LIMIT = 50, - nestedUpdateCount = 0, - rootWithNestedUpdates = null, - isFlushingPassiveEffects = !1, - didScheduleUpdateDuringPassiveEffects = !1, - NESTED_PASSIVE_UPDATE_LIMIT = 50, - nestedPassiveUpdateCount = 0, - rootWithPassiveNestedUpdates = null, - isRunningInsertionEffect = !1, - didWarnStateUpdateForNotYetMountedComponent = null, - didWarnAboutUpdateInRender = !1; - var didWarnAboutUpdateInRenderForAnotherComponent = new Set(); - var fakeActCallbackNode = {}, - resolveFamily = null, - failedBoundaries = null; - var hasBadMapPolyfill = !1; - try { - var nonExtensibleObject = Object.preventExtensions({}); - new Map([[nonExtensibleObject, null]]); - new Set([nonExtensibleObject]); - } catch (e) { - hasBadMapPolyfill = !0; - } - var didWarnAboutNestedUpdates = !1; - var didWarnAboutFindNodeInStrictMode = {}; - var overrideHookState = null, - overrideHookStateDeletePath = null, - overrideHookStateRenamePath = null, - overrideProps = null, - overridePropsDeletePath = null, - overridePropsRenamePath = null, - scheduleUpdate = null, - setErrorHandler = null, - setSuspenseHandler = null; - overrideHookState = function (fiber, id, path, value) { - id = findHook(fiber, id); - null !== id && - ((path = copyWithSetImpl(id.memoizedState, path, 0, value)), - (id.memoizedState = path), - (id.baseState = path), - (fiber.memoizedProps = assign({}, fiber.memoizedProps)), - (path = enqueueConcurrentRenderForLane(fiber, SyncLane)), - null !== path && scheduleUpdateOnFiber(path, fiber, SyncLane)); - }; - overrideHookStateDeletePath = function (fiber, id, path) { - id = findHook(fiber, id); - null !== id && - ((path = copyWithDeleteImpl(id.memoizedState, path, 0)), - (id.memoizedState = path), - (id.baseState = path), - (fiber.memoizedProps = assign({}, fiber.memoizedProps)), - (path = enqueueConcurrentRenderForLane(fiber, SyncLane)), - null !== path && scheduleUpdateOnFiber(path, fiber, SyncLane)); - }; - overrideHookStateRenamePath = function (fiber, id, oldPath, newPath) { - id = findHook(fiber, id); - null !== id && - ((oldPath = copyWithRename(id.memoizedState, oldPath, newPath)), - (id.memoizedState = oldPath), - (id.baseState = oldPath), - (fiber.memoizedProps = assign({}, fiber.memoizedProps)), - (oldPath = enqueueConcurrentRenderForLane(fiber, SyncLane)), - null !== oldPath && scheduleUpdateOnFiber(oldPath, fiber, SyncLane)); - }; - overrideProps = function (fiber, path, value) { - fiber.pendingProps = copyWithSetImpl(fiber.memoizedProps, path, 0, value); - fiber.alternate && (fiber.alternate.pendingProps = fiber.pendingProps); - path = enqueueConcurrentRenderForLane(fiber, SyncLane); - null !== path && scheduleUpdateOnFiber(path, fiber, SyncLane); - }; - overridePropsDeletePath = function (fiber, path) { - fiber.pendingProps = copyWithDeleteImpl(fiber.memoizedProps, path, 0); - fiber.alternate && (fiber.alternate.pendingProps = fiber.pendingProps); - path = enqueueConcurrentRenderForLane(fiber, SyncLane); - null !== path && scheduleUpdateOnFiber(path, fiber, SyncLane); - }; - overridePropsRenamePath = function (fiber, oldPath, newPath) { - fiber.pendingProps = copyWithRename( - fiber.memoizedProps, - oldPath, - newPath - ); - fiber.alternate && (fiber.alternate.pendingProps = fiber.pendingProps); - oldPath = enqueueConcurrentRenderForLane(fiber, SyncLane); - null !== oldPath && scheduleUpdateOnFiber(oldPath, fiber, SyncLane); - }; - scheduleUpdate = function (fiber) { - var root = enqueueConcurrentRenderForLane(fiber, SyncLane); - null !== root && scheduleUpdateOnFiber(root, fiber, SyncLane); - }; - setErrorHandler = function (newShouldErrorImpl) { - shouldErrorImpl = newShouldErrorImpl; - }; - setSuspenseHandler = function (newShouldSuspendImpl) { - shouldSuspendImpl = newShouldSuspendImpl; - }; - var emptyObject = {}; - Object.freeze(emptyObject); - var isomorphicReactPackageVersion = React.version; - if ("19.0.0-rc-fb9a90fa48-20240614" !== isomorphicReactPackageVersion) - throw Error( - 'Incompatible React versions: The "react" and "react-native-renderer" packages must have the exact same version. Instead got:\n - react: ' + - (isomorphicReactPackageVersion + - "\n - react-native-renderer: 19.0.0-rc-fb9a90fa48-20240614\nLearn more: https://react.dev/warnings/version-mismatch") - ); - if ( - "function" !== - typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog - ) - throw Error( - "Expected ReactFiberErrorDialog.showErrorDialog to be a function." - ); - batchedUpdatesImpl = function (fn, a) { - var prevExecutionContext = executionContext; - executionContext |= 1; - try { - return fn(a); - } finally { - (executionContext = prevExecutionContext), - executionContext !== NoContext || - ReactSharedInternals.isBatchingLegacy || - ((workInProgressRootRenderTargetTime = now$1() + RENDER_TIMEOUT_MS), - flushSyncWorkAcrossRoots_impl(!0)); + + function getInspectorDataForViewTag(viewTag) { + { + var closestInstance = getInstanceFromTag(viewTag); + return getInspectorDataForInstance(closestInstance); } - }; - var roots = new Map(); - (function (devToolsConfig) { - return injectInternals({ - bundleType: devToolsConfig.bundleType, - version: devToolsConfig.version, - rendererPackageName: devToolsConfig.rendererPackageName, - rendererConfig: devToolsConfig.rendererConfig, - overrideHookState: overrideHookState, - overrideHookStateDeletePath: overrideHookStateDeletePath, - overrideHookStateRenamePath: overrideHookStateRenamePath, - overrideProps: overrideProps, - overridePropsDeletePath: overridePropsDeletePath, - overridePropsRenamePath: overridePropsRenamePath, - setErrorHandler: setErrorHandler, - setSuspenseHandler: setSuspenseHandler, - scheduleUpdate: scheduleUpdate, - currentDispatcherRef: ReactSharedInternals, - findHostInstanceByFiber: findHostInstanceByFiber, - findFiberByHostInstance: - devToolsConfig.findFiberByHostInstance || - emptyFindFiberByHostInstance, - findHostInstancesForRefresh: findHostInstancesForRefresh, - scheduleRefresh: scheduleRefresh, - scheduleRoot: scheduleRoot, - setRefreshHandler: setRefreshHandler, - getCurrentFiber: getCurrentFiberForDevTools, - reconcilerVersion: "19.0.0-rc-fb9a90fa48-20240614" - }); - })({ - findFiberByHostInstance: getInstanceFromTag, - bundleType: 1, - version: "19.0.0-rc-fb9a90fa48-20240614", - rendererPackageName: "react-native-renderer", - rendererConfig: { - getInspectorDataForInstance: getInspectorDataForInstance, - getInspectorDataForViewTag: function (viewTag) { - viewTag = getInstanceFromTag(viewTag); - return getInspectorDataForInstance(viewTag); - }, - getInspectorDataForViewAtPoint: function ( - findNodeHandle, - inspectedView, - locationX, - locationY, - callback - ) { - var closestInstance = null, - fabricNode = - ReactNativePrivateInterface.getNodeFromPublicInstance( - inspectedView - ); - fabricNode - ? nativeFabricUIManager.findNodeAtPoint( - fabricNode, - locationX, - locationY, - function (internalInstanceHandle) { - var node = - null != internalInstanceHandle - ? internalInstanceHandle && - internalInstanceHandle.stateNode && - internalInstanceHandle.stateNode.node - : null; - if (null == internalInstanceHandle || null == node) - callback( - assign( - { - pointerY: locationY, - frame: { left: 0, top: 0, width: 0, height: 0 } - }, - getInspectorDataForInstance(closestInstance) - ) - ); - else { - closestInstance = - internalInstanceHandle.stateNode.canonical - .internalInstanceHandle; - var nativeViewTag = - internalInstanceHandle.stateNode.canonical.nativeTag; - nativeFabricUIManager.measure( - node, - function (x, y, width, height, pageX, pageY) { - x = getInspectorDataForInstance(closestInstance); - callback( - assign({}, x, { - pointerY: locationY, - frame: { - left: pageX, - top: pageY, - width: width, - height: height - }, - touchedViewTag: nativeViewTag - }) - ); + } + + function getInspectorDataForViewAtPoint( + findNodeHandle, + inspectedView, + locationX, + locationY, + callback + ) { + { + var closestInstance = null; + var fabricNode = + ReactNativePrivateInterface.getNodeFromPublicInstance(inspectedView); + + if (fabricNode) { + // For Fabric we can look up the instance handle directly and measure it. + nativeFabricUIManager.findNodeAtPoint( + fabricNode, + locationX, + locationY, + function (internalInstanceHandle) { + var node = + internalInstanceHandle != null + ? getNodeFromInternalInstanceHandle(internalInstanceHandle) + : null; + + if (internalInstanceHandle == null || node == null) { + callback( + assign( + { + pointerY: locationY, + frame: { + left: 0, + top: 0, + width: 0, + height: 0 } - ); - } - } - ) - : null != inspectedView._internalFiberInstanceHandleDEV - ? ReactNativePrivateInterface.UIManager.findSubviewIn( - findNodeHandle(inspectedView), - [locationX, locationY], - function (nativeViewTag, left, top, width, height) { - var inspectorData = getInspectorDataForInstance( - getInstanceFromTag(nativeViewTag) - ); + }, + getInspectorDataForInstance(closestInstance) + ) + ); + return; + } + + closestInstance = + 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( + node, + function (x, y, width, height, pageX, pageY) { + var inspectorData = + getInspectorDataForInstance(closestInstance); callback( assign({}, inspectorData, { pointerY: locationY, frame: { - left: left, - top: top, + left: pageX, + top: pageY, width: width, height: height }, @@ -16779,175 +27683,148 @@ __DEV__ && }) ); } - ) - : error$jscomp$0( - "getInspectorDataForViewAtPoint expects to receive a host component" ); - }.bind(null, findNodeHandle) - } - }); - exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = { - computeComponentStackForErrorReporting: function (reactTag) { - return (reactTag = getInstanceFromTag(reactTag)) - ? getStackByFiberInDevAndProd(reactTag) - : ""; - } - }; - exports.createPortal = function (children, containerTag) { - return createPortal$1( - children, - containerTag, - null, - 2 < arguments.length && void 0 !== arguments[2] ? arguments[2] : null - ); - }; - exports.dispatchCommand = function (handle, command, args) { - var nativeTag = - null != handle._nativeTag - ? handle._nativeTag - : ReactNativePrivateInterface.getNativeTagFromPublicInstance(handle); - null == nativeTag - ? error$jscomp$0( - "dispatchCommand was called with a ref that isn't a native component. Use React.forwardRef to get access to the underlying native component" - ) - : ((handle = - ReactNativePrivateInterface.getNodeFromPublicInstance(handle)), - null != handle - ? nativeFabricUIManager.dispatchCommand(handle, command, args) - : ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( - nativeTag, - command, - args - )); - }; - exports.findHostInstance_DEPRECATED = function (componentOrHandle) { - var owner = current; - null !== owner && - isRendering && - null !== owner.stateNode && - (owner.stateNode._warnedAboutRefsInRender || - error$jscomp$0( - "%s is accessing findNodeHandle inside its render(). render() should be a pure function of props and state. It should never access something that requires stale data from the previous render, such as refs. Move this logic to componentDidMount and componentDidUpdate instead.", - getComponentNameFromType(owner.type) || "A component" - ), - (owner.stateNode._warnedAboutRefsInRender = !0)); - return null == componentOrHandle - ? null - : componentOrHandle.canonical && - componentOrHandle.canonical.publicInstance - ? componentOrHandle.canonical.publicInstance - : componentOrHandle._nativeTag - ? componentOrHandle - : findHostInstanceWithWarning( - componentOrHandle, - "findHostInstance_DEPRECATED" + } ); - }; - exports.findNodeHandle = findNodeHandle; - exports.getInspectorDataForInstance = getInspectorDataForInstance; - exports.isChildPublicInstance = function (parentInstance, childInstance) { - if ( - parentInstance._internalFiberInstanceHandleDEV && - childInstance._internalFiberInstanceHandleDEV - ) - return doesFiberContain( - parentInstance._internalFiberInstanceHandleDEV, - childInstance._internalFiberInstanceHandleDEV - ); - parentInstance = - ReactNativePrivateInterface.getInternalInstanceHandleFromPublicInstance( - parentInstance - ); - childInstance = - ReactNativePrivateInterface.getInternalInstanceHandleFromPublicInstance( - childInstance - ); - return null != parentInstance && null != childInstance - ? doesFiberContain(parentInstance, childInstance) - : !1; - }; - exports.render = function (element, containerTag, callback, options) { + } else if (inspectedView._internalFiberInstanceHandleDEV != null) { + // For Paper we fall back to the old strategy using the React tag. + ReactNativePrivateInterface.UIManager.findSubviewIn( + findNodeHandle(inspectedView), + [locationX, locationY], + function (nativeViewTag, left, top, width, height) { + var inspectorData = getInspectorDataForInstance( + getInstanceFromTag(nativeViewTag) + ); + callback( + assign({}, inspectorData, { + pointerY: locationY, + frame: { + left: left, + top: top, + width: width, + height: height + }, + touchedViewTag: nativeViewTag + }) + ); + } + ); + } else { + error( + "getInspectorDataForViewAtPoint expects to receive a host component" + ); + + return; + } + } + } + + function onRecoverableError(error$1) { + // TODO: Expose onRecoverableError option to userspace + // eslint-disable-next-line react-internal/no-production-logging, react-internal/warning-args + error(error$1); + } + + function render(element, containerTag, callback) { var root = roots.get(containerTag); + if (!root) { - root = nativeOnUncaughtError; - var onCaughtError = nativeOnCaughtError, - onRecoverableError = defaultOnRecoverableError; - options && - void 0 !== options.onUncaughtError && - (root = options.onUncaughtError); - options && - void 0 !== options.onCaughtError && - (onCaughtError = options.onCaughtError); - options && - void 0 !== options.onRecoverableError && - (onRecoverableError = options.onRecoverableError); - options = new FiberRootNode( + // 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, - 0, - !1, + LegacyRoot, + null, + false, + null, "", - root, - onCaughtError, onRecoverableError, null ); - root = 0; - isDevToolsPresent && (root |= 2); - root = createFiber(3, null, null, root); - options.current = root; - root.stateNode = options; - onCaughtError = createCache(); - retainCache(onCaughtError); - options.pooledCache = onCaughtError; - retainCache(onCaughtError); - root.memoizedState = { - element: null, - isDehydrated: !1, - cache: onCaughtError - }; - initializeUpdateQueue(root); - root = options; roots.set(containerTag, root); } + updateContainer(element, root, null, callback); - a: if (((element = root.current), element.child)) - switch (element.child.tag) { - case 27: - case 5: - element = getPublicInstance(element.child.stateNode); - break a; - default: - element = element.child.stateNode; - } - else element = null; - return element; - }; - exports.sendAccessibilityEvent = function (handle, eventType) { - var nativeTag = - null != handle._nativeTag - ? handle._nativeTag - : ReactNativePrivateInterface.getNativeTagFromPublicInstance(handle); - null == nativeTag - ? error$jscomp$0( - "sendAccessibilityEvent was called with a ref that isn't a native component. Use React.forwardRef to get access to the underlying native component" - ) - : ((handle = - ReactNativePrivateInterface.getNodeFromPublicInstance(handle)), - null != handle - ? nativeFabricUIManager.sendAccessibilityEvent(handle, eventType) - : ReactNativePrivateInterface.legacySendAccessibilityEvent( - nativeTag, - eventType - )); - }; - exports.unmountComponentAtNode = unmountComponentAtNode; - exports.unmountComponentAtNodeAndRemoveContainer = function (containerTag) { - unmountComponentAtNode(containerTag); + return getPublicRootInstance(root); + } + + function unmountComponentAtNode(containerTag) { + var root = roots.get(containerTag); + + if (root) { + // TODO: Is it safe to reset this now or should I wait since this unmount could be deferred? + updateContainer(null, root, null, function () { + roots.delete(containerTag); + }); + } + } + + function unmountComponentAtNodeAndRemoveContainer(containerTag) { + unmountComponentAtNode(containerTag); // Call back into native to remove all of the subviews from this container + ReactNativePrivateInterface.UIManager.removeRootView(containerTag); + } + + function createPortal(children, containerTag) { + var key = + arguments.length > 2 && arguments[2] !== undefined + ? arguments[2] + : null; + return createPortal$1(children, containerTag, null, key); + } + + setBatchingImplementation(batchedUpdates); + + function computeComponentStackForErrorReporting(reactTag) { + var fiber = getInstanceFromTag(reactTag); + + if (!fiber) { + return ""; + } + + return getStackByFiberInDevAndProd(fiber); + } + + var roots = new Map(); + var Internals = { + computeComponentStackForErrorReporting: + computeComponentStackForErrorReporting }; + injectIntoDevTools({ + findFiberByHostInstance: getInstanceFromTag, + bundleType: 1, + version: ReactVersion, + rendererPackageName: "react-native-renderer", + rendererConfig: { + getInspectorDataForInstance: getInspectorDataForInstance, + getInspectorDataForViewTag: getInspectorDataForViewTag, + getInspectorDataForViewAtPoint: getInspectorDataForViewAtPoint.bind( + null, + findNodeHandle + ) + } + }); + + exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = Internals; + exports.createPortal = createPortal; + exports.dispatchCommand = dispatchCommand; + exports.findHostInstance_DEPRECATED = findHostInstance_DEPRECATED; + exports.findNodeHandle = findNodeHandle; + exports.getInspectorDataForInstance = getInspectorDataForInstance; + exports.isChildPublicInstance = isChildPublicInstance; + exports.render = render; + exports.sendAccessibilityEvent = sendAccessibilityEvent; + exports.unmountComponentAtNode = unmountComponentAtNode; + exports.unmountComponentAtNodeAndRemoveContainer = + unmountComponentAtNodeAndRemoveContainer; exports.unstable_batchedUpdates = batchedUpdates$1; - "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && - "function" === - typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && - __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error()); + /* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */ + if ( + typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined" && + typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop === + "function" + ) { + __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(new Error()); + } })(); +} diff --git a/packages/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js b/packages/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js index 3b1eb756f41663..98d026ddcf474e 100644 --- a/packages/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js +++ b/packages/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js @@ -6,10 +6,9 @@ * * @noflow * @nolint + * @providesModule ReactNativeRenderer-prod * @preventMunge - * @generated SignedSource<<226c75c8c0da1809490c500dfe746b96>> - * - * This file was sync'd from the facebook/react repository. + * @generated SignedSource<> */ "use strict"; @@ -18,219 +17,7 @@ var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/R React = require("react"), Scheduler = require("scheduler"), isArrayImpl = Array.isArray, - ReactSharedInternals = - React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, - REACT_LEGACY_ELEMENT_TYPE = Symbol.for("react.element"), - REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"), - REACT_PORTAL_TYPE = Symbol.for("react.portal"), - REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"), - REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"), - REACT_PROFILER_TYPE = Symbol.for("react.profiler"), - REACT_PROVIDER_TYPE = Symbol.for("react.provider"), - REACT_CONSUMER_TYPE = Symbol.for("react.consumer"), - REACT_CONTEXT_TYPE = Symbol.for("react.context"), - REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"), - REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"), - REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"), - REACT_MEMO_TYPE = Symbol.for("react.memo"), - REACT_LAZY_TYPE = Symbol.for("react.lazy"); -Symbol.for("react.scope"); -Symbol.for("react.debug_trace_mode"); -var REACT_OFFSCREEN_TYPE = Symbol.for("react.offscreen"); -Symbol.for("react.legacy_hidden"); -Symbol.for("react.tracing_marker"); -var REACT_MEMO_CACHE_SENTINEL = Symbol.for("react.memo_cache_sentinel"), - MAYBE_ITERATOR_SYMBOL = Symbol.iterator; -function getIteratorFn(maybeIterable) { - if (null === maybeIterable || "object" !== typeof maybeIterable) return null; - maybeIterable = - (MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL]) || - maybeIterable["@@iterator"]; - return "function" === typeof maybeIterable ? maybeIterable : null; -} -var assign = Object.assign, - prefix; -function describeBuiltInComponentFrame(name) { - if (void 0 === prefix) - try { - throw Error(); - } catch (x) { - var match = x.stack.trim().match(/\n( *(at )?)/); - prefix = (match && match[1]) || ""; - } - return "\n" + prefix + name; -} -var reentry = !1; -function describeNativeComponentFrame(fn, construct) { - if (!fn || reentry) return ""; - reentry = !0; - var previousPrepareStackTrace = Error.prepareStackTrace; - Error.prepareStackTrace = void 0; - var RunInRootFrame = { - DetermineComponentFrameRoot: function () { - try { - if (construct) { - var Fake = function () { - throw Error(); - }; - Object.defineProperty(Fake.prototype, "props", { - set: function () { - throw Error(); - } - }); - if ("object" === typeof Reflect && Reflect.construct) { - try { - Reflect.construct(Fake, []); - } catch (x) { - var control = x; - } - Reflect.construct(fn, [], Fake); - } else { - try { - Fake.call(); - } catch (x$0) { - control = x$0; - } - fn.call(Fake.prototype); - } - } else { - try { - throw Error(); - } catch (x$1) { - control = x$1; - } - (Fake = fn()) && - "function" === typeof Fake.catch && - Fake.catch(function () {}); - } - } catch (sample) { - if (sample && control && "string" === typeof sample.stack) - return [sample.stack, control.stack]; - } - return [null, null]; - } - }; - RunInRootFrame.DetermineComponentFrameRoot.displayName = - "DetermineComponentFrameRoot"; - var namePropDescriptor = Object.getOwnPropertyDescriptor( - RunInRootFrame.DetermineComponentFrameRoot, - "name" - ); - namePropDescriptor && - namePropDescriptor.configurable && - Object.defineProperty(RunInRootFrame.DetermineComponentFrameRoot, "name", { - value: "DetermineComponentFrameRoot" - }); - try { - var _RunInRootFrame$Deter = RunInRootFrame.DetermineComponentFrameRoot(), - sampleStack = _RunInRootFrame$Deter[0], - controlStack = _RunInRootFrame$Deter[1]; - if (sampleStack && controlStack) { - var sampleLines = sampleStack.split("\n"), - controlLines = controlStack.split("\n"); - for ( - namePropDescriptor = RunInRootFrame = 0; - RunInRootFrame < sampleLines.length && - !sampleLines[RunInRootFrame].includes("DetermineComponentFrameRoot"); - - ) - RunInRootFrame++; - for ( - ; - namePropDescriptor < controlLines.length && - !controlLines[namePropDescriptor].includes( - "DetermineComponentFrameRoot" - ); - - ) - namePropDescriptor++; - if ( - RunInRootFrame === sampleLines.length || - namePropDescriptor === controlLines.length - ) - for ( - RunInRootFrame = sampleLines.length - 1, - namePropDescriptor = controlLines.length - 1; - 1 <= RunInRootFrame && - 0 <= namePropDescriptor && - sampleLines[RunInRootFrame] !== controlLines[namePropDescriptor]; - - ) - namePropDescriptor--; - for ( - ; - 1 <= RunInRootFrame && 0 <= namePropDescriptor; - RunInRootFrame--, namePropDescriptor-- - ) - if (sampleLines[RunInRootFrame] !== controlLines[namePropDescriptor]) { - if (1 !== RunInRootFrame || 1 !== namePropDescriptor) { - do - if ( - (RunInRootFrame--, - namePropDescriptor--, - 0 > namePropDescriptor || - sampleLines[RunInRootFrame] !== - controlLines[namePropDescriptor]) - ) { - var frame = - "\n" + - sampleLines[RunInRootFrame].replace(" at new ", " at "); - fn.displayName && - frame.includes("") && - (frame = frame.replace("", fn.displayName)); - return frame; - } - while (1 <= RunInRootFrame && 0 <= namePropDescriptor); - } - break; - } - } - } finally { - (reentry = !1), (Error.prepareStackTrace = previousPrepareStackTrace); - } - return (previousPrepareStackTrace = fn ? fn.displayName || fn.name : "") - ? describeBuiltInComponentFrame(previousPrepareStackTrace) - : ""; -} -function describeFiber(fiber) { - switch (fiber.tag) { - case 26: - case 27: - case 5: - return describeBuiltInComponentFrame(fiber.type); - case 16: - return describeBuiltInComponentFrame("Lazy"); - case 13: - return describeBuiltInComponentFrame("Suspense"); - case 19: - return describeBuiltInComponentFrame("SuspenseList"); - case 0: - case 15: - return (fiber = describeNativeComponentFrame(fiber.type, !1)), fiber; - case 11: - return ( - (fiber = describeNativeComponentFrame(fiber.type.render, !1)), fiber - ); - case 1: - return (fiber = describeNativeComponentFrame(fiber.type, !0)), fiber; - default: - return ""; - } -} -function getStackByFiberInDevAndProd(workInProgress) { - try { - var info = ""; - do - (info += describeFiber(workInProgress)), - (workInProgress = workInProgress.return); - while (workInProgress); - return info; - } catch (x) { - return "\nError generating stack: " + x.message + "\n" + x.stack; - } -} -Symbol.for("react.client.reference"); -var hasError = !1, + hasError = !1, caughtError = null, getFiberCurrentPropsFromNode$1 = null, getInstanceFromNode = null, @@ -257,6 +44,7 @@ function executeDirectDispatch(event) { event._dispatchInstances = null; return dispatchListener; } +var assign = Object.assign; function functionThatReturnsTrue() { return !0; } @@ -1105,7 +893,7 @@ eventPluginOrder = Array.prototype.slice.call([ "ReactNativeBridgeEventPlugin" ]); recomputePluginOrdering(); -var injectedNamesToPlugins$jscomp$inline_286 = { +var injectedNamesToPlugins$jscomp$inline_234 = { ResponderEventPlugin: ResponderEventPlugin, ReactNativeBridgeEventPlugin: { eventTypes: {}, @@ -1151,32 +939,32 @@ var injectedNamesToPlugins$jscomp$inline_286 = { } } }, - isOrderingDirty$jscomp$inline_287 = !1, - pluginName$jscomp$inline_288; -for (pluginName$jscomp$inline_288 in injectedNamesToPlugins$jscomp$inline_286) + isOrderingDirty$jscomp$inline_235 = !1, + pluginName$jscomp$inline_236; +for (pluginName$jscomp$inline_236 in injectedNamesToPlugins$jscomp$inline_234) if ( - injectedNamesToPlugins$jscomp$inline_286.hasOwnProperty( - pluginName$jscomp$inline_288 + injectedNamesToPlugins$jscomp$inline_234.hasOwnProperty( + pluginName$jscomp$inline_236 ) ) { - var pluginModule$jscomp$inline_289 = - injectedNamesToPlugins$jscomp$inline_286[pluginName$jscomp$inline_288]; + var pluginModule$jscomp$inline_237 = + injectedNamesToPlugins$jscomp$inline_234[pluginName$jscomp$inline_236]; if ( - !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_288) || - namesToPlugins[pluginName$jscomp$inline_288] !== - pluginModule$jscomp$inline_289 + !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_236) || + namesToPlugins[pluginName$jscomp$inline_236] !== + pluginModule$jscomp$inline_237 ) { - if (namesToPlugins[pluginName$jscomp$inline_288]) + if (namesToPlugins[pluginName$jscomp$inline_236]) throw Error( "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - (pluginName$jscomp$inline_288 + "`.") + (pluginName$jscomp$inline_236 + "`.") ); - namesToPlugins[pluginName$jscomp$inline_288] = - pluginModule$jscomp$inline_289; - isOrderingDirty$jscomp$inline_287 = !0; + namesToPlugins[pluginName$jscomp$inline_236] = + pluginModule$jscomp$inline_237; + isOrderingDirty$jscomp$inline_235 = !0; } } -isOrderingDirty$jscomp$inline_287 && recomputePluginOrdering(); +isOrderingDirty$jscomp$inline_235 && recomputePluginOrdering(); var instanceCache = new Map(), instanceProps = new Map(); function getInstanceFromTag(tag) { @@ -1273,13 +1061,13 @@ ReactNativePrivateInterface.RCTEventEmitter.register({ ) { var JSCompiler_temp = []; for (var i = 0; i < changedIndices.length; i++) { - var index$4 = changedIndices[i]; - JSCompiler_temp.push(touches[index$4]); - touches[index$4] = null; + var index$0 = changedIndices[i]; + JSCompiler_temp.push(touches[index$0]); + touches[index$0] = null; } for (i = changedIndices = 0; i < touches.length; i++) - (index$4 = touches[i]), - null !== index$4 && (touches[changedIndices++] = index$4); + (index$0 = touches[i]), + null !== index$0 && (touches[changedIndices++] = index$0); touches.length = changedIndices; } else for (JSCompiler_temp = [], i = 0; i < changedIndices.length; i++) @@ -1292,10 +1080,10 @@ ReactNativePrivateInterface.RCTEventEmitter.register({ i = JSCompiler_temp[changedIndices]; i.changedTouches = JSCompiler_temp; i.touches = touches; - index$4 = null; + index$0 = null; var target = i.target; - null === target || void 0 === target || 1 > target || (index$4 = target); - _receiveRootNodeIDEvent(index$4, eventTopLevelType, i); + null === target || void 0 === target || 1 > target || (index$0 = target); + _receiveRootNodeIDEvent(index$0, eventTopLevelType, i); } } }); @@ -1322,6 +1110,36 @@ ResponderEventPlugin.injection.injectGlobalResponderHandler({ : ReactNativePrivateInterface.UIManager.clearJSResponder(); } }); +var ReactSharedInternals = + React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED, + REACT_ELEMENT_TYPE = Symbol.for("react.element"), + REACT_PORTAL_TYPE = Symbol.for("react.portal"), + REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"), + REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"), + REACT_PROFILER_TYPE = Symbol.for("react.profiler"), + REACT_PROVIDER_TYPE = Symbol.for("react.provider"), + REACT_CONSUMER_TYPE = Symbol.for("react.consumer"), + REACT_CONTEXT_TYPE = Symbol.for("react.context"), + REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"), + REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"), + REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"), + REACT_MEMO_TYPE = Symbol.for("react.memo"), + REACT_LAZY_TYPE = Symbol.for("react.lazy"); +Symbol.for("react.scope"); +Symbol.for("react.debug_trace_mode"); +var REACT_OFFSCREEN_TYPE = Symbol.for("react.offscreen"); +Symbol.for("react.legacy_hidden"); +Symbol.for("react.cache"); +Symbol.for("react.tracing_marker"); +var MAYBE_ITERATOR_SYMBOL = Symbol.iterator; +function getIteratorFn(maybeIterable) { + if (null === maybeIterable || "object" !== typeof maybeIterable) return null; + maybeIterable = + (MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL]) || + maybeIterable["@@iterator"]; + return "function" === typeof maybeIterable ? maybeIterable : null; +} +Symbol.for("react.client.reference"); function getNearestMountedFiber(fiber) { var node = fiber, nearestMounted = fiber; @@ -1370,36 +1188,36 @@ function findCurrentFiberUsingSlowPath(fiber) { } if (a.return !== b.return) (a = parentA), (b = parentB); else { - for (var didFindChild = !1, child$5 = parentA.child; child$5; ) { - if (child$5 === a) { + for (var didFindChild = !1, child$1 = parentA.child; child$1; ) { + if (child$1 === a) { didFindChild = !0; a = parentA; b = parentB; break; } - if (child$5 === b) { + if (child$1 === b) { didFindChild = !0; b = parentA; a = parentB; break; } - child$5 = child$5.sibling; + child$1 = child$1.sibling; } if (!didFindChild) { - for (child$5 = parentB.child; child$5; ) { - if (child$5 === a) { + for (child$1 = parentB.child; child$1; ) { + if (child$1 === a) { didFindChild = !0; a = parentB; b = parentA; break; } - if (child$5 === b) { + if (child$1 === b) { didFindChild = !0; b = parentB; a = parentA; break; } - child$5 = child$5.sibling; + child$1 = child$1.sibling; } if (!didFindChild) throw Error( @@ -1633,19 +1451,19 @@ function diffProperties(updatePayload, prevProps, nextProps, validAttributes) { ), (removedKeys = null)); } - for (var propKey$7 in prevProps) - void 0 === nextProps[propKey$7] && - (!(attributeConfig = validAttributes[propKey$7]) || - (updatePayload && void 0 !== updatePayload[propKey$7]) || - ((prevProp = prevProps[propKey$7]), + for (var propKey$3 in prevProps) + void 0 === nextProps[propKey$3] && + (!(attributeConfig = validAttributes[propKey$3]) || + (updatePayload && void 0 !== updatePayload[propKey$3]) || + ((prevProp = prevProps[propKey$3]), void 0 !== prevProp && ("object" !== typeof attributeConfig || "function" === typeof attributeConfig.diff || "function" === typeof attributeConfig.process - ? (((updatePayload || (updatePayload = {}))[propKey$7] = null), + ? (((updatePayload || (updatePayload = {}))[propKey$3] = null), removedKeys || (removedKeys = {}), - removedKeys[propKey$7] || - ((removedKeys[propKey$7] = !0), removedKeyCount++)) + removedKeys[propKey$3] || + ((removedKeys[propKey$3] = !0), removedKeyCount++)) : (updatePayload = clearNestedProperty( updatePayload, prevProp, @@ -1718,17 +1536,15 @@ var ReactNativeFiberHostComponent = (function () { }; return ReactNativeFiberHostComponent; })(), - scheduleCallback$3 = Scheduler.unstable_scheduleCallback, + scheduleCallback$2 = Scheduler.unstable_scheduleCallback, cancelCallback$1 = Scheduler.unstable_cancelCallback, shouldYield = Scheduler.unstable_shouldYield, requestPaint = Scheduler.unstable_requestPaint, now = Scheduler.unstable_now, ImmediatePriority = Scheduler.unstable_ImmediatePriority, UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, - NormalPriority$1 = Scheduler.unstable_NormalPriority, + NormalPriority = Scheduler.unstable_NormalPriority, IdlePriority = Scheduler.unstable_IdlePriority, - log$1 = Scheduler.log, - unstable_setDisableYieldValue = Scheduler.unstable_setDisableYieldValue, rendererID = null, injectedHook = null; function onCommitRoot(root) { @@ -1742,13 +1558,6 @@ function onCommitRoot(root) { ); } catch (err) {} } -function setIsStrictModeForDevtools(newIsStrictMode) { - "function" === typeof log$1 && unstable_setDisableYieldValue(newIsStrictMode); - if (injectedHook && "function" === typeof injectedHook.setStrictMode) - try { - injectedHook.setStrictMode(rendererID, newIsStrictMode); - } catch (err) {} -} var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback, log = Math.log, LN2 = Math.LN2; @@ -1902,6 +1711,11 @@ function createLaneMap(initial) { for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); return laneMap; } +function markRootUpdated$1(root, updateLane) { + root.pendingLanes |= updateLane; + 268435456 !== updateLane && + ((root.suspendedLanes = 0), (root.pingedLanes = 0)); +} function markRootFinished(root, remainingLanes, spawnedLane) { var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; root.pendingLanes = remainingLanes; @@ -1918,18 +1732,18 @@ function markRootFinished(root, remainingLanes, spawnedLane) { 0 < noLongerPendingLanes; ) { - var index$11 = 31 - clz32(noLongerPendingLanes), - lane = 1 << index$11; - remainingLanes[index$11] = 0; - expirationTimes[index$11] = -1; - var hiddenUpdatesForLane = hiddenUpdates[index$11]; + var index$7 = 31 - clz32(noLongerPendingLanes), + lane = 1 << index$7; + remainingLanes[index$7] = 0; + expirationTimes[index$7] = -1; + var hiddenUpdatesForLane = hiddenUpdates[index$7]; if (null !== hiddenUpdatesForLane) for ( - hiddenUpdates[index$11] = null, index$11 = 0; - index$11 < hiddenUpdatesForLane.length; - index$11++ + hiddenUpdates[index$7] = null, index$7 = 0; + index$7 < hiddenUpdatesForLane.length; + index$7++ ) { - var update = hiddenUpdatesForLane[index$11]; + var update = hiddenUpdatesForLane[index$7]; null !== update && (update.lane &= -536870913); } noLongerPendingLanes &= ~lane; @@ -1949,13 +1763,14 @@ function markSpawnedDeferredLane(root, spawnedLane, entangledLanes) { function markRootEntangled(root, entangledLanes) { var rootEntangledLanes = (root.entangledLanes |= entangledLanes); for (root = root.entanglements; rootEntangledLanes; ) { - var index$12 = 31 - clz32(rootEntangledLanes), - lane = 1 << index$12; - (lane & entangledLanes) | (root[index$12] & entangledLanes) && - (root[index$12] |= entangledLanes); + var index$8 = 31 - clz32(rootEntangledLanes), + lane = 1 << index$8; + (lane & entangledLanes) | (root[index$8] & entangledLanes) && + (root[index$8] |= entangledLanes); rootEntangledLanes &= ~lane; } } +var currentUpdatePriority = 0; function lanesToEventPriority(lanes) { lanes &= -lanes; return 2 < lanes @@ -1971,11 +1786,6 @@ function shim$1() { "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." ); } -function shim() { - throw Error( - "The current renderer does not support Resources. This error is likely caused by a bug in React. Please file an issue." - ); -} var getViewConfigForType = ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get, nextReactTag = 3; @@ -2013,7 +1823,6 @@ function getPublicInstance(instance) { } var scheduleTimeout = setTimeout, cancelTimeout = clearTimeout, - currentUpdatePriority = 0, valueStack = [], index = -1; function createCursor(defaultValue) { @@ -2033,28 +1842,9 @@ 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, - CapturedStacks = new WeakMap(); -function createCapturedValueAtFiber(value, source) { - if ("object" === typeof value && null !== value) { - var stack = CapturedStacks.get(value); - "string" !== typeof stack && - ((stack = getStackByFiberInDevAndProd(source)), - CapturedStacks.set(value, stack)); - } else stack = getStackByFiberInDevAndProd(source); - return { value: value, source: source, stack: stack }; -} -var contextStackCursor = createCursor(null), + contextStackCursor = createCursor(null), contextFiberStackCursor = createCursor(null), - rootInstanceStackCursor = createCursor(null), - hostTransitionProviderCursor = createCursor(null), - HostTransitionContext = { - $$typeof: REACT_CONTEXT_TYPE, - Provider: null, - Consumer: null, - _currentValue: null, - _currentValue2: null, - _threadCount: 0 - }; + rootInstanceStackCursor = createCursor(null); function pushHostContainer(fiber, nextRootInstance) { push(rootInstanceStackCursor, nextRootInstance); push(contextFiberStackCursor, fiber); @@ -2068,7 +1858,6 @@ function popHostContainer() { pop(rootInstanceStackCursor); } function pushHostContext(fiber) { - null !== fiber.memoizedState && push(hostTransitionProviderCursor, fiber); var context = contextStackCursor.current; var JSCompiler_inline_result = fiber.type; JSCompiler_inline_result = @@ -2088,9 +1877,6 @@ function pushHostContext(fiber) { function popHostContext(fiber) { contextFiberStackCursor.current === fiber && (pop(contextStackCursor), pop(contextFiberStackCursor)); - hostTransitionProviderCursor.current === fiber && - (pop(hostTransitionProviderCursor), - (HostTransitionContext._currentValue = null)); } var hydrationErrors = null, concurrentQueues = [], @@ -2131,10 +1917,6 @@ function enqueueUpdate$1(fiber, queue, update, lane) { fiber = fiber.alternate; null !== fiber && (fiber.lanes |= lane); } -function enqueueConcurrentHookUpdate(fiber, queue, update, lane) { - enqueueUpdate$1(fiber, queue, update, lane); - return getRootForUpdatedFiber(fiber); -} function enqueueConcurrentRenderForLane(fiber, lane) { enqueueUpdate$1(fiber, null, null, lane); return getRootForUpdatedFiber(fiber); @@ -2165,7 +1947,14 @@ function markUpdateLaneFromFiberToRoot(sourceFiber, update, lane) { (update.lane = lane | 536870912)); } function getRootForUpdatedFiber(sourceFiber) { - throwIfInfiniteUpdateLoopDetected(); + if (50 < nestedUpdateCount) + throw ( + ((nestedUpdateCount = 0), + (rootWithNestedUpdates = null), + Error( + "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." + )) + ); for (var parent = sourceFiber.return; null !== parent; ) (sourceFiber = parent), (parent = sourceFiber.return); return 3 === sourceFiber.tag ? sourceFiber.stateNode : null; @@ -2185,30 +1974,104 @@ function ensureRootIsScheduled(root) { mightHavePendingSyncWork = !0; didScheduleMicrotask || ((didScheduleMicrotask = !0), - scheduleCallback$3(ImmediatePriority, processRootScheduleInMicrotask)); + scheduleCallback$2(ImmediatePriority, processRootScheduleInMicrotask)); + scheduleTaskForRootDuringMicrotask(root, now()); } function flushSyncWorkAcrossRoots_impl(onlyLegacy) { if (!isFlushingWork && mightHavePendingSyncWork) { + var errors = null; isFlushingWork = !0; do { var didPerformSomeWork = !1; for (var root = firstScheduledRoot; null !== root; ) { if (!onlyLegacy || 0 === root.tag) { - var workInProgressRootRenderLanes$15 = workInProgressRootRenderLanes; - workInProgressRootRenderLanes$15 = getNextLanes( - root, - root === workInProgressRoot ? workInProgressRootRenderLanes$15 : 0 - ); - 0 !== (workInProgressRootRenderLanes$15 & 3) && - ((didPerformSomeWork = !0), - performSyncWorkOnRoot(root, workInProgressRootRenderLanes$15)); + var workInProgressRootRenderLanes$11 = workInProgressRootRenderLanes, + nextLanes = getNextLanes( + root, + root === workInProgressRoot ? workInProgressRootRenderLanes$11 : 0 + ); + if (0 !== (nextLanes & 3)) + try { + didPerformSomeWork = !0; + workInProgressRootRenderLanes$11 = root; + if (0 !== (executionContext & 6)) + throw Error("Should not already be working."); + if (!flushPassiveEffects()) { + var exitStatus = renderRootSync( + workInProgressRootRenderLanes$11, + nextLanes + ); + if ( + 0 !== workInProgressRootRenderLanes$11.tag && + 2 === exitStatus + ) { + var originallyAttemptedLanes = nextLanes, + errorRetryLanes = getLanesToRetrySynchronouslyOnError( + workInProgressRootRenderLanes$11, + originallyAttemptedLanes + ); + 0 !== errorRetryLanes && + ((nextLanes = errorRetryLanes), + (exitStatus = recoverFromConcurrentError( + workInProgressRootRenderLanes$11, + originallyAttemptedLanes, + errorRetryLanes + ))); + } + if (1 === exitStatus) + throw ( + ((originallyAttemptedLanes = workInProgressRootFatalError), + prepareFreshStack(workInProgressRootRenderLanes$11, 0), + markRootSuspended( + workInProgressRootRenderLanes$11, + nextLanes, + 0 + ), + ensureRootIsScheduled(workInProgressRootRenderLanes$11), + originallyAttemptedLanes) + ); + 6 === exitStatus + ? markRootSuspended( + workInProgressRootRenderLanes$11, + nextLanes, + workInProgressDeferredLane + ) + : ((workInProgressRootRenderLanes$11.finishedWork = + workInProgressRootRenderLanes$11.current.alternate), + (workInProgressRootRenderLanes$11.finishedLanes = + nextLanes), + commitRoot( + workInProgressRootRenderLanes$11, + workInProgressRootRecoverableErrors, + workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, + workInProgressDeferredLane + )); + } + ensureRootIsScheduled(workInProgressRootRenderLanes$11); + } catch (error) { + null === errors ? (errors = [error]) : errors.push(error); + } } root = root.next; } } while (didPerformSomeWork); isFlushingWork = !1; + if (null !== errors) { + if (1 < errors.length) { + if ("function" === typeof AggregateError) + throw new AggregateError(errors); + for (onlyLegacy = 1; onlyLegacy < errors.length; onlyLegacy++) + (didPerformSomeWork = throwError.bind(null, errors[onlyLegacy])), + scheduleCallback$2(ImmediatePriority, didPerformSomeWork); + } + throw errors[0]; + } } } +function throwError(error) { + throw error; +} function processRootScheduleInMicrotask() { mightHavePendingSyncWork = didScheduleMicrotask = !1; for ( @@ -2238,12 +2101,12 @@ function scheduleTaskForRootDuringMicrotask(root, currentTime) { 0 < lanes; ) { - var index$9 = 31 - clz32(lanes), - lane = 1 << index$9, - expirationTime = expirationTimes[index$9]; + var index$5 = 31 - clz32(lanes), + lane = 1 << index$5, + expirationTime = expirationTimes[index$5]; if (-1 === expirationTime) { if (0 === (lane & suspendedLanes) || 0 !== (lane & pingedLanes)) - expirationTimes[index$9] = computeExpirationTime(lane, currentTime); + expirationTimes[index$5] = computeExpirationTime(lane, currentTime); } else expirationTime <= currentTime && (root.expiredLanes |= lane); lanes &= ~lane; } @@ -2286,85 +2149,20 @@ function scheduleTaskForRootDuringMicrotask(root, currentTime) { suspendedLanes = UserBlockingPriority; break; case 32: - suspendedLanes = NormalPriority$1; + suspendedLanes = NormalPriority; break; case 268435456: suspendedLanes = IdlePriority; break; default: - suspendedLanes = NormalPriority$1; + suspendedLanes = NormalPriority; } pingedLanes = performConcurrentWorkOnRoot.bind(null, root); - suspendedLanes = scheduleCallback$3(suspendedLanes, pingedLanes); + suspendedLanes = scheduleCallback$2(suspendedLanes, pingedLanes); root.callbackPriority = currentTime; root.callbackNode = suspendedLanes; return currentTime; } -function requestTransitionLane() { - 0 === currentEventTransitionLane && - (currentEventTransitionLane = claimNextTransitionLane()); - return currentEventTransitionLane; -} -var currentEntangledListeners = null, - currentEntangledPendingCount = 0, - currentEntangledLane = 0, - currentEntangledActionThenable = null; -function entangleAsyncAction(transition, thenable) { - if (null === currentEntangledListeners) { - var entangledListeners = (currentEntangledListeners = []); - currentEntangledPendingCount = 0; - currentEntangledLane = requestTransitionLane(); - currentEntangledActionThenable = { - status: "pending", - value: void 0, - then: function (resolve) { - entangledListeners.push(resolve); - } - }; - } - currentEntangledPendingCount++; - thenable.then(pingEngtangledActionScope, pingEngtangledActionScope); - return thenable; -} -function pingEngtangledActionScope() { - if ( - null !== currentEntangledListeners && - 0 === --currentEntangledPendingCount - ) { - null !== currentEntangledActionThenable && - (currentEntangledActionThenable.status = "fulfilled"); - var listeners = currentEntangledListeners; - currentEntangledListeners = null; - currentEntangledLane = 0; - currentEntangledActionThenable = null; - for (var i = 0; i < listeners.length; i++) (0, listeners[i])(); - } -} -function chainThenableValue(thenable, result) { - var listeners = [], - thenableWithOverride = { - status: "pending", - value: null, - reason: null, - then: function (resolve) { - listeners.push(resolve); - } - }; - thenable.then( - function () { - thenableWithOverride.status = "fulfilled"; - thenableWithOverride.value = result; - for (var i = 0; i < listeners.length; i++) (0, listeners[i])(result); - }, - function (error) { - thenableWithOverride.status = "rejected"; - thenableWithOverride.reason = error; - for (error = 0; error < listeners.length; error++) - (0, listeners[error])(void 0); - } - ); - return thenableWithOverride; -} var hasForceUpdate = !1; function initializeUpdateQueue(fiber) { fiber.updateQueue = { @@ -2460,20 +2258,12 @@ function enqueueCapturedUpdate(workInProgress, capturedUpdate) { : (workInProgress.next = capturedUpdate); queue.lastBaseUpdate = capturedUpdate; } -var didReadFromEntangledAsyncAction = !1; -function suspendIfUpdateReadFromEntangledAsyncAction() { - if (didReadFromEntangledAsyncAction) { - var entangledActionThenable = currentEntangledActionThenable; - if (null !== entangledActionThenable) throw entangledActionThenable; - } -} function processUpdateQueue( workInProgress$jscomp$0, props, instance$jscomp$0, renderLanes ) { - didReadFromEntangledAsyncAction = !1; var queue = workInProgress$jscomp$0.updateQueue; hasForceUpdate = !1; var firstBaseUpdate = queue.firstBaseUpdate, @@ -2511,9 +2301,6 @@ function processUpdateQueue( ? (workInProgressRootRenderLanes & updateLane) === updateLane : (renderLanes & updateLane) === updateLane ) { - 0 !== updateLane && - updateLane === currentEntangledLane && - (didReadFromEntangledAsyncAction = !0); null !== current && (current = current.next = { @@ -2635,6 +2422,52 @@ function shallowEqual(objA, objB) { } return !0; } +function describeComponentFrame(name, ownerName) { + var sourceInfo = ""; + ownerName && (sourceInfo = " (created by " + ownerName + ")"); + return "\n in " + (name || "Unknown") + sourceInfo; +} +function describeFunctionComponentFrame(fn) { + return fn + ? describeComponentFrame(fn.displayName || fn.name || null, null) + : ""; +} +function describeFiber(fiber) { + switch (fiber.tag) { + case 26: + case 27: + case 5: + return describeComponentFrame(fiber.type, null); + case 16: + return describeComponentFrame("Lazy", null); + case 13: + return describeComponentFrame("Suspense", null); + case 19: + return describeComponentFrame("SuspenseList", null); + case 0: + case 2: + case 15: + return describeFunctionComponentFrame(fiber.type); + case 11: + return describeFunctionComponentFrame(fiber.type.render); + case 1: + return (fiber = describeFunctionComponentFrame(fiber.type)), fiber; + default: + return ""; + } +} +function getStackByFiberInDevAndProd(workInProgress) { + try { + var info = ""; + do + (info += describeFiber(workInProgress)), + (workInProgress = workInProgress.return); + while (workInProgress); + return info; + } catch (x) { + return "\nError generating stack: " + x.message + "\n" + x.stack; + } +} var SuspenseException = Error( "Suspense Exception: This is not a real error! It's an implementation detail of `use` to interrupt the current render. You must either rethrow it immediately, or move the `use` call outside of the `try/catch` block. Capturing without rethrowing will lead to unexpected behavior.\n\nTo handle async errors, wrap your component in an error boundary, or call the promise's `.catch` method and pass the result to `use`" ), @@ -2726,15 +2559,56 @@ function unwrapThenable(thenable) { null === thenableState$1 && (thenableState$1 = []); return trackUsedThenable(thenableState$1, thenable, index); } +function convertStringRefToCallbackRef( + returnFiber, + current, + element, + mixedRef +) { + function ref(value) { + var refs = inst.refs; + null === value ? delete refs[stringRef] : (refs[stringRef] = value); + } + var stringRef = "" + mixedRef; + returnFiber = element._owner; + if (!returnFiber) + throw Error( + "Element ref was specified as a string (" + + stringRef + + ") but no owner was set. This could happen for one of the following reasons:\n1. You may be adding a ref to a function component\n2. You may be adding a ref to a component that was not created inside a component's render method\n3. You have multiple copies of React loaded\nSee https://react.dev/link/refs-must-have-owner for more information." + ); + if (1 !== returnFiber.tag) + throw Error( + "Function components cannot have string refs. We recommend using useRef() instead. Learn more about using refs safely here: https://react.dev/link/strict-mode-string-ref" + ); + var inst = returnFiber.stateNode; + if (!inst) + throw Error( + "Missing owner for string ref " + + stringRef + + ". This error is likely caused by a bug in React. Please file an issue." + ); + if ( + null !== current && + null !== current.ref && + "function" === typeof current.ref && + current.ref._stringRef === stringRef + ) + return current.ref; + ref._stringRef = stringRef; + return ref; +} function coerceRef(returnFiber, current, workInProgress, element) { - returnFiber = element.props.ref; - workInProgress.ref = void 0 !== returnFiber ? returnFiber : null; + var mixedRef = element.ref; + returnFiber = + "string" === typeof mixedRef || + "number" === typeof mixedRef || + "boolean" === typeof mixedRef + ? convertStringRefToCallbackRef(returnFiber, current, element, mixedRef) + : mixedRef; + workInProgress.ref = returnFiber; } function throwOnInvalidObjectType(returnFiber, newChild) { - if (newChild.$$typeof === REACT_LEGACY_ELEMENT_TYPE) - throw Error( - 'A React Element from an older version of React was rendered. This is not supported. It can happen if:\n- Multiple copies of the "react" package is used.\n- A library pre-bundled an old copy of "react" or "react/jsx-runtime".\n- A compiler tries to "inline" JSX instead of using the runtime.' - ); returnFiber = Object.prototype.toString.call(newChild); throw Error( "Objects are not valid as a React child (found: " + @@ -2881,8 +2755,7 @@ function createChildReconciler(shouldTrackSideEffects) { function createChild(returnFiber, newChild, lanes) { if ( ("string" === typeof newChild && "" !== newChild) || - "number" === typeof newChild || - "bigint" === typeof newChild + "number" === typeof newChild ) return ( (newChild = createFiberFromText( @@ -2921,8 +2794,7 @@ function createChildReconciler(shouldTrackSideEffects) { ); case REACT_LAZY_TYPE: var init = newChild._init; - newChild = init(newChild._payload); - return createChild(returnFiber, newChild, lanes); + return createChild(returnFiber, init(newChild._payload), lanes); } if (isArrayImpl(newChild) || getIteratorFn(newChild)) return ( @@ -2951,8 +2823,7 @@ function createChildReconciler(shouldTrackSideEffects) { var key = null !== oldFiber ? oldFiber.key : null; if ( ("string" === typeof newChild && "" !== newChild) || - "number" === typeof newChild || - "bigint" === typeof newChild + "number" === typeof newChild ) return null !== key ? null @@ -2970,8 +2841,7 @@ function createChildReconciler(shouldTrackSideEffects) { case REACT_LAZY_TYPE: return ( (key = newChild._init), - (newChild = key(newChild._payload)), - updateSlot(returnFiber, oldFiber, newChild, lanes) + updateSlot(returnFiber, oldFiber, key(newChild._payload), lanes) ); } if (isArrayImpl(newChild) || getIteratorFn(newChild)) @@ -3005,8 +2875,7 @@ function createChildReconciler(shouldTrackSideEffects) { ) { if ( ("string" === typeof newChild && "" !== newChild) || - "number" === typeof newChild || - "bigint" === typeof newChild + "number" === typeof newChild ) return ( (existingChildren = existingChildren.get(newIdx) || null), @@ -3032,12 +2901,11 @@ function createChildReconciler(shouldTrackSideEffects) { ); case REACT_LAZY_TYPE: var init = newChild._init; - newChild = init(newChild._payload); return updateFromMap( existingChildren, returnFiber, newIdx, - newChild, + init(newChild._payload), lanes ); } @@ -3160,20 +3028,25 @@ function createChildReconciler(shouldTrackSideEffects) { function reconcileChildrenIterator( returnFiber, currentFirstChild, - newChildren, + newChildrenIterable, lanes ) { - if (null == newChildren) + var iteratorFn = getIteratorFn(newChildrenIterable); + if ("function" !== typeof iteratorFn) + throw Error( + "An object is not an iterable. This error is likely caused by a bug in React. Please file an issue." + ); + newChildrenIterable = iteratorFn.call(newChildrenIterable); + if (null == newChildrenIterable) throw Error("An iterable object provided no iterator."); for ( - var resultingFirstChild = null, - previousNewFiber = null, + var previousNewFiber = (iteratorFn = null), oldFiber = currentFirstChild, newIdx = (currentFirstChild = 0), nextOldFiber = null, - step = newChildren.next(); + step = newChildrenIterable.next(); null !== oldFiber && !step.done; - newIdx++, step = newChildren.next() + newIdx++, step = newChildrenIterable.next() ) { oldFiber.index > newIdx ? ((nextOldFiber = oldFiber), (oldFiber = null)) @@ -3189,30 +3062,28 @@ function createChildReconciler(shouldTrackSideEffects) { deleteChild(returnFiber, oldFiber); currentFirstChild = placeChild(newFiber, currentFirstChild, newIdx); null === previousNewFiber - ? (resultingFirstChild = newFiber) + ? (iteratorFn = newFiber) : (previousNewFiber.sibling = newFiber); previousNewFiber = newFiber; oldFiber = nextOldFiber; } if (step.done) - return ( - deleteRemainingChildren(returnFiber, oldFiber), resultingFirstChild - ); + return deleteRemainingChildren(returnFiber, oldFiber), iteratorFn; if (null === oldFiber) { - for (; !step.done; newIdx++, step = newChildren.next()) + for (; !step.done; newIdx++, step = newChildrenIterable.next()) (step = createChild(returnFiber, step.value, lanes)), null !== step && ((currentFirstChild = placeChild(step, currentFirstChild, newIdx)), null === previousNewFiber - ? (resultingFirstChild = step) + ? (iteratorFn = step) : (previousNewFiber.sibling = step), (previousNewFiber = step)); - return resultingFirstChild; + return iteratorFn; } for ( oldFiber = mapRemainingChildren(oldFiber); !step.done; - newIdx++, step = newChildren.next() + newIdx++, step = newChildrenIterable.next() ) (step = updateFromMap(oldFiber, returnFiber, newIdx, step.value, lanes)), null !== step && @@ -3221,14 +3092,14 @@ function createChildReconciler(shouldTrackSideEffects) { oldFiber.delete(null === step.key ? newIdx : step.key), (currentFirstChild = placeChild(step, currentFirstChild, newIdx)), null === previousNewFiber - ? (resultingFirstChild = step) + ? (iteratorFn = step) : (previousNewFiber.sibling = step), (previousNewFiber = step)); shouldTrackSideEffects && oldFiber.forEach(function (child) { return deleteChild(returnFiber, child); }); - return resultingFirstChild; + return iteratorFn; } function reconcileChildFibersImpl( returnFiber, @@ -3345,11 +3216,10 @@ function createChildReconciler(shouldTrackSideEffects) { case REACT_LAZY_TYPE: return ( (child = newChild._init), - (newChild = child(newChild._payload)), reconcileChildFibersImpl( returnFiber, currentFirstChild, - newChild, + child(newChild._payload), lanes ) ); @@ -3361,20 +3231,13 @@ function createChildReconciler(shouldTrackSideEffects) { newChild, lanes ); - if (getIteratorFn(newChild)) { - child = getIteratorFn(newChild); - if ("function" !== typeof child) - throw Error( - "An object is not an iterable. This error is likely caused by a bug in React. Please file an issue." - ); - newChild = child.call(newChild); + if (getIteratorFn(newChild)) return reconcileChildrenIterator( returnFiber, currentFirstChild, newChild, lanes ); - } if ("function" === typeof newChild.then) return reconcileChildFibersImpl( returnFiber, @@ -3392,8 +3255,7 @@ function createChildReconciler(shouldTrackSideEffects) { throwOnInvalidObjectType(returnFiber, newChild); } return ("string" === typeof newChild && "" !== newChild) || - "number" === typeof newChild || - "bigint" === typeof newChild + "number" === typeof newChild ? ((newChild = "" + newChild), null !== currentFirstChild && 6 === currentFirstChild.tag ? (deleteRemainingChildren(returnFiber, currentFirstChild.sibling), @@ -3412,31 +3274,15 @@ function createChildReconciler(shouldTrackSideEffects) { : deleteRemainingChildren(returnFiber, currentFirstChild); } return function (returnFiber, currentFirstChild, newChild, lanes) { - try { - thenableIndexCounter$1 = 0; - var firstChildFiber = reconcileChildFibersImpl( - returnFiber, - currentFirstChild, - newChild, - lanes - ); - thenableState$1 = null; - return firstChildFiber; - } catch (x) { - if ( - x === SuspenseException || - (0 === (returnFiber.mode & 1) && - "object" === typeof x && - null !== x && - "function" === typeof x.then) - ) - throw x; - var fiber = createFiber(29, x, null, returnFiber.mode); - fiber.lanes = lanes; - fiber.return = returnFiber; - return fiber; - } finally { - } + thenableIndexCounter$1 = 0; + returnFiber = reconcileChildFibersImpl( + returnFiber, + currentFirstChild, + newChild, + lanes + ); + thenableState$1 = null; + return returnFiber; }; } var reconcileChildFibers = createChildReconciler(!0), @@ -3516,7 +3362,9 @@ function findFirstSuspended(row) { } return null; } -var renderLanes = 0, +var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, + ReactCurrentBatchConfig$2 = ReactSharedInternals.ReactCurrentBatchConfig, + renderLanes = 0, currentlyRenderingFiber$1 = null, currentHook = null, workInProgressHook = null, @@ -3550,7 +3398,7 @@ function renderWithHooks( workInProgress.memoizedState = null; workInProgress.updateQueue = null; workInProgress.lanes = 0; - ReactSharedInternals.H = + ReactCurrentDispatcher$1.current = null === current || null === current.memoizedState ? HooksDispatcherOnMount : HooksDispatcherOnUpdate; @@ -3568,7 +3416,7 @@ function renderWithHooks( return current; } function finishRenderingHooks() { - ReactSharedInternals.H = ContextOnlyDispatcher; + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; var didRenderTooFewHooks = null !== currentHook && null !== currentHook.next; renderLanes = 0; workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; @@ -3594,23 +3442,11 @@ function renderWithHooksAgain(workInProgress, Component, props, secondArg) { numberOfReRenders += 1; workInProgressHook = currentHook = null; workInProgress.updateQueue = null; - ReactSharedInternals.H = HooksDispatcherOnRerender; + ReactCurrentDispatcher$1.current = HooksDispatcherOnRerender; var children = Component(props, secondArg); } while (didScheduleRenderPhaseUpdateDuringThisPass); return children; } -function TransitionAwareHostComponent() { - var dispatcher = ReactSharedInternals.H, - maybeThenable = dispatcher.useState()[0]; - maybeThenable = - "function" === typeof maybeThenable.then - ? useThenable(maybeThenable) - : maybeThenable; - dispatcher = dispatcher.useState()[0]; - (null !== currentHook ? currentHook.memoizedState : null) !== dispatcher && - (currentlyRenderingFiber$1.flags |= 1024); - return maybeThenable; -} function bailoutHooks(current, workInProgress, lanes) { workInProgress.updateQueue = current.updateQueue; workInProgress.flags &= -2053; @@ -3686,23 +3522,18 @@ function updateWorkInProgressHook() { } var createFunctionComponentUpdateQueue; createFunctionComponentUpdateQueue = function () { - return { lastEffect: null, events: null, stores: null, memoCache: null }; + return { lastEffect: null, events: null, stores: null }; }; function useThenable(thenable) { var index = thenableIndexCounter; thenableIndexCounter += 1; null === thenableState && (thenableState = []); thenable = trackUsedThenable(thenableState, thenable, index); - index = currentlyRenderingFiber$1; - null === + null === currentlyRenderingFiber$1.alternate && (null === workInProgressHook - ? index.memoizedState - : workInProgressHook.next) && - ((index = index.alternate), - (ReactSharedInternals.H = - null === index || null === index.memoizedState - ? HooksDispatcherOnMount - : HooksDispatcherOnUpdate)); + ? null === currentlyRenderingFiber$1.memoizedState + : null === workInProgressHook.next) && + (ReactCurrentDispatcher$1.current = HooksDispatcherOnMount); return thenable; } function use(usable) { @@ -3712,52 +3543,16 @@ function use(usable) { } throw Error("An unsupported type was passed to use(): " + String(usable)); } -function useMemoCache(size) { - var memoCache = null, - updateQueue = currentlyRenderingFiber$1.updateQueue; - null !== updateQueue && (memoCache = updateQueue.memoCache); - if (null == memoCache) { - var current = currentlyRenderingFiber$1.alternate; - null !== current && - ((current = current.updateQueue), - null !== current && - ((current = current.memoCache), - null != current && - (memoCache = { - data: current.data.map(function (array) { - return array.slice(); - }), - index: 0 - }))); - } - null == memoCache && (memoCache = { data: [], index: 0 }); - null === updateQueue && - ((updateQueue = createFunctionComponentUpdateQueue()), - (currentlyRenderingFiber$1.updateQueue = updateQueue)); - updateQueue.memoCache = memoCache; - updateQueue = memoCache.data[memoCache.index]; - if (void 0 === updateQueue) - for ( - updateQueue = memoCache.data[memoCache.index] = Array(size), current = 0; - current < size; - current++ - ) - updateQueue[current] = REACT_MEMO_CACHE_SENTINEL; - memoCache.index++; - return updateQueue; -} function basicStateReducer(state, action) { return "function" === typeof action ? action(state) : action; } function updateReducer(reducer) { - var hook = updateWorkInProgressHook(); - return updateReducerImpl(hook, currentHook, reducer); -} -function updateReducerImpl(hook, current, reducer) { - var queue = hook.queue; + var hook = updateWorkInProgressHook(), + current = currentHook, + queue = hook.queue; if (null === queue) throw Error( - "Should have a queue. You are likely calling Hooks conditionally, which is not allowed. (https://react.dev/link/invalid-hook-call)" + "Should have a queue. This is likely a bug in React. Please file an issue." ); queue.lastRenderedReducer = reducer; var baseQueue = hook.baseQueue, @@ -3777,82 +3572,52 @@ function updateReducerImpl(hook, current, reducer) { current = baseQueue.next; var newBaseQueueFirst = (baseFirst = null), newBaseQueueLast = null, - update = current, - didReadFromEntangledAsyncAction$45 = !1; + update = current; do { var updateLane = update.lane & -536870913; if ( updateLane !== update.lane ? (workInProgressRootRenderLanes & updateLane) === updateLane : (renderLanes & updateLane) === updateLane - ) { - var revertLane = update.revertLane; - if (0 === revertLane) - null !== newBaseQueueLast && - (newBaseQueueLast = newBaseQueueLast.next = - { - lane: 0, - revertLane: 0, - action: update.action, - hasEagerState: update.hasEagerState, - eagerState: update.eagerState, - next: null - }), - updateLane === currentEntangledLane && - (didReadFromEntangledAsyncAction$45 = !0); - else if ((renderLanes & revertLane) === revertLane) { - update = update.next; - revertLane === currentEntangledLane && - (didReadFromEntangledAsyncAction$45 = !0); - continue; - } else - (updateLane = { - lane: 0, - revertLane: update.revertLane, - action: update.action, - hasEagerState: update.hasEagerState, - eagerState: update.eagerState, - next: null - }), - null === newBaseQueueLast - ? ((newBaseQueueFirst = newBaseQueueLast = updateLane), - (baseFirst = pendingQueue)) - : (newBaseQueueLast = newBaseQueueLast.next = updateLane), - (currentlyRenderingFiber$1.lanes |= revertLane), - (workInProgressRootSkippedLanes |= revertLane); - updateLane = update.action; - shouldDoubleInvokeUserFnsInHooksDEV && - reducer(pendingQueue, updateLane); - pendingQueue = update.hasEagerState - ? update.eagerState - : reducer(pendingQueue, updateLane); - } else - (revertLane = { + ) + null !== newBaseQueueLast && + (newBaseQueueLast = newBaseQueueLast.next = + { + lane: 0, + revertLane: 0, + action: update.action, + hasEagerState: update.hasEagerState, + eagerState: update.eagerState, + next: null + }), + (updateLane = update.action), + shouldDoubleInvokeUserFnsInHooksDEV && + reducer(pendingQueue, updateLane), + (pendingQueue = update.hasEagerState + ? update.eagerState + : reducer(pendingQueue, updateLane)); + else { + var clone = { lane: updateLane, revertLane: update.revertLane, action: update.action, hasEagerState: update.hasEagerState, eagerState: update.eagerState, next: null - }), - null === newBaseQueueLast - ? ((newBaseQueueFirst = newBaseQueueLast = revertLane), - (baseFirst = pendingQueue)) - : (newBaseQueueLast = newBaseQueueLast.next = revertLane), - (currentlyRenderingFiber$1.lanes |= updateLane), - (workInProgressRootSkippedLanes |= updateLane); + }; + null === newBaseQueueLast + ? ((newBaseQueueFirst = newBaseQueueLast = clone), + (baseFirst = pendingQueue)) + : (newBaseQueueLast = newBaseQueueLast.next = clone); + currentlyRenderingFiber$1.lanes |= updateLane; + workInProgressRootSkippedLanes |= updateLane; + } update = update.next; } while (null !== update && update !== current); null === newBaseQueueLast ? (baseFirst = pendingQueue) : (newBaseQueueLast.next = newBaseQueueFirst); - if ( - !objectIs(pendingQueue, hook.memoizedState) && - ((didReceiveUpdate = !0), - didReadFromEntangledAsyncAction$45 && - ((reducer = currentEntangledActionThenable), null !== reducer)) - ) - throw reducer; + objectIs(pendingQueue, hook.memoizedState) || (didReceiveUpdate = !0); hook.memoizedState = pendingQueue; hook.baseState = baseFirst; hook.baseQueue = newBaseQueueLast; @@ -3866,7 +3631,7 @@ function rerenderReducer(reducer) { queue = hook.queue; if (null === queue) throw Error( - "Should have a queue. You are likely calling Hooks conditionally, which is not allowed. (https://react.dev/link/invalid-hook-call)" + "Should have a queue. This is likely a bug in React. Please file an issue." ); queue.lastRenderedReducer = reducer; var dispatch = queue.dispatch, @@ -3961,10 +3726,7 @@ function mountStateImpl(initialState) { if ("function" === typeof initialState) { var initialStateInitializer = initialState; initialState = initialStateInitializer(); - shouldDoubleInvokeUserFnsInHooksDEV && - (setIsStrictModeForDevtools(!0), - initialStateInitializer(), - setIsStrictModeForDevtools(!1)); + shouldDoubleInvokeUserFnsInHooksDEV && initialStateInitializer(); } hook.memoizedState = hook.baseState = initialState; hook.queue = { @@ -3976,214 +3738,6 @@ function mountStateImpl(initialState) { }; return hook; } -function updateOptimisticImpl(hook, current, passthrough, reducer) { - hook.baseState = passthrough; - return updateReducerImpl( - hook, - currentHook, - "function" === typeof reducer ? reducer : basicStateReducer - ); -} -function dispatchActionState( - fiber, - actionQueue, - setPendingState, - setState, - payload -) { - if (isRenderPhaseUpdate(fiber)) - throw Error("Cannot update form state while rendering."); - fiber = actionQueue.action; - if (null !== fiber) { - var actionNode = { - payload: payload, - action: fiber, - next: null, - isTransition: !0, - status: "pending", - value: null, - reason: null, - listeners: [], - then: function (listener) { - actionNode.listeners.push(listener); - } - }; - null !== ReactSharedInternals.T - ? setPendingState(!0) - : (actionNode.isTransition = !1); - setState(actionNode); - setPendingState = actionQueue.pending; - null === setPendingState - ? ((actionNode.next = actionQueue.pending = actionNode), - runActionStateAction(actionQueue, actionNode)) - : ((actionNode.next = setPendingState.next), - (actionQueue.pending = setPendingState.next = actionNode)); - } -} -function runActionStateAction(actionQueue, node) { - var action = node.action, - payload = node.payload, - prevState = actionQueue.state; - if (node.isTransition) { - var prevTransition = ReactSharedInternals.T, - currentTransition = {}; - ReactSharedInternals.T = currentTransition; - try { - var returnValue = action(prevState, payload), - onStartTransitionFinish = ReactSharedInternals.S; - null !== onStartTransitionFinish && - onStartTransitionFinish(currentTransition, returnValue); - handleActionReturnValue(actionQueue, node, returnValue); - } catch (error) { - onActionError(actionQueue, node, error); - } finally { - ReactSharedInternals.T = prevTransition; - } - } else - try { - (prevTransition = action(prevState, payload)), - handleActionReturnValue(actionQueue, node, prevTransition); - } catch (error$49) { - onActionError(actionQueue, node, error$49); - } -} -function handleActionReturnValue(actionQueue, node, returnValue) { - null !== returnValue && - "object" === typeof returnValue && - "function" === typeof returnValue.then - ? returnValue.then( - function (nextState) { - onActionSuccess(actionQueue, node, nextState); - }, - function (error) { - return onActionError(actionQueue, node, error); - } - ) - : onActionSuccess(actionQueue, node, returnValue); -} -function onActionSuccess(actionQueue, actionNode, nextState) { - actionNode.status = "fulfilled"; - actionNode.value = nextState; - notifyActionListeners(actionNode); - actionQueue.state = nextState; - actionNode = actionQueue.pending; - null !== actionNode && - ((nextState = actionNode.next), - nextState === actionNode - ? (actionQueue.pending = null) - : ((nextState = nextState.next), - (actionNode.next = nextState), - runActionStateAction(actionQueue, nextState))); -} -function onActionError(actionQueue, actionNode, error) { - var last = actionQueue.pending; - actionQueue.pending = null; - if (null !== last) { - last = last.next; - do - (actionNode.status = "rejected"), - (actionNode.reason = error), - notifyActionListeners(actionNode), - (actionNode = actionNode.next); - while (actionNode !== last); - } - actionQueue.action = null; -} -function notifyActionListeners(actionNode) { - actionNode = actionNode.listeners; - for (var i = 0; i < actionNode.length; i++) (0, actionNode[i])(); -} -function actionStateReducer(oldState, newState) { - return newState; -} -function mountActionState(action, initialStateProp) { - var stateHook = mountWorkInProgressHook(); - stateHook.memoizedState = stateHook.baseState = initialStateProp; - var stateQueue = { - pending: null, - lanes: 0, - dispatch: null, - lastRenderedReducer: actionStateReducer, - lastRenderedState: initialStateProp - }; - stateHook.queue = stateQueue; - stateHook = dispatchSetState.bind( - null, - currentlyRenderingFiber$1, - stateQueue - ); - stateQueue.dispatch = stateHook; - stateQueue = mountStateImpl(!1); - var setPendingState = dispatchOptimisticSetState.bind( - null, - currentlyRenderingFiber$1, - !1, - stateQueue.queue - ); - stateQueue = mountWorkInProgressHook(); - var actionQueue = { - state: initialStateProp, - dispatch: null, - action: action, - pending: null - }; - stateQueue.queue = actionQueue; - stateHook = dispatchActionState.bind( - null, - currentlyRenderingFiber$1, - actionQueue, - setPendingState, - stateHook - ); - actionQueue.dispatch = stateHook; - stateQueue.memoizedState = action; - return [initialStateProp, stateHook, !1]; -} -function updateActionState(action) { - var stateHook = updateWorkInProgressHook(); - return updateActionStateImpl(stateHook, currentHook, action); -} -function updateActionStateImpl(stateHook, currentStateHook, action) { - currentStateHook = updateReducerImpl( - stateHook, - currentStateHook, - actionStateReducer - )[0]; - stateHook = updateReducer(basicStateReducer)[0]; - currentStateHook = - "object" === typeof currentStateHook && - null !== currentStateHook && - "function" === typeof currentStateHook.then - ? useThenable(currentStateHook) - : currentStateHook; - var actionQueueHook = updateWorkInProgressHook(), - actionQueue = actionQueueHook.queue, - dispatch = actionQueue.dispatch; - action !== actionQueueHook.memoizedState && - ((currentlyRenderingFiber$1.flags |= 2048), - pushEffect( - 9, - actionStateActionEffect.bind(null, actionQueue, action), - { destroy: void 0 }, - null - )); - return [currentStateHook, dispatch, stateHook]; -} -function actionStateActionEffect(actionQueue, action) { - actionQueue.action = action; -} -function rerenderActionState(action) { - var stateHook = updateWorkInProgressHook(), - currentStateHook = currentHook; - if (null !== currentStateHook) - return updateActionStateImpl(stateHook, currentStateHook, action); - updateWorkInProgressHook(); - stateHook = stateHook.memoizedState; - currentStateHook = updateWorkInProgressHook(); - var dispatch = currentStateHook.queue.dispatch; - currentStateHook.memoizedState = action; - return [stateHook, dispatch, !1]; -} function pushEffect(tag, create, inst, deps) { tag = { tag: tag, create: create, inst: inst, deps: deps, next: null }; create = currentlyRenderingFiber$1.updateQueue; @@ -4237,13 +3791,14 @@ function updateLayoutEffect(create, deps) { return updateEffectImpl(4, 4, create, deps); } function imperativeHandleEffect(create, ref) { - if ("function" === typeof ref) { - create = create(); - var refCleanup = ref(create); - return function () { - "function" === typeof refCleanup ? refCleanup() : ref(null); - }; - } + if ("function" === typeof ref) + return ( + (create = create()), + ref(create), + function () { + ref(null); + } + ); if (null !== ref && void 0 !== ref) return ( (create = create()), @@ -4274,21 +3829,18 @@ function updateMemo(nextCreate, deps) { if (null !== deps && areHookInputsEqual(deps, prevState[1])) return prevState[0]; prevState = nextCreate(); - shouldDoubleInvokeUserFnsInHooksDEV && - (setIsStrictModeForDevtools(!0), - nextCreate(), - setIsStrictModeForDevtools(!1)); + shouldDoubleInvokeUserFnsInHooksDEV && nextCreate(); hook.memoizedState = [prevState, deps]; return prevState; } function mountDeferredValueImpl(hook, value, initialValue) { - if (void 0 === initialValue || 0 !== (renderLanes & 1073741824)) - return (hook.memoizedState = value); - hook.memoizedState = initialValue; - hook = requestDeferredLane(); - currentlyRenderingFiber$1.lanes |= hook; - workInProgressRootSkippedLanes |= hook; - return initialValue; + return void 0 !== initialValue && 0 === (renderLanes & 1073741824) + ? ((hook.memoizedState = initialValue), + (hook = requestDeferredLane()), + (currentlyRenderingFiber$1.lanes |= hook), + (workInProgressRootSkippedLanes |= hook), + initialValue) + : (hook.memoizedState = value); } function updateDeferredValueImpl(hook, prevValue, value, initialValue) { if (objectIs(value, prevValue)) return value; @@ -4309,65 +3861,23 @@ function startTransition(fiber, queue, pendingState, finishedState, callback) { var previousPriority = currentUpdatePriority; currentUpdatePriority = 0 !== previousPriority && 8 > previousPriority ? previousPriority : 8; - var prevTransition = ReactSharedInternals.T, - currentTransition = {}; - ReactSharedInternals.T = currentTransition; - dispatchOptimisticSetState(fiber, !1, queue, pendingState); + var prevTransition = ReactCurrentBatchConfig$2.transition, + currentTransition = { _callbacks: new Set() }; + ReactCurrentBatchConfig$2.transition = null; + dispatchSetState(fiber, queue, pendingState); + ReactCurrentBatchConfig$2.transition = currentTransition; try { - var returnValue = callback(), - onStartTransitionFinish = ReactSharedInternals.S; - null !== onStartTransitionFinish && - onStartTransitionFinish(currentTransition, returnValue); - if ( - null !== returnValue && - "object" === typeof returnValue && - "function" === typeof returnValue.then - ) { - var thenableForFinishedState = chainThenableValue( - returnValue, - finishedState - ); - dispatchSetState(fiber, queue, thenableForFinishedState); - } else dispatchSetState(fiber, queue, finishedState); + dispatchSetState(fiber, queue, finishedState), callback(); } catch (error) { - dispatchSetState(fiber, queue, { - then: function () {}, - status: "rejected", - reason: error - }); + throw error; } finally { (currentUpdatePriority = previousPriority), - (ReactSharedInternals.T = prevTransition); + (ReactCurrentBatchConfig$2.transition = prevTransition); } } -function useHostTransitionStatus() { - var status = readContext(HostTransitionContext); - return null !== status ? status : null; -} function updateId() { return updateWorkInProgressHook().memoizedState; } -function updateRefresh() { - return updateWorkInProgressHook().memoizedState; -} -function refreshCache(fiber) { - for (var provider = fiber.return; null !== provider; ) { - switch (provider.tag) { - case 24: - case 3: - var lane = requestUpdateLane(provider); - fiber = createUpdate(lane); - var root = enqueueUpdate(provider, fiber, lane); - null !== root && - (scheduleUpdateOnFiber(root, provider, lane), - entangleTransitions(root, provider, lane)); - provider = { cache: createCache() }; - fiber.payload = provider; - return; - } - provider = provider.return; - } -} function dispatchReducerAction(fiber, queue, action) { var lane = requestUpdateLane(fiber); action = { @@ -4380,7 +3890,8 @@ function dispatchReducerAction(fiber, queue, action) { }; isRenderPhaseUpdate(fiber) ? enqueueRenderPhaseUpdate(queue, action) - : ((action = enqueueConcurrentHookUpdate(fiber, queue, action, lane)), + : (enqueueUpdate$1(fiber, queue, action, lane), + (action = getRootForUpdatedFiber(fiber)), null !== action && (scheduleUpdateOnFiber(action, fiber, lane), entangleTransitionUpdate(action, queue, lane))); @@ -4416,34 +3927,13 @@ function dispatchSetState(fiber, queue, action) { } catch (error) { } finally { } - action = enqueueConcurrentHookUpdate(fiber, queue, update, lane); + enqueueUpdate$1(fiber, queue, update, lane); + action = getRootForUpdatedFiber(fiber); null !== action && (scheduleUpdateOnFiber(action, fiber, lane), entangleTransitionUpdate(action, queue, lane)); } } -function dispatchOptimisticSetState(fiber, throwIfDuringRender, queue, action) { - action = { - lane: 2, - revertLane: requestTransitionLane(), - action: action, - hasEagerState: !1, - eagerState: null, - next: null - }; - if (isRenderPhaseUpdate(fiber)) { - if (throwIfDuringRender) - throw Error("Cannot update optimistic state while rendering."); - } else - (throwIfDuringRender = enqueueConcurrentHookUpdate( - fiber, - queue, - action, - 2 - )), - null !== throwIfDuringRender && - scheduleUpdateOnFiber(throwIfDuringRender, fiber, 2); -} function isRenderPhaseUpdate(fiber) { var alternate = fiber.alternate; return ( @@ -4470,285 +3960,237 @@ function entangleTransitionUpdate(root, queue, lane) { } } var ContextOnlyDispatcher = { - readContext: readContext, - use: use, - useCallback: throwInvalidHookError, - useContext: throwInvalidHookError, - useEffect: throwInvalidHookError, - useImperativeHandle: throwInvalidHookError, - useLayoutEffect: throwInvalidHookError, - useInsertionEffect: throwInvalidHookError, - useMemo: throwInvalidHookError, - useReducer: throwInvalidHookError, - useRef: throwInvalidHookError, - useState: throwInvalidHookError, - useDebugValue: throwInvalidHookError, - useDeferredValue: throwInvalidHookError, - useTransition: throwInvalidHookError, - useSyncExternalStore: throwInvalidHookError, - useId: throwInvalidHookError -}; -ContextOnlyDispatcher.useCacheRefresh = throwInvalidHookError; -ContextOnlyDispatcher.useMemoCache = throwInvalidHookError; -ContextOnlyDispatcher.useHostTransitionStatus = throwInvalidHookError; -ContextOnlyDispatcher.useFormState = throwInvalidHookError; -ContextOnlyDispatcher.useActionState = throwInvalidHookError; -ContextOnlyDispatcher.useOptimistic = throwInvalidHookError; -var HooksDispatcherOnMount = { - readContext: readContext, - use: use, - useCallback: function (callback, deps) { - mountWorkInProgressHook().memoizedState = [ - callback, - void 0 === deps ? null : deps - ]; - return callback; - }, - useContext: readContext, - useEffect: mountEffect, - useImperativeHandle: function (ref, create, deps) { - deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; - mountEffectImpl( - 4194308, - 4, - imperativeHandleEffect.bind(null, create, ref), - deps - ); - }, - useLayoutEffect: function (create, deps) { - return mountEffectImpl(4194308, 4, create, deps); - }, - useInsertionEffect: function (create, deps) { - mountEffectImpl(4, 2, create, deps); - }, - useMemo: function (nextCreate, deps) { - var hook = mountWorkInProgressHook(); - deps = void 0 === deps ? null : deps; - var nextValue = nextCreate(); - shouldDoubleInvokeUserFnsInHooksDEV && - (setIsStrictModeForDevtools(!0), - nextCreate(), - setIsStrictModeForDevtools(!1)); - hook.memoizedState = [nextValue, deps]; - return nextValue; - }, - useReducer: function (reducer, initialArg, init) { - var hook = mountWorkInProgressHook(); - if (void 0 !== init) { - var initialState = init(initialArg); - shouldDoubleInvokeUserFnsInHooksDEV && - (setIsStrictModeForDevtools(!0), - init(initialArg), - setIsStrictModeForDevtools(!1)); - } else initialState = initialArg; - hook.memoizedState = hook.baseState = initialState; - reducer = { - pending: null, - lanes: 0, - dispatch: null, - lastRenderedReducer: reducer, - lastRenderedState: initialState - }; - hook.queue = reducer; - reducer = reducer.dispatch = dispatchReducerAction.bind( - null, - currentlyRenderingFiber$1, - reducer - ); - return [hook.memoizedState, reducer]; - }, - useRef: function (initialValue) { - var hook = mountWorkInProgressHook(); - initialValue = { current: initialValue }; - return (hook.memoizedState = initialValue); - }, - useState: function (initialState) { - initialState = mountStateImpl(initialState); - var queue = initialState.queue, - dispatch = dispatchSetState.bind(null, currentlyRenderingFiber$1, queue); - queue.dispatch = dispatch; - return [initialState.memoizedState, dispatch]; - }, - useDebugValue: mountDebugValue, - useDeferredValue: function (value, initialValue) { - var hook = mountWorkInProgressHook(); - return mountDeferredValueImpl(hook, value, initialValue); - }, - useTransition: function () { - var stateHook = mountStateImpl(!1); - stateHook = startTransition.bind( - null, - currentlyRenderingFiber$1, - stateHook.queue, - !0, - !1 - ); - mountWorkInProgressHook().memoizedState = stateHook; - return [!1, stateHook]; + readContext: readContext, + use: use, + useCallback: throwInvalidHookError, + useContext: throwInvalidHookError, + useEffect: throwInvalidHookError, + useImperativeHandle: throwInvalidHookError, + useInsertionEffect: throwInvalidHookError, + useLayoutEffect: throwInvalidHookError, + useMemo: throwInvalidHookError, + useReducer: throwInvalidHookError, + useRef: throwInvalidHookError, + useState: throwInvalidHookError, + useDebugValue: throwInvalidHookError, + useDeferredValue: throwInvalidHookError, + useTransition: throwInvalidHookError, + useSyncExternalStore: throwInvalidHookError, + useId: throwInvalidHookError }, - useSyncExternalStore: function (subscribe, getSnapshot) { - var fiber = currentlyRenderingFiber$1, - hook = mountWorkInProgressHook(); - var nextSnapshot = getSnapshot(); - if (null === workInProgressRoot) - throw Error( - "Expected a work-in-progress root. This is a bug in React. Please file an issue." + HooksDispatcherOnMount = { + readContext: readContext, + use: use, + useCallback: function (callback, deps) { + mountWorkInProgressHook().memoizedState = [ + callback, + void 0 === deps ? null : deps + ]; + return callback; + }, + useContext: readContext, + useEffect: mountEffect, + useImperativeHandle: function (ref, create, deps) { + deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; + mountEffectImpl( + 4194308, + 4, + imperativeHandleEffect.bind(null, create, ref), + deps ); - 0 !== (workInProgressRootRenderLanes & 60) || - pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot); - hook.memoizedState = nextSnapshot; - var inst = { value: nextSnapshot, getSnapshot: getSnapshot }; - hook.queue = inst; - mountEffect(subscribeToStore.bind(null, fiber, inst, subscribe), [ - subscribe - ]); - fiber.flags |= 2048; - pushEffect( - 9, - updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot), - { destroy: void 0 }, - null - ); - return nextSnapshot; - }, - useId: function () { - var hook = mountWorkInProgressHook(), - identifierPrefix = workInProgressRoot.identifierPrefix, - globalClientId = globalClientIdCounter++; - identifierPrefix = - ":" + identifierPrefix + "r" + globalClientId.toString(32) + ":"; - return (hook.memoizedState = identifierPrefix); - }, - useCacheRefresh: function () { - return (mountWorkInProgressHook().memoizedState = refreshCache.bind( - null, - currentlyRenderingFiber$1 - )); - } -}; -HooksDispatcherOnMount.useMemoCache = useMemoCache; -HooksDispatcherOnMount.useHostTransitionStatus = useHostTransitionStatus; -HooksDispatcherOnMount.useFormState = mountActionState; -HooksDispatcherOnMount.useActionState = mountActionState; -HooksDispatcherOnMount.useOptimistic = function (passthrough) { - var hook = mountWorkInProgressHook(); - hook.memoizedState = hook.baseState = passthrough; - var queue = { - pending: null, - lanes: 0, - dispatch: null, - lastRenderedReducer: null, - lastRenderedState: null - }; - hook.queue = queue; - hook = dispatchOptimisticSetState.bind( - null, - currentlyRenderingFiber$1, - !0, - queue - ); - queue.dispatch = hook; - return [passthrough, hook]; -}; -var HooksDispatcherOnUpdate = { - readContext: readContext, - use: use, - useCallback: updateCallback, - useContext: readContext, - useEffect: updateEffect, - useImperativeHandle: updateImperativeHandle, - useInsertionEffect: updateInsertionEffect, - useLayoutEffect: updateLayoutEffect, - useMemo: updateMemo, - useReducer: updateReducer, - useRef: updateRef, - useState: function () { - return updateReducer(basicStateReducer); - }, - useDebugValue: mountDebugValue, - useDeferredValue: function (value, initialValue) { - var hook = updateWorkInProgressHook(); - return updateDeferredValueImpl( - hook, - currentHook.memoizedState, - value, - initialValue - ); - }, - useTransition: function () { - var booleanOrThenable = updateReducer(basicStateReducer)[0], - start = updateWorkInProgressHook().memoizedState; - return [ - "boolean" === typeof booleanOrThenable - ? booleanOrThenable - : useThenable(booleanOrThenable), - start - ]; - }, - useSyncExternalStore: updateSyncExternalStore, - useId: updateId -}; -HooksDispatcherOnUpdate.useCacheRefresh = updateRefresh; -HooksDispatcherOnUpdate.useMemoCache = useMemoCache; -HooksDispatcherOnUpdate.useHostTransitionStatus = useHostTransitionStatus; -HooksDispatcherOnUpdate.useFormState = updateActionState; -HooksDispatcherOnUpdate.useActionState = updateActionState; -HooksDispatcherOnUpdate.useOptimistic = function (passthrough, reducer) { - var hook = updateWorkInProgressHook(); - return updateOptimisticImpl(hook, currentHook, passthrough, reducer); -}; -var HooksDispatcherOnRerender = { - readContext: readContext, - use: use, - useCallback: updateCallback, - useContext: readContext, - useEffect: updateEffect, - useImperativeHandle: updateImperativeHandle, - useInsertionEffect: updateInsertionEffect, - useLayoutEffect: updateLayoutEffect, - useMemo: updateMemo, - useReducer: rerenderReducer, - useRef: updateRef, - useState: function () { - return rerenderReducer(basicStateReducer); - }, - useDebugValue: mountDebugValue, - useDeferredValue: function (value, initialValue) { - var hook = updateWorkInProgressHook(); - return null === currentHook - ? mountDeferredValueImpl(hook, value, initialValue) - : updateDeferredValueImpl( - hook, - currentHook.memoizedState, - value, - initialValue + }, + useLayoutEffect: function (create, deps) { + return mountEffectImpl(4194308, 4, create, deps); + }, + useInsertionEffect: function (create, deps) { + mountEffectImpl(4, 2, create, deps); + }, + useMemo: function (nextCreate, deps) { + var hook = mountWorkInProgressHook(); + deps = void 0 === deps ? null : deps; + var nextValue = nextCreate(); + shouldDoubleInvokeUserFnsInHooksDEV && nextCreate(); + hook.memoizedState = [nextValue, deps]; + return nextValue; + }, + useReducer: function (reducer, initialArg, init) { + var hook = mountWorkInProgressHook(); + if (void 0 !== init) { + var initialState = init(initialArg); + shouldDoubleInvokeUserFnsInHooksDEV && init(initialArg); + } else initialState = initialArg; + hook.memoizedState = hook.baseState = initialState; + reducer = { + pending: null, + lanes: 0, + dispatch: null, + lastRenderedReducer: reducer, + lastRenderedState: initialState + }; + hook.queue = reducer; + reducer = reducer.dispatch = dispatchReducerAction.bind( + null, + currentlyRenderingFiber$1, + reducer + ); + return [hook.memoizedState, reducer]; + }, + useRef: function (initialValue) { + var hook = mountWorkInProgressHook(); + initialValue = { current: initialValue }; + return (hook.memoizedState = initialValue); + }, + useState: function (initialState) { + initialState = mountStateImpl(initialState); + var queue = initialState.queue, + dispatch = dispatchSetState.bind( + null, + currentlyRenderingFiber$1, + queue + ); + queue.dispatch = dispatch; + return [initialState.memoizedState, dispatch]; + }, + useDebugValue: mountDebugValue, + useDeferredValue: function (value, initialValue) { + var hook = mountWorkInProgressHook(); + return mountDeferredValueImpl(hook, value, initialValue); + }, + useTransition: function () { + var stateHook = mountStateImpl(!1); + stateHook = startTransition.bind( + null, + currentlyRenderingFiber$1, + stateHook.queue, + !0, + !1 + ); + mountWorkInProgressHook().memoizedState = stateHook; + return [!1, stateHook]; + }, + useSyncExternalStore: function (subscribe, getSnapshot) { + var fiber = currentlyRenderingFiber$1, + hook = mountWorkInProgressHook(); + var nextSnapshot = getSnapshot(); + if (null === workInProgressRoot) + throw Error( + "Expected a work-in-progress root. This is a bug in React. Please file an issue." ); + 0 !== (workInProgressRootRenderLanes & 60) || + pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot); + hook.memoizedState = nextSnapshot; + var inst = { value: nextSnapshot, getSnapshot: getSnapshot }; + hook.queue = inst; + mountEffect(subscribeToStore.bind(null, fiber, inst, subscribe), [ + subscribe + ]); + fiber.flags |= 2048; + pushEffect( + 9, + updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot), + { destroy: void 0 }, + null + ); + return nextSnapshot; + }, + useId: function () { + var hook = mountWorkInProgressHook(), + identifierPrefix = workInProgressRoot.identifierPrefix, + globalClientId = globalClientIdCounter++; + identifierPrefix = + ":" + identifierPrefix + "r" + globalClientId.toString(32) + ":"; + return (hook.memoizedState = identifierPrefix); + } }, - useTransition: function () { - var booleanOrThenable = rerenderReducer(basicStateReducer)[0], - start = updateWorkInProgressHook().memoizedState; - return [ - "boolean" === typeof booleanOrThenable - ? booleanOrThenable - : useThenable(booleanOrThenable), - start - ]; + HooksDispatcherOnUpdate = { + readContext: readContext, + use: use, + useCallback: updateCallback, + useContext: readContext, + useEffect: updateEffect, + useImperativeHandle: updateImperativeHandle, + useInsertionEffect: updateInsertionEffect, + useLayoutEffect: updateLayoutEffect, + useMemo: updateMemo, + useReducer: updateReducer, + useRef: updateRef, + useState: function () { + return updateReducer(basicStateReducer); + }, + useDebugValue: mountDebugValue, + useDeferredValue: function (value, initialValue) { + var hook = updateWorkInProgressHook(); + return updateDeferredValueImpl( + hook, + currentHook.memoizedState, + value, + initialValue + ); + }, + useTransition: function () { + var booleanOrThenable = updateReducer(basicStateReducer)[0], + start = updateWorkInProgressHook().memoizedState; + return [ + "boolean" === typeof booleanOrThenable + ? booleanOrThenable + : useThenable(booleanOrThenable), + start + ]; + }, + useSyncExternalStore: updateSyncExternalStore, + useId: updateId }, - useSyncExternalStore: updateSyncExternalStore, - useId: updateId -}; -HooksDispatcherOnRerender.useCacheRefresh = updateRefresh; -HooksDispatcherOnRerender.useMemoCache = useMemoCache; -HooksDispatcherOnRerender.useHostTransitionStatus = useHostTransitionStatus; -HooksDispatcherOnRerender.useFormState = rerenderActionState; -HooksDispatcherOnRerender.useActionState = rerenderActionState; -HooksDispatcherOnRerender.useOptimistic = function (passthrough, reducer) { - var hook = updateWorkInProgressHook(); - if (null !== currentHook) - return updateOptimisticImpl(hook, currentHook, passthrough, reducer); - hook.baseState = passthrough; - return [passthrough, hook.queue.dispatch]; -}; + HooksDispatcherOnRerender = { + readContext: readContext, + use: use, + useCallback: updateCallback, + useContext: readContext, + useEffect: updateEffect, + useImperativeHandle: updateImperativeHandle, + useInsertionEffect: updateInsertionEffect, + useLayoutEffect: updateLayoutEffect, + useMemo: updateMemo, + useReducer: rerenderReducer, + useRef: updateRef, + useState: function () { + return rerenderReducer(basicStateReducer); + }, + useDebugValue: mountDebugValue, + useDeferredValue: function (value, initialValue) { + var hook = updateWorkInProgressHook(); + return null === currentHook + ? mountDeferredValueImpl(hook, value, initialValue) + : updateDeferredValueImpl( + hook, + currentHook.memoizedState, + value, + initialValue + ); + }, + useTransition: function () { + var booleanOrThenable = rerenderReducer(basicStateReducer)[0], + start = updateWorkInProgressHook().memoizedState; + return [ + "boolean" === typeof booleanOrThenable + ? booleanOrThenable + : useThenable(booleanOrThenable), + start + ]; + }, + useSyncExternalStore: updateSyncExternalStore, + useId: updateId + }; +function resolveDefaultProps(Component, baseProps) { + if (Component && Component.defaultProps) { + baseProps = assign({}, baseProps); + Component = Component.defaultProps; + for (var propName in Component) + void 0 === baseProps[propName] && + (baseProps[propName] = Component[propName]); + return baseProps; + } + return baseProps; +} function applyDerivedStateFromProps( workInProgress, ctor, @@ -4878,111 +4320,80 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { ctor !== instance.state && classComponentUpdater.enqueueReplaceState(instance, instance.state, null), processUpdateQueue(workInProgress, newProps, instance, renderLanes), - suspendIfUpdateReadFromEntangledAsyncAction(), (instance.state = workInProgress.memoizedState)); "function" === typeof instance.componentDidMount && (workInProgress.flags |= 4194308); } -function resolveClassComponentProps(Component, baseProps) { - var newProps = baseProps; - if ("ref" in baseProps) { - newProps = {}; - for (var propName in baseProps) - "ref" !== propName && (newProps[propName] = baseProps[propName]); - } - if ((Component = Component.defaultProps)) { - newProps === baseProps && (newProps = assign({}, newProps)); - for (var propName$51 in Component) - void 0 === newProps[propName$51] && - (newProps[propName$51] = Component[propName$51]); - } - return newProps; -} -var reportGlobalError = - "function" === typeof reportError - ? reportError - : function (error) { - if ( - "object" === typeof window && - "function" === typeof window.ErrorEvent - ) { - var event = new window.ErrorEvent("error", { - bubbles: !0, - cancelable: !0, - message: - "object" === typeof error && - null !== error && - "string" === typeof error.message - ? String(error.message) - : String(error), - error: error - }); - if (!window.dispatchEvent(event)) return; - } else if ( - "object" === typeof process && - "function" === typeof process.emit - ) { - process.emit("uncaughtException", error); - return; - } - console.error(error); - }; -function defaultOnRecoverableError(error) { - reportGlobalError(error); +var CapturedStacks = new WeakMap(); +function createCapturedValueAtFiber(value, source) { + if ("object" === typeof value && null !== value) { + var stack = CapturedStacks.get(value); + "string" !== typeof stack && + ((stack = getStackByFiberInDevAndProd(source)), + CapturedStacks.set(value, stack)); + } else stack = getStackByFiberInDevAndProd(source); + return { value: value, source: source, stack: stack, digest: null }; } -function logUncaughtError(root, errorInfo) { - try { - var onUncaughtError = root.onUncaughtError; - onUncaughtError(errorInfo.value, { componentStack: errorInfo.stack }); - } catch (e) { - setTimeout(function () { - throw e; - }); - } +function createCapturedValueFromError(value, digest, stack) { + "string" === typeof stack && CapturedStacks.set(value, stack); + return { + value: value, + source: null, + stack: null != stack ? stack : null, + digest: null != digest ? digest : null + }; } -function logCaughtError(root, boundary, errorInfo) { +if ( + "function" !== + typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog +) + throw Error( + "Expected ReactFiberErrorDialog.showErrorDialog to be a function." + ); +function logCapturedError(boundary, errorInfo) { try { - var onCaughtError = root.onCaughtError; - onCaughtError(errorInfo.value, { - componentStack: errorInfo.stack, - errorBoundary: 1 === boundary.tag ? boundary.stateNode : null - }); + !1 !== + ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog({ + componentStack: null !== errorInfo.stack ? errorInfo.stack : "", + error: errorInfo.value, + errorBoundary: + null !== boundary && 1 === boundary.tag ? boundary.stateNode : null + }) && console.error(errorInfo.value); } catch (e) { setTimeout(function () { throw e; }); } } -function createRootErrorUpdate(root, errorInfo, lane) { +function createRootErrorUpdate(fiber, errorInfo, lane) { lane = createUpdate(lane); lane.tag = 3; lane.payload = { element: null }; + var error = errorInfo.value; lane.callback = function () { - logUncaughtError(root, errorInfo); + hasUncaughtError || ((hasUncaughtError = !0), (firstUncaughtError = error)); + logCapturedError(fiber, errorInfo); }; return lane; } -function createClassErrorUpdate(lane) { +function createClassErrorUpdate(fiber, errorInfo, lane) { lane = createUpdate(lane); lane.tag = 3; - return lane; -} -function initializeClassErrorUpdate(update, root, fiber, errorInfo) { var getDerivedStateFromError = fiber.type.getDerivedStateFromError; if ("function" === typeof getDerivedStateFromError) { var error = errorInfo.value; - update.payload = function () { + lane.payload = function () { return getDerivedStateFromError(error); }; - update.callback = function () { - logCaughtError(root, fiber, errorInfo); + lane.callback = function () { + logCapturedError(fiber, errorInfo); }; } var inst = fiber.stateNode; null !== inst && "function" === typeof inst.componentDidCatch && - (update.callback = function () { - logCaughtError(root, fiber, errorInfo); + (lane.callback = function () { + logCapturedError(fiber, errorInfo); "function" !== typeof getDerivedStateFromError && (null === legacyErrorBoundariesThatAlreadyFailed ? (legacyErrorBoundariesThatAlreadyFailed = new Set([this])) @@ -4992,6 +4403,7 @@ function initializeClassErrorUpdate(update, root, fiber, errorInfo) { componentStack: null !== stack ? stack : "" }); }); + return lane; } function throwException( root, @@ -5033,15 +4445,12 @@ function throwException( : ((tag.flags |= 128), (sourceFiber.flags |= 131072), (sourceFiber.flags &= -52805), - 1 === sourceFiber.tag - ? null === sourceFiber.alternate + 1 === sourceFiber.tag && + (null === sourceFiber.alternate ? (sourceFiber.tag = 17) : ((returnFiber = createUpdate(2)), (returnFiber.tag = 2), - enqueueUpdate(sourceFiber, returnFiber, 2)) - : 0 === sourceFiber.tag && - null === sourceFiber.alternate && - (sourceFiber.tag = 28), + enqueueUpdate(sourceFiber, returnFiber, 2))), (sourceFiber.lanes |= 2)) : ((tag.flags |= 65536), (tag.lanes = rootRenderLanes)), value === noopSuspenseyCommitThenable @@ -5092,35 +4501,34 @@ function throwException( "A component suspended while responding to synchronous input. This will cause the UI to be replaced with a loading indicator. To fix, updates that suspend should be wrapped with startTransition." ); } - tag = createCapturedValueAtFiber( - Error( - "There was an error during concurrent rendering but React was able to recover by instead synchronously rendering the entire root.", - { cause: value } - ), - sourceFiber - ); - null === workInProgressRootConcurrentErrors - ? (workInProgressRootConcurrentErrors = [tag]) - : workInProgressRootConcurrentErrors.push(tag); + root = value = createCapturedValueAtFiber(value, sourceFiber); 4 !== workInProgressRootExitStatus && (workInProgressRootExitStatus = 2); + null === workInProgressRootConcurrentErrors + ? (workInProgressRootConcurrentErrors = [root]) + : workInProgressRootConcurrentErrors.push(root); if (null === returnFiber) return !0; - value = createCapturedValueAtFiber(value, sourceFiber); + root = returnFiber; do { - switch (returnFiber.tag) { + switch (root.tag) { case 3: return ( - (returnFiber.flags |= 65536), - (root = rootRenderLanes & -rootRenderLanes), - (returnFiber.lanes |= root), - (root = createRootErrorUpdate(returnFiber.stateNode, value, root)), - enqueueCapturedUpdate(returnFiber, root), + (root.flags |= 65536), + (rootRenderLanes &= -rootRenderLanes), + (root.lanes |= rootRenderLanes), + (rootRenderLanes = createRootErrorUpdate( + root, + value, + rootRenderLanes + )), + enqueueCapturedUpdate(root, rootRenderLanes), !1 ); case 1: if ( - ((sourceFiber = returnFiber.type), - (tag = returnFiber.stateNode), - 0 === (returnFiber.flags & 128) && + ((returnFiber = value), + (sourceFiber = root.type), + (tag = root.stateNode), + 0 === (root.flags & 128) && ("function" === typeof sourceFiber.getDerivedStateFromError || (null !== tag && "function" === typeof tag.componentDidCatch && @@ -5128,25 +4536,24 @@ function throwException( !legacyErrorBoundariesThatAlreadyFailed.has(tag))))) ) return ( - (returnFiber.flags |= 65536), + (root.flags |= 65536), (rootRenderLanes &= -rootRenderLanes), - (returnFiber.lanes |= rootRenderLanes), - (rootRenderLanes = createClassErrorUpdate(rootRenderLanes)), - initializeClassErrorUpdate( - rootRenderLanes, + (root.lanes |= rootRenderLanes), + (rootRenderLanes = createClassErrorUpdate( root, returnFiber, - value - ), - enqueueCapturedUpdate(returnFiber, rootRenderLanes), + rootRenderLanes + )), + enqueueCapturedUpdate(root, rootRenderLanes), !1 ); } - returnFiber = returnFiber.return; - } while (null !== returnFiber); + root = root.return; + } while (null !== root); return !1; } -var SelectiveHydrationException = Error( +var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner, + SelectiveHydrationException = Error( "This is not a real error. It's an implementation detail of React's selective hydration feature. If this leaks into userspace, it's a bug in React. Please file an issue." ), didReceiveUpdate = !1; @@ -5170,17 +4577,12 @@ function updateForwardRef( ) { Component = Component.render; var ref = workInProgress.ref; - if ("ref" in nextProps) { - var propsWithoutRef = {}; - for (var key in nextProps) - "ref" !== key && (propsWithoutRef[key] = nextProps[key]); - } else propsWithoutRef = nextProps; prepareToReadContext(workInProgress, renderLanes); nextProps = renderWithHooks( current, workInProgress, Component, - propsWithoutRef, + nextProps, ref, renderLanes ); @@ -5206,7 +4608,8 @@ function updateMemoComponent( "function" === typeof type && !shouldConstruct(type) && void 0 === type.defaultProps && - null === Component.compare + null === Component.compare && + void 0 === Component.defaultProps ) return ( (workInProgress.tag = 15), @@ -5304,52 +4707,35 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { } if (0 === (workInProgress.mode & 1)) (workInProgress.memoizedState = { baseLanes: 0, cachePool: null }), - null !== current && pushTransition(workInProgress, null), - reuseHiddenContextOnStack(), - pushOffscreenSuspenseHandler(workInProgress); - else if (0 !== (renderLanes & 536870912)) - (workInProgress.memoizedState = { baseLanes: 0, cachePool: null }), - null !== current && - pushTransition( + reuseHiddenContextOnStack(); + else { + if (0 === (renderLanes & 536870912)) + return ( + (workInProgress.lanes = workInProgress.childLanes = 536870912), + deferHiddenOffscreenComponent( + current, workInProgress, - null !== prevState ? prevState.cachePool : null - ), - null !== prevState - ? pushHiddenContext(workInProgress, prevState) - : reuseHiddenContextOnStack(), - pushOffscreenSuspenseHandler(workInProgress); - else - return ( - (workInProgress.lanes = workInProgress.childLanes = 536870912), - deferHiddenOffscreenComponent( - current, - workInProgress, - null !== prevState ? prevState.baseLanes | renderLanes : renderLanes - ) - ); + null !== prevState ? prevState.baseLanes | renderLanes : renderLanes + ) + ); + workInProgress.memoizedState = { baseLanes: 0, cachePool: null }; + null !== prevState + ? pushHiddenContext(workInProgress, prevState) + : reuseHiddenContextOnStack(); + } + pushOffscreenSuspenseHandler(workInProgress); } else null !== prevState - ? (pushTransition(workInProgress, prevState.cachePool), - pushHiddenContext(workInProgress, prevState), + ? (pushHiddenContext(workInProgress, prevState), reuseSuspenseHandlerOnStack(workInProgress), (workInProgress.memoizedState = null)) - : (null !== current && pushTransition(workInProgress, null), - reuseHiddenContextOnStack(), + : (reuseHiddenContextOnStack(), reuseSuspenseHandlerOnStack(workInProgress)); reconcileChildren(current, workInProgress, nextChildren, renderLanes); return workInProgress.child; } function deferHiddenOffscreenComponent(current, workInProgress, nextBaseLanes) { - var JSCompiler_inline_result = peekCacheFromPool(); - JSCompiler_inline_result = - null === JSCompiler_inline_result - ? null - : { parent: CacheContext._currentValue, pool: JSCompiler_inline_result }; - workInProgress.memoizedState = { - baseLanes: nextBaseLanes, - cachePool: JSCompiler_inline_result - }; - null !== current && pushTransition(workInProgress, null); + workInProgress.memoizedState = { baseLanes: nextBaseLanes, cachePool: null }; reuseHiddenContextOnStack(); pushOffscreenSuspenseHandler(workInProgress); return null; @@ -5434,8 +4820,7 @@ function updateClassComponent( (nextProps = !0); else if (null === current) { var instance = workInProgress.stateNode, - unresolvedOldProps = workInProgress.memoizedProps, - oldProps = resolveClassComponentProps(Component, unresolvedOldProps); + oldProps = workInProgress.memoizedProps; instance.props = oldProps; var oldContext = instance.context, contextType = Component.contextType, @@ -5444,14 +4829,12 @@ function updateClassComponent( null !== contextType && (nextContext = readContext(contextType)); var getDerivedStateFromProps = Component.getDerivedStateFromProps; - contextType = + (contextType = "function" === typeof getDerivedStateFromProps || - "function" === typeof instance.getSnapshotBeforeUpdate; - unresolvedOldProps = workInProgress.pendingProps !== unresolvedOldProps; - contextType || + "function" === typeof instance.getSnapshotBeforeUpdate) || ("function" !== typeof instance.UNSAFE_componentWillReceiveProps && "function" !== typeof instance.componentWillReceiveProps) || - ((unresolvedOldProps || oldContext !== nextContext) && + ((oldProps !== nextProps || oldContext !== nextContext) && callComponentWillReceiveProps( workInProgress, instance, @@ -5462,9 +4845,8 @@ function updateClassComponent( var oldState = workInProgress.memoizedState; instance.state = oldState; processUpdateQueue(workInProgress, nextProps, instance, renderLanes); - suspendIfUpdateReadFromEntangledAsyncAction(); oldContext = workInProgress.memoizedState; - unresolvedOldProps || oldState !== oldContext || hasForceUpdate + oldProps !== nextProps || oldState !== oldContext || hasForceUpdate ? ("function" === typeof getDerivedStateFromProps && (applyDerivedStateFromProps( workInProgress, @@ -5508,22 +4890,26 @@ function updateClassComponent( instance = workInProgress.stateNode; cloneUpdateQueue(current, workInProgress); nextContext = workInProgress.memoizedProps; - contextType = resolveClassComponentProps(Component, nextContext); + contextType = + workInProgress.type === workInProgress.elementType + ? nextContext + : resolveDefaultProps(workInProgress.type, nextContext); instance.props = contextType; getDerivedStateFromProps = workInProgress.pendingProps; - oldState = instance.context; + var oldContext$jscomp$0 = instance.context; oldContext = Component.contextType; oldProps = emptyContextObject; "object" === typeof oldContext && null !== oldContext && (oldProps = readContext(oldContext)); - unresolvedOldProps = Component.getDerivedStateFromProps; + oldState = Component.getDerivedStateFromProps; (oldContext = - "function" === typeof unresolvedOldProps || + "function" === typeof oldState || "function" === typeof instance.getSnapshotBeforeUpdate) || ("function" !== typeof instance.UNSAFE_componentWillReceiveProps && "function" !== typeof instance.componentWillReceiveProps) || - ((nextContext !== getDerivedStateFromProps || oldState !== oldProps) && + ((nextContext !== getDerivedStateFromProps || + oldContext$jscomp$0 !== oldProps) && callComponentWillReceiveProps( workInProgress, instance, @@ -5531,19 +4917,18 @@ function updateClassComponent( oldProps )); hasForceUpdate = !1; - oldState = workInProgress.memoizedState; - instance.state = oldState; + oldContext$jscomp$0 = workInProgress.memoizedState; + instance.state = oldContext$jscomp$0; processUpdateQueue(workInProgress, nextProps, instance, renderLanes); - suspendIfUpdateReadFromEntangledAsyncAction(); var newState = workInProgress.memoizedState; nextContext !== getDerivedStateFromProps || - oldState !== newState || + oldContext$jscomp$0 !== newState || hasForceUpdate - ? ("function" === typeof unresolvedOldProps && + ? ("function" === typeof oldState && (applyDerivedStateFromProps( workInProgress, Component, - unresolvedOldProps, + oldState, nextProps ), (newState = workInProgress.memoizedState)), @@ -5554,7 +4939,7 @@ function updateClassComponent( Component, contextType, nextProps, - oldState, + oldContext$jscomp$0, newState, oldProps ) || @@ -5576,11 +4961,11 @@ function updateClassComponent( (workInProgress.flags |= 1024)) : ("function" !== typeof instance.componentDidUpdate || (nextContext === current.memoizedProps && - oldState === current.memoizedState) || + oldContext$jscomp$0 === current.memoizedState) || (workInProgress.flags |= 4), "function" !== typeof instance.getSnapshotBeforeUpdate || (nextContext === current.memoizedProps && - oldState === current.memoizedState) || + oldContext$jscomp$0 === current.memoizedState) || (workInProgress.flags |= 1024), (workInProgress.memoizedProps = nextProps), (workInProgress.memoizedState = newState)), @@ -5590,11 +4975,11 @@ function updateClassComponent( (nextProps = contextType)) : ("function" !== typeof instance.componentDidUpdate || (nextContext === current.memoizedProps && - oldState === current.memoizedState) || + oldContext$jscomp$0 === current.memoizedState) || (workInProgress.flags |= 4), "function" !== typeof instance.getSnapshotBeforeUpdate || (nextContext === current.memoizedProps && - oldState === current.memoizedState) || + oldContext$jscomp$0 === current.memoizedState) || (workInProgress.flags |= 1024), (nextProps = !1)); } @@ -5620,6 +5005,7 @@ function finishClassComponent( if (!shouldUpdate && !hasContext) return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); shouldUpdate = workInProgress.stateNode; + ReactCurrentOwner$1.current = workInProgress; Component = hasContext && "function" !== typeof Component.getDerivedStateFromError ? null @@ -5644,7 +5030,7 @@ function finishClassComponent( } var SUSPENDED_MARKER = { dehydrated: null, treeContext: null, retryLane: 0 }; function mountSuspenseOffscreenState(renderLanes) { - return { baseLanes: renderLanes, cachePool: getSuspendedCache() }; + return { baseLanes: renderLanes, cachePool: null }; } function getRemainingWorkInPrimaryTree( current, @@ -5669,248 +5055,100 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { JSCompiler_temp = 0 !== (workInProgress.flags & 32); workInProgress.flags &= -33; if (null === current) { - var nextPrimaryChildren = nextProps.children; + didSuspend = nextProps.children; nextProps = nextProps.fallback; - if (showFallback) - return ( - reuseSuspenseHandlerOnStack(workInProgress), - (showFallback = workInProgress.mode), - (didSuspend = workInProgress.child), - (nextPrimaryChildren = { - mode: "hidden", - children: nextPrimaryChildren - }), - 0 === (showFallback & 1) && null !== didSuspend - ? ((didSuspend.childLanes = 0), - (didSuspend.pendingProps = nextPrimaryChildren)) - : (didSuspend = createFiberFromOffscreen( - nextPrimaryChildren, - showFallback, - 0, - null - )), - (nextProps = createFiberFromFragment( - nextProps, - showFallback, - renderLanes, - null - )), - (didSuspend.return = workInProgress), - (nextProps.return = workInProgress), - (didSuspend.sibling = nextProps), - (workInProgress.child = didSuspend), - (nextPrimaryChildren = workInProgress.child), - (nextPrimaryChildren.memoizedState = - mountSuspenseOffscreenState(renderLanes)), - (nextPrimaryChildren.childLanes = getRemainingWorkInPrimaryTree( - current, - JSCompiler_temp, - renderLanes - )), - (workInProgress.memoizedState = SUSPENDED_MARKER), - nextProps - ); - pushPrimaryTreeSuspenseHandler(workInProgress); - return mountSuspensePrimaryChildren(workInProgress, nextPrimaryChildren); - } - nextPrimaryChildren = current.memoizedState; - if (null !== nextPrimaryChildren && null !== nextPrimaryChildren.dehydrated) { - if (didSuspend) - workInProgress.flags & 256 - ? (pushPrimaryTreeSuspenseHandler(workInProgress), - (workInProgress.flags &= -257), - (workInProgress = retrySuspenseComponentWithoutHydrating( - current, - workInProgress, - renderLanes - ))) - : null !== workInProgress.memoizedState - ? (reuseSuspenseHandlerOnStack(workInProgress), - (workInProgress.child = current.child), - (workInProgress.flags |= 128), - (workInProgress = null)) - : (reuseSuspenseHandlerOnStack(workInProgress), - (nextPrimaryChildren = nextProps.fallback), - (showFallback = workInProgress.mode), - (nextProps = createFiberFromOffscreen( - { mode: "visible", children: nextProps.children }, + if (showFallback) { + reuseSuspenseHandlerOnStack(workInProgress); + showFallback = workInProgress.mode; + var progressedPrimaryFragment = workInProgress.child; + didSuspend = { mode: "hidden", children: didSuspend }; + 0 === (showFallback & 1) && null !== progressedPrimaryFragment + ? ((progressedPrimaryFragment.childLanes = 0), + (progressedPrimaryFragment.pendingProps = didSuspend)) + : (progressedPrimaryFragment = createFiberFromOffscreen( + didSuspend, showFallback, 0, null - )), - (nextPrimaryChildren = createFiberFromFragment( - nextPrimaryChildren, - showFallback, - renderLanes, - null - )), - (nextPrimaryChildren.flags |= 2), - (nextProps.return = workInProgress), - (nextPrimaryChildren.return = workInProgress), - (nextProps.sibling = nextPrimaryChildren), - (workInProgress.child = nextProps), - 0 !== (workInProgress.mode & 1) && - reconcileChildFibers( - workInProgress, - current.child, - null, - renderLanes - ), - (nextProps = workInProgress.child), - (nextProps.memoizedState = mountSuspenseOffscreenState(renderLanes)), - (nextProps.childLanes = getRemainingWorkInPrimaryTree( - current, - JSCompiler_temp, - renderLanes - )), - (workInProgress.memoizedState = SUSPENDED_MARKER), - (workInProgress = nextPrimaryChildren)); - else if ((pushPrimaryTreeSuspenseHandler(workInProgress), shim$1())) - (JSCompiler_temp = shim$1().digest), - (nextProps = Error( - "The server could not finish this Suspense boundary, likely due to an error during server rendering. Switched to client rendering." - )), - (nextProps.stack = ""), - (nextProps.digest = JSCompiler_temp), - (JSCompiler_temp = { value: nextProps, source: null, stack: null }), - null === hydrationErrors - ? (hydrationErrors = [JSCompiler_temp]) - : hydrationErrors.push(JSCompiler_temp), - (workInProgress = retrySuspenseComponentWithoutHydrating( - current, - workInProgress, - renderLanes - )); - else if ( - ((JSCompiler_temp = 0 !== (renderLanes & current.childLanes)), - didReceiveUpdate || JSCompiler_temp) - ) { - JSCompiler_temp = workInProgressRoot; - if (null !== JSCompiler_temp) { - nextProps = renderLanes & -renderLanes; - if (0 !== (nextProps & 42)) nextProps = 1; - else - switch (nextProps) { - case 2: - nextProps = 1; - break; - case 8: - nextProps = 4; - break; - case 32: - nextProps = 16; - break; - case 128: - case 256: - case 512: - case 1024: - case 2048: - case 4096: - case 8192: - case 16384: - case 32768: - case 65536: - case 131072: - case 262144: - case 524288: - case 1048576: - case 2097152: - case 4194304: - case 8388608: - case 16777216: - case 33554432: - nextProps = 64; - break; - case 268435456: - nextProps = 134217728; - break; - default: - nextProps = 0; - } - nextProps = - 0 !== (nextProps & (JSCompiler_temp.suspendedLanes | renderLanes)) - ? 0 - : nextProps; - if (0 !== nextProps && nextProps !== nextPrimaryChildren.retryLane) - throw ( - ((nextPrimaryChildren.retryLane = nextProps), - enqueueConcurrentRenderForLane(current, nextProps), - scheduleUpdateOnFiber(JSCompiler_temp, current, nextProps), - SelectiveHydrationException) - ); - } - shim$1() || renderDidSuspendDelayIfPossible(); - workInProgress = retrySuspenseComponentWithoutHydrating( + )); + nextProps = createFiberFromFragment( + nextProps, + showFallback, + renderLanes, + null + ); + progressedPrimaryFragment.return = workInProgress; + nextProps.return = workInProgress; + progressedPrimaryFragment.sibling = nextProps; + workInProgress.child = progressedPrimaryFragment; + showFallback = workInProgress.child; + showFallback.memoizedState = mountSuspenseOffscreenState(renderLanes); + showFallback.childLanes = getRemainingWorkInPrimaryTree( + current, + JSCompiler_temp, + renderLanes + ); + workInProgress.memoizedState = SUSPENDED_MARKER; + return nextProps; + } + pushPrimaryTreeSuspenseHandler(workInProgress); + return mountSuspensePrimaryChildren(workInProgress, didSuspend); + } + progressedPrimaryFragment = current.memoizedState; + if (null !== progressedPrimaryFragment) { + var dehydrated = progressedPrimaryFragment.dehydrated; + if (null !== dehydrated) + return updateDehydratedSuspenseComponent( current, workInProgress, + didSuspend, + JSCompiler_temp, + nextProps, + dehydrated, + progressedPrimaryFragment, renderLanes ); - } else - shim$1() - ? ((workInProgress.flags |= 128), - (workInProgress.child = current.child), - retryDehydratedSuspenseBoundary.bind(null, current), - shim$1(), - (workInProgress = null)) - : ((workInProgress = mountSuspensePrimaryChildren( - workInProgress, - nextProps.children - )), - (workInProgress.flags |= 4096)); - return workInProgress; } if (showFallback) { reuseSuspenseHandlerOnStack(workInProgress); - nextPrimaryChildren = nextProps.fallback; - showFallback = workInProgress.mode; - didSuspend = current.child; - var currentFallbackChildFragment = didSuspend.sibling, - primaryChildProps = { mode: "hidden", children: nextProps.children }; - 0 === (showFallback & 1) && workInProgress.child !== didSuspend + showFallback = nextProps.fallback; + didSuspend = workInProgress.mode; + progressedPrimaryFragment = current.child; + dehydrated = progressedPrimaryFragment.sibling; + var primaryChildProps = { mode: "hidden", children: nextProps.children }; + 0 === (didSuspend & 1) && workInProgress.child !== progressedPrimaryFragment ? ((nextProps = workInProgress.child), (nextProps.childLanes = 0), (nextProps.pendingProps = primaryChildProps), (workInProgress.deletions = null)) - : ((nextProps = createWorkInProgress(didSuspend, primaryChildProps)), - (nextProps.subtreeFlags = didSuspend.subtreeFlags & 31457280)); - null !== currentFallbackChildFragment - ? (nextPrimaryChildren = createWorkInProgress( - currentFallbackChildFragment, - nextPrimaryChildren - )) - : ((nextPrimaryChildren = createFiberFromFragment( - nextPrimaryChildren, + : ((nextProps = createWorkInProgress( + progressedPrimaryFragment, + primaryChildProps + )), + (nextProps.subtreeFlags = + progressedPrimaryFragment.subtreeFlags & 31457280)); + null !== dehydrated + ? (showFallback = createWorkInProgress(dehydrated, showFallback)) + : ((showFallback = createFiberFromFragment( showFallback, + didSuspend, renderLanes, null )), - (nextPrimaryChildren.flags |= 2)); - nextPrimaryChildren.return = workInProgress; + (showFallback.flags |= 2)); + showFallback.return = workInProgress; nextProps.return = workInProgress; - nextProps.sibling = nextPrimaryChildren; + nextProps.sibling = showFallback; workInProgress.child = nextProps; - nextProps = nextPrimaryChildren; - nextPrimaryChildren = workInProgress.child; - showFallback = current.child.memoizedState; - null === showFallback - ? (showFallback = mountSuspenseOffscreenState(renderLanes)) - : ((didSuspend = showFallback.cachePool), - null !== didSuspend - ? ((currentFallbackChildFragment = CacheContext._currentValue), - (didSuspend = - didSuspend.parent !== currentFallbackChildFragment - ? { - parent: currentFallbackChildFragment, - pool: currentFallbackChildFragment - } - : didSuspend)) - : (didSuspend = getSuspendedCache()), - (showFallback = { - baseLanes: showFallback.baseLanes | renderLanes, - cachePool: didSuspend - })); - nextPrimaryChildren.memoizedState = showFallback; - nextPrimaryChildren.childLanes = getRemainingWorkInPrimaryTree( + nextProps = showFallback; + showFallback = workInProgress.child; + didSuspend = current.child.memoizedState; + didSuspend = + null === didSuspend + ? mountSuspenseOffscreenState(renderLanes) + : { baseLanes: didSuspend.baseLanes | renderLanes, cachePool: null }; + showFallback.memoizedState = didSuspend; + showFallback.childLanes = getRemainingWorkInPrimaryTree( current, JSCompiler_temp, renderLanes @@ -5950,8 +5188,13 @@ function mountSuspensePrimaryChildren(workInProgress, primaryChildren) { function retrySuspenseComponentWithoutHydrating( current, workInProgress, - renderLanes + renderLanes, + recoverableError ) { + null !== recoverableError && + (null === hydrationErrors + ? (hydrationErrors = [recoverableError]) + : hydrationErrors.push(recoverableError)); reconcileChildFibers(workInProgress, current.child, null, renderLanes); current = mountSuspensePrimaryChildren( workInProgress, @@ -5961,6 +5204,176 @@ function retrySuspenseComponentWithoutHydrating( workInProgress.memoizedState = null; return current; } +function updateDehydratedSuspenseComponent( + current, + workInProgress, + didSuspend, + didPrimaryChildrenDefer, + nextProps, + suspenseInstance, + suspenseState, + renderLanes +) { + if (didSuspend) { + if (workInProgress.flags & 256) + return ( + pushPrimaryTreeSuspenseHandler(workInProgress), + (workInProgress.flags &= -257), + (didPrimaryChildrenDefer = createCapturedValueFromError( + Error( + "There was an error while hydrating this Suspense boundary. Switched to client rendering." + ) + )), + retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + didPrimaryChildrenDefer + ) + ); + if (null !== workInProgress.memoizedState) + return ( + reuseSuspenseHandlerOnStack(workInProgress), + (workInProgress.child = current.child), + (workInProgress.flags |= 128), + null + ); + reuseSuspenseHandlerOnStack(workInProgress); + suspenseState = nextProps.fallback; + didSuspend = workInProgress.mode; + nextProps = createFiberFromOffscreen( + { mode: "visible", children: nextProps.children }, + didSuspend, + 0, + null + ); + suspenseState = createFiberFromFragment( + suspenseState, + didSuspend, + renderLanes, + null + ); + suspenseState.flags |= 2; + nextProps.return = workInProgress; + suspenseState.return = workInProgress; + nextProps.sibling = suspenseState; + workInProgress.child = nextProps; + 0 !== (workInProgress.mode & 1) && + reconcileChildFibers(workInProgress, current.child, null, renderLanes); + nextProps = workInProgress.child; + nextProps.memoizedState = mountSuspenseOffscreenState(renderLanes); + nextProps.childLanes = getRemainingWorkInPrimaryTree( + current, + didPrimaryChildrenDefer, + renderLanes + ); + workInProgress.memoizedState = SUSPENDED_MARKER; + return suspenseState; + } + pushPrimaryTreeSuspenseHandler(workInProgress); + if (0 === (workInProgress.mode & 1)) + return retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + null + ); + if (shim$1()) + return ( + (didPrimaryChildrenDefer = shim$1().digest), + (suspenseState = Error( + "The server could not finish this Suspense boundary, likely due to an error during server rendering. Switched to client rendering." + )), + (suspenseState.digest = didPrimaryChildrenDefer), + (didPrimaryChildrenDefer = createCapturedValueFromError( + suspenseState, + didPrimaryChildrenDefer, + void 0 + )), + retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + didPrimaryChildrenDefer + ) + ); + didPrimaryChildrenDefer = 0 !== (renderLanes & current.childLanes); + if (didReceiveUpdate || didPrimaryChildrenDefer) { + didPrimaryChildrenDefer = workInProgressRoot; + if (null !== didPrimaryChildrenDefer) { + nextProps = renderLanes & -renderLanes; + if (0 !== (nextProps & 42)) nextProps = 1; + else + switch (nextProps) { + case 2: + nextProps = 1; + break; + case 8: + nextProps = 4; + break; + case 32: + nextProps = 16; + break; + case 128: + case 256: + case 512: + case 1024: + case 2048: + case 4096: + case 8192: + case 16384: + case 32768: + case 65536: + case 131072: + case 262144: + case 524288: + case 1048576: + case 2097152: + case 4194304: + case 8388608: + case 16777216: + case 33554432: + nextProps = 64; + break; + case 268435456: + nextProps = 134217728; + break; + default: + nextProps = 0; + } + nextProps = + 0 !== + (nextProps & (didPrimaryChildrenDefer.suspendedLanes | renderLanes)) + ? 0 + : nextProps; + if (0 !== nextProps && nextProps !== suspenseState.retryLane) + throw ( + ((suspenseState.retryLane = nextProps), + enqueueConcurrentRenderForLane(current, nextProps), + scheduleUpdateOnFiber(didPrimaryChildrenDefer, current, nextProps), + SelectiveHydrationException) + ); + } + shim$1() || renderDidSuspendDelayIfPossible(); + return retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + null + ); + } + if (shim$1()) + return ( + (workInProgress.flags |= 128), + (workInProgress.child = current.child), + retryDehydratedSuspenseBoundary.bind(null, current), + shim$1(), + null + ); + current = mountSuspensePrimaryChildren(workInProgress, nextProps.children); + current.flags |= 4096; + return current; +} function scheduleSuspenseWorkOnFiber(fiber, renderLanes, propagationRoot) { fiber.lanes |= renderLanes; var alternate = fiber.alternate; @@ -6112,7 +5525,6 @@ function attemptEarlyBailoutIfNoScheduledUpdate( switch (workInProgress.tag) { case 3: pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); - pushProvider(workInProgress, CacheContext, current.memoizedState.cache); break; case 27: case 5: @@ -6122,16 +5534,15 @@ function attemptEarlyBailoutIfNoScheduledUpdate( pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); break; case 10: - pushProvider( - workInProgress, - workInProgress.type, - workInProgress.memoizedProps.value - ); + var newValue = workInProgress.memoizedProps.value, + context = workInProgress.type._context; + push(valueCursor, context._currentValue); + context._currentValue = newValue; break; case 13: - var state = workInProgress.memoizedState; - if (null !== state) { - if (null !== state.dehydrated) + newValue = workInProgress.memoizedState; + if (null !== newValue) { + if (null !== newValue.dehydrated) return ( pushPrimaryTreeSuspenseHandler(workInProgress), (workInProgress.flags |= 128), @@ -6150,9 +5561,9 @@ function attemptEarlyBailoutIfNoScheduledUpdate( pushPrimaryTreeSuspenseHandler(workInProgress); break; case 19: - state = 0 !== (renderLanes & workInProgress.childLanes); + newValue = 0 !== (renderLanes & workInProgress.childLanes); if (0 !== (current.flags & 128)) { - if (state) + if (newValue) return updateSuspenseListComponent( current, workInProgress, @@ -6160,13 +5571,13 @@ function attemptEarlyBailoutIfNoScheduledUpdate( ); workInProgress.flags |= 128; } - var renderState = workInProgress.memoizedState; - null !== renderState && - ((renderState.rendering = null), - (renderState.tail = null), - (renderState.lastEffect = null)); + context = workInProgress.memoizedState; + null !== context && + ((context.rendering = null), + (context.tail = null), + (context.lastEffect = null)); push(suspenseStackCursor, suspenseStackCursor.current); - if (state) break; + if (newValue) break; else return null; case 22: case 23: @@ -6174,8 +5585,6 @@ function attemptEarlyBailoutIfNoScheduledUpdate( (workInProgress.lanes = 0), updateOffscreenComponent(current, workInProgress, renderLanes) ); - case 24: - pushProvider(workInProgress, CacheContext, current.memoizedState.cache); } return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); } @@ -6201,86 +5610,132 @@ function beginWork(current, workInProgress, renderLanes) { else didReceiveUpdate = !1; workInProgress.lanes = 0; switch (workInProgress.tag) { + case 2: + var Component = workInProgress.type; + resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress); + current = workInProgress.pendingProps; + prepareToReadContext(workInProgress, renderLanes); + var value = renderWithHooks( + null, + workInProgress, + Component, + current, + void 0, + renderLanes + ); + workInProgress.flags |= 1; + "object" === typeof value && + null !== value && + "function" === typeof value.render && + void 0 === value.$$typeof + ? ((workInProgress.tag = 1), + (workInProgress.memoizedState = null), + (workInProgress.updateQueue = null), + (workInProgress.memoizedState = + null !== value.state && void 0 !== value.state + ? value.state + : null), + initializeUpdateQueue(workInProgress), + (value.updater = classComponentUpdater), + (workInProgress.stateNode = value), + (value._reactInternals = workInProgress), + mountClassInstance(workInProgress, Component, current, renderLanes), + (workInProgress = finishClassComponent( + null, + workInProgress, + Component, + !0, + !1, + renderLanes + ))) + : ((workInProgress.tag = 0), + reconcileChildren(null, workInProgress, value, renderLanes), + (workInProgress = workInProgress.child)); + return workInProgress; case 16: - var elementType = workInProgress.elementType; + Component = workInProgress.elementType; a: { resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress); current = workInProgress.pendingProps; - var init = elementType._init; - elementType = init(elementType._payload); - workInProgress.type = elementType; - if ("function" === typeof elementType) - shouldConstruct(elementType) - ? ((current = resolveClassComponentProps(elementType, current)), - (workInProgress.tag = 1), - (workInProgress = updateClassComponent( - null, - workInProgress, - elementType, - current, - renderLanes - ))) - : ((workInProgress.tag = 0), - (workInProgress = updateFunctionComponent( - null, - workInProgress, - elementType, - current, - renderLanes - ))); - else { - if (void 0 !== elementType && null !== elementType) - if ( - ((init = elementType.$$typeof), init === REACT_FORWARD_REF_TYPE) - ) { - workInProgress.tag = 11; - workInProgress = updateForwardRef( - null, - workInProgress, - elementType, - current, - renderLanes - ); - break a; - } else if (init === REACT_MEMO_TYPE) { - workInProgress.tag = 14; - workInProgress = updateMemoComponent( - null, - workInProgress, - elementType, - current, - renderLanes - ); - break a; - } - throw Error( - "Element type is invalid. Received a promise that resolves to: " + - elementType + - ". Lazy element type must resolve to a class or function." - ); + value = Component._init; + Component = value(Component._payload); + workInProgress.type = Component; + value = workInProgress.tag = resolveLazyComponentTag(Component); + current = resolveDefaultProps(Component, current); + switch (value) { + case 0: + workInProgress = updateFunctionComponent( + null, + workInProgress, + Component, + current, + renderLanes + ); + break a; + case 1: + workInProgress = updateClassComponent( + null, + workInProgress, + Component, + current, + renderLanes + ); + break a; + case 11: + workInProgress = updateForwardRef( + null, + workInProgress, + Component, + current, + renderLanes + ); + break a; + case 14: + workInProgress = updateMemoComponent( + null, + workInProgress, + Component, + resolveDefaultProps(Component.type, current), + renderLanes + ); + break a; } + throw Error( + "Element type is invalid. Received a promise that resolves to: " + + Component + + ". Lazy element type must resolve to a class or function." + ); } return workInProgress; case 0: - return updateFunctionComponent( - current, - workInProgress, - workInProgress.type, - workInProgress.pendingProps, - renderLanes + return ( + (Component = workInProgress.type), + (value = workInProgress.pendingProps), + (value = + workInProgress.elementType === Component + ? value + : resolveDefaultProps(Component, value)), + updateFunctionComponent( + current, + workInProgress, + Component, + value, + renderLanes + ) ); case 1: return ( - (elementType = workInProgress.type), - (init = resolveClassComponentProps( - elementType, - workInProgress.pendingProps - )), + (Component = workInProgress.type), + (value = workInProgress.pendingProps), + (value = + workInProgress.elementType === Component + ? value + : resolveDefaultProps(Component, value)), updateClassComponent( current, workInProgress, - elementType, - init, + Component, + value, renderLanes ) ); @@ -6288,25 +5743,18 @@ function beginWork(current, workInProgress, renderLanes) { pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); if (null === current) throw Error("Should have a current fiber. This is a bug in React."); - var nextProps = workInProgress.pendingProps; - init = workInProgress.memoizedState; - elementType = init.element; + value = workInProgress.pendingProps; + Component = workInProgress.memoizedState.element; cloneUpdateQueue(current, workInProgress); - processUpdateQueue(workInProgress, nextProps, null, renderLanes); - nextProps = workInProgress.memoizedState; - var nextCache = nextProps.cache; - pushProvider(workInProgress, CacheContext, nextCache); - nextCache !== init.cache && - propagateContextChange(workInProgress, CacheContext, renderLanes); - suspendIfUpdateReadFromEntangledAsyncAction(); - init = nextProps.element; - init === elementType + processUpdateQueue(workInProgress, value, null, renderLanes); + value = workInProgress.memoizedState.element; + value === Component ? (workInProgress = bailoutOnAlreadyFinishedWork( current, workInProgress, renderLanes )) - : (reconcileChildren(current, workInProgress, init, renderLanes), + : (reconcileChildren(current, workInProgress, value, renderLanes), (workInProgress = workInProgress.child)); return workInProgress; case 26: @@ -6314,27 +5762,9 @@ function beginWork(current, workInProgress, renderLanes) { case 5: return ( pushHostContext(workInProgress), - (elementType = workInProgress.pendingProps.children), - null !== workInProgress.memoizedState && - ((init = renderWithHooks( - current, - workInProgress, - TransitionAwareHostComponent, - null, - null, - renderLanes - )), - (HostTransitionContext._currentValue = init), - didReceiveUpdate && - null !== current && - current.memoizedState.memoizedState !== init && - propagateContextChange( - workInProgress, - HostTransitionContext, - renderLanes - )), + (Component = workInProgress.pendingProps.children), markRef(current, workInProgress), - reconcileChildren(current, workInProgress, elementType, renderLanes), + reconcileChildren(current, workInProgress, Component, renderLanes), workInProgress.child ); case 6: @@ -6347,29 +5777,26 @@ function beginWork(current, workInProgress, renderLanes) { workInProgress, workInProgress.stateNode.containerInfo ), - (elementType = workInProgress.pendingProps), + (Component = workInProgress.pendingProps), null === current ? (workInProgress.child = reconcileChildFibers( workInProgress, null, - elementType, + Component, renderLanes )) - : reconcileChildren( - current, - workInProgress, - elementType, - renderLanes - ), + : reconcileChildren(current, workInProgress, Component, renderLanes), workInProgress.child ); case 11: - return updateForwardRef( - current, - workInProgress, - workInProgress.type, - workInProgress.pendingProps, - renderLanes + return ( + (Component = workInProgress.type), + (value = workInProgress.pendingProps), + (value = + workInProgress.elementType === Component + ? value + : resolveDefaultProps(Component, value)), + updateForwardRef(current, workInProgress, Component, value, renderLanes) ); case 7: return ( @@ -6403,14 +5830,15 @@ function beginWork(current, workInProgress, renderLanes) { ); case 10: a: { - elementType = workInProgress.type; - init = workInProgress.pendingProps; - nextProps = workInProgress.memoizedProps; - nextCache = init.value; - pushProvider(workInProgress, elementType, nextCache); - if (null !== nextProps) - if (objectIs(nextProps.value, nextCache)) { - if (nextProps.children === init.children) { + Component = workInProgress.type._context; + value = workInProgress.pendingProps; + var oldProps = workInProgress.memoizedProps, + newValue = value.value; + push(valueCursor, Component._currentValue); + Component._currentValue = newValue; + if (null !== oldProps) + if (objectIs(oldProps.value, newValue)) { + if (oldProps.children === value.children) { workInProgress = bailoutOnAlreadyFinishedWork( current, workInProgress, @@ -6419,29 +5847,111 @@ function beginWork(current, workInProgress, renderLanes) { break a; } } else - propagateContextChange(workInProgress, elementType, renderLanes); - reconcileChildren(current, workInProgress, init.children, renderLanes); + for ( + oldProps = workInProgress.child, + null !== oldProps && (oldProps.return = workInProgress); + null !== oldProps; + + ) { + var list = oldProps.dependencies; + if (null !== list) { + newValue = oldProps.child; + for ( + var dependency = list.firstContext; + null !== dependency; + + ) { + if (dependency.context === Component) { + if (1 === oldProps.tag) { + dependency = createUpdate(renderLanes & -renderLanes); + dependency.tag = 2; + var updateQueue = oldProps.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; + } + } + oldProps.lanes |= renderLanes; + dependency = oldProps.alternate; + null !== dependency && (dependency.lanes |= renderLanes); + scheduleContextWorkOnParentPath( + oldProps.return, + renderLanes, + workInProgress + ); + list.lanes |= renderLanes; + break; + } + dependency = dependency.next; + } + } else if (10 === oldProps.tag) + newValue = + oldProps.type === workInProgress.type ? null : oldProps.child; + else if (18 === oldProps.tag) { + newValue = oldProps.return; + if (null === newValue) + throw Error( + "We just came from a parent so we must have had a parent. This is a bug in React." + ); + newValue.lanes |= renderLanes; + list = newValue.alternate; + null !== list && (list.lanes |= renderLanes); + scheduleContextWorkOnParentPath( + newValue, + renderLanes, + workInProgress + ); + newValue = oldProps.sibling; + } else newValue = oldProps.child; + if (null !== newValue) newValue.return = oldProps; + else + for (newValue = oldProps; null !== newValue; ) { + if (newValue === workInProgress) { + newValue = null; + break; + } + oldProps = newValue.sibling; + if (null !== oldProps) { + oldProps.return = newValue.return; + newValue = oldProps; + break; + } + newValue = newValue.return; + } + oldProps = newValue; + } + reconcileChildren(current, workInProgress, value.children, renderLanes); workInProgress = workInProgress.child; } return workInProgress; case 9: return ( - (init = workInProgress.type._context), - (elementType = workInProgress.pendingProps.children), + (value = workInProgress.type), + (Component = workInProgress.pendingProps.children), prepareToReadContext(workInProgress, renderLanes), - (init = readContext(init)), - (elementType = elementType(init)), + (value = readContext(value)), + (Component = Component(value)), (workInProgress.flags |= 1), - reconcileChildren(current, workInProgress, elementType, renderLanes), + reconcileChildren(current, workInProgress, Component, renderLanes), workInProgress.child ); case 14: - return updateMemoComponent( - current, - workInProgress, - workInProgress.type, - workInProgress.pendingProps, - renderLanes + return ( + (Component = workInProgress.type), + (value = resolveDefaultProps(Component, workInProgress.pendingProps)), + (value = resolveDefaultProps(Component.type, value)), + updateMemoComponent( + current, + workInProgress, + Component, + value, + renderLanes + ) ); case 15: return updateSimpleMemoComponent( @@ -6453,97 +5963,30 @@ function beginWork(current, workInProgress, renderLanes) { ); case 17: return ( - (elementType = workInProgress.type), - (init = resolveClassComponentProps( - elementType, - workInProgress.pendingProps - )), + (Component = workInProgress.type), + (value = workInProgress.pendingProps), + (value = + workInProgress.elementType === Component + ? value + : resolveDefaultProps(Component, value)), resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress), (workInProgress.tag = 1), prepareToReadContext(workInProgress, renderLanes), - constructClassInstance(workInProgress, elementType, init), - mountClassInstance(workInProgress, elementType, init, renderLanes), + constructClassInstance(workInProgress, Component, value), + mountClassInstance(workInProgress, Component, value, renderLanes), finishClassComponent( null, workInProgress, - elementType, + Component, !0, !1, renderLanes - ) - ); - case 28: - return ( - (elementType = workInProgress.type), - (init = resolveClassComponentProps( - elementType, - workInProgress.pendingProps - )), - resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress), - (workInProgress.tag = 0), - updateFunctionComponent( - null, - workInProgress, - elementType, - init, - renderLanes - ) - ); - case 19: - return updateSuspenseListComponent(current, workInProgress, renderLanes); - case 22: - return updateOffscreenComponent(current, workInProgress, renderLanes); - case 24: - return ( - prepareToReadContext(workInProgress, renderLanes), - (elementType = readContext(CacheContext)), - null === current - ? ((init = peekCacheFromPool()), - null === init && - ((init = workInProgressRoot), - (nextProps = createCache()), - (init.pooledCache = nextProps), - nextProps.refCount++, - null !== nextProps && (init.pooledCacheLanes |= renderLanes), - (init = nextProps)), - (workInProgress.memoizedState = { - parent: elementType, - cache: init - }), - initializeUpdateQueue(workInProgress), - pushProvider(workInProgress, CacheContext, init)) - : (0 !== (current.lanes & renderLanes) && - (cloneUpdateQueue(current, workInProgress), - processUpdateQueue(workInProgress, null, null, renderLanes), - suspendIfUpdateReadFromEntangledAsyncAction()), - (init = current.memoizedState), - (nextProps = workInProgress.memoizedState), - init.parent !== elementType - ? ((init = { parent: elementType, cache: elementType }), - (workInProgress.memoizedState = init), - 0 === workInProgress.lanes && - (workInProgress.memoizedState = - workInProgress.updateQueue.baseState = - init), - pushProvider(workInProgress, CacheContext, elementType)) - : ((elementType = nextProps.cache), - pushProvider(workInProgress, CacheContext, elementType), - elementType !== init.cache && - propagateContextChange( - workInProgress, - CacheContext, - renderLanes - ))), - reconcileChildren( - current, - workInProgress, - workInProgress.pendingProps.children, - renderLanes - ), - workInProgress.child + ) ); - case 29: - throw workInProgress.pendingProps; + case 19: + return updateSuspenseListComponent(current, workInProgress, renderLanes); + case 22: + return updateOffscreenComponent(current, workInProgress, renderLanes); } throw Error( "Unknown unit of work tag (" + @@ -6561,10 +6004,6 @@ function resetContextDependencies() { currentlyRenderingFiber = null; } -function pushProvider(providerFiber, context, nextValue) { - push(valueCursor, context._currentValue); - context._currentValue = nextValue; -} function popProvider(context) { context._currentValue = valueCursor.current; pop(valueCursor); @@ -6582,74 +6021,6 @@ function scheduleContextWorkOnParentPath(parent, renderLanes, propagationRoot) { parent = parent.return; } } -function propagateContextChange(workInProgress, context, renderLanes) { - var fiber = workInProgress.child; - null !== fiber && (fiber.return = workInProgress); - for (; null !== fiber; ) { - var list = fiber.dependencies; - if (null !== list) { - var nextFiber = fiber.child; - for (var dependency = list.firstContext; null !== dependency; ) { - if (dependency.context === context) { - if (1 === fiber.tag) { - dependency = createUpdate(renderLanes & -renderLanes); - dependency.tag = 2; - var updateQueue = fiber.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; - } - } - fiber.lanes |= renderLanes; - dependency = fiber.alternate; - null !== dependency && (dependency.lanes |= renderLanes); - scheduleContextWorkOnParentPath( - fiber.return, - renderLanes, - workInProgress - ); - list.lanes |= renderLanes; - break; - } - dependency = dependency.next; - } - } else if (10 === fiber.tag) - nextFiber = fiber.type === workInProgress.type ? null : fiber.child; - else if (18 === fiber.tag) { - nextFiber = fiber.return; - if (null === nextFiber) - throw Error( - "We just came from a parent so we must have had a parent. This is a bug in React." - ); - nextFiber.lanes |= renderLanes; - list = nextFiber.alternate; - null !== list && (list.lanes |= renderLanes); - scheduleContextWorkOnParentPath(nextFiber, renderLanes, workInProgress); - nextFiber = fiber.sibling; - } else nextFiber = fiber.child; - if (null !== nextFiber) nextFiber.return = fiber; - else - for (nextFiber = fiber; null !== nextFiber; ) { - if (nextFiber === workInProgress) { - nextFiber = null; - break; - } - fiber = nextFiber.sibling; - if (null !== fiber) { - fiber.return = nextFiber.return; - nextFiber = fiber; - break; - } - nextFiber = nextFiber.return; - } - fiber = nextFiber; - } -} function prepareToReadContext(workInProgress, renderLanes) { currentlyRenderingFiber = workInProgress; lastFullyObservedContext = lastContextDependency = null; @@ -6683,75 +6054,8 @@ function readContextForConsumer(consumer, context) { } else lastContextDependency = lastContextDependency.next = context; return value; } -var AbortControllerLocal = - "undefined" !== typeof AbortController - ? AbortController - : function () { - var listeners = [], - signal = (this.signal = { - aborted: !1, - addEventListener: function (type, listener) { - listeners.push(listener); - } - }); - this.abort = function () { - signal.aborted = !0; - listeners.forEach(function (listener) { - return listener(); - }); - }; - }, - scheduleCallback$1 = Scheduler.unstable_scheduleCallback, - NormalPriority = Scheduler.unstable_NormalPriority, - CacheContext = { - $$typeof: REACT_CONTEXT_TYPE, - Consumer: null, - Provider: null, - _currentValue: null, - _currentValue2: null, - _threadCount: 0 - }; -function createCache() { - return { - controller: new AbortControllerLocal(), - data: new Map(), - refCount: 0 - }; -} -function releaseCache(cache) { - cache.refCount--; - 0 === cache.refCount && - scheduleCallback$1(NormalPriority, function () { - cache.controller.abort(); - }); -} -var prevOnStartTransitionFinish = ReactSharedInternals.S; -ReactSharedInternals.S = function (transition, returnValue) { - "object" === typeof returnValue && - null !== returnValue && - "function" === typeof returnValue.then && - entangleAsyncAction(transition, returnValue); - null !== prevOnStartTransitionFinish && - prevOnStartTransitionFinish(transition, returnValue); -}; -var resumedCache = createCursor(null); -function peekCacheFromPool() { - var cacheResumedFromPreviousRender = resumedCache.current; - return null !== cacheResumedFromPreviousRender - ? cacheResumedFromPreviousRender - : workInProgressRoot.pooledCache; -} -function pushTransition(offscreenWorkInProgress, prevCachePool) { - null === prevCachePool - ? push(resumedCache, resumedCache.current) - : push(resumedCache, prevCachePool.pool); -} -function getSuspendedCache() { - var cacheFromPool = peekCacheFromPool(); - return null === cacheFromPool - ? null - : { parent: CacheContext._currentValue, pool: cacheFromPool }; -} +var ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig; +function handleAsyncAction() {} function scheduleRetryEffect(workInProgress, retryQueue) { null !== retryQueue ? (workInProgress.flags |= 4) @@ -6774,14 +6078,14 @@ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { break; case "collapsed": lastTailNode = renderState.tail; - for (var lastTailNode$88 = null; null !== lastTailNode; ) - null !== lastTailNode.alternate && (lastTailNode$88 = lastTailNode), + for (var lastTailNode$61 = null; null !== lastTailNode; ) + null !== lastTailNode.alternate && (lastTailNode$61 = lastTailNode), (lastTailNode = lastTailNode.sibling); - null === lastTailNode$88 + null === lastTailNode$61 ? hasRenderedATailFallback || null === renderState.tail ? (renderState.tail = null) : (renderState.tail.sibling = null) - : (lastTailNode$88.sibling = null); + : (lastTailNode$61.sibling = null); } } function bubbleProperties(completedWork) { @@ -6791,19 +6095,19 @@ function bubbleProperties(completedWork) { newChildLanes = 0, subtreeFlags = 0; if (didBailout) - for (var child$89 = completedWork.child; null !== child$89; ) - (newChildLanes |= child$89.lanes | child$89.childLanes), - (subtreeFlags |= child$89.subtreeFlags & 31457280), - (subtreeFlags |= child$89.flags & 31457280), - (child$89.return = completedWork), - (child$89 = child$89.sibling); + for (var child$62 = completedWork.child; null !== child$62; ) + (newChildLanes |= child$62.lanes | child$62.childLanes), + (subtreeFlags |= child$62.subtreeFlags & 31457280), + (subtreeFlags |= child$62.flags & 31457280), + (child$62.return = completedWork), + (child$62 = child$62.sibling); else - for (child$89 = completedWork.child; null !== child$89; ) - (newChildLanes |= child$89.lanes | child$89.childLanes), - (subtreeFlags |= child$89.subtreeFlags), - (subtreeFlags |= child$89.flags), - (child$89.return = completedWork), - (child$89 = child$89.sibling); + for (child$62 = completedWork.child; null !== child$62; ) + (newChildLanes |= child$62.lanes | child$62.childLanes), + (subtreeFlags |= child$62.subtreeFlags), + (subtreeFlags |= child$62.flags), + (child$62.return = completedWork), + (child$62 = child$62.sibling); completedWork.subtreeFlags |= subtreeFlags; completedWork.childLanes = newChildLanes; return didBailout; @@ -6811,7 +6115,7 @@ function bubbleProperties(completedWork) { function completeWork(current, workInProgress, renderLanes) { var newProps = workInProgress.pendingProps; switch (workInProgress.tag) { - case 28: + case 2: case 16: case 15: case 0: @@ -6827,11 +6131,6 @@ function completeWork(current, workInProgress, renderLanes) { case 3: return ( (renderLanes = workInProgress.stateNode), - (newProps = null), - null !== current && (newProps = current.memoizedState.cache), - workInProgress.memoizedState.cache !== newProps && - (workInProgress.flags |= 2048), - popProvider(CacheContext), popHostContainer(), renderLanes.pendingContext && ((renderLanes.context = renderLanes.pendingContext), @@ -6863,8 +6162,8 @@ function completeWork(current, workInProgress, renderLanes) { bubbleProperties(workInProgress); return null; } - renderLanes = rootInstanceStackCursor.current; - current = allocateTag(); + current = rootInstanceStackCursor.current; + renderLanes = allocateTag(); type = getViewConfigForType(type); var updatePayload = diffProperties( null, @@ -6873,37 +6172,40 @@ function completeWork(current, workInProgress, renderLanes) { type.validAttributes ); ReactNativePrivateInterface.UIManager.createView( - current, - type.uiViewClassName, renderLanes, + type.uiViewClassName, + current, updatePayload ); - renderLanes = new ReactNativeFiberHostComponent( - current, + current = new ReactNativeFiberHostComponent( + renderLanes, type, workInProgress ); - instanceCache.set(current, workInProgress); - instanceProps.set(current, newProps); - a: for (current = workInProgress.child; null !== current; ) { - if (5 === current.tag || 6 === current.tag) - renderLanes._children.push(current.stateNode); - else if (4 !== current.tag && null !== current.child) { - current.child.return = current; - current = current.child; + instanceCache.set(renderLanes, workInProgress); + instanceProps.set(renderLanes, newProps); + a: for (renderLanes = workInProgress.child; null !== renderLanes; ) { + if (5 === renderLanes.tag || 6 === renderLanes.tag) + current._children.push(renderLanes.stateNode); + else if (4 !== renderLanes.tag && null !== renderLanes.child) { + renderLanes.child.return = renderLanes; + renderLanes = renderLanes.child; continue; } - if (current === workInProgress) break a; - for (; null === current.sibling; ) { - if (null === current.return || current.return === workInProgress) + if (renderLanes === workInProgress) break a; + for (; null === renderLanes.sibling; ) { + if ( + null === renderLanes.return || + renderLanes.return === workInProgress + ) break a; - current = current.return; + renderLanes = renderLanes.return; } - current.sibling.return = current.return; - current = current.sibling; + renderLanes.sibling.return = renderLanes.return; + renderLanes = renderLanes.sibling; } - workInProgress.stateNode = renderLanes; - finalizeInitialChildren(renderLanes) && (workInProgress.flags |= 4); + workInProgress.stateNode = current; + finalizeInitialChildren(current) && (workInProgress.flags |= 4); } bubbleProperties(workInProgress); workInProgress.flags &= -16777217; @@ -6916,20 +6218,20 @@ function completeWork(current, workInProgress, renderLanes) { throw Error( "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." ); - current = rootInstanceStackCursor.current; + renderLanes = rootInstanceStackCursor.current; if (!contextStackCursor.current.isInAParentText) throw Error( "Text strings must be rendered within a component." ); - renderLanes = allocateTag(); + current = allocateTag(); ReactNativePrivateInterface.UIManager.createView( - renderLanes, - "RCTRawText", current, + "RCTRawText", + renderLanes, { text: newProps } ); - instanceCache.set(renderLanes, workInProgress); - workInProgress.stateNode = renderLanes; + instanceCache.set(current, workInProgress); + workInProgress.stateNode = current; } bubbleProperties(workInProgress); return null; @@ -6969,20 +6271,7 @@ function completeWork(current, workInProgress, renderLanes) { if (0 !== (workInProgress.flags & 128)) return (workInProgress.lanes = renderLanes), workInProgress; renderLanes = null !== newProps; - current = null !== current && null !== current.memoizedState; - renderLanes && - ((newProps = workInProgress.child), - (type = null), - null !== newProps.alternate && - null !== newProps.alternate.memoizedState && - null !== newProps.alternate.memoizedState.cachePool && - (type = newProps.alternate.memoizedState.cachePool.pool), - (updatePayload = null), - null !== newProps.memoizedState && - null !== newProps.memoizedState.cachePool && - (updatePayload = newProps.memoizedState.cachePool.pool), - updatePayload !== type && (newProps.flags |= 2048)); - renderLanes !== current && + renderLanes !== (null !== current && null !== current.memoizedState) && renderLanes && (workInProgress.child.flags |= 8192); scheduleRetryEffect(workInProgress, workInProgress.updateQueue); @@ -6992,7 +6281,9 @@ function completeWork(current, workInProgress, renderLanes) { return popHostContainer(), bubbleProperties(workInProgress), null; case 10: return ( - popProvider(workInProgress.type), bubbleProperties(workInProgress), null + popProvider(workInProgress.type._context), + bubbleProperties(workInProgress), + null ); case 17: return bubbleProperties(workInProgress), null; @@ -7018,10 +6309,9 @@ function completeWork(current, workInProgress, renderLanes) { workInProgress.updateQueue = current; scheduleRetryEffect(workInProgress, current); workInProgress.subtreeFlags = 0; - current = renderLanes; - for (renderLanes = workInProgress.child; null !== renderLanes; ) - resetWorkInProgress(renderLanes, current), - (renderLanes = renderLanes.sibling); + for (current = workInProgress.child; null !== current; ) + resetWorkInProgress(current, renderLanes), + (current = current.sibling); push( suspenseStackCursor, (suspenseStackCursor.current & 1) | 2 @@ -7045,9 +6335,9 @@ function completeWork(current, workInProgress, renderLanes) { if ( ((workInProgress.flags |= 128), (newProps = !0), - (current = current.updateQueue), - (workInProgress.updateQueue = current), - scheduleRetryEffect(workInProgress, current), + (renderLanes = current.updateQueue), + (workInProgress.updateQueue = renderLanes), + scheduleRetryEffect(workInProgress, renderLanes), cutOffTailIfNeeded(type, !0), null === type.tail && "hidden" === type.tailMode && @@ -7065,9 +6355,9 @@ function completeWork(current, workInProgress, renderLanes) { type.isBackwards ? ((updatePayload.sibling = workInProgress.child), (workInProgress.child = updatePayload)) - : ((current = type.last), - null !== current - ? (current.sibling = updatePayload) + : ((renderLanes = type.last), + null !== renderLanes + ? (renderLanes.sibling = updatePayload) : (workInProgress.child = updatePayload), (type.last = updatePayload)); } @@ -7078,8 +6368,11 @@ function completeWork(current, workInProgress, renderLanes) { (type.tail = workInProgress.sibling), (type.renderingStartTime = now()), (workInProgress.sibling = null), - (current = suspenseStackCursor.current), - push(suspenseStackCursor, newProps ? (current & 1) | 2 : current & 1), + (renderLanes = suspenseStackCursor.current), + push( + suspenseStackCursor, + newProps ? (renderLanes & 1) | 2 : renderLanes & 1 + ), workInProgress ); bubbleProperties(workInProgress); @@ -7103,32 +6396,11 @@ function completeWork(current, workInProgress, renderLanes) { (renderLanes = workInProgress.updateQueue), null !== renderLanes && scheduleRetryEffect(workInProgress, renderLanes.retryQueue), - (renderLanes = null), - null !== current && - null !== current.memoizedState && - null !== current.memoizedState.cachePool && - (renderLanes = current.memoizedState.cachePool.pool), - (newProps = null), - null !== workInProgress.memoizedState && - null !== workInProgress.memoizedState.cachePool && - (newProps = workInProgress.memoizedState.cachePool.pool), - newProps !== renderLanes && (workInProgress.flags |= 2048), - null !== current && pop(resumedCache), null ); case 24: - return ( - (renderLanes = null), - null !== current && (renderLanes = current.memoizedState.cache), - workInProgress.memoizedState.cache !== renderLanes && - (workInProgress.flags |= 2048), - popProvider(CacheContext), - bubbleProperties(workInProgress), - null - ); - case 25: return null; - case 29: + case 25: return null; } throw Error( @@ -7148,7 +6420,6 @@ function unwindWork(current, workInProgress) { ); case 3: return ( - popProvider(CacheContext), popHostContainer(), (current = workInProgress.flags), 0 !== (current & 65536) && 0 === (current & 128) @@ -7179,20 +6450,19 @@ function unwindWork(current, workInProgress) { case 4: return popHostContainer(), null; case 10: - return popProvider(workInProgress.type), null; + return popProvider(workInProgress.type._context), null; case 22: case 23: return ( popSuspenseHandler(workInProgress), popHiddenContext(), - null !== current && pop(resumedCache), (current = workInProgress.flags), current & 65536 ? ((workInProgress.flags = (current & -65537) | 128), workInProgress) : null ); case 24: - return popProvider(CacheContext), null; + return null; case 25: return null; default: @@ -7202,7 +6472,6 @@ function unwindWork(current, workInProgress) { function unwindInterruptedWork(current, interruptedWork) { switch (interruptedWork.tag) { case 3: - popProvider(CacheContext); popHostContainer(); break; case 26: @@ -7220,30 +6489,17 @@ function unwindInterruptedWork(current, interruptedWork) { pop(suspenseStackCursor); break; case 10: - popProvider(interruptedWork.type); + popProvider(interruptedWork.type._context); break; case 22: case 23: - popSuspenseHandler(interruptedWork); - popHiddenContext(); - null !== current && pop(resumedCache); - break; - case 24: - popProvider(CacheContext); + popSuspenseHandler(interruptedWork), popHiddenContext(); } } var offscreenSubtreeIsHidden = !1, offscreenSubtreeWasHidden = !1, PossiblyWeakSet = "function" === typeof WeakSet ? WeakSet : Set, nextEffect = null; -function callComponentWillUnmountWithTimer(current, instance) { - instance.props = resolveClassComponentProps( - current.type, - current.memoizedProps - ); - instance.state = current.memoizedState; - instance.componentWillUnmount(); -} function safelyAttachRef(current, nearestMountedAncestor) { try { var ref = current.ref; @@ -7283,8 +6539,8 @@ function safelyDetachRef(current, nearestMountedAncestor) { else if ("function" === typeof ref) try { ref(null); - } catch (error$110) { - captureCommitPhaseError(current, nearestMountedAncestor, error$110); + } catch (error$76) { + captureCommitPhaseError(current, nearestMountedAncestor, error$76); } else ref.current = null; } @@ -7318,13 +6574,13 @@ function commitBeforeMutationEffects(root, firstChild) { break; case 1: if (0 !== (flags & 1024) && null !== current) { - var prevState = current.memoizedState, + var prevProps = current.memoizedProps, + prevState = current.memoizedState, instance = root.stateNode, snapshot = instance.getSnapshotBeforeUpdate( - resolveClassComponentProps( - root.type, - current.memoizedProps - ), + root.elementType === root.type + ? prevProps + : resolveDefaultProps(root.type, prevProps), prevState ); instance.__reactInternalSnapshotBeforeUpdate = snapshot; @@ -7388,10 +6644,10 @@ function commitHookEffectListMount(flags, finishedWork) { var effect = (finishedWork = finishedWork.next); do { if ((effect.tag & flags) === flags) { - var create$111 = effect.create, + var create$77 = effect.create, inst = effect.inst; - create$111 = create$111(); - inst.destroy = create$111; + create$77 = create$77(); + inst.destroy = create$77; } effect = effect.next; } while (effect !== finishedWork); @@ -7434,10 +6690,10 @@ function commitLayoutEffectOnFiber(finishedRoot, current, finishedWork) { captureCommitPhaseError(finishedWork, finishedWork.return, error); } else { - var prevProps = resolveClassComponentProps( - finishedWork.type, - current.memoizedProps - ); + var prevProps = + finishedWork.elementType === finishedWork.type + ? current.memoizedProps + : resolveDefaultProps(finishedWork.type, current.memoizedProps); current = current.memoizedState; try { finishedRoot.componentDidUpdate( @@ -7445,11 +6701,11 @@ function commitLayoutEffectOnFiber(finishedRoot, current, finishedWork) { current, finishedRoot.__reactInternalSnapshotBeforeUpdate ); - } catch (error$112) { + } catch (error$78) { captureCommitPhaseError( finishedWork, finishedWork.return, - error$112 + error$78 ); } } @@ -7770,7 +7026,9 @@ function commitDeletionEffectsOnFiber( "function" === typeof prevHostParent.componentWillUnmount) ) try { - callComponentWillUnmountWithTimer(deletedFiber, prevHostParent); + (prevHostParent.props = deletedFiber.memoizedProps), + (prevHostParent.state = deletedFiber.memoizedState), + prevHostParent.componentWillUnmount(); } catch (error) { captureCommitPhaseError(deletedFiber, nearestMountedAncestor, error); } @@ -7886,7 +7144,7 @@ function recursivelyTraverseMutationEffects(root$jscomp$0, parentFiber) { captureCommitPhaseError(childToDelete, parentFiber, error); } } - if (parentFiber.subtreeFlags & 13878) + if (parentFiber.subtreeFlags & 12854) for (parentFiber = parentFiber.child; null !== parentFiber; ) commitMutationEffectsOnFiber(parentFiber, root$jscomp$0), (parentFiber = parentFiber.sibling); @@ -7910,8 +7168,8 @@ function commitMutationEffectsOnFiber(finishedWork, root) { } try { commitHookEffectListUnmount(5, finishedWork, finishedWork.return); - } catch (error$120) { - captureCommitPhaseError(finishedWork, finishedWork.return, error$120); + } catch (error$86) { + captureCommitPhaseError(finishedWork, finishedWork.return, error$86); } } break; @@ -7942,6 +7200,7 @@ function commitMutationEffectsOnFiber(finishedWork, root) { if (flags & 4 && ((flags = finishedWork.stateNode), null != flags)) { var newProps = finishedWork.memoizedProps; current = null !== current ? current.memoizedProps : newProps; + finishedWork.updateQueue = null; try { var viewConfig = flags.viewConfig; instanceProps.set(flags._nativeTag, newProps); @@ -7957,8 +7216,8 @@ function commitMutationEffectsOnFiber(finishedWork, root) { viewConfig.uiViewClassName, updatePayload ); - } catch (error$123) { - captureCommitPhaseError(finishedWork, finishedWork.return, error$123); + } catch (error$89) { + captureCommitPhaseError(finishedWork, finishedWork.return, error$89); } } break; @@ -7978,8 +7237,8 @@ function commitMutationEffectsOnFiber(finishedWork, root) { "RCTRawText", { text: current } ); - } catch (error$124) { - captureCommitPhaseError(finishedWork, finishedWork.return, error$124); + } catch (error$90) { + captureCommitPhaseError(finishedWork, finishedWork.return, error$90); } } break; @@ -8090,11 +7349,11 @@ function commitMutationEffectsOnFiber(finishedWork, root) { if (null === current) try { throw Error("Not yet implemented."); - } catch (error$114) { + } catch (error$80) { captureCommitPhaseError( finishedWork, finishedWork.return, - error$114 + error$80 ); } } else if ( @@ -8168,12 +7427,12 @@ function commitReconciliationEffects(finishedWork) { break; case 3: case 4: - var parent$115 = JSCompiler_inline_result.stateNode.containerInfo, - before$116 = getHostSibling(finishedWork); + var parent$81 = JSCompiler_inline_result.stateNode.containerInfo, + before$82 = getHostSibling(finishedWork); insertOrAppendPlacementNodeIntoContainer( finishedWork, - before$116, - parent$115 + before$82, + parent$81 ); break; default: @@ -8212,7 +7471,10 @@ function recursivelyTraverseDisappearLayoutEffects(parentFiber) { var current = finishedWork, nearestMountedAncestor = finishedWork.return; try { - callComponentWillUnmountWithTimer(current, instance); + var current$jscomp$0 = current; + instance.props = current$jscomp$0.memoizedProps; + instance.state = current$jscomp$0.memoizedState; + instance.componentWillUnmount(); } catch (error) { captureCommitPhaseError(current, nearestMountedAncestor, error); } @@ -8337,166 +7599,61 @@ function commitHookPassiveMountEffects(finishedWork, hookFlags) { captureCommitPhaseError(finishedWork, finishedWork.return, error); } } -function commitOffscreenPassiveMountEffects(current, finishedWork) { - var previousCache = null; - null !== current && - null !== current.memoizedState && - null !== current.memoizedState.cachePool && - (previousCache = current.memoizedState.cachePool.pool); - current = null; - null !== finishedWork.memoizedState && - null !== finishedWork.memoizedState.cachePool && - (current = finishedWork.memoizedState.cachePool.pool); - current !== previousCache && - (null != current && current.refCount++, - null != previousCache && releaseCache(previousCache)); -} -function commitCachePassiveMountEffect(current, finishedWork) { - current = null; - null !== finishedWork.alternate && - (current = finishedWork.alternate.memoizedState.cache); - finishedWork = finishedWork.memoizedState.cache; - finishedWork !== current && - (finishedWork.refCount++, null != current && releaseCache(current)); -} -function recursivelyTraversePassiveMountEffects( - root, - parentFiber, - committedLanes, - committedTransitions -) { +function recursivelyTraversePassiveMountEffects(root, parentFiber) { if (parentFiber.subtreeFlags & 10256) for (parentFiber = parentFiber.child; null !== parentFiber; ) - commitPassiveMountOnFiber( - root, - parentFiber, - committedLanes, - committedTransitions - ), + commitPassiveMountOnFiber(root, parentFiber), (parentFiber = parentFiber.sibling); } -function commitPassiveMountOnFiber( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions -) { +function commitPassiveMountOnFiber(finishedRoot, finishedWork) { var flags = finishedWork.flags; switch (finishedWork.tag) { case 0: case 11: case 15: - recursivelyTraversePassiveMountEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - ); + recursivelyTraversePassiveMountEffects(finishedRoot, finishedWork); flags & 2048 && commitHookPassiveMountEffects(finishedWork, 9); break; case 3: - recursivelyTraversePassiveMountEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - ); - flags & 2048 && - ((finishedRoot = null), - null !== finishedWork.alternate && - (finishedRoot = finishedWork.alternate.memoizedState.cache), - (finishedWork = finishedWork.memoizedState.cache), - finishedWork !== finishedRoot && - (finishedWork.refCount++, - null != finishedRoot && releaseCache(finishedRoot))); + recursivelyTraversePassiveMountEffects(finishedRoot, finishedWork); break; case 23: break; case 22: - var instance = finishedWork.stateNode; + flags = finishedWork.stateNode; null !== finishedWork.memoizedState - ? instance._visibility & 4 - ? recursivelyTraversePassiveMountEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - ) - : finishedWork.mode & 1 - ? recursivelyTraverseAtomicPassiveEffects(finishedRoot, finishedWork) - : ((instance._visibility |= 4), - recursivelyTraversePassiveMountEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - )) - : instance._visibility & 4 - ? recursivelyTraversePassiveMountEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - ) - : ((instance._visibility |= 4), + ? flags._visibility & 4 + ? recursivelyTraversePassiveMountEffects(finishedRoot, finishedWork) + : finishedWork.mode & 1 || + ((flags._visibility |= 4), + recursivelyTraversePassiveMountEffects(finishedRoot, finishedWork)) + : flags._visibility & 4 + ? recursivelyTraversePassiveMountEffects(finishedRoot, finishedWork) + : ((flags._visibility |= 4), recursivelyTraverseReconnectPassiveEffects( finishedRoot, - finishedWork, - committedLanes, - committedTransitions, - 0 !== (finishedWork.subtreeFlags & 10256) + finishedWork )); - flags & 2048 && - commitOffscreenPassiveMountEffects( - finishedWork.alternate, - finishedWork - ); break; case 24: - recursivelyTraversePassiveMountEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - ); - flags & 2048 && - commitCachePassiveMountEffect(finishedWork.alternate, finishedWork); + recursivelyTraversePassiveMountEffects(finishedRoot, finishedWork); break; default: - recursivelyTraversePassiveMountEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - ); + recursivelyTraversePassiveMountEffects(finishedRoot, finishedWork); } } function recursivelyTraverseReconnectPassiveEffects( finishedRoot$jscomp$0, - parentFiber, - committedLanes$jscomp$0, - committedTransitions$jscomp$0, - includeWorkInProgressEffects + parentFiber ) { - includeWorkInProgressEffects = - includeWorkInProgressEffects && 0 !== (parentFiber.subtreeFlags & 10256); for (parentFiber = parentFiber.child; null !== parentFiber; ) { var finishedRoot = finishedRoot$jscomp$0, - finishedWork = parentFiber, - committedLanes = committedLanes$jscomp$0, - committedTransitions = committedTransitions$jscomp$0, - flags = finishedWork.flags; + finishedWork = parentFiber; switch (finishedWork.tag) { case 0: case 11: case 15: - recursivelyTraverseReconnectPassiveEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions, - includeWorkInProgressEffects - ); + recursivelyTraverseReconnectPassiveEffects(finishedRoot, finishedWork); commitHookPassiveMountEffects(finishedWork, 8); break; case 23: @@ -8506,93 +7663,30 @@ function recursivelyTraverseReconnectPassiveEffects( null !== finishedWork.memoizedState ? instance._visibility & 4 ? recursivelyTraverseReconnectPassiveEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions, - includeWorkInProgressEffects - ) - : finishedWork.mode & 1 - ? recursivelyTraverseAtomicPassiveEffects( finishedRoot, finishedWork ) - : ((instance._visibility |= 4), + : finishedWork.mode & 1 || + ((instance._visibility |= 4), recursivelyTraverseReconnectPassiveEffects( finishedRoot, - finishedWork, - committedLanes, - committedTransitions, - includeWorkInProgressEffects + finishedWork )) : ((instance._visibility |= 4), recursivelyTraverseReconnectPassiveEffects( finishedRoot, - finishedWork, - committedLanes, - committedTransitions, - includeWorkInProgressEffects + finishedWork )); - includeWorkInProgressEffects && - flags & 2048 && - commitOffscreenPassiveMountEffects( - finishedWork.alternate, - finishedWork - ); break; case 24: - recursivelyTraverseReconnectPassiveEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions, - includeWorkInProgressEffects - ); - includeWorkInProgressEffects && - flags & 2048 && - commitCachePassiveMountEffect(finishedWork.alternate, finishedWork); + recursivelyTraverseReconnectPassiveEffects(finishedRoot, finishedWork); break; default: - recursivelyTraverseReconnectPassiveEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions, - includeWorkInProgressEffects - ); + recursivelyTraverseReconnectPassiveEffects(finishedRoot, finishedWork); } parentFiber = parentFiber.sibling; } } -function recursivelyTraverseAtomicPassiveEffects( - finishedRoot$jscomp$0, - parentFiber -) { - if (parentFiber.subtreeFlags & 10256) - for (parentFiber = parentFiber.child; null !== parentFiber; ) { - var finishedRoot = finishedRoot$jscomp$0, - finishedWork = parentFiber, - flags = finishedWork.flags; - switch (finishedWork.tag) { - case 22: - recursivelyTraverseAtomicPassiveEffects(finishedRoot, finishedWork); - flags & 2048 && - commitOffscreenPassiveMountEffects( - finishedWork.alternate, - finishedWork - ); - break; - case 24: - recursivelyTraverseAtomicPassiveEffects(finishedRoot, finishedWork); - flags & 2048 && - commitCachePassiveMountEffect(finishedWork.alternate, finishedWork); - break; - default: - recursivelyTraverseAtomicPassiveEffects(finishedRoot, finishedWork); - } - parentFiber = parentFiber.sibling; - } -} var suspenseyCommitFlag = 8192; function recursivelyAccumulateSuspenseyCommit(parentFiber) { if (parentFiber.subtreeFlags & suspenseyCommitFlag) @@ -8604,9 +7698,10 @@ function accumulateSuspenseyCommitOnFiber(fiber) { switch (fiber.tag) { case 26: recursivelyAccumulateSuspenseyCommit(fiber); - fiber.flags & suspenseyCommitFlag && - null !== fiber.memoizedState && - shim(); + if (fiber.flags & suspenseyCommitFlag && null !== fiber.memoizedState) + throw Error( + "The current renderer does not support Resources. This error is likely caused by a bug in React. Please file an issue." + ); break; case 5: recursivelyAccumulateSuspenseyCommit(fiber); @@ -8731,29 +7826,16 @@ function commitPassiveUnmountEffectsInsideOfDeletedTree_begin( case 11: case 15: commitHookEffectListUnmount(8, fiber, nearestMountedAncestor); - break; - case 23: - case 22: - if ( - null !== fiber.memoizedState && - null !== fiber.memoizedState.cachePool - ) { - var cache = fiber.memoizedState.cachePool.pool; - null != cache && cache.refCount++; - } - break; - case 24: - releaseCache(fiber.memoizedState.cache); } - cache = fiber.child; - if (null !== cache) (cache.return = fiber), (nextEffect = cache); + var child = fiber.child; + if (null !== child) (child.return = fiber), (nextEffect = child); else a: for (fiber = deletedSubtreeRoot; null !== nextEffect; ) { - cache = nextEffect; - var sibling = cache.sibling, - returnFiber = cache.return; - detachFiberAfterEffects(cache); - if (cache === fiber) { + child = nextEffect; + var sibling = child.sibling, + returnFiber = child.return; + detachFiberAfterEffects(child); + if (child === fiber) { nextEffect = null; break a; } @@ -8766,17 +7848,10 @@ function commitPassiveUnmountEffectsInsideOfDeletedTree_begin( } } } -var DefaultAsyncDispatcher = { - getCacheForType: function (resourceType) { - var cache = readContext(CacheContext), - cacheForType = cache.data.get(resourceType); - void 0 === cacheForType && - ((cacheForType = resourceType()), - cache.data.set(resourceType, cacheForType)); - return cacheForType; - } - }, - PossiblyWeakMap = "function" === typeof WeakMap ? WeakMap : Map, +var PossiblyWeakMap = "function" === typeof WeakMap ? WeakMap : Map, + ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, + ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner, + ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig, executionContext = 0, workInProgressRoot = null, workInProgress = null, @@ -8786,6 +7861,7 @@ var DefaultAsyncDispatcher = { workInProgressRootDidAttachPingListener = !1, entangledRenderLanes = 0, workInProgressRootExitStatus = 0, + workInProgressRootFatalError = null, workInProgressRootSkippedLanes = 0, workInProgressRootInterleavedUpdatedLanes = 0, workInProgressRootPingedLanes = 0, @@ -8793,29 +7869,31 @@ var DefaultAsyncDispatcher = { workInProgressRootConcurrentErrors = null, workInProgressRootRecoverableErrors = null, workInProgressRootDidIncludeRecursiveRenderUpdate = !1, - didIncludeCommitPhaseUpdate = !1, globalMostRecentFallbackTime = 0, workInProgressRootRenderTargetTime = Infinity, workInProgressTransitions = null, + hasUncaughtError = !1, + firstUncaughtError = null, legacyErrorBoundariesThatAlreadyFailed = null, rootDoesHavePassiveEffects = !1, rootWithPendingPassiveEffects = null, pendingPassiveEffectsLanes = 0, - pendingPassiveEffectsRemainingLanes = 0, - pendingPassiveTransitions = null, nestedUpdateCount = 0, rootWithNestedUpdates = null; function requestUpdateLane(fiber) { if (0 === (fiber.mode & 1)) return 2; if (0 !== (executionContext & 2) && 0 !== workInProgressRootRenderLanes) return workInProgressRootRenderLanes & -workInProgressRootRenderLanes; - if (null !== ReactSharedInternals.T) + fiber = ReactCurrentBatchConfig$1.transition; + null !== fiber && fiber._callbacks.add(handleAsyncAction); + if (null !== fiber) return ( - (fiber = currentEntangledLane), - 0 !== fiber ? fiber : requestTransitionLane() + 0 === currentEventTransitionLane && + (currentEventTransitionLane = claimNextTransitionLane()), + currentEventTransitionLane ); - fiber = 0 !== currentUpdatePriority ? currentUpdatePriority : 32; - return fiber; + fiber = currentUpdatePriority; + return 0 !== fiber ? fiber : 32; } function requestDeferredLane() { 0 === workInProgressDeferredLane && @@ -8838,7 +7916,7 @@ function scheduleUpdateOnFiber(root, fiber, lane) { workInProgressRootRenderLanes, workInProgressDeferredLane ); - markRootUpdated(root, lane); + markRootUpdated$1(root, lane); if (0 === (executionContext & 2) || root !== workInProgressRoot) root === workInProgressRoot && (0 === (executionContext & 2) && @@ -8891,24 +7969,22 @@ function performConcurrentWorkOnRoot(root, didTimeout) { root, renderWasConcurrent ); - if ( - 0 !== errorRetryLanes && + 0 !== errorRetryLanes && ((lanes = errorRetryLanes), (exitStatus = recoverFromConcurrentError( root, renderWasConcurrent, errorRetryLanes - )), - (renderWasConcurrent = !1), - 2 !== exitStatus) - ) - continue; - } - if (1 === exitStatus) { - prepareFreshStack(root, 0); - markRootSuspended(root, lanes, 0); - break; + ))); } + if (1 === exitStatus) + throw ( + ((originalCallbackNode = workInProgressRootFatalError), + prepareFreshStack(root, 0), + markRootSuspended(root, lanes, 0), + ensureRootIsScheduled(root), + originalCallbackNode) + ); root.finishedWork = didTimeout; root.finishedLanes = lanes; a: { @@ -8928,8 +8004,6 @@ function performConcurrentWorkOnRoot(root, didTimeout) { } break; case 2: - workInProgressRootRecoverableErrors = null; - break; case 3: case 5: break; @@ -8990,10 +8064,13 @@ function recoverFromConcurrentError( originallyAttemptedLanes, errorRetryLanes ) { - var errorsFromFirstAttempt = workInProgressRootConcurrentErrors; + var errorsFromFirstAttempt = workInProgressRootConcurrentErrors, + JSCompiler_inline_result; + (JSCompiler_inline_result = root.current.memoizedState.isDehydrated) && + (prepareFreshStack(root, errorRetryLanes).flags |= 256); errorRetryLanes = renderRootSync(root, errorRetryLanes); if (2 !== errorRetryLanes) { - if (workInProgressRootDidAttachPingListener) + if (workInProgressRootDidAttachPingListener && !JSCompiler_inline_result) return ( (root.errorRecoveryDisabledLanes |= originallyAttemptedLanes), (workInProgressRootInterleavedUpdatedLanes |= originallyAttemptedLanes), @@ -9022,9 +8099,7 @@ function commitRootWhenReady( lanes, spawnedLane ) { - lanes = finishedWork.subtreeFlags; - (lanes & 8192 || 16785408 === (lanes & 16785408)) && - accumulateSuspenseyCommitOnFiber(finishedWork); + 0 === (lanes & 42) && accumulateSuspenseyCommitOnFiber(finishedWork); commitRoot( root, recoverableErrors, @@ -9067,15 +8142,6 @@ function isRenderConsistentWithExternalStores(finishedWork) { } return !0; } -function markRootUpdated(root, updatedLanes) { - root.pendingLanes |= updatedLanes; - 268435456 !== updatedLanes && - ((root.suspendedLanes = 0), (root.pingedLanes = 0)); - executionContext & 2 - ? (workInProgressRootDidIncludeRecursiveRenderUpdate = !0) - : executionContext & 4 && (didIncludeCommitPhaseUpdate = !0); - throwIfInfiniteUpdateLoopDetected(); -} function markRootSuspended(root, suspendedLanes, spawnedLane) { suspendedLanes &= ~workInProgressRootPingedLanes; suspendedLanes &= ~workInProgressRootInterleavedUpdatedLanes; @@ -9086,58 +8152,14 @@ function markRootSuspended(root, suspendedLanes, spawnedLane) { 0 < lanes; ) { - var index$10 = 31 - clz32(lanes), - lane = 1 << index$10; - expirationTimes[index$10] = -1; + var index$6 = 31 - clz32(lanes), + lane = 1 << index$6; + expirationTimes[index$6] = -1; lanes &= ~lane; } 0 !== spawnedLane && markSpawnedDeferredLane(root, spawnedLane, suspendedLanes); } -function performSyncWorkOnRoot(root, lanes) { - if (0 !== (executionContext & 6)) - throw Error("Should not already be working."); - if (flushPassiveEffects()) return ensureRootIsScheduled(root), null; - var exitStatus = renderRootSync(root, lanes); - if (0 !== root.tag && 2 === exitStatus) { - var originallyAttemptedLanes = lanes, - errorRetryLanes = getLanesToRetrySynchronouslyOnError( - root, - originallyAttemptedLanes - ); - 0 !== errorRetryLanes && - ((lanes = errorRetryLanes), - (exitStatus = recoverFromConcurrentError( - root, - originallyAttemptedLanes, - errorRetryLanes - ))); - } - if (1 === exitStatus) - return ( - prepareFreshStack(root, 0), - markRootSuspended(root, lanes, 0), - ensureRootIsScheduled(root), - null - ); - if (6 === exitStatus) - return ( - markRootSuspended(root, lanes, workInProgressDeferredLane), - ensureRootIsScheduled(root), - null - ); - root.finishedWork = root.current.alternate; - root.finishedLanes = lanes; - commitRoot( - root, - workInProgressRootRecoverableErrors, - workInProgressTransitions, - workInProgressRootDidIncludeRecursiveRenderUpdate, - workInProgressDeferredLane - ); - ensureRootIsScheduled(root); - return null; -} function resetWorkInProgressStack() { if (null !== workInProgress) { if (0 === workInProgressSuspendedReason) @@ -9171,11 +8193,12 @@ function prepareFreshStack(root, lanes) { workInProgressSuspendedReason = 0; workInProgressThrownValue = null; workInProgressRootDidAttachPingListener = !1; + workInProgressRootExitStatus = 0; + workInProgressRootFatalError = null; workInProgressDeferredLane = workInProgressRootPingedLanes = workInProgressRootInterleavedUpdatedLanes = workInProgressRootSkippedLanes = - workInProgressRootExitStatus = 0; workInProgressRootRecoverableErrors = workInProgressRootConcurrentErrors = null; @@ -9188,9 +8211,9 @@ function prepareFreshStack(root, lanes) { 0 < allEntangledLanes; ) { - var index$8 = 31 - clz32(allEntangledLanes), - lane = 1 << index$8; - lanes |= root[index$8]; + var index$4 = 31 - clz32(allEntangledLanes), + lane = 1 << index$4; + lanes |= root[index$4]; allEntangledLanes &= ~lane; } entangledRenderLanes = lanes; @@ -9199,53 +8222,45 @@ function prepareFreshStack(root, lanes) { } function handleThrow(root, thrownValue) { currentlyRenderingFiber$1 = null; - ReactSharedInternals.H = ContextOnlyDispatcher; - if (thrownValue === SuspenseException) { - thrownValue = getSuspendedThenable(); - var handler = suspenseHandlerStackCursor.current; - workInProgressSuspendedReason = - (null !== handler && - ((workInProgressRootRenderLanes & 4194176) === - workInProgressRootRenderLanes - ? null !== shellBoundary - : ((workInProgressRootRenderLanes & 62914560) !== - workInProgressRootRenderLanes && - 0 === (workInProgressRootRenderLanes & 536870912)) || - handler !== shellBoundary)) || - 0 !== (workInProgressRootSkippedLanes & 134217727) || - 0 !== (workInProgressRootInterleavedUpdatedLanes & 134217727) - ? 3 - : 2; - } else - thrownValue === SuspenseyCommitException - ? ((thrownValue = getSuspendedThenable()), - (workInProgressSuspendedReason = 4)) - : (workInProgressSuspendedReason = - thrownValue === SelectiveHydrationException - ? 8 - : null !== thrownValue && - "object" === typeof thrownValue && - "function" === typeof thrownValue.then - ? 6 - : 1); + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + ReactCurrentOwner.current = null; + thrownValue === SuspenseException + ? ((thrownValue = getSuspendedThenable()), + (root = suspenseHandlerStackCursor.current), + (workInProgressSuspendedReason = + (null !== root && + ((workInProgressRootRenderLanes & 4194176) === + workInProgressRootRenderLanes + ? null !== shellBoundary + : ((workInProgressRootRenderLanes & 62914560) !== + workInProgressRootRenderLanes && + 0 === (workInProgressRootRenderLanes & 536870912)) || + root !== shellBoundary)) || + 0 !== (workInProgressRootSkippedLanes & 134217727) || + 0 !== (workInProgressRootInterleavedUpdatedLanes & 134217727) + ? 3 + : 2)) + : thrownValue === SuspenseyCommitException + ? ((thrownValue = getSuspendedThenable()), + (workInProgressSuspendedReason = 4)) + : (workInProgressSuspendedReason = + thrownValue === SelectiveHydrationException + ? 8 + : null !== thrownValue && + "object" === typeof thrownValue && + "function" === typeof thrownValue.then + ? 6 + : 1); workInProgressThrownValue = thrownValue; null === workInProgress && ((workInProgressRootExitStatus = 1), - logUncaughtError( - root, - createCapturedValueAtFiber(thrownValue, root.current) - )); + (workInProgressRootFatalError = thrownValue)); } function pushDispatcher() { - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = ContextOnlyDispatcher; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = ContextOnlyDispatcher; return null === prevDispatcher ? ContextOnlyDispatcher : prevDispatcher; } -function pushAsyncDispatcher() { - var prevAsyncDispatcher = ReactSharedInternals.A; - ReactSharedInternals.A = DefaultAsyncDispatcher; - return prevAsyncDispatcher; -} function renderDidSuspendDelayIfPossible() { workInProgressRootExitStatus = 4; (0 === (workInProgressRootSkippedLanes & 134217727) && @@ -9260,8 +8275,7 @@ function renderDidSuspendDelayIfPossible() { function renderRootSync(root, lanes) { var prevExecutionContext = executionContext; executionContext |= 2; - var prevDispatcher = pushDispatcher(), - prevAsyncDispatcher = pushAsyncDispatcher(); + var prevDispatcher = pushDispatcher(); if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) (workInProgressTransitions = null), prepareFreshStack(root, lanes); lanes = !1; @@ -9288,15 +8302,14 @@ function renderRootSync(root, lanes) { } workLoopSync(); break; - } catch (thrownValue$132) { - handleThrow(root, thrownValue$132); + } catch (thrownValue$94) { + handleThrow(root, thrownValue$94); } while (1); lanes && root.shellSuspendCounter++; resetContextDependencies(); executionContext = prevExecutionContext; - ReactSharedInternals.H = prevDispatcher; - ReactSharedInternals.A = prevAsyncDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; if (null !== workInProgress) throw Error( "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." @@ -9312,8 +8325,7 @@ function workLoopSync() { function renderRootConcurrent(root, lanes) { var prevExecutionContext = executionContext; executionContext |= 2; - var prevDispatcher = pushDispatcher(), - prevAsyncDispatcher = pushAsyncDispatcher(); + var prevDispatcher = pushDispatcher(); if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) (workInProgressTransitions = null), (workInProgressRootRenderTargetTime = now() + 500), @@ -9360,27 +8372,23 @@ function renderRootConcurrent(root, lanes) { throwAndUnwindWorkLoop(root, lanes, thrownValue)); break; case 5: - var resource = null; switch (workInProgress.tag) { - case 26: - resource = workInProgress.memoizedState; case 5: + case 26: case 27: - var hostFiber = workInProgress; - if (resource ? shim(resource) : 1) { - workInProgressSuspendedReason = 0; - workInProgressThrownValue = null; - var sibling = hostFiber.sibling; - if (null !== sibling) workInProgress = sibling; - else { - var returnFiber = hostFiber.return; - null !== returnFiber - ? ((workInProgress = returnFiber), - completeUnitOfWork(returnFiber)) - : (workInProgress = null); - } - break b; + lanes = workInProgress; + workInProgressSuspendedReason = 0; + workInProgressThrownValue = null; + var sibling = lanes.sibling; + if (null !== sibling) workInProgress = sibling; + else { + var returnFiber = lanes.return; + null !== returnFiber + ? ((workInProgress = returnFiber), + completeUnitOfWork(returnFiber)) + : (workInProgress = null); } + break b; } workInProgressSuspendedReason = 0; workInProgressThrownValue = null; @@ -9401,13 +8409,12 @@ function renderRootConcurrent(root, lanes) { } workLoopConcurrent(); break; - } catch (thrownValue$134) { - handleThrow(root, thrownValue$134); + } catch (thrownValue$96) { + handleThrow(root, thrownValue$96); } while (1); resetContextDependencies(); - ReactSharedInternals.H = prevDispatcher; - ReactSharedInternals.A = prevAsyncDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; executionContext = prevExecutionContext; if (null !== workInProgress) return 0; workInProgressRoot = null; @@ -9423,42 +8430,59 @@ function performUnitOfWork(unitOfWork) { var next = beginWork(unitOfWork.alternate, unitOfWork, entangledRenderLanes); unitOfWork.memoizedProps = unitOfWork.pendingProps; null === next ? completeUnitOfWork(unitOfWork) : (workInProgress = next); + ReactCurrentOwner.current = null; } function replaySuspendedUnitOfWork(unitOfWork) { - var next = unitOfWork; - var current = next.alternate; - switch (next.tag) { + var current = unitOfWork.alternate; + switch (unitOfWork.tag) { + case 2: + unitOfWork.tag = 0; case 15: case 0: - next = replayFunctionComponent( + var Component = unitOfWork.type, + unresolvedProps = unitOfWork.pendingProps; + unresolvedProps = + unitOfWork.elementType === Component + ? unresolvedProps + : resolveDefaultProps(Component, unresolvedProps); + current = replayFunctionComponent( current, - next, - next.pendingProps, - next.type, + unitOfWork, + unresolvedProps, + Component, void 0, workInProgressRootRenderLanes ); break; case 11: - next = replayFunctionComponent( + Component = unitOfWork.type.render; + unresolvedProps = unitOfWork.pendingProps; + unresolvedProps = + unitOfWork.elementType === Component + ? unresolvedProps + : resolveDefaultProps(Component, unresolvedProps); + current = replayFunctionComponent( current, - next, - next.pendingProps, - next.type.render, - next.ref, + unitOfWork, + unresolvedProps, + Component, + unitOfWork.ref, workInProgressRootRenderLanes ); break; case 5: - resetHooksOnUnwind(next); + resetHooksOnUnwind(unitOfWork); default: - unwindInterruptedWork(current, next), - (next = workInProgress = - resetWorkInProgress(next, entangledRenderLanes)), - (next = beginWork(current, next, entangledRenderLanes)); + unwindInterruptedWork(current, unitOfWork), + (unitOfWork = workInProgress = + resetWorkInProgress(unitOfWork, entangledRenderLanes)), + (current = beginWork(current, unitOfWork, entangledRenderLanes)); } unitOfWork.memoizedProps = unitOfWork.pendingProps; - null === next ? completeUnitOfWork(unitOfWork) : (workInProgress = next); + null === current + ? completeUnitOfWork(unitOfWork) + : (workInProgress = current); + ReactCurrentOwner.current = null; } function throwAndUnwindWorkLoop(root, unitOfWork, thrownValue) { resetContextDependencies(); @@ -9477,20 +8501,14 @@ function throwAndUnwindWorkLoop(root, unitOfWork, thrownValue) { ) ) { workInProgressRootExitStatus = 1; - logUncaughtError( - root, - createCapturedValueAtFiber(thrownValue, root.current) - ); + workInProgressRootFatalError = thrownValue; workInProgress = null; return; } } catch (error) { if (null !== returnFiber) throw ((workInProgress = returnFiber), error); workInProgressRootExitStatus = 1; - logUncaughtError( - root, - createCapturedValueAtFiber(thrownValue, root.current) - ); + workInProgressRootFatalError = thrownValue; workInProgress = null; return; } @@ -9545,11 +8563,11 @@ function commitRoot( didIncludeRenderPhaseUpdate, spawnedLane ) { - var prevTransition = ReactSharedInternals.T, - previousUpdateLanePriority = currentUpdatePriority; + var previousUpdateLanePriority = currentUpdatePriority, + prevTransition = ReactCurrentBatchConfig.transition; try { - (currentUpdatePriority = 2), - (ReactSharedInternals.T = null), + (ReactCurrentBatchConfig.transition = null), + (currentUpdatePriority = 2), commitRootImpl( root, recoverableErrors, @@ -9559,7 +8577,7 @@ function commitRoot( spawnedLane ); } finally { - (ReactSharedInternals.T = prevTransition), + (ReactCurrentBatchConfig.transition = prevTransition), (currentUpdatePriority = previousUpdateLanePriority); } return null; @@ -9576,78 +8594,88 @@ function commitRootImpl( while (null !== rootWithPendingPassiveEffects); if (0 !== (executionContext & 6)) throw Error("Should not already be working."); - var finishedWork = root.finishedWork, - lanes = root.finishedLanes; - if (null === finishedWork) return null; + didIncludeRenderPhaseUpdate = root.finishedWork; + transitions = root.finishedLanes; + if (null === didIncludeRenderPhaseUpdate) return null; root.finishedWork = null; root.finishedLanes = 0; - if (finishedWork === root.current) + if (didIncludeRenderPhaseUpdate === root.current) throw Error( "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." ); root.callbackNode = null; root.callbackPriority = 0; root.cancelPendingCommit = null; - var remainingLanes = finishedWork.lanes | finishedWork.childLanes; + var remainingLanes = + didIncludeRenderPhaseUpdate.lanes | didIncludeRenderPhaseUpdate.childLanes; remainingLanes |= concurrentlyUpdatedLanes; markRootFinished(root, remainingLanes, spawnedLane); - didIncludeCommitPhaseUpdate = !1; root === workInProgressRoot && ((workInProgress = workInProgressRoot = null), (workInProgressRootRenderLanes = 0)); - (0 === (finishedWork.subtreeFlags & 10256) && - 0 === (finishedWork.flags & 10256)) || + (0 === (didIncludeRenderPhaseUpdate.subtreeFlags & 10256) && + 0 === (didIncludeRenderPhaseUpdate.flags & 10256)) || rootDoesHavePassiveEffects || ((rootDoesHavePassiveEffects = !0), - (pendingPassiveEffectsRemainingLanes = remainingLanes), - (pendingPassiveTransitions = transitions), - scheduleCallback(NormalPriority$1, function () { + scheduleCallback(NormalPriority, function () { flushPassiveEffects(); return null; })); - transitions = 0 !== (finishedWork.flags & 15990); - if (0 !== (finishedWork.subtreeFlags & 15990) || transitions) { - transitions = ReactSharedInternals.T; - ReactSharedInternals.T = null; - spawnedLane = currentUpdatePriority; + spawnedLane = 0 !== (didIncludeRenderPhaseUpdate.flags & 15990); + if (0 !== (didIncludeRenderPhaseUpdate.subtreeFlags & 15990) || spawnedLane) { + spawnedLane = ReactCurrentBatchConfig.transition; + ReactCurrentBatchConfig.transition = null; + remainingLanes = currentUpdatePriority; currentUpdatePriority = 2; var prevExecutionContext = executionContext; executionContext |= 4; - commitBeforeMutationEffects(root, finishedWork); - commitMutationEffectsOnFiber(finishedWork, root); - root.current = finishedWork; - commitLayoutEffectOnFiber(root, finishedWork.alternate, finishedWork); + ReactCurrentOwner.current = null; + commitBeforeMutationEffects(root, didIncludeRenderPhaseUpdate); + commitMutationEffectsOnFiber(didIncludeRenderPhaseUpdate, root); + root.current = didIncludeRenderPhaseUpdate; + commitLayoutEffectOnFiber( + root, + didIncludeRenderPhaseUpdate.alternate, + didIncludeRenderPhaseUpdate + ); requestPaint(); executionContext = prevExecutionContext; - currentUpdatePriority = spawnedLane; - ReactSharedInternals.T = transitions; - } else root.current = finishedWork; - rootDoesHavePassiveEffects - ? ((rootDoesHavePassiveEffects = !1), - (rootWithPendingPassiveEffects = root), - (pendingPassiveEffectsLanes = lanes)) - : releaseRootPooledCache(root, remainingLanes); + currentUpdatePriority = remainingLanes; + ReactCurrentBatchConfig.transition = spawnedLane; + } else root.current = didIncludeRenderPhaseUpdate; + rootDoesHavePassiveEffects && + ((rootDoesHavePassiveEffects = !1), + (rootWithPendingPassiveEffects = root), + (pendingPassiveEffectsLanes = transitions)); remainingLanes = root.pendingLanes; 0 === remainingLanes && (legacyErrorBoundariesThatAlreadyFailed = null); - onCommitRoot(finishedWork.stateNode, renderPriorityLevel); + onCommitRoot(didIncludeRenderPhaseUpdate.stateNode, renderPriorityLevel); ensureRootIsScheduled(root); if (null !== recoverableErrors) for ( - renderPriorityLevel = root.onRecoverableError, finishedWork = 0; - finishedWork < recoverableErrors.length; - finishedWork++ + renderPriorityLevel = root.onRecoverableError, + didIncludeRenderPhaseUpdate = 0; + didIncludeRenderPhaseUpdate < recoverableErrors.length; + didIncludeRenderPhaseUpdate++ ) - (remainingLanes = recoverableErrors[finishedWork]), - renderPriorityLevel(remainingLanes.value, { - componentStack: remainingLanes.stack - }); + (spawnedLane = recoverableErrors[didIncludeRenderPhaseUpdate]), + (remainingLanes = { + digest: spawnedLane.digest, + componentStack: spawnedLane.stack + }), + renderPriorityLevel(spawnedLane.value, remainingLanes); + if (hasUncaughtError) + throw ( + ((hasUncaughtError = !1), + (root = firstUncaughtError), + (firstUncaughtError = null), + root) + ); 0 !== (pendingPassiveEffectsLanes & 3) && 0 !== root.tag && flushPassiveEffects(); remainingLanes = root.pendingLanes; - didIncludeRenderPhaseUpdate || - didIncludeCommitPhaseUpdate || - (0 !== (lanes & 4194218) && 0 !== (remainingLanes & 42)) + 0 !== (transitions & 4194218) && 0 !== (remainingLanes & 42) ? root === rootWithNestedUpdates ? nestedUpdateCount++ : ((nestedUpdateCount = 0), (rootWithNestedUpdates = root)) @@ -9655,43 +8683,26 @@ function commitRootImpl( flushSyncWorkAcrossRoots_impl(!1); return null; } -function releaseRootPooledCache(root, remainingLanes) { - 0 === (root.pooledCacheLanes &= remainingLanes) && - ((remainingLanes = root.pooledCache), - null != remainingLanes && - ((root.pooledCache = null), releaseCache(remainingLanes))); -} function flushPassiveEffects() { if (null !== rootWithPendingPassiveEffects) { - var root = rootWithPendingPassiveEffects, - remainingLanes = pendingPassiveEffectsRemainingLanes; - pendingPassiveEffectsRemainingLanes = 0; var renderPriority = lanesToEventPriority(pendingPassiveEffectsLanes), - prevTransition = ReactSharedInternals.T, + prevTransition = ReactCurrentBatchConfig.transition, previousPriority = currentUpdatePriority; try { + ReactCurrentBatchConfig.transition = null; currentUpdatePriority = 32 > renderPriority ? 32 : renderPriority; - ReactSharedInternals.T = null; if (null === rootWithPendingPassiveEffects) var JSCompiler_inline_result = !1; else { - renderPriority = pendingPassiveTransitions; - pendingPassiveTransitions = null; - var root$jscomp$0 = rootWithPendingPassiveEffects, - lanes = pendingPassiveEffectsLanes; + renderPriority = rootWithPendingPassiveEffects; rootWithPendingPassiveEffects = null; pendingPassiveEffectsLanes = 0; if (0 !== (executionContext & 6)) throw Error("Cannot flush passive effects while already rendering."); var prevExecutionContext = executionContext; executionContext |= 4; - commitPassiveUnmountOnFiber(root$jscomp$0.current); - commitPassiveMountOnFiber( - root$jscomp$0, - root$jscomp$0.current, - lanes, - renderPriority - ); + commitPassiveUnmountOnFiber(renderPriority.current); + commitPassiveMountOnFiber(renderPriority, renderPriority.current); executionContext = prevExecutionContext; flushSyncWorkAcrossRoots_impl(!1); if ( @@ -9699,25 +8710,24 @@ function flushPassiveEffects() { "function" === typeof injectedHook.onPostCommitFiberRoot ) try { - injectedHook.onPostCommitFiberRoot(rendererID, root$jscomp$0); + injectedHook.onPostCommitFiberRoot(rendererID, renderPriority); } catch (err) {} JSCompiler_inline_result = !0; } return JSCompiler_inline_result; } finally { (currentUpdatePriority = previousPriority), - (ReactSharedInternals.T = prevTransition), - releaseRootPooledCache(root, remainingLanes); + (ReactCurrentBatchConfig.transition = prevTransition); } } return !1; } function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { sourceFiber = createCapturedValueAtFiber(error, sourceFiber); - sourceFiber = createRootErrorUpdate(rootFiber.stateNode, sourceFiber, 2); + sourceFiber = createRootErrorUpdate(rootFiber, sourceFiber, 2); rootFiber = enqueueUpdate(rootFiber, sourceFiber, 2); null !== rootFiber && - (markRootUpdated(rootFiber, 2), ensureRootIsScheduled(rootFiber)); + (markRootUpdated$1(rootFiber, 2), ensureRootIsScheduled(rootFiber)); } function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error) { if (3 === sourceFiber.tag) @@ -9741,17 +8751,19 @@ function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error) { !legacyErrorBoundariesThatAlreadyFailed.has(instance))) ) { sourceFiber = createCapturedValueAtFiber(error, sourceFiber); - error = createClassErrorUpdate(2); - instance = enqueueUpdate(nearestMountedAncestor, error, 2); - null !== instance && - (initializeClassErrorUpdate( - error, - instance, - nearestMountedAncestor, - sourceFiber - ), - markRootUpdated(instance, 2), - ensureRootIsScheduled(instance)); + sourceFiber = createClassErrorUpdate( + nearestMountedAncestor, + sourceFiber, + 2 + ); + nearestMountedAncestor = enqueueUpdate( + nearestMountedAncestor, + sourceFiber, + 2 + ); + null !== nearestMountedAncestor && + (markRootUpdated$1(nearestMountedAncestor, 2), + ensureRootIsScheduled(nearestMountedAncestor)); break; } } @@ -9778,10 +8790,6 @@ function pingSuspendedRoot(root, wakeable, pingedLanes) { var pingCache = root.pingCache; null !== pingCache && pingCache.delete(wakeable); root.pingedLanes |= root.suspendedLanes & pingedLanes; - executionContext & 2 - ? (workInProgressRootDidIncludeRecursiveRenderUpdate = !0) - : executionContext & 4 && (didIncludeCommitPhaseUpdate = !0); - throwIfInfiniteUpdateLoopDetected(); workInProgressRoot === root && (workInProgressRootRenderLanes & pingedLanes) === pingedLanes && (4 === workInProgressRootExitStatus || @@ -9798,7 +8806,7 @@ function retryTimedOutBoundary(boundaryFiber, retryLane) { (retryLane = 0 === (boundaryFiber.mode & 1) ? 2 : claimNextRetryLane()); boundaryFiber = enqueueConcurrentRenderForLane(boundaryFiber, retryLane); null !== boundaryFiber && - (markRootUpdated(boundaryFiber, retryLane), + (markRootUpdated$1(boundaryFiber, retryLane), ensureRootIsScheduled(boundaryFiber)); } function retryDehydratedSuspenseBoundary(boundaryFiber) { @@ -9829,22 +8837,8 @@ function resolveRetryWakeable(boundaryFiber, wakeable) { null !== retryCache && retryCache.delete(wakeable); retryTimedOutBoundary(boundaryFiber, retryLane); } -function throwIfInfiniteUpdateLoopDetected() { - if (50 < nestedUpdateCount) - throw ( - ((nestedUpdateCount = 0), - (rootWithNestedUpdates = null), - executionContext & 2 && - null !== workInProgressRoot && - (workInProgressRoot.errorRecoveryDisabledLanes |= - workInProgressRootRenderLanes), - Error( - "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." - )) - ); -} function scheduleCallback(priorityLevel, callback) { - return scheduleCallback$3(priorityLevel, callback); + return scheduleCallback$2(priorityLevel, callback); } function FiberNode(tag, pendingProps, key, mode) { this.tag = tag; @@ -9877,6 +8871,16 @@ function shouldConstruct(Component) { Component = Component.prototype; return !(!Component || !Component.isReactComponent); } +function resolveLazyComponentTag(Component) { + if ("function" === typeof Component) + return shouldConstruct(Component) ? 1 : 0; + if (void 0 !== Component && null !== Component) { + Component = Component.$$typeof; + if (Component === REACT_FORWARD_REF_TYPE) return 11; + if (Component === REACT_MEMO_TYPE) return 14; + } + return 2; +} function createWorkInProgress(current, pendingProps) { var workInProgress = current.alternate; null === workInProgress @@ -9954,7 +8958,7 @@ function createFiberFromTypeAndProps( mode, lanes ) { - var fiberTag = 0; + var fiberTag = 2; owner = type; if ("function" === typeof type) shouldConstruct(type) && (fiberTag = 1); else if ("string" === typeof type) fiberTag = 5; @@ -9994,12 +8998,12 @@ function createFiberFromTypeAndProps( if ("object" === typeof type && null !== type) switch (type.$$typeof) { case REACT_PROVIDER_TYPE: - case REACT_CONTEXT_TYPE: fiberTag = 10; break a; - case REACT_CONSUMER_TYPE: + case REACT_CONTEXT_TYPE: fiberTag = 9; break a; + case REACT_CONSUMER_TYPE: case REACT_FORWARD_REF_TYPE: fiberTag = 11; break a; @@ -10013,7 +9017,7 @@ function createFiberFromTypeAndProps( } throw Error( "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + - ((null === type ? "null" : typeof type) + ".") + ((null == type ? type : typeof type) + ".") ); } key = createFiber(fiberTag, pendingProps, key, mode); @@ -10093,8 +9097,6 @@ function FiberRootNode( tag, hydrate, identifierPrefix, - onUncaughtError, - onCaughtError, onRecoverableError, formState ) { @@ -10126,11 +9128,7 @@ function FiberRootNode( this.entanglements = createLaneMap(0); this.hiddenUpdates = createLaneMap(null); this.identifierPrefix = identifierPrefix; - this.onUncaughtError = onUncaughtError; - this.onCaughtError = onCaughtError; this.onRecoverableError = onRecoverableError; - this.pooledCache = null; - this.pooledCacheLanes = 0; this.formState = formState; this.incompleteTransitions = new Map(); } @@ -10203,37 +9201,8 @@ function findNodeHandle(componentOrHandle) { function getInspectorDataForInstance() { throw Error("getInspectorDataForInstance() is not available in production"); } -var isomorphicReactPackageVersion = React.version; -if ("19.0.0-rc-fb9a90fa48-20240614" !== isomorphicReactPackageVersion) - throw Error( - 'Incompatible React versions: The "react" and "react-native-renderer" packages must have the exact same version. Instead got:\n - react: ' + - (isomorphicReactPackageVersion + - "\n - react-native-renderer: 19.0.0-rc-fb9a90fa48-20240614\nLearn more: https://react.dev/warnings/version-mismatch") - ); -if ( - "function" !== - typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog -) - throw Error( - "Expected ReactFiberErrorDialog.showErrorDialog to be a function." - ); -function nativeOnUncaughtError(error, errorInfo) { - !1 !== - ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog({ - errorBoundary: null, - error: error, - componentStack: - null != errorInfo.componentStack ? errorInfo.componentStack : "" - }) && reportGlobalError(error); -} -function nativeOnCaughtError(error, errorInfo) { - !1 !== - ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog({ - errorBoundary: errorInfo.errorBoundary, - error: error, - componentStack: - null != errorInfo.componentStack ? errorInfo.componentStack : "" - }) && console.error(error); +function onRecoverableError(error) { + console.error(error); } function unmountComponentAtNode(containerTag) { var root = roots.get(containerTag); @@ -10255,10 +9224,10 @@ batchedUpdatesImpl = function (fn, a) { } }; var roots = new Map(), - devToolsConfig$jscomp$inline_1180 = { + devToolsConfig$jscomp$inline_1100 = { findFiberByHostInstance: getInstanceFromTag, bundleType: 0, - version: "19.0.0-rc-fb9a90fa48-20240614", + version: "18.3.0-canary-9372c6311-20240315", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForInstance: getInspectorDataForInstance, @@ -10274,11 +9243,11 @@ var roots = new Map(), }.bind(null, findNodeHandle) } }; -var internals$jscomp$inline_1431 = { - bundleType: devToolsConfig$jscomp$inline_1180.bundleType, - version: devToolsConfig$jscomp$inline_1180.version, - rendererPackageName: devToolsConfig$jscomp$inline_1180.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_1180.rendererConfig, +var internals$jscomp$inline_1342 = { + bundleType: devToolsConfig$jscomp$inline_1100.bundleType, + version: devToolsConfig$jscomp$inline_1100.version, + rendererPackageName: devToolsConfig$jscomp$inline_1100.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_1100.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -10288,32 +9257,32 @@ var internals$jscomp$inline_1431 = { setErrorHandler: null, setSuspenseHandler: null, scheduleUpdate: null, - currentDispatcherRef: ReactSharedInternals, + currentDispatcherRef: ReactSharedInternals.ReactCurrentDispatcher, findHostInstanceByFiber: function (fiber) { fiber = findCurrentHostFiber(fiber); return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_1180.findFiberByHostInstance || + devToolsConfig$jscomp$inline_1100.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "19.0.0-rc-fb9a90fa48-20240614" + reconcilerVersion: "18.3.0-canary-9372c6311-20240315" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_1432 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_1343 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_1432.isDisabled && - hook$jscomp$inline_1432.supportsFiber + !hook$jscomp$inline_1343.isDisabled && + hook$jscomp$inline_1343.supportsFiber ) try { - (rendererID = hook$jscomp$inline_1432.inject( - internals$jscomp$inline_1431 + (rendererID = hook$jscomp$inline_1343.inject( + internals$jscomp$inline_1342 )), - (injectedHook = hook$jscomp$inline_1432); + (injectedHook = hook$jscomp$inline_1343); } catch (err) {} } exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = { @@ -10360,45 +9329,19 @@ exports.getInspectorDataForInstance = getInspectorDataForInstance; exports.isChildPublicInstance = function () { throw Error("isChildPublicInstance() is not available in production."); }; -exports.render = function (element, containerTag, callback, options) { +exports.render = function (element, containerTag, callback) { var root = roots.get(containerTag); if (!root) { - root = nativeOnUncaughtError; - var onCaughtError = nativeOnCaughtError, - onRecoverableError = defaultOnRecoverableError; - options && - void 0 !== options.onUncaughtError && - (root = options.onUncaughtError); - options && - void 0 !== options.onCaughtError && - (onCaughtError = options.onCaughtError); - options && - void 0 !== options.onRecoverableError && - (onRecoverableError = options.onRecoverableError); - options = new FiberRootNode( - containerTag, - 0, - !1, - "", - root, - onCaughtError, - onRecoverableError, - null - ); - root = createFiber(3, null, null, 0); - options.current = root; - root.stateNode = options; - onCaughtError = createCache(); - onCaughtError.refCount++; - options.pooledCache = onCaughtError; - onCaughtError.refCount++; - root.memoizedState = { + root = new FiberRootNode(containerTag, 0, !1, "", onRecoverableError, null); + 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, isDehydrated: !1, - cache: onCaughtError + cache: null }; - initializeUpdateQueue(root); - root = options; + initializeUpdateQueue(JSCompiler_inline_result); roots.set(containerTag, root); } updateContainer(element, root, null, callback); diff --git a/packages/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js b/packages/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js index fd462a38f49c86..7e31d29013403a 100644 --- a/packages/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js +++ b/packages/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js @@ -6,10 +6,9 @@ * * @noflow * @nolint + * @providesModule ReactNativeRenderer-profiling * @preventMunge - * @generated SignedSource<> - * - * This file was sync'd from the facebook/react repository. + * @generated SignedSource<<7ad664bd0b8a14a802c352b7131a3eb2>> */ "use strict"; @@ -22,219 +21,7 @@ var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/R React = require("react"), Scheduler = require("scheduler"), isArrayImpl = Array.isArray, - ReactSharedInternals = - React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, - REACT_LEGACY_ELEMENT_TYPE = Symbol.for("react.element"), - REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"), - REACT_PORTAL_TYPE = Symbol.for("react.portal"), - REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"), - REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"), - REACT_PROFILER_TYPE = Symbol.for("react.profiler"), - REACT_PROVIDER_TYPE = Symbol.for("react.provider"), - REACT_CONSUMER_TYPE = Symbol.for("react.consumer"), - REACT_CONTEXT_TYPE = Symbol.for("react.context"), - REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"), - REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"), - REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"), - REACT_MEMO_TYPE = Symbol.for("react.memo"), - REACT_LAZY_TYPE = Symbol.for("react.lazy"); -Symbol.for("react.scope"); -Symbol.for("react.debug_trace_mode"); -var REACT_OFFSCREEN_TYPE = Symbol.for("react.offscreen"); -Symbol.for("react.legacy_hidden"); -Symbol.for("react.tracing_marker"); -var REACT_MEMO_CACHE_SENTINEL = Symbol.for("react.memo_cache_sentinel"), - MAYBE_ITERATOR_SYMBOL = Symbol.iterator; -function getIteratorFn(maybeIterable) { - if (null === maybeIterable || "object" !== typeof maybeIterable) return null; - maybeIterable = - (MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL]) || - maybeIterable["@@iterator"]; - return "function" === typeof maybeIterable ? maybeIterable : null; -} -var assign = Object.assign, - prefix; -function describeBuiltInComponentFrame(name) { - if (void 0 === prefix) - try { - throw Error(); - } catch (x) { - var match = x.stack.trim().match(/\n( *(at )?)/); - prefix = (match && match[1]) || ""; - } - return "\n" + prefix + name; -} -var reentry = !1; -function describeNativeComponentFrame(fn, construct) { - if (!fn || reentry) return ""; - reentry = !0; - var previousPrepareStackTrace = Error.prepareStackTrace; - Error.prepareStackTrace = void 0; - var RunInRootFrame = { - DetermineComponentFrameRoot: function () { - try { - if (construct) { - var Fake = function () { - throw Error(); - }; - Object.defineProperty(Fake.prototype, "props", { - set: function () { - throw Error(); - } - }); - if ("object" === typeof Reflect && Reflect.construct) { - try { - Reflect.construct(Fake, []); - } catch (x) { - var control = x; - } - Reflect.construct(fn, [], Fake); - } else { - try { - Fake.call(); - } catch (x$0) { - control = x$0; - } - fn.call(Fake.prototype); - } - } else { - try { - throw Error(); - } catch (x$1) { - control = x$1; - } - (Fake = fn()) && - "function" === typeof Fake.catch && - Fake.catch(function () {}); - } - } catch (sample) { - if (sample && control && "string" === typeof sample.stack) - return [sample.stack, control.stack]; - } - return [null, null]; - } - }; - RunInRootFrame.DetermineComponentFrameRoot.displayName = - "DetermineComponentFrameRoot"; - var namePropDescriptor = Object.getOwnPropertyDescriptor( - RunInRootFrame.DetermineComponentFrameRoot, - "name" - ); - namePropDescriptor && - namePropDescriptor.configurable && - Object.defineProperty(RunInRootFrame.DetermineComponentFrameRoot, "name", { - value: "DetermineComponentFrameRoot" - }); - try { - var _RunInRootFrame$Deter = RunInRootFrame.DetermineComponentFrameRoot(), - sampleStack = _RunInRootFrame$Deter[0], - controlStack = _RunInRootFrame$Deter[1]; - if (sampleStack && controlStack) { - var sampleLines = sampleStack.split("\n"), - controlLines = controlStack.split("\n"); - for ( - namePropDescriptor = RunInRootFrame = 0; - RunInRootFrame < sampleLines.length && - !sampleLines[RunInRootFrame].includes("DetermineComponentFrameRoot"); - - ) - RunInRootFrame++; - for ( - ; - namePropDescriptor < controlLines.length && - !controlLines[namePropDescriptor].includes( - "DetermineComponentFrameRoot" - ); - - ) - namePropDescriptor++; - if ( - RunInRootFrame === sampleLines.length || - namePropDescriptor === controlLines.length - ) - for ( - RunInRootFrame = sampleLines.length - 1, - namePropDescriptor = controlLines.length - 1; - 1 <= RunInRootFrame && - 0 <= namePropDescriptor && - sampleLines[RunInRootFrame] !== controlLines[namePropDescriptor]; - - ) - namePropDescriptor--; - for ( - ; - 1 <= RunInRootFrame && 0 <= namePropDescriptor; - RunInRootFrame--, namePropDescriptor-- - ) - if (sampleLines[RunInRootFrame] !== controlLines[namePropDescriptor]) { - if (1 !== RunInRootFrame || 1 !== namePropDescriptor) { - do - if ( - (RunInRootFrame--, - namePropDescriptor--, - 0 > namePropDescriptor || - sampleLines[RunInRootFrame] !== - controlLines[namePropDescriptor]) - ) { - var frame = - "\n" + - sampleLines[RunInRootFrame].replace(" at new ", " at "); - fn.displayName && - frame.includes("") && - (frame = frame.replace("", fn.displayName)); - return frame; - } - while (1 <= RunInRootFrame && 0 <= namePropDescriptor); - } - break; - } - } - } finally { - (reentry = !1), (Error.prepareStackTrace = previousPrepareStackTrace); - } - return (previousPrepareStackTrace = fn ? fn.displayName || fn.name : "") - ? describeBuiltInComponentFrame(previousPrepareStackTrace) - : ""; -} -function describeFiber(fiber) { - switch (fiber.tag) { - case 26: - case 27: - case 5: - return describeBuiltInComponentFrame(fiber.type); - case 16: - return describeBuiltInComponentFrame("Lazy"); - case 13: - return describeBuiltInComponentFrame("Suspense"); - case 19: - return describeBuiltInComponentFrame("SuspenseList"); - case 0: - case 15: - return (fiber = describeNativeComponentFrame(fiber.type, !1)), fiber; - case 11: - return ( - (fiber = describeNativeComponentFrame(fiber.type.render, !1)), fiber - ); - case 1: - return (fiber = describeNativeComponentFrame(fiber.type, !0)), fiber; - default: - return ""; - } -} -function getStackByFiberInDevAndProd(workInProgress) { - try { - var info = ""; - do - (info += describeFiber(workInProgress)), - (workInProgress = workInProgress.return); - while (workInProgress); - return info; - } catch (x) { - return "\nError generating stack: " + x.message + "\n" + x.stack; - } -} -Symbol.for("react.client.reference"); -var hasError = !1, + hasError = !1, caughtError = null, getFiberCurrentPropsFromNode$1 = null, getInstanceFromNode = null, @@ -261,6 +48,7 @@ function executeDirectDispatch(event) { event._dispatchInstances = null; return dispatchListener; } +var assign = Object.assign; function functionThatReturnsTrue() { return !0; } @@ -1109,7 +897,7 @@ eventPluginOrder = Array.prototype.slice.call([ "ReactNativeBridgeEventPlugin" ]); recomputePluginOrdering(); -var injectedNamesToPlugins$jscomp$inline_302 = { +var injectedNamesToPlugins$jscomp$inline_249 = { ResponderEventPlugin: ResponderEventPlugin, ReactNativeBridgeEventPlugin: { eventTypes: {}, @@ -1155,32 +943,32 @@ var injectedNamesToPlugins$jscomp$inline_302 = { } } }, - isOrderingDirty$jscomp$inline_303 = !1, - pluginName$jscomp$inline_304; -for (pluginName$jscomp$inline_304 in injectedNamesToPlugins$jscomp$inline_302) + isOrderingDirty$jscomp$inline_250 = !1, + pluginName$jscomp$inline_251; +for (pluginName$jscomp$inline_251 in injectedNamesToPlugins$jscomp$inline_249) if ( - injectedNamesToPlugins$jscomp$inline_302.hasOwnProperty( - pluginName$jscomp$inline_304 + injectedNamesToPlugins$jscomp$inline_249.hasOwnProperty( + pluginName$jscomp$inline_251 ) ) { - var pluginModule$jscomp$inline_305 = - injectedNamesToPlugins$jscomp$inline_302[pluginName$jscomp$inline_304]; + var pluginModule$jscomp$inline_252 = + injectedNamesToPlugins$jscomp$inline_249[pluginName$jscomp$inline_251]; if ( - !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_304) || - namesToPlugins[pluginName$jscomp$inline_304] !== - pluginModule$jscomp$inline_305 + !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_251) || + namesToPlugins[pluginName$jscomp$inline_251] !== + pluginModule$jscomp$inline_252 ) { - if (namesToPlugins[pluginName$jscomp$inline_304]) + if (namesToPlugins[pluginName$jscomp$inline_251]) throw Error( "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - (pluginName$jscomp$inline_304 + "`.") + (pluginName$jscomp$inline_251 + "`.") ); - namesToPlugins[pluginName$jscomp$inline_304] = - pluginModule$jscomp$inline_305; - isOrderingDirty$jscomp$inline_303 = !0; + namesToPlugins[pluginName$jscomp$inline_251] = + pluginModule$jscomp$inline_252; + isOrderingDirty$jscomp$inline_250 = !0; } } -isOrderingDirty$jscomp$inline_303 && recomputePluginOrdering(); +isOrderingDirty$jscomp$inline_250 && recomputePluginOrdering(); var instanceCache = new Map(), instanceProps = new Map(); function getInstanceFromTag(tag) { @@ -1277,13 +1065,13 @@ ReactNativePrivateInterface.RCTEventEmitter.register({ ) { var JSCompiler_temp = []; for (var i = 0; i < changedIndices.length; i++) { - var index$4 = changedIndices[i]; - JSCompiler_temp.push(touches[index$4]); - touches[index$4] = null; + var index$0 = changedIndices[i]; + JSCompiler_temp.push(touches[index$0]); + touches[index$0] = null; } for (i = changedIndices = 0; i < touches.length; i++) - (index$4 = touches[i]), - null !== index$4 && (touches[changedIndices++] = index$4); + (index$0 = touches[i]), + null !== index$0 && (touches[changedIndices++] = index$0); touches.length = changedIndices; } else for (JSCompiler_temp = [], i = 0; i < changedIndices.length; i++) @@ -1296,10 +1084,10 @@ ReactNativePrivateInterface.RCTEventEmitter.register({ i = JSCompiler_temp[changedIndices]; i.changedTouches = JSCompiler_temp; i.touches = touches; - index$4 = null; + index$0 = null; var target = i.target; - null === target || void 0 === target || 1 > target || (index$4 = target); - _receiveRootNodeIDEvent(index$4, eventTopLevelType, i); + null === target || void 0 === target || 1 > target || (index$0 = target); + _receiveRootNodeIDEvent(index$0, eventTopLevelType, i); } } }); @@ -1326,6 +1114,36 @@ ResponderEventPlugin.injection.injectGlobalResponderHandler({ : ReactNativePrivateInterface.UIManager.clearJSResponder(); } }); +var ReactSharedInternals = + React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED, + REACT_ELEMENT_TYPE = Symbol.for("react.element"), + REACT_PORTAL_TYPE = Symbol.for("react.portal"), + REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"), + REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"), + REACT_PROFILER_TYPE = Symbol.for("react.profiler"), + REACT_PROVIDER_TYPE = Symbol.for("react.provider"), + REACT_CONSUMER_TYPE = Symbol.for("react.consumer"), + REACT_CONTEXT_TYPE = Symbol.for("react.context"), + REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"), + REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"), + REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"), + REACT_MEMO_TYPE = Symbol.for("react.memo"), + REACT_LAZY_TYPE = Symbol.for("react.lazy"); +Symbol.for("react.scope"); +Symbol.for("react.debug_trace_mode"); +var REACT_OFFSCREEN_TYPE = Symbol.for("react.offscreen"); +Symbol.for("react.legacy_hidden"); +Symbol.for("react.cache"); +Symbol.for("react.tracing_marker"); +var MAYBE_ITERATOR_SYMBOL = Symbol.iterator; +function getIteratorFn(maybeIterable) { + if (null === maybeIterable || "object" !== typeof maybeIterable) return null; + maybeIterable = + (MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL]) || + maybeIterable["@@iterator"]; + return "function" === typeof maybeIterable ? maybeIterable : null; +} +Symbol.for("react.client.reference"); function getNearestMountedFiber(fiber) { var node = fiber, nearestMounted = fiber; @@ -1374,36 +1192,36 @@ function findCurrentFiberUsingSlowPath(fiber) { } if (a.return !== b.return) (a = parentA), (b = parentB); else { - for (var didFindChild = !1, child$5 = parentA.child; child$5; ) { - if (child$5 === a) { + for (var didFindChild = !1, child$1 = parentA.child; child$1; ) { + if (child$1 === a) { didFindChild = !0; a = parentA; b = parentB; break; } - if (child$5 === b) { + if (child$1 === b) { didFindChild = !0; b = parentA; a = parentB; break; } - child$5 = child$5.sibling; + child$1 = child$1.sibling; } if (!didFindChild) { - for (child$5 = parentB.child; child$5; ) { - if (child$5 === a) { + for (child$1 = parentB.child; child$1; ) { + if (child$1 === a) { didFindChild = !0; a = parentB; b = parentA; break; } - if (child$5 === b) { + if (child$1 === b) { didFindChild = !0; b = parentB; a = parentA; break; } - child$5 = child$5.sibling; + child$1 = child$1.sibling; } if (!didFindChild) throw Error( @@ -1637,19 +1455,19 @@ function diffProperties(updatePayload, prevProps, nextProps, validAttributes) { ), (removedKeys = null)); } - for (var propKey$7 in prevProps) - void 0 === nextProps[propKey$7] && - (!(attributeConfig = validAttributes[propKey$7]) || - (updatePayload && void 0 !== updatePayload[propKey$7]) || - ((prevProp = prevProps[propKey$7]), + for (var propKey$3 in prevProps) + void 0 === nextProps[propKey$3] && + (!(attributeConfig = validAttributes[propKey$3]) || + (updatePayload && void 0 !== updatePayload[propKey$3]) || + ((prevProp = prevProps[propKey$3]), void 0 !== prevProp && ("object" !== typeof attributeConfig || "function" === typeof attributeConfig.diff || "function" === typeof attributeConfig.process - ? (((updatePayload || (updatePayload = {}))[propKey$7] = null), + ? (((updatePayload || (updatePayload = {}))[propKey$3] = null), removedKeys || (removedKeys = {}), - removedKeys[propKey$7] || - ((removedKeys[propKey$7] = !0), removedKeyCount++)) + removedKeys[propKey$3] || + ((removedKeys[propKey$3] = !0), removedKeyCount++)) : (updatePayload = clearNestedProperty( updatePayload, prevProp, @@ -1722,20 +1540,17 @@ var ReactNativeFiberHostComponent = (function () { }; return ReactNativeFiberHostComponent; })(), - scheduleCallback$3 = Scheduler.unstable_scheduleCallback, + scheduleCallback$2 = Scheduler.unstable_scheduleCallback, cancelCallback$1 = Scheduler.unstable_cancelCallback, shouldYield = Scheduler.unstable_shouldYield, requestPaint = Scheduler.unstable_requestPaint, now$1 = Scheduler.unstable_now, ImmediatePriority = Scheduler.unstable_ImmediatePriority, UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, - NormalPriority$1 = Scheduler.unstable_NormalPriority, + NormalPriority = Scheduler.unstable_NormalPriority, IdlePriority = Scheduler.unstable_IdlePriority, - log$1 = Scheduler.log, - unstable_setDisableYieldValue = Scheduler.unstable_setDisableYieldValue, rendererID = null, injectedHook = null, - injectedProfilingHooks = null, isDevToolsPresent = "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__; function onCommitRoot(root, eventPriority) { if (injectedHook && "function" === typeof injectedHook.onCommitFiberRoot) @@ -1749,13 +1564,13 @@ function onCommitRoot(root, eventPriority) { schedulerPriority = UserBlockingPriority; break; case 32: - schedulerPriority = NormalPriority$1; + schedulerPriority = NormalPriority; break; case 268435456: schedulerPriority = IdlePriority; break; default: - schedulerPriority = NormalPriority$1; + schedulerPriority = NormalPriority; } injectedHook.onCommitFiberRoot( rendererID, @@ -1765,66 +1580,6 @@ function onCommitRoot(root, eventPriority) { ); } catch (err) {} } -function setIsStrictModeForDevtools(newIsStrictMode) { - "function" === typeof log$1 && unstable_setDisableYieldValue(newIsStrictMode); - if (injectedHook && "function" === typeof injectedHook.setStrictMode) - try { - injectedHook.setStrictMode(rendererID, newIsStrictMode); - } catch (err) {} -} -function injectProfilingHooks(profilingHooks) { - injectedProfilingHooks = profilingHooks; -} -function getLaneLabelMap() { - for (var map = new Map(), lane = 1, index$8 = 0; 31 > index$8; index$8++) { - var label = getLabelForLane(lane); - map.set(lane, label); - lane *= 2; - } - return map; -} -function markCommitStopped() { - null !== injectedProfilingHooks && - "function" === typeof injectedProfilingHooks.markCommitStopped && - injectedProfilingHooks.markCommitStopped(); -} -function markComponentRenderStarted(fiber) { - null !== injectedProfilingHooks && - "function" === typeof injectedProfilingHooks.markComponentRenderStarted && - injectedProfilingHooks.markComponentRenderStarted(fiber); -} -function markComponentRenderStopped() { - null !== injectedProfilingHooks && - "function" === typeof injectedProfilingHooks.markComponentRenderStopped && - injectedProfilingHooks.markComponentRenderStopped(); -} -function markComponentLayoutEffectUnmountStarted(fiber) { - null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markComponentLayoutEffectUnmountStarted && - injectedProfilingHooks.markComponentLayoutEffectUnmountStarted(fiber); -} -function markComponentLayoutEffectUnmountStopped() { - null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markComponentLayoutEffectUnmountStopped && - injectedProfilingHooks.markComponentLayoutEffectUnmountStopped(); -} -function markRenderStarted(lanes) { - null !== injectedProfilingHooks && - "function" === typeof injectedProfilingHooks.markRenderStarted && - injectedProfilingHooks.markRenderStarted(lanes); -} -function markRenderStopped() { - null !== injectedProfilingHooks && - "function" === typeof injectedProfilingHooks.markRenderStopped && - injectedProfilingHooks.markRenderStopped(); -} -function markStateUpdateScheduled(fiber, lane) { - null !== injectedProfilingHooks && - "function" === typeof injectedProfilingHooks.markStateUpdateScheduled && - injectedProfilingHooks.markStateUpdateScheduled(fiber, lane); -} var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback, log = Math.log, LN2 = Math.LN2; @@ -1832,22 +1587,6 @@ function clz32Fallback(x) { x >>>= 0; return 0 === x ? 32 : (31 - ((log(x) / LN2) | 0)) | 0; } -function getLabelForLane(lane) { - if (lane & 1) return "SyncHydrationLane"; - if (lane & 2) return "Sync"; - if (lane & 4) return "InputContinuousHydration"; - if (lane & 8) return "InputContinuous"; - if (lane & 16) return "DefaultHydration"; - if (lane & 32) return "Default"; - if (lane & 64) return "TransitionHydration"; - if (lane & 4194176) return "Transition"; - if (lane & 62914560) return "Retry"; - if (lane & 67108864) return "SelectiveHydration"; - if (lane & 134217728) return "IdleHydration"; - if (lane & 268435456) return "Idle"; - if (lane & 536870912) return "Offscreen"; - if (lane & 1073741824) return "Deferred"; -} var nextTransitionLane = 128, nextRetryLane = 4194304; function getHighestPriorityLanes(lanes) { @@ -1994,6 +1733,11 @@ function createLaneMap(initial) { for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); return laneMap; } +function markRootUpdated$1(root, updateLane) { + root.pendingLanes |= updateLane; + 268435456 !== updateLane && + ((root.suspendedLanes = 0), (root.pingedLanes = 0)); +} function markRootFinished(root, remainingLanes, spawnedLane) { var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; root.pendingLanes = remainingLanes; @@ -2010,18 +1754,18 @@ function markRootFinished(root, remainingLanes, spawnedLane) { 0 < noLongerPendingLanes; ) { - var index$12 = 31 - clz32(noLongerPendingLanes), - lane = 1 << index$12; - remainingLanes[index$12] = 0; - expirationTimes[index$12] = -1; - var hiddenUpdatesForLane = hiddenUpdates[index$12]; + var index$7 = 31 - clz32(noLongerPendingLanes), + lane = 1 << index$7; + remainingLanes[index$7] = 0; + expirationTimes[index$7] = -1; + var hiddenUpdatesForLane = hiddenUpdates[index$7]; if (null !== hiddenUpdatesForLane) for ( - hiddenUpdates[index$12] = null, index$12 = 0; - index$12 < hiddenUpdatesForLane.length; - index$12++ + hiddenUpdates[index$7] = null, index$7 = 0; + index$7 < hiddenUpdatesForLane.length; + index$7++ ) { - var update = hiddenUpdatesForLane[index$12]; + var update = hiddenUpdatesForLane[index$7]; null !== update && (update.lane &= -536870913); } noLongerPendingLanes &= ~lane; @@ -2041,19 +1785,19 @@ function markSpawnedDeferredLane(root, spawnedLane, entangledLanes) { function markRootEntangled(root, entangledLanes) { var rootEntangledLanes = (root.entangledLanes |= entangledLanes); for (root = root.entanglements; rootEntangledLanes; ) { - var index$13 = 31 - clz32(rootEntangledLanes), - lane = 1 << index$13; - (lane & entangledLanes) | (root[index$13] & entangledLanes) && - (root[index$13] |= entangledLanes); + var index$8 = 31 - clz32(rootEntangledLanes), + lane = 1 << index$8; + (lane & entangledLanes) | (root[index$8] & entangledLanes) && + (root[index$8] |= entangledLanes); rootEntangledLanes &= ~lane; } } function addFiberToLanesMap(root, fiber, lanes) { if (isDevToolsPresent) for (root = root.pendingUpdatersLaneMap; 0 < lanes; ) { - var index$14 = 31 - clz32(lanes), - lane = 1 << index$14; - root[index$14].add(fiber); + var index$9 = 31 - clz32(lanes), + lane = 1 << index$9; + root[index$9].add(fiber); lanes &= ~lane; } } @@ -2065,19 +1809,20 @@ function movePendingFibersToMemoized(root, lanes) { 0 < lanes; ) { - var index$15 = 31 - clz32(lanes); - root = 1 << index$15; - index$15 = pendingUpdatersLaneMap[index$15]; - 0 < index$15.size && - (index$15.forEach(function (fiber) { + var index$10 = 31 - clz32(lanes); + root = 1 << index$10; + index$10 = pendingUpdatersLaneMap[index$10]; + 0 < index$10.size && + (index$10.forEach(function (fiber) { var alternate = fiber.alternate; (null !== alternate && memoizedUpdaters.has(alternate)) || memoizedUpdaters.add(fiber); }), - index$15.clear()); + index$10.clear()); lanes &= ~root; } } +var currentUpdatePriority = 0; function lanesToEventPriority(lanes) { lanes &= -lanes; return 2 < lanes @@ -2093,11 +1838,6 @@ function shim$1() { "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." ); } -function shim() { - throw Error( - "The current renderer does not support Resources. This error is likely caused by a bug in React. Please file an issue." - ); -} var getViewConfigForType = ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get, nextReactTag = 3; @@ -2135,7 +1875,6 @@ function getPublicInstance(instance) { } var scheduleTimeout = setTimeout, cancelTimeout = clearTimeout, - currentUpdatePriority = 0, valueStack = [], index = -1; function createCursor(defaultValue) { @@ -2155,28 +1894,9 @@ 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, - CapturedStacks = new WeakMap(); -function createCapturedValueAtFiber(value, source) { - if ("object" === typeof value && null !== value) { - var stack = CapturedStacks.get(value); - "string" !== typeof stack && - ((stack = getStackByFiberInDevAndProd(source)), - CapturedStacks.set(value, stack)); - } else stack = getStackByFiberInDevAndProd(source); - return { value: value, source: source, stack: stack }; -} -var contextStackCursor = createCursor(null), + contextStackCursor = createCursor(null), contextFiberStackCursor = createCursor(null), - rootInstanceStackCursor = createCursor(null), - hostTransitionProviderCursor = createCursor(null), - HostTransitionContext = { - $$typeof: REACT_CONTEXT_TYPE, - Provider: null, - Consumer: null, - _currentValue: null, - _currentValue2: null, - _threadCount: 0 - }; + rootInstanceStackCursor = createCursor(null); function pushHostContainer(fiber, nextRootInstance) { push(rootInstanceStackCursor, nextRootInstance); push(contextFiberStackCursor, fiber); @@ -2190,7 +1910,6 @@ function popHostContainer() { pop(rootInstanceStackCursor); } function pushHostContext(fiber) { - null !== fiber.memoizedState && push(hostTransitionProviderCursor, fiber); var context = contextStackCursor.current; var JSCompiler_inline_result = fiber.type; JSCompiler_inline_result = @@ -2210,9 +1929,6 @@ function pushHostContext(fiber) { function popHostContext(fiber) { contextFiberStackCursor.current === fiber && (pop(contextStackCursor), pop(contextFiberStackCursor)); - hostTransitionProviderCursor.current === fiber && - (pop(hostTransitionProviderCursor), - (HostTransitionContext._currentValue = null)); } var hydrationErrors = null, concurrentQueues = [], @@ -2253,10 +1969,6 @@ function enqueueUpdate$1(fiber, queue, update, lane) { fiber = fiber.alternate; null !== fiber && (fiber.lanes |= lane); } -function enqueueConcurrentHookUpdate(fiber, queue, update, lane) { - enqueueUpdate$1(fiber, queue, update, lane); - return getRootForUpdatedFiber(fiber); -} function enqueueConcurrentRenderForLane(fiber, lane) { enqueueUpdate$1(fiber, null, null, lane); return getRootForUpdatedFiber(fiber); @@ -2287,7 +1999,14 @@ function markUpdateLaneFromFiberToRoot(sourceFiber, update, lane) { (update.lane = lane | 536870912)); } function getRootForUpdatedFiber(sourceFiber) { - throwIfInfiniteUpdateLoopDetected(); + if (50 < nestedUpdateCount) + throw ( + ((nestedUpdateCount = 0), + (rootWithNestedUpdates = null), + Error( + "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." + )) + ); for (var parent = sourceFiber.return; null !== parent; ) (sourceFiber = parent), (parent = sourceFiber.return); return 3 === sourceFiber.tag ? sourceFiber.stateNode : null; @@ -2307,30 +2026,106 @@ function ensureRootIsScheduled(root) { mightHavePendingSyncWork = !0; didScheduleMicrotask || ((didScheduleMicrotask = !0), - scheduleCallback$3(ImmediatePriority, processRootScheduleInMicrotask)); + scheduleCallback$2(ImmediatePriority, processRootScheduleInMicrotask)); + scheduleTaskForRootDuringMicrotask(root, now$1()); } function flushSyncWorkAcrossRoots_impl(onlyLegacy) { if (!isFlushingWork && mightHavePendingSyncWork) { + var errors = null; isFlushingWork = !0; do { var didPerformSomeWork = !1; for (var root = firstScheduledRoot; null !== root; ) { if (!onlyLegacy || 0 === root.tag) { - var workInProgressRootRenderLanes$18 = workInProgressRootRenderLanes; - workInProgressRootRenderLanes$18 = getNextLanes( - root, - root === workInProgressRoot ? workInProgressRootRenderLanes$18 : 0 - ); - 0 !== (workInProgressRootRenderLanes$18 & 3) && - ((didPerformSomeWork = !0), - performSyncWorkOnRoot(root, workInProgressRootRenderLanes$18)); + var workInProgressRootRenderLanes$13 = workInProgressRootRenderLanes, + nextLanes = getNextLanes( + root, + root === workInProgressRoot ? workInProgressRootRenderLanes$13 : 0 + ); + if (0 !== (nextLanes & 3)) + try { + didPerformSomeWork = !0; + workInProgressRootRenderLanes$13 = root; + if (0 !== (executionContext & 6)) + throw Error("Should not already be working."); + if (!flushPassiveEffects()) { + currentUpdateIsNested = nestedUpdateScheduled; + nestedUpdateScheduled = !1; + var exitStatus = renderRootSync( + workInProgressRootRenderLanes$13, + nextLanes + ); + if ( + 0 !== workInProgressRootRenderLanes$13.tag && + 2 === exitStatus + ) { + var originallyAttemptedLanes = nextLanes, + errorRetryLanes = getLanesToRetrySynchronouslyOnError( + workInProgressRootRenderLanes$13, + originallyAttemptedLanes + ); + 0 !== errorRetryLanes && + ((nextLanes = errorRetryLanes), + (exitStatus = recoverFromConcurrentError( + workInProgressRootRenderLanes$13, + originallyAttemptedLanes, + errorRetryLanes + ))); + } + if (1 === exitStatus) + throw ( + ((originallyAttemptedLanes = workInProgressRootFatalError), + prepareFreshStack(workInProgressRootRenderLanes$13, 0), + markRootSuspended( + workInProgressRootRenderLanes$13, + nextLanes, + 0 + ), + ensureRootIsScheduled(workInProgressRootRenderLanes$13), + originallyAttemptedLanes) + ); + 6 === exitStatus + ? markRootSuspended( + workInProgressRootRenderLanes$13, + nextLanes, + workInProgressDeferredLane + ) + : ((workInProgressRootRenderLanes$13.finishedWork = + workInProgressRootRenderLanes$13.current.alternate), + (workInProgressRootRenderLanes$13.finishedLanes = + nextLanes), + commitRoot( + workInProgressRootRenderLanes$13, + workInProgressRootRecoverableErrors, + workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, + workInProgressDeferredLane + )); + } + ensureRootIsScheduled(workInProgressRootRenderLanes$13); + } catch (error) { + null === errors ? (errors = [error]) : errors.push(error); + } } root = root.next; } } while (didPerformSomeWork); isFlushingWork = !1; + if (null !== errors) { + if (1 < errors.length) { + if ("function" === typeof AggregateError) + throw new AggregateError(errors); + for (onlyLegacy = 1; onlyLegacy < errors.length; onlyLegacy++) + (didPerformSomeWork = throwError.bind(null, errors[onlyLegacy])), + scheduleCallback$2(ImmediatePriority, didPerformSomeWork); + } + throw errors[0]; + } } } +function throwError(error) { + throw error; +} function processRootScheduleInMicrotask() { mightHavePendingSyncWork = didScheduleMicrotask = !1; for ( @@ -2360,12 +2155,12 @@ function scheduleTaskForRootDuringMicrotask(root, currentTime) { 0 < lanes; ) { - var index$10 = 31 - clz32(lanes), - lane = 1 << index$10, - expirationTime = expirationTimes[index$10]; + var index$5 = 31 - clz32(lanes), + lane = 1 << index$5, + expirationTime = expirationTimes[index$5]; if (-1 === expirationTime) { if (0 === (lane & suspendedLanes) || 0 !== (lane & pingedLanes)) - expirationTimes[index$10] = computeExpirationTime(lane, currentTime); + expirationTimes[index$5] = computeExpirationTime(lane, currentTime); } else expirationTime <= currentTime && (root.expiredLanes |= lane); lanes &= ~lane; } @@ -2408,85 +2203,20 @@ function scheduleTaskForRootDuringMicrotask(root, currentTime) { suspendedLanes = UserBlockingPriority; break; case 32: - suspendedLanes = NormalPriority$1; + suspendedLanes = NormalPriority; break; case 268435456: suspendedLanes = IdlePriority; break; default: - suspendedLanes = NormalPriority$1; + suspendedLanes = NormalPriority; } pingedLanes = performConcurrentWorkOnRoot.bind(null, root); - suspendedLanes = scheduleCallback$3(suspendedLanes, pingedLanes); + suspendedLanes = scheduleCallback$2(suspendedLanes, pingedLanes); root.callbackPriority = currentTime; root.callbackNode = suspendedLanes; return currentTime; } -function requestTransitionLane() { - 0 === currentEventTransitionLane && - (currentEventTransitionLane = claimNextTransitionLane()); - return currentEventTransitionLane; -} -var currentEntangledListeners = null, - currentEntangledPendingCount = 0, - currentEntangledLane = 0, - currentEntangledActionThenable = null; -function entangleAsyncAction(transition, thenable) { - if (null === currentEntangledListeners) { - var entangledListeners = (currentEntangledListeners = []); - currentEntangledPendingCount = 0; - currentEntangledLane = requestTransitionLane(); - currentEntangledActionThenable = { - status: "pending", - value: void 0, - then: function (resolve) { - entangledListeners.push(resolve); - } - }; - } - currentEntangledPendingCount++; - thenable.then(pingEngtangledActionScope, pingEngtangledActionScope); - return thenable; -} -function pingEngtangledActionScope() { - if ( - null !== currentEntangledListeners && - 0 === --currentEntangledPendingCount - ) { - null !== currentEntangledActionThenable && - (currentEntangledActionThenable.status = "fulfilled"); - var listeners = currentEntangledListeners; - currentEntangledListeners = null; - currentEntangledLane = 0; - currentEntangledActionThenable = null; - for (var i = 0; i < listeners.length; i++) (0, listeners[i])(); - } -} -function chainThenableValue(thenable, result) { - var listeners = [], - thenableWithOverride = { - status: "pending", - value: null, - reason: null, - then: function (resolve) { - listeners.push(resolve); - } - }; - thenable.then( - function () { - thenableWithOverride.status = "fulfilled"; - thenableWithOverride.value = result; - for (var i = 0; i < listeners.length; i++) (0, listeners[i])(result); - }, - function (error) { - thenableWithOverride.status = "rejected"; - thenableWithOverride.reason = error; - for (error = 0; error < listeners.length; error++) - (0, listeners[error])(void 0); - } - ); - return thenableWithOverride; -} var hasForceUpdate = !1; function initializeUpdateQueue(fiber) { fiber.updateQueue = { @@ -2582,20 +2312,12 @@ function enqueueCapturedUpdate(workInProgress, capturedUpdate) { : (workInProgress.next = capturedUpdate); queue.lastBaseUpdate = capturedUpdate; } -var didReadFromEntangledAsyncAction = !1; -function suspendIfUpdateReadFromEntangledAsyncAction() { - if (didReadFromEntangledAsyncAction) { - var entangledActionThenable = currentEntangledActionThenable; - if (null !== entangledActionThenable) throw entangledActionThenable; - } -} function processUpdateQueue( workInProgress$jscomp$0, props, instance$jscomp$0, renderLanes ) { - didReadFromEntangledAsyncAction = !1; var queue = workInProgress$jscomp$0.updateQueue; hasForceUpdate = !1; var firstBaseUpdate = queue.firstBaseUpdate, @@ -2633,9 +2355,6 @@ function processUpdateQueue( ? (workInProgressRootRenderLanes & updateLane) === updateLane : (renderLanes & updateLane) === updateLane ) { - 0 !== updateLane && - updateLane === currentEntangledLane && - (didReadFromEntangledAsyncAction = !0); null !== current && (current = current.next = { @@ -2757,6 +2476,52 @@ function shallowEqual(objA, objB) { } return !0; } +function describeComponentFrame(name, ownerName) { + var sourceInfo = ""; + ownerName && (sourceInfo = " (created by " + ownerName + ")"); + return "\n in " + (name || "Unknown") + sourceInfo; +} +function describeFunctionComponentFrame(fn) { + return fn + ? describeComponentFrame(fn.displayName || fn.name || null, null) + : ""; +} +function describeFiber(fiber) { + switch (fiber.tag) { + case 26: + case 27: + case 5: + return describeComponentFrame(fiber.type, null); + case 16: + return describeComponentFrame("Lazy", null); + case 13: + return describeComponentFrame("Suspense", null); + case 19: + return describeComponentFrame("SuspenseList", null); + case 0: + case 2: + case 15: + return describeFunctionComponentFrame(fiber.type); + case 11: + return describeFunctionComponentFrame(fiber.type.render); + case 1: + return (fiber = describeFunctionComponentFrame(fiber.type)), fiber; + default: + return ""; + } +} +function getStackByFiberInDevAndProd(workInProgress) { + try { + var info = ""; + do + (info += describeFiber(workInProgress)), + (workInProgress = workInProgress.return); + while (workInProgress); + return info; + } catch (x) { + return "\nError generating stack: " + x.message + "\n" + x.stack; + } +} var SuspenseException = Error( "Suspense Exception: This is not a real error! It's an implementation detail of `use` to interrupt the current render. You must either rethrow it immediately, or move the `use` call outside of the `try/catch` block. Capturing without rethrowing will lead to unexpected behavior.\n\nTo handle async errors, wrap your component in an error boundary, or call the promise's `.catch` method and pass the result to `use`" ), @@ -2848,15 +2613,56 @@ function unwrapThenable(thenable) { null === thenableState$1 && (thenableState$1 = []); return trackUsedThenable(thenableState$1, thenable, index); } +function convertStringRefToCallbackRef( + returnFiber, + current, + element, + mixedRef +) { + function ref(value) { + var refs = inst.refs; + null === value ? delete refs[stringRef] : (refs[stringRef] = value); + } + var stringRef = "" + mixedRef; + returnFiber = element._owner; + if (!returnFiber) + throw Error( + "Element ref was specified as a string (" + + stringRef + + ") but no owner was set. This could happen for one of the following reasons:\n1. You may be adding a ref to a function component\n2. You may be adding a ref to a component that was not created inside a component's render method\n3. You have multiple copies of React loaded\nSee https://react.dev/link/refs-must-have-owner for more information." + ); + if (1 !== returnFiber.tag) + throw Error( + "Function components cannot have string refs. We recommend using useRef() instead. Learn more about using refs safely here: https://react.dev/link/strict-mode-string-ref" + ); + var inst = returnFiber.stateNode; + if (!inst) + throw Error( + "Missing owner for string ref " + + stringRef + + ". This error is likely caused by a bug in React. Please file an issue." + ); + if ( + null !== current && + null !== current.ref && + "function" === typeof current.ref && + current.ref._stringRef === stringRef + ) + return current.ref; + ref._stringRef = stringRef; + return ref; +} function coerceRef(returnFiber, current, workInProgress, element) { - returnFiber = element.props.ref; - workInProgress.ref = void 0 !== returnFiber ? returnFiber : null; + var mixedRef = element.ref; + returnFiber = + "string" === typeof mixedRef || + "number" === typeof mixedRef || + "boolean" === typeof mixedRef + ? convertStringRefToCallbackRef(returnFiber, current, element, mixedRef) + : mixedRef; + workInProgress.ref = returnFiber; } function throwOnInvalidObjectType(returnFiber, newChild) { - if (newChild.$$typeof === REACT_LEGACY_ELEMENT_TYPE) - throw Error( - 'A React Element from an older version of React was rendered. This is not supported. It can happen if:\n- Multiple copies of the "react" package is used.\n- A library pre-bundled an old copy of "react" or "react/jsx-runtime".\n- A compiler tries to "inline" JSX instead of using the runtime.' - ); returnFiber = Object.prototype.toString.call(newChild); throw Error( "Objects are not valid as a React child (found: " + @@ -3003,8 +2809,7 @@ function createChildReconciler(shouldTrackSideEffects) { function createChild(returnFiber, newChild, lanes) { if ( ("string" === typeof newChild && "" !== newChild) || - "number" === typeof newChild || - "bigint" === typeof newChild + "number" === typeof newChild ) return ( (newChild = createFiberFromText( @@ -3043,8 +2848,7 @@ function createChildReconciler(shouldTrackSideEffects) { ); case REACT_LAZY_TYPE: var init = newChild._init; - newChild = init(newChild._payload); - return createChild(returnFiber, newChild, lanes); + return createChild(returnFiber, init(newChild._payload), lanes); } if (isArrayImpl(newChild) || getIteratorFn(newChild)) return ( @@ -3073,8 +2877,7 @@ function createChildReconciler(shouldTrackSideEffects) { var key = null !== oldFiber ? oldFiber.key : null; if ( ("string" === typeof newChild && "" !== newChild) || - "number" === typeof newChild || - "bigint" === typeof newChild + "number" === typeof newChild ) return null !== key ? null @@ -3092,8 +2895,7 @@ function createChildReconciler(shouldTrackSideEffects) { case REACT_LAZY_TYPE: return ( (key = newChild._init), - (newChild = key(newChild._payload)), - updateSlot(returnFiber, oldFiber, newChild, lanes) + updateSlot(returnFiber, oldFiber, key(newChild._payload), lanes) ); } if (isArrayImpl(newChild) || getIteratorFn(newChild)) @@ -3127,8 +2929,7 @@ function createChildReconciler(shouldTrackSideEffects) { ) { if ( ("string" === typeof newChild && "" !== newChild) || - "number" === typeof newChild || - "bigint" === typeof newChild + "number" === typeof newChild ) return ( (existingChildren = existingChildren.get(newIdx) || null), @@ -3154,12 +2955,11 @@ function createChildReconciler(shouldTrackSideEffects) { ); case REACT_LAZY_TYPE: var init = newChild._init; - newChild = init(newChild._payload); return updateFromMap( existingChildren, returnFiber, newIdx, - newChild, + init(newChild._payload), lanes ); } @@ -3282,20 +3082,25 @@ function createChildReconciler(shouldTrackSideEffects) { function reconcileChildrenIterator( returnFiber, currentFirstChild, - newChildren, + newChildrenIterable, lanes ) { - if (null == newChildren) + var iteratorFn = getIteratorFn(newChildrenIterable); + if ("function" !== typeof iteratorFn) + throw Error( + "An object is not an iterable. This error is likely caused by a bug in React. Please file an issue." + ); + newChildrenIterable = iteratorFn.call(newChildrenIterable); + if (null == newChildrenIterable) throw Error("An iterable object provided no iterator."); for ( - var resultingFirstChild = null, - previousNewFiber = null, + var previousNewFiber = (iteratorFn = null), oldFiber = currentFirstChild, newIdx = (currentFirstChild = 0), nextOldFiber = null, - step = newChildren.next(); + step = newChildrenIterable.next(); null !== oldFiber && !step.done; - newIdx++, step = newChildren.next() + newIdx++, step = newChildrenIterable.next() ) { oldFiber.index > newIdx ? ((nextOldFiber = oldFiber), (oldFiber = null)) @@ -3311,30 +3116,28 @@ function createChildReconciler(shouldTrackSideEffects) { deleteChild(returnFiber, oldFiber); currentFirstChild = placeChild(newFiber, currentFirstChild, newIdx); null === previousNewFiber - ? (resultingFirstChild = newFiber) + ? (iteratorFn = newFiber) : (previousNewFiber.sibling = newFiber); previousNewFiber = newFiber; oldFiber = nextOldFiber; } if (step.done) - return ( - deleteRemainingChildren(returnFiber, oldFiber), resultingFirstChild - ); + return deleteRemainingChildren(returnFiber, oldFiber), iteratorFn; if (null === oldFiber) { - for (; !step.done; newIdx++, step = newChildren.next()) + for (; !step.done; newIdx++, step = newChildrenIterable.next()) (step = createChild(returnFiber, step.value, lanes)), null !== step && ((currentFirstChild = placeChild(step, currentFirstChild, newIdx)), null === previousNewFiber - ? (resultingFirstChild = step) + ? (iteratorFn = step) : (previousNewFiber.sibling = step), (previousNewFiber = step)); - return resultingFirstChild; + return iteratorFn; } for ( oldFiber = mapRemainingChildren(oldFiber); !step.done; - newIdx++, step = newChildren.next() + newIdx++, step = newChildrenIterable.next() ) (step = updateFromMap(oldFiber, returnFiber, newIdx, step.value, lanes)), null !== step && @@ -3343,14 +3146,14 @@ function createChildReconciler(shouldTrackSideEffects) { oldFiber.delete(null === step.key ? newIdx : step.key), (currentFirstChild = placeChild(step, currentFirstChild, newIdx)), null === previousNewFiber - ? (resultingFirstChild = step) + ? (iteratorFn = step) : (previousNewFiber.sibling = step), (previousNewFiber = step)); shouldTrackSideEffects && oldFiber.forEach(function (child) { return deleteChild(returnFiber, child); }); - return resultingFirstChild; + return iteratorFn; } function reconcileChildFibersImpl( returnFiber, @@ -3467,11 +3270,10 @@ function createChildReconciler(shouldTrackSideEffects) { case REACT_LAZY_TYPE: return ( (child = newChild._init), - (newChild = child(newChild._payload)), reconcileChildFibersImpl( returnFiber, currentFirstChild, - newChild, + child(newChild._payload), lanes ) ); @@ -3483,20 +3285,13 @@ function createChildReconciler(shouldTrackSideEffects) { newChild, lanes ); - if (getIteratorFn(newChild)) { - child = getIteratorFn(newChild); - if ("function" !== typeof child) - throw Error( - "An object is not an iterable. This error is likely caused by a bug in React. Please file an issue." - ); - newChild = child.call(newChild); + if (getIteratorFn(newChild)) return reconcileChildrenIterator( returnFiber, currentFirstChild, newChild, lanes ); - } if ("function" === typeof newChild.then) return reconcileChildFibersImpl( returnFiber, @@ -3514,8 +3309,7 @@ function createChildReconciler(shouldTrackSideEffects) { throwOnInvalidObjectType(returnFiber, newChild); } return ("string" === typeof newChild && "" !== newChild) || - "number" === typeof newChild || - "bigint" === typeof newChild + "number" === typeof newChild ? ((newChild = "" + newChild), null !== currentFirstChild && 6 === currentFirstChild.tag ? (deleteRemainingChildren(returnFiber, currentFirstChild.sibling), @@ -3534,31 +3328,15 @@ function createChildReconciler(shouldTrackSideEffects) { : deleteRemainingChildren(returnFiber, currentFirstChild); } return function (returnFiber, currentFirstChild, newChild, lanes) { - try { - thenableIndexCounter$1 = 0; - var firstChildFiber = reconcileChildFibersImpl( - returnFiber, - currentFirstChild, - newChild, - lanes - ); - thenableState$1 = null; - return firstChildFiber; - } catch (x) { - if ( - x === SuspenseException || - (0 === (returnFiber.mode & 1) && - "object" === typeof x && - null !== x && - "function" === typeof x.then) - ) - throw x; - var fiber = createFiber(29, x, null, returnFiber.mode); - fiber.lanes = lanes; - fiber.return = returnFiber; - return fiber; - } finally { - } + thenableIndexCounter$1 = 0; + returnFiber = reconcileChildFibersImpl( + returnFiber, + currentFirstChild, + newChild, + lanes + ); + thenableState$1 = null; + return returnFiber; }; } var reconcileChildFibers = createChildReconciler(!0), @@ -3638,7 +3416,9 @@ function findFirstSuspended(row) { } return null; } -var renderLanes = 0, +var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, + ReactCurrentBatchConfig$2 = ReactSharedInternals.ReactCurrentBatchConfig, + renderLanes = 0, currentlyRenderingFiber$1 = null, currentHook = null, workInProgressHook = null, @@ -3672,7 +3452,7 @@ function renderWithHooks( workInProgress.memoizedState = null; workInProgress.updateQueue = null; workInProgress.lanes = 0; - ReactSharedInternals.H = + ReactCurrentDispatcher$1.current = null === current || null === current.memoizedState ? HooksDispatcherOnMount : HooksDispatcherOnUpdate; @@ -3690,7 +3470,7 @@ function renderWithHooks( return current; } function finishRenderingHooks() { - ReactSharedInternals.H = ContextOnlyDispatcher; + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; var didRenderTooFewHooks = null !== currentHook && null !== currentHook.next; renderLanes = 0; workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; @@ -3716,23 +3496,11 @@ function renderWithHooksAgain(workInProgress, Component, props, secondArg) { numberOfReRenders += 1; workInProgressHook = currentHook = null; workInProgress.updateQueue = null; - ReactSharedInternals.H = HooksDispatcherOnRerender; + ReactCurrentDispatcher$1.current = HooksDispatcherOnRerender; var children = Component(props, secondArg); } while (didScheduleRenderPhaseUpdateDuringThisPass); return children; } -function TransitionAwareHostComponent() { - var dispatcher = ReactSharedInternals.H, - maybeThenable = dispatcher.useState()[0]; - maybeThenable = - "function" === typeof maybeThenable.then - ? useThenable(maybeThenable) - : maybeThenable; - dispatcher = dispatcher.useState()[0]; - (null !== currentHook ? currentHook.memoizedState : null) !== dispatcher && - (currentlyRenderingFiber$1.flags |= 1024); - return maybeThenable; -} function bailoutHooks(current, workInProgress, lanes) { workInProgress.updateQueue = current.updateQueue; workInProgress.flags &= -2053; @@ -3808,23 +3576,18 @@ function updateWorkInProgressHook() { } var createFunctionComponentUpdateQueue; createFunctionComponentUpdateQueue = function () { - return { lastEffect: null, events: null, stores: null, memoCache: null }; + return { lastEffect: null, events: null, stores: null }; }; function useThenable(thenable) { var index = thenableIndexCounter; thenableIndexCounter += 1; null === thenableState && (thenableState = []); thenable = trackUsedThenable(thenableState, thenable, index); - index = currentlyRenderingFiber$1; - null === + null === currentlyRenderingFiber$1.alternate && (null === workInProgressHook - ? index.memoizedState - : workInProgressHook.next) && - ((index = index.alternate), - (ReactSharedInternals.H = - null === index || null === index.memoizedState - ? HooksDispatcherOnMount - : HooksDispatcherOnUpdate)); + ? null === currentlyRenderingFiber$1.memoizedState + : null === workInProgressHook.next) && + (ReactCurrentDispatcher$1.current = HooksDispatcherOnMount); return thenable; } function use(usable) { @@ -3834,52 +3597,16 @@ function use(usable) { } throw Error("An unsupported type was passed to use(): " + String(usable)); } -function useMemoCache(size) { - var memoCache = null, - updateQueue = currentlyRenderingFiber$1.updateQueue; - null !== updateQueue && (memoCache = updateQueue.memoCache); - if (null == memoCache) { - var current = currentlyRenderingFiber$1.alternate; - null !== current && - ((current = current.updateQueue), - null !== current && - ((current = current.memoCache), - null != current && - (memoCache = { - data: current.data.map(function (array) { - return array.slice(); - }), - index: 0 - }))); - } - null == memoCache && (memoCache = { data: [], index: 0 }); - null === updateQueue && - ((updateQueue = createFunctionComponentUpdateQueue()), - (currentlyRenderingFiber$1.updateQueue = updateQueue)); - updateQueue.memoCache = memoCache; - updateQueue = memoCache.data[memoCache.index]; - if (void 0 === updateQueue) - for ( - updateQueue = memoCache.data[memoCache.index] = Array(size), current = 0; - current < size; - current++ - ) - updateQueue[current] = REACT_MEMO_CACHE_SENTINEL; - memoCache.index++; - return updateQueue; -} function basicStateReducer(state, action) { return "function" === typeof action ? action(state) : action; } function updateReducer(reducer) { - var hook = updateWorkInProgressHook(); - return updateReducerImpl(hook, currentHook, reducer); -} -function updateReducerImpl(hook, current, reducer) { - var queue = hook.queue; + var hook = updateWorkInProgressHook(), + current = currentHook, + queue = hook.queue; if (null === queue) throw Error( - "Should have a queue. You are likely calling Hooks conditionally, which is not allowed. (https://react.dev/link/invalid-hook-call)" + "Should have a queue. This is likely a bug in React. Please file an issue." ); queue.lastRenderedReducer = reducer; var baseQueue = hook.baseQueue, @@ -3899,82 +3626,52 @@ function updateReducerImpl(hook, current, reducer) { current = baseQueue.next; var newBaseQueueFirst = (baseFirst = null), newBaseQueueLast = null, - update = current, - didReadFromEntangledAsyncAction$48 = !1; + update = current; do { var updateLane = update.lane & -536870913; if ( updateLane !== update.lane ? (workInProgressRootRenderLanes & updateLane) === updateLane : (renderLanes & updateLane) === updateLane - ) { - var revertLane = update.revertLane; - if (0 === revertLane) - null !== newBaseQueueLast && - (newBaseQueueLast = newBaseQueueLast.next = - { - lane: 0, - revertLane: 0, - action: update.action, - hasEagerState: update.hasEagerState, - eagerState: update.eagerState, - next: null - }), - updateLane === currentEntangledLane && - (didReadFromEntangledAsyncAction$48 = !0); - else if ((renderLanes & revertLane) === revertLane) { - update = update.next; - revertLane === currentEntangledLane && - (didReadFromEntangledAsyncAction$48 = !0); - continue; - } else - (updateLane = { - lane: 0, - revertLane: update.revertLane, - action: update.action, - hasEagerState: update.hasEagerState, - eagerState: update.eagerState, - next: null - }), - null === newBaseQueueLast - ? ((newBaseQueueFirst = newBaseQueueLast = updateLane), - (baseFirst = pendingQueue)) - : (newBaseQueueLast = newBaseQueueLast.next = updateLane), - (currentlyRenderingFiber$1.lanes |= revertLane), - (workInProgressRootSkippedLanes |= revertLane); - updateLane = update.action; - shouldDoubleInvokeUserFnsInHooksDEV && - reducer(pendingQueue, updateLane); - pendingQueue = update.hasEagerState - ? update.eagerState - : reducer(pendingQueue, updateLane); - } else - (revertLane = { + ) + null !== newBaseQueueLast && + (newBaseQueueLast = newBaseQueueLast.next = + { + lane: 0, + revertLane: 0, + action: update.action, + hasEagerState: update.hasEagerState, + eagerState: update.eagerState, + next: null + }), + (updateLane = update.action), + shouldDoubleInvokeUserFnsInHooksDEV && + reducer(pendingQueue, updateLane), + (pendingQueue = update.hasEagerState + ? update.eagerState + : reducer(pendingQueue, updateLane)); + else { + var clone = { lane: updateLane, revertLane: update.revertLane, action: update.action, hasEagerState: update.hasEagerState, eagerState: update.eagerState, next: null - }), - null === newBaseQueueLast - ? ((newBaseQueueFirst = newBaseQueueLast = revertLane), - (baseFirst = pendingQueue)) - : (newBaseQueueLast = newBaseQueueLast.next = revertLane), - (currentlyRenderingFiber$1.lanes |= updateLane), - (workInProgressRootSkippedLanes |= updateLane); + }; + null === newBaseQueueLast + ? ((newBaseQueueFirst = newBaseQueueLast = clone), + (baseFirst = pendingQueue)) + : (newBaseQueueLast = newBaseQueueLast.next = clone); + currentlyRenderingFiber$1.lanes |= updateLane; + workInProgressRootSkippedLanes |= updateLane; + } update = update.next; } while (null !== update && update !== current); null === newBaseQueueLast ? (baseFirst = pendingQueue) : (newBaseQueueLast.next = newBaseQueueFirst); - if ( - !objectIs(pendingQueue, hook.memoizedState) && - ((didReceiveUpdate = !0), - didReadFromEntangledAsyncAction$48 && - ((reducer = currentEntangledActionThenable), null !== reducer)) - ) - throw reducer; + objectIs(pendingQueue, hook.memoizedState) || (didReceiveUpdate = !0); hook.memoizedState = pendingQueue; hook.baseState = baseFirst; hook.baseQueue = newBaseQueueLast; @@ -3988,7 +3685,7 @@ function rerenderReducer(reducer) { queue = hook.queue; if (null === queue) throw Error( - "Should have a queue. You are likely calling Hooks conditionally, which is not allowed. (https://react.dev/link/invalid-hook-call)" + "Should have a queue. This is likely a bug in React. Please file an issue." ); queue.lastRenderedReducer = reducer; var dispatch = queue.dispatch, @@ -4083,10 +3780,7 @@ function mountStateImpl(initialState) { if ("function" === typeof initialState) { var initialStateInitializer = initialState; initialState = initialStateInitializer(); - shouldDoubleInvokeUserFnsInHooksDEV && - (setIsStrictModeForDevtools(!0), - initialStateInitializer(), - setIsStrictModeForDevtools(!1)); + shouldDoubleInvokeUserFnsInHooksDEV && initialStateInitializer(); } hook.memoizedState = hook.baseState = initialState; hook.queue = { @@ -4098,214 +3792,6 @@ function mountStateImpl(initialState) { }; return hook; } -function updateOptimisticImpl(hook, current, passthrough, reducer) { - hook.baseState = passthrough; - return updateReducerImpl( - hook, - currentHook, - "function" === typeof reducer ? reducer : basicStateReducer - ); -} -function dispatchActionState( - fiber, - actionQueue, - setPendingState, - setState, - payload -) { - if (isRenderPhaseUpdate(fiber)) - throw Error("Cannot update form state while rendering."); - fiber = actionQueue.action; - if (null !== fiber) { - var actionNode = { - payload: payload, - action: fiber, - next: null, - isTransition: !0, - status: "pending", - value: null, - reason: null, - listeners: [], - then: function (listener) { - actionNode.listeners.push(listener); - } - }; - null !== ReactSharedInternals.T - ? setPendingState(!0) - : (actionNode.isTransition = !1); - setState(actionNode); - setPendingState = actionQueue.pending; - null === setPendingState - ? ((actionNode.next = actionQueue.pending = actionNode), - runActionStateAction(actionQueue, actionNode)) - : ((actionNode.next = setPendingState.next), - (actionQueue.pending = setPendingState.next = actionNode)); - } -} -function runActionStateAction(actionQueue, node) { - var action = node.action, - payload = node.payload, - prevState = actionQueue.state; - if (node.isTransition) { - var prevTransition = ReactSharedInternals.T, - currentTransition = {}; - ReactSharedInternals.T = currentTransition; - try { - var returnValue = action(prevState, payload), - onStartTransitionFinish = ReactSharedInternals.S; - null !== onStartTransitionFinish && - onStartTransitionFinish(currentTransition, returnValue); - handleActionReturnValue(actionQueue, node, returnValue); - } catch (error) { - onActionError(actionQueue, node, error); - } finally { - ReactSharedInternals.T = prevTransition; - } - } else - try { - (prevTransition = action(prevState, payload)), - handleActionReturnValue(actionQueue, node, prevTransition); - } catch (error$52) { - onActionError(actionQueue, node, error$52); - } -} -function handleActionReturnValue(actionQueue, node, returnValue) { - null !== returnValue && - "object" === typeof returnValue && - "function" === typeof returnValue.then - ? returnValue.then( - function (nextState) { - onActionSuccess(actionQueue, node, nextState); - }, - function (error) { - return onActionError(actionQueue, node, error); - } - ) - : onActionSuccess(actionQueue, node, returnValue); -} -function onActionSuccess(actionQueue, actionNode, nextState) { - actionNode.status = "fulfilled"; - actionNode.value = nextState; - notifyActionListeners(actionNode); - actionQueue.state = nextState; - actionNode = actionQueue.pending; - null !== actionNode && - ((nextState = actionNode.next), - nextState === actionNode - ? (actionQueue.pending = null) - : ((nextState = nextState.next), - (actionNode.next = nextState), - runActionStateAction(actionQueue, nextState))); -} -function onActionError(actionQueue, actionNode, error) { - var last = actionQueue.pending; - actionQueue.pending = null; - if (null !== last) { - last = last.next; - do - (actionNode.status = "rejected"), - (actionNode.reason = error), - notifyActionListeners(actionNode), - (actionNode = actionNode.next); - while (actionNode !== last); - } - actionQueue.action = null; -} -function notifyActionListeners(actionNode) { - actionNode = actionNode.listeners; - for (var i = 0; i < actionNode.length; i++) (0, actionNode[i])(); -} -function actionStateReducer(oldState, newState) { - return newState; -} -function mountActionState(action, initialStateProp) { - var stateHook = mountWorkInProgressHook(); - stateHook.memoizedState = stateHook.baseState = initialStateProp; - var stateQueue = { - pending: null, - lanes: 0, - dispatch: null, - lastRenderedReducer: actionStateReducer, - lastRenderedState: initialStateProp - }; - stateHook.queue = stateQueue; - stateHook = dispatchSetState.bind( - null, - currentlyRenderingFiber$1, - stateQueue - ); - stateQueue.dispatch = stateHook; - stateQueue = mountStateImpl(!1); - var setPendingState = dispatchOptimisticSetState.bind( - null, - currentlyRenderingFiber$1, - !1, - stateQueue.queue - ); - stateQueue = mountWorkInProgressHook(); - var actionQueue = { - state: initialStateProp, - dispatch: null, - action: action, - pending: null - }; - stateQueue.queue = actionQueue; - stateHook = dispatchActionState.bind( - null, - currentlyRenderingFiber$1, - actionQueue, - setPendingState, - stateHook - ); - actionQueue.dispatch = stateHook; - stateQueue.memoizedState = action; - return [initialStateProp, stateHook, !1]; -} -function updateActionState(action) { - var stateHook = updateWorkInProgressHook(); - return updateActionStateImpl(stateHook, currentHook, action); -} -function updateActionStateImpl(stateHook, currentStateHook, action) { - currentStateHook = updateReducerImpl( - stateHook, - currentStateHook, - actionStateReducer - )[0]; - stateHook = updateReducer(basicStateReducer)[0]; - currentStateHook = - "object" === typeof currentStateHook && - null !== currentStateHook && - "function" === typeof currentStateHook.then - ? useThenable(currentStateHook) - : currentStateHook; - var actionQueueHook = updateWorkInProgressHook(), - actionQueue = actionQueueHook.queue, - dispatch = actionQueue.dispatch; - action !== actionQueueHook.memoizedState && - ((currentlyRenderingFiber$1.flags |= 2048), - pushEffect( - 9, - actionStateActionEffect.bind(null, actionQueue, action), - { destroy: void 0 }, - null - )); - return [currentStateHook, dispatch, stateHook]; -} -function actionStateActionEffect(actionQueue, action) { - actionQueue.action = action; -} -function rerenderActionState(action) { - var stateHook = updateWorkInProgressHook(), - currentStateHook = currentHook; - if (null !== currentStateHook) - return updateActionStateImpl(stateHook, currentStateHook, action); - updateWorkInProgressHook(); - stateHook = stateHook.memoizedState; - currentStateHook = updateWorkInProgressHook(); - var dispatch = currentStateHook.queue.dispatch; - currentStateHook.memoizedState = action; - return [stateHook, dispatch, !1]; -} function pushEffect(tag, create, inst, deps) { tag = { tag: tag, create: create, inst: inst, deps: deps, next: null }; create = currentlyRenderingFiber$1.updateQueue; @@ -4359,13 +3845,14 @@ function updateLayoutEffect(create, deps) { return updateEffectImpl(4, 4, create, deps); } function imperativeHandleEffect(create, ref) { - if ("function" === typeof ref) { - create = create(); - var refCleanup = ref(create); - return function () { - "function" === typeof refCleanup ? refCleanup() : ref(null); - }; - } + if ("function" === typeof ref) + return ( + (create = create()), + ref(create), + function () { + ref(null); + } + ); if (null !== ref && void 0 !== ref) return ( (create = create()), @@ -4396,21 +3883,18 @@ function updateMemo(nextCreate, deps) { if (null !== deps && areHookInputsEqual(deps, prevState[1])) return prevState[0]; prevState = nextCreate(); - shouldDoubleInvokeUserFnsInHooksDEV && - (setIsStrictModeForDevtools(!0), - nextCreate(), - setIsStrictModeForDevtools(!1)); + shouldDoubleInvokeUserFnsInHooksDEV && nextCreate(); hook.memoizedState = [prevState, deps]; return prevState; } function mountDeferredValueImpl(hook, value, initialValue) { - if (void 0 === initialValue || 0 !== (renderLanes & 1073741824)) - return (hook.memoizedState = value); - hook.memoizedState = initialValue; - hook = requestDeferredLane(); - currentlyRenderingFiber$1.lanes |= hook; - workInProgressRootSkippedLanes |= hook; - return initialValue; + return void 0 !== initialValue && 0 === (renderLanes & 1073741824) + ? ((hook.memoizedState = initialValue), + (hook = requestDeferredLane()), + (currentlyRenderingFiber$1.lanes |= hook), + (workInProgressRootSkippedLanes |= hook), + initialValue) + : (hook.memoizedState = value); } function updateDeferredValueImpl(hook, prevValue, value, initialValue) { if (objectIs(value, prevValue)) return value; @@ -4431,65 +3915,23 @@ function startTransition(fiber, queue, pendingState, finishedState, callback) { var previousPriority = currentUpdatePriority; currentUpdatePriority = 0 !== previousPriority && 8 > previousPriority ? previousPriority : 8; - var prevTransition = ReactSharedInternals.T, - currentTransition = {}; - ReactSharedInternals.T = currentTransition; - dispatchOptimisticSetState(fiber, !1, queue, pendingState); + var prevTransition = ReactCurrentBatchConfig$2.transition, + currentTransition = { _callbacks: new Set() }; + ReactCurrentBatchConfig$2.transition = null; + dispatchSetState(fiber, queue, pendingState); + ReactCurrentBatchConfig$2.transition = currentTransition; try { - var returnValue = callback(), - onStartTransitionFinish = ReactSharedInternals.S; - null !== onStartTransitionFinish && - onStartTransitionFinish(currentTransition, returnValue); - if ( - null !== returnValue && - "object" === typeof returnValue && - "function" === typeof returnValue.then - ) { - var thenableForFinishedState = chainThenableValue( - returnValue, - finishedState - ); - dispatchSetState(fiber, queue, thenableForFinishedState); - } else dispatchSetState(fiber, queue, finishedState); + dispatchSetState(fiber, queue, finishedState), callback(); } catch (error) { - dispatchSetState(fiber, queue, { - then: function () {}, - status: "rejected", - reason: error - }); + throw error; } finally { (currentUpdatePriority = previousPriority), - (ReactSharedInternals.T = prevTransition); + (ReactCurrentBatchConfig$2.transition = prevTransition); } } -function useHostTransitionStatus() { - var status = readContext(HostTransitionContext); - return null !== status ? status : null; -} function updateId() { return updateWorkInProgressHook().memoizedState; } -function updateRefresh() { - return updateWorkInProgressHook().memoizedState; -} -function refreshCache(fiber) { - for (var provider = fiber.return; null !== provider; ) { - switch (provider.tag) { - case 24: - case 3: - var lane = requestUpdateLane(provider); - fiber = createUpdate(lane); - var root = enqueueUpdate(provider, fiber, lane); - null !== root && - (scheduleUpdateOnFiber(root, provider, lane), - entangleTransitions(root, provider, lane)); - provider = { cache: createCache() }; - fiber.payload = provider; - return; - } - provider = provider.return; - } -} function dispatchReducerAction(fiber, queue, action) { var lane = requestUpdateLane(fiber); action = { @@ -4502,11 +3944,11 @@ function dispatchReducerAction(fiber, queue, action) { }; isRenderPhaseUpdate(fiber) ? enqueueRenderPhaseUpdate(queue, action) - : ((action = enqueueConcurrentHookUpdate(fiber, queue, action, lane)), + : (enqueueUpdate$1(fiber, queue, action, lane), + (action = getRootForUpdatedFiber(fiber)), null !== action && (scheduleUpdateOnFiber(action, fiber, lane), entangleTransitionUpdate(action, queue, lane))); - markStateUpdateScheduled(fiber, lane); } function dispatchSetState(fiber, queue, action) { var lane = requestUpdateLane(fiber), @@ -4539,35 +3981,12 @@ function dispatchSetState(fiber, queue, action) { } catch (error) { } finally { } - action = enqueueConcurrentHookUpdate(fiber, queue, update, lane); + enqueueUpdate$1(fiber, queue, update, lane); + action = getRootForUpdatedFiber(fiber); null !== action && (scheduleUpdateOnFiber(action, fiber, lane), entangleTransitionUpdate(action, queue, lane)); } - markStateUpdateScheduled(fiber, lane); -} -function dispatchOptimisticSetState(fiber, throwIfDuringRender, queue, action) { - action = { - lane: 2, - revertLane: requestTransitionLane(), - action: action, - hasEagerState: !1, - eagerState: null, - next: null - }; - if (isRenderPhaseUpdate(fiber)) { - if (throwIfDuringRender) - throw Error("Cannot update optimistic state while rendering."); - } else - (throwIfDuringRender = enqueueConcurrentHookUpdate( - fiber, - queue, - action, - 2 - )), - null !== throwIfDuringRender && - scheduleUpdateOnFiber(throwIfDuringRender, fiber, 2); - markStateUpdateScheduled(fiber, 2); } function isRenderPhaseUpdate(fiber) { var alternate = fiber.alternate; @@ -4595,286 +4014,227 @@ function entangleTransitionUpdate(root, queue, lane) { } } var ContextOnlyDispatcher = { - readContext: readContext, - use: use, - useCallback: throwInvalidHookError, - useContext: throwInvalidHookError, - useEffect: throwInvalidHookError, - useImperativeHandle: throwInvalidHookError, - useLayoutEffect: throwInvalidHookError, - useInsertionEffect: throwInvalidHookError, - useMemo: throwInvalidHookError, - useReducer: throwInvalidHookError, - useRef: throwInvalidHookError, - useState: throwInvalidHookError, - useDebugValue: throwInvalidHookError, - useDeferredValue: throwInvalidHookError, - useTransition: throwInvalidHookError, - useSyncExternalStore: throwInvalidHookError, - useId: throwInvalidHookError -}; -ContextOnlyDispatcher.useCacheRefresh = throwInvalidHookError; -ContextOnlyDispatcher.useMemoCache = throwInvalidHookError; -ContextOnlyDispatcher.useHostTransitionStatus = throwInvalidHookError; -ContextOnlyDispatcher.useFormState = throwInvalidHookError; -ContextOnlyDispatcher.useActionState = throwInvalidHookError; -ContextOnlyDispatcher.useOptimistic = throwInvalidHookError; -var HooksDispatcherOnMount = { - readContext: readContext, - use: use, - useCallback: function (callback, deps) { - mountWorkInProgressHook().memoizedState = [ - callback, - void 0 === deps ? null : deps - ]; - return callback; - }, - useContext: readContext, - useEffect: mountEffect, - useImperativeHandle: function (ref, create, deps) { - deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; - mountEffectImpl( - 4194308, - 4, - imperativeHandleEffect.bind(null, create, ref), - deps - ); - }, - useLayoutEffect: function (create, deps) { - return mountEffectImpl(4194308, 4, create, deps); - }, - useInsertionEffect: function (create, deps) { - mountEffectImpl(4, 2, create, deps); + readContext: readContext, + use: use, + useCallback: throwInvalidHookError, + useContext: throwInvalidHookError, + useEffect: throwInvalidHookError, + useImperativeHandle: throwInvalidHookError, + useInsertionEffect: throwInvalidHookError, + useLayoutEffect: throwInvalidHookError, + useMemo: throwInvalidHookError, + useReducer: throwInvalidHookError, + useRef: throwInvalidHookError, + useState: throwInvalidHookError, + useDebugValue: throwInvalidHookError, + useDeferredValue: throwInvalidHookError, + useTransition: throwInvalidHookError, + useSyncExternalStore: throwInvalidHookError, + useId: throwInvalidHookError }, - useMemo: function (nextCreate, deps) { - var hook = mountWorkInProgressHook(); - deps = void 0 === deps ? null : deps; - var nextValue = nextCreate(); - shouldDoubleInvokeUserFnsInHooksDEV && - (setIsStrictModeForDevtools(!0), - nextCreate(), - setIsStrictModeForDevtools(!1)); - hook.memoizedState = [nextValue, deps]; - return nextValue; - }, - useReducer: function (reducer, initialArg, init) { - var hook = mountWorkInProgressHook(); - if (void 0 !== init) { - var initialState = init(initialArg); - shouldDoubleInvokeUserFnsInHooksDEV && - (setIsStrictModeForDevtools(!0), - init(initialArg), - setIsStrictModeForDevtools(!1)); - } else initialState = initialArg; - hook.memoizedState = hook.baseState = initialState; - reducer = { - pending: null, - lanes: 0, - dispatch: null, - lastRenderedReducer: reducer, - lastRenderedState: initialState - }; - hook.queue = reducer; - reducer = reducer.dispatch = dispatchReducerAction.bind( - null, - currentlyRenderingFiber$1, - reducer - ); - return [hook.memoizedState, reducer]; - }, - useRef: function (initialValue) { - var hook = mountWorkInProgressHook(); - initialValue = { current: initialValue }; - return (hook.memoizedState = initialValue); - }, - useState: function (initialState) { - initialState = mountStateImpl(initialState); - var queue = initialState.queue, - dispatch = dispatchSetState.bind(null, currentlyRenderingFiber$1, queue); - queue.dispatch = dispatch; - return [initialState.memoizedState, dispatch]; - }, - useDebugValue: mountDebugValue, - useDeferredValue: function (value, initialValue) { - var hook = mountWorkInProgressHook(); - return mountDeferredValueImpl(hook, value, initialValue); - }, - useTransition: function () { - var stateHook = mountStateImpl(!1); - stateHook = startTransition.bind( - null, - currentlyRenderingFiber$1, - stateHook.queue, - !0, - !1 - ); - mountWorkInProgressHook().memoizedState = stateHook; - return [!1, stateHook]; - }, - useSyncExternalStore: function (subscribe, getSnapshot) { - var fiber = currentlyRenderingFiber$1, - hook = mountWorkInProgressHook(); - var nextSnapshot = getSnapshot(); - if (null === workInProgressRoot) - throw Error( - "Expected a work-in-progress root. This is a bug in React. Please file an issue." + HooksDispatcherOnMount = { + readContext: readContext, + use: use, + useCallback: function (callback, deps) { + mountWorkInProgressHook().memoizedState = [ + callback, + void 0 === deps ? null : deps + ]; + return callback; + }, + useContext: readContext, + useEffect: mountEffect, + useImperativeHandle: function (ref, create, deps) { + deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; + mountEffectImpl( + 4194308, + 4, + imperativeHandleEffect.bind(null, create, ref), + deps ); - 0 !== (workInProgressRootRenderLanes & 60) || - pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot); - hook.memoizedState = nextSnapshot; - var inst = { value: nextSnapshot, getSnapshot: getSnapshot }; - hook.queue = inst; - mountEffect(subscribeToStore.bind(null, fiber, inst, subscribe), [ - subscribe - ]); - fiber.flags |= 2048; - pushEffect( - 9, - updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot), - { destroy: void 0 }, - null - ); - return nextSnapshot; - }, - useId: function () { - var hook = mountWorkInProgressHook(), - identifierPrefix = workInProgressRoot.identifierPrefix, - globalClientId = globalClientIdCounter++; - identifierPrefix = - ":" + identifierPrefix + "r" + globalClientId.toString(32) + ":"; - return (hook.memoizedState = identifierPrefix); - }, - useCacheRefresh: function () { - return (mountWorkInProgressHook().memoizedState = refreshCache.bind( - null, - currentlyRenderingFiber$1 - )); - } -}; -HooksDispatcherOnMount.useMemoCache = useMemoCache; -HooksDispatcherOnMount.useHostTransitionStatus = useHostTransitionStatus; -HooksDispatcherOnMount.useFormState = mountActionState; -HooksDispatcherOnMount.useActionState = mountActionState; -HooksDispatcherOnMount.useOptimistic = function (passthrough) { - var hook = mountWorkInProgressHook(); - hook.memoizedState = hook.baseState = passthrough; - var queue = { - pending: null, - lanes: 0, - dispatch: null, - lastRenderedReducer: null, - lastRenderedState: null - }; - hook.queue = queue; - hook = dispatchOptimisticSetState.bind( - null, - currentlyRenderingFiber$1, - !0, - queue - ); - queue.dispatch = hook; - return [passthrough, hook]; -}; -var HooksDispatcherOnUpdate = { - readContext: readContext, - use: use, - useCallback: updateCallback, - useContext: readContext, - useEffect: updateEffect, - useImperativeHandle: updateImperativeHandle, - useInsertionEffect: updateInsertionEffect, - useLayoutEffect: updateLayoutEffect, - useMemo: updateMemo, - useReducer: updateReducer, - useRef: updateRef, - useState: function () { - return updateReducer(basicStateReducer); - }, - useDebugValue: mountDebugValue, - useDeferredValue: function (value, initialValue) { - var hook = updateWorkInProgressHook(); - return updateDeferredValueImpl( - hook, - currentHook.memoizedState, - value, - initialValue - ); - }, - useTransition: function () { - var booleanOrThenable = updateReducer(basicStateReducer)[0], - start = updateWorkInProgressHook().memoizedState; - return [ - "boolean" === typeof booleanOrThenable - ? booleanOrThenable - : useThenable(booleanOrThenable), - start - ]; - }, - useSyncExternalStore: updateSyncExternalStore, - useId: updateId -}; -HooksDispatcherOnUpdate.useCacheRefresh = updateRefresh; -HooksDispatcherOnUpdate.useMemoCache = useMemoCache; -HooksDispatcherOnUpdate.useHostTransitionStatus = useHostTransitionStatus; -HooksDispatcherOnUpdate.useFormState = updateActionState; -HooksDispatcherOnUpdate.useActionState = updateActionState; -HooksDispatcherOnUpdate.useOptimistic = function (passthrough, reducer) { - var hook = updateWorkInProgressHook(); - return updateOptimisticImpl(hook, currentHook, passthrough, reducer); -}; -var HooksDispatcherOnRerender = { - readContext: readContext, - use: use, - useCallback: updateCallback, - useContext: readContext, - useEffect: updateEffect, - useImperativeHandle: updateImperativeHandle, - useInsertionEffect: updateInsertionEffect, - useLayoutEffect: updateLayoutEffect, - useMemo: updateMemo, - useReducer: rerenderReducer, - useRef: updateRef, - useState: function () { - return rerenderReducer(basicStateReducer); - }, - useDebugValue: mountDebugValue, - useDeferredValue: function (value, initialValue) { - var hook = updateWorkInProgressHook(); - return null === currentHook - ? mountDeferredValueImpl(hook, value, initialValue) - : updateDeferredValueImpl( - hook, - currentHook.memoizedState, - value, - initialValue + }, + useLayoutEffect: function (create, deps) { + return mountEffectImpl(4194308, 4, create, deps); + }, + useInsertionEffect: function (create, deps) { + mountEffectImpl(4, 2, create, deps); + }, + useMemo: function (nextCreate, deps) { + var hook = mountWorkInProgressHook(); + deps = void 0 === deps ? null : deps; + var nextValue = nextCreate(); + shouldDoubleInvokeUserFnsInHooksDEV && nextCreate(); + hook.memoizedState = [nextValue, deps]; + return nextValue; + }, + useReducer: function (reducer, initialArg, init) { + var hook = mountWorkInProgressHook(); + if (void 0 !== init) { + var initialState = init(initialArg); + shouldDoubleInvokeUserFnsInHooksDEV && init(initialArg); + } else initialState = initialArg; + hook.memoizedState = hook.baseState = initialState; + reducer = { + pending: null, + lanes: 0, + dispatch: null, + lastRenderedReducer: reducer, + lastRenderedState: initialState + }; + hook.queue = reducer; + reducer = reducer.dispatch = dispatchReducerAction.bind( + null, + currentlyRenderingFiber$1, + reducer + ); + return [hook.memoizedState, reducer]; + }, + useRef: function (initialValue) { + var hook = mountWorkInProgressHook(); + initialValue = { current: initialValue }; + return (hook.memoizedState = initialValue); + }, + useState: function (initialState) { + initialState = mountStateImpl(initialState); + var queue = initialState.queue, + dispatch = dispatchSetState.bind( + null, + currentlyRenderingFiber$1, + queue + ); + queue.dispatch = dispatch; + return [initialState.memoizedState, dispatch]; + }, + useDebugValue: mountDebugValue, + useDeferredValue: function (value, initialValue) { + var hook = mountWorkInProgressHook(); + return mountDeferredValueImpl(hook, value, initialValue); + }, + useTransition: function () { + var stateHook = mountStateImpl(!1); + stateHook = startTransition.bind( + null, + currentlyRenderingFiber$1, + stateHook.queue, + !0, + !1 + ); + mountWorkInProgressHook().memoizedState = stateHook; + return [!1, stateHook]; + }, + useSyncExternalStore: function (subscribe, getSnapshot) { + var fiber = currentlyRenderingFiber$1, + hook = mountWorkInProgressHook(); + var nextSnapshot = getSnapshot(); + if (null === workInProgressRoot) + throw Error( + "Expected a work-in-progress root. This is a bug in React. Please file an issue." ); + 0 !== (workInProgressRootRenderLanes & 60) || + pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot); + hook.memoizedState = nextSnapshot; + var inst = { value: nextSnapshot, getSnapshot: getSnapshot }; + hook.queue = inst; + mountEffect(subscribeToStore.bind(null, fiber, inst, subscribe), [ + subscribe + ]); + fiber.flags |= 2048; + pushEffect( + 9, + updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot), + { destroy: void 0 }, + null + ); + return nextSnapshot; + }, + useId: function () { + var hook = mountWorkInProgressHook(), + identifierPrefix = workInProgressRoot.identifierPrefix, + globalClientId = globalClientIdCounter++; + identifierPrefix = + ":" + identifierPrefix + "r" + globalClientId.toString(32) + ":"; + return (hook.memoizedState = identifierPrefix); + } }, - useTransition: function () { - var booleanOrThenable = rerenderReducer(basicStateReducer)[0], - start = updateWorkInProgressHook().memoizedState; - return [ - "boolean" === typeof booleanOrThenable - ? booleanOrThenable - : useThenable(booleanOrThenable), - start - ]; + HooksDispatcherOnUpdate = { + readContext: readContext, + use: use, + useCallback: updateCallback, + useContext: readContext, + useEffect: updateEffect, + useImperativeHandle: updateImperativeHandle, + useInsertionEffect: updateInsertionEffect, + useLayoutEffect: updateLayoutEffect, + useMemo: updateMemo, + useReducer: updateReducer, + useRef: updateRef, + useState: function () { + return updateReducer(basicStateReducer); + }, + useDebugValue: mountDebugValue, + useDeferredValue: function (value, initialValue) { + var hook = updateWorkInProgressHook(); + return updateDeferredValueImpl( + hook, + currentHook.memoizedState, + value, + initialValue + ); + }, + useTransition: function () { + var booleanOrThenable = updateReducer(basicStateReducer)[0], + start = updateWorkInProgressHook().memoizedState; + return [ + "boolean" === typeof booleanOrThenable + ? booleanOrThenable + : useThenable(booleanOrThenable), + start + ]; + }, + useSyncExternalStore: updateSyncExternalStore, + useId: updateId }, - useSyncExternalStore: updateSyncExternalStore, - useId: updateId -}; -HooksDispatcherOnRerender.useCacheRefresh = updateRefresh; -HooksDispatcherOnRerender.useMemoCache = useMemoCache; -HooksDispatcherOnRerender.useHostTransitionStatus = useHostTransitionStatus; -HooksDispatcherOnRerender.useFormState = rerenderActionState; -HooksDispatcherOnRerender.useActionState = rerenderActionState; -HooksDispatcherOnRerender.useOptimistic = function (passthrough, reducer) { - var hook = updateWorkInProgressHook(); - if (null !== currentHook) - return updateOptimisticImpl(hook, currentHook, passthrough, reducer); - hook.baseState = passthrough; - return [passthrough, hook.queue.dispatch]; -}; -var now = Scheduler.unstable_now, + HooksDispatcherOnRerender = { + readContext: readContext, + use: use, + useCallback: updateCallback, + useContext: readContext, + useEffect: updateEffect, + useImperativeHandle: updateImperativeHandle, + useInsertionEffect: updateInsertionEffect, + useLayoutEffect: updateLayoutEffect, + useMemo: updateMemo, + useReducer: rerenderReducer, + useRef: updateRef, + useState: function () { + return rerenderReducer(basicStateReducer); + }, + useDebugValue: mountDebugValue, + useDeferredValue: function (value, initialValue) { + var hook = updateWorkInProgressHook(); + return null === currentHook + ? mountDeferredValueImpl(hook, value, initialValue) + : updateDeferredValueImpl( + hook, + currentHook.memoizedState, + value, + initialValue + ); + }, + useTransition: function () { + var booleanOrThenable = rerenderReducer(basicStateReducer)[0], + start = updateWorkInProgressHook().memoizedState; + return [ + "boolean" === typeof booleanOrThenable + ? booleanOrThenable + : useThenable(booleanOrThenable), + start + ]; + }, + useSyncExternalStore: updateSyncExternalStore, + useId: updateId + }, + now = Scheduler.unstable_now, commitTime = 0, layoutEffectStartTime = -1, profilerStartTime = -1, @@ -4936,6 +4296,17 @@ function transferActualDuration(fiber) { for (var child = fiber.child; child; ) (fiber.actualDuration += child.actualDuration), (child = child.sibling); } +function resolveDefaultProps(Component, baseProps) { + if (Component && Component.defaultProps) { + baseProps = assign({}, baseProps); + Component = Component.defaultProps; + for (var propName in Component) + void 0 === baseProps[propName] && + (baseProps[propName] = Component[propName]); + return baseProps; + } + return baseProps; +} function applyDerivedStateFromProps( workInProgress, ctor, @@ -4968,7 +4339,6 @@ var classComponentUpdater = { null !== payload && (scheduleUpdateOnFiber(payload, inst, lane), entangleTransitions(payload, inst, lane)); - markStateUpdateScheduled(inst, lane); }, enqueueReplaceState: function (inst, payload, callback) { inst = inst._reactInternals; @@ -4981,7 +4351,6 @@ var classComponentUpdater = { null !== payload && (scheduleUpdateOnFiber(payload, inst, lane), entangleTransitions(payload, inst, lane)); - markStateUpdateScheduled(inst, lane); }, enqueueForceUpdate: function (inst, callback) { inst = inst._reactInternals; @@ -4993,9 +4362,6 @@ var classComponentUpdater = { null !== callback && (scheduleUpdateOnFiber(callback, inst, lane), entangleTransitions(callback, inst, lane)); - null !== injectedProfilingHooks && - "function" === typeof injectedProfilingHooks.markForceUpdateScheduled && - injectedProfilingHooks.markForceUpdateScheduled(inst, lane); } }; function checkShouldComponentUpdate( @@ -5070,111 +4436,80 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { ctor !== instance.state && classComponentUpdater.enqueueReplaceState(instance, instance.state, null), processUpdateQueue(workInProgress, newProps, instance, renderLanes), - suspendIfUpdateReadFromEntangledAsyncAction(), (instance.state = workInProgress.memoizedState)); "function" === typeof instance.componentDidMount && (workInProgress.flags |= 4194308); } -function resolveClassComponentProps(Component, baseProps) { - var newProps = baseProps; - if ("ref" in baseProps) { - newProps = {}; - for (var propName in baseProps) - "ref" !== propName && (newProps[propName] = baseProps[propName]); - } - if ((Component = Component.defaultProps)) { - newProps === baseProps && (newProps = assign({}, newProps)); - for (var propName$54 in Component) - void 0 === newProps[propName$54] && - (newProps[propName$54] = Component[propName$54]); - } - return newProps; -} -var reportGlobalError = - "function" === typeof reportError - ? reportError - : function (error) { - if ( - "object" === typeof window && - "function" === typeof window.ErrorEvent - ) { - var event = new window.ErrorEvent("error", { - bubbles: !0, - cancelable: !0, - message: - "object" === typeof error && - null !== error && - "string" === typeof error.message - ? String(error.message) - : String(error), - error: error - }); - if (!window.dispatchEvent(event)) return; - } else if ( - "object" === typeof process && - "function" === typeof process.emit - ) { - process.emit("uncaughtException", error); - return; - } - console.error(error); - }; -function defaultOnRecoverableError(error) { - reportGlobalError(error); +var CapturedStacks = new WeakMap(); +function createCapturedValueAtFiber(value, source) { + if ("object" === typeof value && null !== value) { + var stack = CapturedStacks.get(value); + "string" !== typeof stack && + ((stack = getStackByFiberInDevAndProd(source)), + CapturedStacks.set(value, stack)); + } else stack = getStackByFiberInDevAndProd(source); + return { value: value, source: source, stack: stack, digest: null }; } -function logUncaughtError(root, errorInfo) { - try { - var onUncaughtError = root.onUncaughtError; - onUncaughtError(errorInfo.value, { componentStack: errorInfo.stack }); - } catch (e) { - setTimeout(function () { - throw e; - }); - } +function createCapturedValueFromError(value, digest, stack) { + "string" === typeof stack && CapturedStacks.set(value, stack); + return { + value: value, + source: null, + stack: null != stack ? stack : null, + digest: null != digest ? digest : null + }; } -function logCaughtError(root, boundary, errorInfo) { +if ( + "function" !== + typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog +) + throw Error( + "Expected ReactFiberErrorDialog.showErrorDialog to be a function." + ); +function logCapturedError(boundary, errorInfo) { try { - var onCaughtError = root.onCaughtError; - onCaughtError(errorInfo.value, { - componentStack: errorInfo.stack, - errorBoundary: 1 === boundary.tag ? boundary.stateNode : null - }); + !1 !== + ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog({ + componentStack: null !== errorInfo.stack ? errorInfo.stack : "", + error: errorInfo.value, + errorBoundary: + null !== boundary && 1 === boundary.tag ? boundary.stateNode : null + }) && console.error(errorInfo.value); } catch (e) { setTimeout(function () { throw e; }); } } -function createRootErrorUpdate(root, errorInfo, lane) { +function createRootErrorUpdate(fiber, errorInfo, lane) { lane = createUpdate(lane); lane.tag = 3; lane.payload = { element: null }; + var error = errorInfo.value; lane.callback = function () { - logUncaughtError(root, errorInfo); + hasUncaughtError || ((hasUncaughtError = !0), (firstUncaughtError = error)); + logCapturedError(fiber, errorInfo); }; return lane; } -function createClassErrorUpdate(lane) { +function createClassErrorUpdate(fiber, errorInfo, lane) { lane = createUpdate(lane); lane.tag = 3; - return lane; -} -function initializeClassErrorUpdate(update, root, fiber, errorInfo) { var getDerivedStateFromError = fiber.type.getDerivedStateFromError; if ("function" === typeof getDerivedStateFromError) { var error = errorInfo.value; - update.payload = function () { + lane.payload = function () { return getDerivedStateFromError(error); }; - update.callback = function () { - logCaughtError(root, fiber, errorInfo); + lane.callback = function () { + logCapturedError(fiber, errorInfo); }; } var inst = fiber.stateNode; null !== inst && "function" === typeof inst.componentDidCatch && - (update.callback = function () { - logCaughtError(root, fiber, errorInfo); + (lane.callback = function () { + logCapturedError(fiber, errorInfo); "function" !== typeof getDerivedStateFromError && (null === legacyErrorBoundariesThatAlreadyFailed ? (legacyErrorBoundariesThatAlreadyFailed = new Set([this])) @@ -5184,6 +4519,7 @@ function initializeClassErrorUpdate(update, root, fiber, errorInfo) { componentStack: null !== stack ? stack : "" }); }); + return lane; } function throwException( root, @@ -5226,15 +4562,12 @@ function throwException( : ((tag.flags |= 128), (sourceFiber.flags |= 131072), (sourceFiber.flags &= -52805), - 1 === sourceFiber.tag - ? null === sourceFiber.alternate + 1 === sourceFiber.tag && + (null === sourceFiber.alternate ? (sourceFiber.tag = 17) : ((returnFiber = createUpdate(2)), (returnFiber.tag = 2), - enqueueUpdate(sourceFiber, returnFiber, 2)) - : 0 === sourceFiber.tag && - null === sourceFiber.alternate && - (sourceFiber.tag = 28), + enqueueUpdate(sourceFiber, returnFiber, 2))), (sourceFiber.lanes |= 2)) : ((tag.flags |= 65536), (tag.lanes = rootRenderLanes)), value === noopSuspenseyCommitThenable @@ -5285,35 +4618,34 @@ function throwException( "A component suspended while responding to synchronous input. This will cause the UI to be replaced with a loading indicator. To fix, updates that suspend should be wrapped with startTransition." ); } - tag = createCapturedValueAtFiber( - Error( - "There was an error during concurrent rendering but React was able to recover by instead synchronously rendering the entire root.", - { cause: value } - ), - sourceFiber - ); - null === workInProgressRootConcurrentErrors - ? (workInProgressRootConcurrentErrors = [tag]) - : workInProgressRootConcurrentErrors.push(tag); + root = value = createCapturedValueAtFiber(value, sourceFiber); 4 !== workInProgressRootExitStatus && (workInProgressRootExitStatus = 2); + null === workInProgressRootConcurrentErrors + ? (workInProgressRootConcurrentErrors = [root]) + : workInProgressRootConcurrentErrors.push(root); if (null === returnFiber) return !0; - value = createCapturedValueAtFiber(value, sourceFiber); + root = returnFiber; do { - switch (returnFiber.tag) { + switch (root.tag) { case 3: return ( - (returnFiber.flags |= 65536), - (root = rootRenderLanes & -rootRenderLanes), - (returnFiber.lanes |= root), - (root = createRootErrorUpdate(returnFiber.stateNode, value, root)), - enqueueCapturedUpdate(returnFiber, root), + (root.flags |= 65536), + (rootRenderLanes &= -rootRenderLanes), + (root.lanes |= rootRenderLanes), + (rootRenderLanes = createRootErrorUpdate( + root, + value, + rootRenderLanes + )), + enqueueCapturedUpdate(root, rootRenderLanes), !1 ); case 1: if ( - ((sourceFiber = returnFiber.type), - (tag = returnFiber.stateNode), - 0 === (returnFiber.flags & 128) && + ((returnFiber = value), + (sourceFiber = root.type), + (tag = root.stateNode), + 0 === (root.flags & 128) && ("function" === typeof sourceFiber.getDerivedStateFromError || (null !== tag && "function" === typeof tag.componentDidCatch && @@ -5321,25 +4653,24 @@ function throwException( !legacyErrorBoundariesThatAlreadyFailed.has(tag))))) ) return ( - (returnFiber.flags |= 65536), + (root.flags |= 65536), (rootRenderLanes &= -rootRenderLanes), - (returnFiber.lanes |= rootRenderLanes), - (rootRenderLanes = createClassErrorUpdate(rootRenderLanes)), - initializeClassErrorUpdate( - rootRenderLanes, + (root.lanes |= rootRenderLanes), + (rootRenderLanes = createClassErrorUpdate( root, returnFiber, - value - ), - enqueueCapturedUpdate(returnFiber, rootRenderLanes), + rootRenderLanes + )), + enqueueCapturedUpdate(root, rootRenderLanes), !1 ); } - returnFiber = returnFiber.return; - } while (null !== returnFiber); + root = root.return; + } while (null !== root); return !1; } -var SelectiveHydrationException = Error( +var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner, + SelectiveHydrationException = Error( "This is not a real error. It's an implementation detail of React's selective hydration feature. If this leaks into userspace, it's a bug in React. Please file an issue." ), didReceiveUpdate = !1; @@ -5363,22 +4694,15 @@ function updateForwardRef( ) { Component = Component.render; var ref = workInProgress.ref; - if ("ref" in nextProps) { - var propsWithoutRef = {}; - for (var key in nextProps) - "ref" !== key && (propsWithoutRef[key] = nextProps[key]); - } else propsWithoutRef = nextProps; prepareToReadContext(workInProgress, renderLanes); - markComponentRenderStarted(workInProgress); nextProps = renderWithHooks( current, workInProgress, Component, - propsWithoutRef, + nextProps, ref, renderLanes ); - markComponentRenderStopped(); if (null !== current && !didReceiveUpdate) return ( bailoutHooks(current, workInProgress, renderLanes), @@ -5401,7 +4725,8 @@ function updateMemoComponent( "function" === typeof type && !shouldConstruct(type) && void 0 === type.defaultProps && - null === Component.compare + null === Component.compare && + void 0 === Component.defaultProps ) return ( (workInProgress.tag = 15), @@ -5499,52 +4824,35 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { } if (0 === (workInProgress.mode & 1)) (workInProgress.memoizedState = { baseLanes: 0, cachePool: null }), - null !== current && pushTransition(workInProgress, null), - reuseHiddenContextOnStack(), - pushOffscreenSuspenseHandler(workInProgress); - else if (0 !== (renderLanes & 536870912)) - (workInProgress.memoizedState = { baseLanes: 0, cachePool: null }), - null !== current && - pushTransition( + reuseHiddenContextOnStack(); + else { + if (0 === (renderLanes & 536870912)) + return ( + (workInProgress.lanes = workInProgress.childLanes = 536870912), + deferHiddenOffscreenComponent( + current, workInProgress, - null !== prevState ? prevState.cachePool : null - ), - null !== prevState - ? pushHiddenContext(workInProgress, prevState) - : reuseHiddenContextOnStack(), - pushOffscreenSuspenseHandler(workInProgress); - else - return ( - (workInProgress.lanes = workInProgress.childLanes = 536870912), - deferHiddenOffscreenComponent( - current, - workInProgress, - null !== prevState ? prevState.baseLanes | renderLanes : renderLanes - ) - ); + null !== prevState ? prevState.baseLanes | renderLanes : renderLanes + ) + ); + workInProgress.memoizedState = { baseLanes: 0, cachePool: null }; + null !== prevState + ? pushHiddenContext(workInProgress, prevState) + : reuseHiddenContextOnStack(); + } + pushOffscreenSuspenseHandler(workInProgress); } else null !== prevState - ? (pushTransition(workInProgress, prevState.cachePool), - pushHiddenContext(workInProgress, prevState), + ? (pushHiddenContext(workInProgress, prevState), reuseSuspenseHandlerOnStack(workInProgress), (workInProgress.memoizedState = null)) - : (null !== current && pushTransition(workInProgress, null), - reuseHiddenContextOnStack(), + : (reuseHiddenContextOnStack(), reuseSuspenseHandlerOnStack(workInProgress)); reconcileChildren(current, workInProgress, nextChildren, renderLanes); return workInProgress.child; } function deferHiddenOffscreenComponent(current, workInProgress, nextBaseLanes) { - var JSCompiler_inline_result = peekCacheFromPool(); - JSCompiler_inline_result = - null === JSCompiler_inline_result - ? null - : { parent: CacheContext._currentValue, pool: JSCompiler_inline_result }; - workInProgress.memoizedState = { - baseLanes: nextBaseLanes, - cachePool: JSCompiler_inline_result - }; - null !== current && pushTransition(workInProgress, null); + workInProgress.memoizedState = { baseLanes: nextBaseLanes, cachePool: null }; reuseHiddenContextOnStack(); pushOffscreenSuspenseHandler(workInProgress); return null; @@ -5572,7 +4880,6 @@ function updateFunctionComponent( renderLanes ) { prepareToReadContext(workInProgress, renderLanes); - markComponentRenderStarted(workInProgress); Component = renderWithHooks( current, workInProgress, @@ -5581,7 +4888,6 @@ function updateFunctionComponent( void 0, renderLanes ); - markComponentRenderStopped(); if (null !== current && !didReceiveUpdate) return ( bailoutHooks(current, workInProgress, renderLanes), @@ -5600,7 +4906,6 @@ function replayFunctionComponent( renderLanes ) { prepareToReadContext(workInProgress, renderLanes); - markComponentRenderStarted(workInProgress); nextProps = renderWithHooksAgain( workInProgress, Component, @@ -5608,7 +4913,6 @@ function replayFunctionComponent( secondArg ); finishRenderingHooks(); - markComponentRenderStopped(); if (null !== current && !didReceiveUpdate) return ( bailoutHooks(current, workInProgress, renderLanes), @@ -5633,8 +4937,7 @@ function updateClassComponent( (nextProps = !0); else if (null === current) { var instance = workInProgress.stateNode, - unresolvedOldProps = workInProgress.memoizedProps, - oldProps = resolveClassComponentProps(Component, unresolvedOldProps); + oldProps = workInProgress.memoizedProps; instance.props = oldProps; var oldContext = instance.context, contextType = Component.contextType, @@ -5643,14 +4946,12 @@ function updateClassComponent( null !== contextType && (nextContext = readContext(contextType)); var getDerivedStateFromProps = Component.getDerivedStateFromProps; - contextType = + (contextType = "function" === typeof getDerivedStateFromProps || - "function" === typeof instance.getSnapshotBeforeUpdate; - unresolvedOldProps = workInProgress.pendingProps !== unresolvedOldProps; - contextType || + "function" === typeof instance.getSnapshotBeforeUpdate) || ("function" !== typeof instance.UNSAFE_componentWillReceiveProps && "function" !== typeof instance.componentWillReceiveProps) || - ((unresolvedOldProps || oldContext !== nextContext) && + ((oldProps !== nextProps || oldContext !== nextContext) && callComponentWillReceiveProps( workInProgress, instance, @@ -5661,9 +4962,8 @@ function updateClassComponent( var oldState = workInProgress.memoizedState; instance.state = oldState; processUpdateQueue(workInProgress, nextProps, instance, renderLanes); - suspendIfUpdateReadFromEntangledAsyncAction(); oldContext = workInProgress.memoizedState; - unresolvedOldProps || oldState !== oldContext || hasForceUpdate + oldProps !== nextProps || oldState !== oldContext || hasForceUpdate ? ("function" === typeof getDerivedStateFromProps && (applyDerivedStateFromProps( workInProgress, @@ -5707,22 +5007,26 @@ function updateClassComponent( instance = workInProgress.stateNode; cloneUpdateQueue(current, workInProgress); nextContext = workInProgress.memoizedProps; - contextType = resolveClassComponentProps(Component, nextContext); + contextType = + workInProgress.type === workInProgress.elementType + ? nextContext + : resolveDefaultProps(workInProgress.type, nextContext); instance.props = contextType; getDerivedStateFromProps = workInProgress.pendingProps; - oldState = instance.context; + var oldContext$jscomp$0 = instance.context; oldContext = Component.contextType; oldProps = emptyContextObject; "object" === typeof oldContext && null !== oldContext && (oldProps = readContext(oldContext)); - unresolvedOldProps = Component.getDerivedStateFromProps; + oldState = Component.getDerivedStateFromProps; (oldContext = - "function" === typeof unresolvedOldProps || + "function" === typeof oldState || "function" === typeof instance.getSnapshotBeforeUpdate) || ("function" !== typeof instance.UNSAFE_componentWillReceiveProps && "function" !== typeof instance.componentWillReceiveProps) || - ((nextContext !== getDerivedStateFromProps || oldState !== oldProps) && + ((nextContext !== getDerivedStateFromProps || + oldContext$jscomp$0 !== oldProps) && callComponentWillReceiveProps( workInProgress, instance, @@ -5730,19 +5034,18 @@ function updateClassComponent( oldProps )); hasForceUpdate = !1; - oldState = workInProgress.memoizedState; - instance.state = oldState; + oldContext$jscomp$0 = workInProgress.memoizedState; + instance.state = oldContext$jscomp$0; processUpdateQueue(workInProgress, nextProps, instance, renderLanes); - suspendIfUpdateReadFromEntangledAsyncAction(); var newState = workInProgress.memoizedState; nextContext !== getDerivedStateFromProps || - oldState !== newState || + oldContext$jscomp$0 !== newState || hasForceUpdate - ? ("function" === typeof unresolvedOldProps && + ? ("function" === typeof oldState && (applyDerivedStateFromProps( workInProgress, Component, - unresolvedOldProps, + oldState, nextProps ), (newState = workInProgress.memoizedState)), @@ -5753,7 +5056,7 @@ function updateClassComponent( Component, contextType, nextProps, - oldState, + oldContext$jscomp$0, newState, oldProps ) || @@ -5775,11 +5078,11 @@ function updateClassComponent( (workInProgress.flags |= 1024)) : ("function" !== typeof instance.componentDidUpdate || (nextContext === current.memoizedProps && - oldState === current.memoizedState) || + oldContext$jscomp$0 === current.memoizedState) || (workInProgress.flags |= 4), "function" !== typeof instance.getSnapshotBeforeUpdate || (nextContext === current.memoizedProps && - oldState === current.memoizedState) || + oldContext$jscomp$0 === current.memoizedState) || (workInProgress.flags |= 1024), (workInProgress.memoizedProps = nextProps), (workInProgress.memoizedState = newState)), @@ -5789,11 +5092,11 @@ function updateClassComponent( (nextProps = contextType)) : ("function" !== typeof instance.componentDidUpdate || (nextContext === current.memoizedProps && - oldState === current.memoizedState) || + oldContext$jscomp$0 === current.memoizedState) || (workInProgress.flags |= 4), "function" !== typeof instance.getSnapshotBeforeUpdate || (nextContext === current.memoizedProps && - oldState === current.memoizedState) || + oldContext$jscomp$0 === current.memoizedState) || (workInProgress.flags |= 1024), (nextProps = !1)); } @@ -5819,11 +5122,10 @@ function finishClassComponent( if (!shouldUpdate && !hasContext) return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); shouldUpdate = workInProgress.stateNode; + ReactCurrentOwner$1.current = workInProgress; hasContext && "function" !== typeof Component.getDerivedStateFromError ? ((Component = null), (profilerStartTime = -1)) - : (markComponentRenderStarted(workInProgress), - (Component = shouldUpdate.render()), - markComponentRenderStopped()); + : (Component = shouldUpdate.render()); workInProgress.flags |= 1; null !== current && hasContext ? ((workInProgress.child = reconcileChildFibers( @@ -5844,7 +5146,7 @@ function finishClassComponent( } var SUSPENDED_MARKER = { dehydrated: null, treeContext: null, retryLane: 0 }; function mountSuspenseOffscreenState(renderLanes) { - return { baseLanes: renderLanes, cachePool: getSuspendedCache() }; + return { baseLanes: renderLanes, cachePool: null }; } function getRemainingWorkInPrimaryTree( current, @@ -5869,258 +5171,112 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { JSCompiler_temp = 0 !== (workInProgress.flags & 32); workInProgress.flags &= -33; if (null === current) { - var nextPrimaryChildren = nextProps.children; + didSuspend = nextProps.children; nextProps = nextProps.fallback; - if (showFallback) - return ( - reuseSuspenseHandlerOnStack(workInProgress), - (showFallback = workInProgress.mode), - (didSuspend = workInProgress.child), - (nextPrimaryChildren = { - mode: "hidden", - children: nextPrimaryChildren - }), - 0 === (showFallback & 1) && null !== didSuspend - ? ((didSuspend.childLanes = 0), - (didSuspend.pendingProps = nextPrimaryChildren), - workInProgress.mode & 2 && - ((didSuspend.actualDuration = 0), - (didSuspend.actualStartTime = -1), - (didSuspend.selfBaseDuration = 0), - (didSuspend.treeBaseDuration = 0))) - : (didSuspend = createFiberFromOffscreen( - nextPrimaryChildren, - showFallback, - 0, - null - )), - (nextProps = createFiberFromFragment( - nextProps, - showFallback, - renderLanes, - null - )), - (didSuspend.return = workInProgress), - (nextProps.return = workInProgress), - (didSuspend.sibling = nextProps), - (workInProgress.child = didSuspend), - (nextPrimaryChildren = workInProgress.child), - (nextPrimaryChildren.memoizedState = - mountSuspenseOffscreenState(renderLanes)), - (nextPrimaryChildren.childLanes = getRemainingWorkInPrimaryTree( - current, - JSCompiler_temp, - renderLanes - )), - (workInProgress.memoizedState = SUSPENDED_MARKER), - nextProps - ); - pushPrimaryTreeSuspenseHandler(workInProgress); - return mountSuspensePrimaryChildren(workInProgress, nextPrimaryChildren); - } - nextPrimaryChildren = current.memoizedState; - if (null !== nextPrimaryChildren && null !== nextPrimaryChildren.dehydrated) { - if (didSuspend) - workInProgress.flags & 256 - ? (pushPrimaryTreeSuspenseHandler(workInProgress), - (workInProgress.flags &= -257), - (workInProgress = retrySuspenseComponentWithoutHydrating( - current, - workInProgress, - renderLanes - ))) - : null !== workInProgress.memoizedState - ? (reuseSuspenseHandlerOnStack(workInProgress), - (workInProgress.child = current.child), - (workInProgress.flags |= 128), - (workInProgress = null)) - : (reuseSuspenseHandlerOnStack(workInProgress), - (nextPrimaryChildren = nextProps.fallback), - (showFallback = workInProgress.mode), - (nextProps = createFiberFromOffscreen( - { mode: "visible", children: nextProps.children }, + if (showFallback) { + reuseSuspenseHandlerOnStack(workInProgress); + showFallback = workInProgress.mode; + var progressedPrimaryFragment = workInProgress.child; + didSuspend = { mode: "hidden", children: didSuspend }; + 0 === (showFallback & 1) && null !== progressedPrimaryFragment + ? ((progressedPrimaryFragment.childLanes = 0), + (progressedPrimaryFragment.pendingProps = didSuspend), + workInProgress.mode & 2 && + ((progressedPrimaryFragment.actualDuration = 0), + (progressedPrimaryFragment.actualStartTime = -1), + (progressedPrimaryFragment.selfBaseDuration = 0), + (progressedPrimaryFragment.treeBaseDuration = 0))) + : (progressedPrimaryFragment = createFiberFromOffscreen( + didSuspend, showFallback, 0, null - )), - (nextPrimaryChildren = createFiberFromFragment( - nextPrimaryChildren, - showFallback, - renderLanes, - null - )), - (nextPrimaryChildren.flags |= 2), - (nextProps.return = workInProgress), - (nextPrimaryChildren.return = workInProgress), - (nextProps.sibling = nextPrimaryChildren), - (workInProgress.child = nextProps), - 0 !== (workInProgress.mode & 1) && - reconcileChildFibers( - workInProgress, - current.child, - null, - renderLanes - ), - (nextProps = workInProgress.child), - (nextProps.memoizedState = mountSuspenseOffscreenState(renderLanes)), - (nextProps.childLanes = getRemainingWorkInPrimaryTree( - current, - JSCompiler_temp, - renderLanes - )), - (workInProgress.memoizedState = SUSPENDED_MARKER), - (workInProgress = nextPrimaryChildren)); - else if ((pushPrimaryTreeSuspenseHandler(workInProgress), shim$1())) - (JSCompiler_temp = shim$1().digest), - (nextProps = Error( - "The server could not finish this Suspense boundary, likely due to an error during server rendering. Switched to client rendering." - )), - (nextProps.stack = ""), - (nextProps.digest = JSCompiler_temp), - (JSCompiler_temp = { value: nextProps, source: null, stack: null }), - null === hydrationErrors - ? (hydrationErrors = [JSCompiler_temp]) - : hydrationErrors.push(JSCompiler_temp), - (workInProgress = retrySuspenseComponentWithoutHydrating( - current, - workInProgress, - renderLanes - )); - else if ( - ((JSCompiler_temp = 0 !== (renderLanes & current.childLanes)), - didReceiveUpdate || JSCompiler_temp) - ) { - JSCompiler_temp = workInProgressRoot; - if (null !== JSCompiler_temp) { - nextProps = renderLanes & -renderLanes; - if (0 !== (nextProps & 42)) nextProps = 1; - else - switch (nextProps) { - case 2: - nextProps = 1; - break; - case 8: - nextProps = 4; - break; - case 32: - nextProps = 16; - break; - case 128: - case 256: - case 512: - case 1024: - case 2048: - case 4096: - case 8192: - case 16384: - case 32768: - case 65536: - case 131072: - case 262144: - case 524288: - case 1048576: - case 2097152: - case 4194304: - case 8388608: - case 16777216: - case 33554432: - nextProps = 64; - break; - case 268435456: - nextProps = 134217728; - break; - default: - nextProps = 0; - } - nextProps = - 0 !== (nextProps & (JSCompiler_temp.suspendedLanes | renderLanes)) - ? 0 - : nextProps; - if (0 !== nextProps && nextProps !== nextPrimaryChildren.retryLane) - throw ( - ((nextPrimaryChildren.retryLane = nextProps), - enqueueConcurrentRenderForLane(current, nextProps), - scheduleUpdateOnFiber(JSCompiler_temp, current, nextProps), - SelectiveHydrationException) - ); - } - shim$1() || renderDidSuspendDelayIfPossible(); - workInProgress = retrySuspenseComponentWithoutHydrating( + )); + nextProps = createFiberFromFragment( + nextProps, + showFallback, + renderLanes, + null + ); + progressedPrimaryFragment.return = workInProgress; + nextProps.return = workInProgress; + progressedPrimaryFragment.sibling = nextProps; + workInProgress.child = progressedPrimaryFragment; + showFallback = workInProgress.child; + showFallback.memoizedState = mountSuspenseOffscreenState(renderLanes); + showFallback.childLanes = getRemainingWorkInPrimaryTree( + current, + JSCompiler_temp, + renderLanes + ); + workInProgress.memoizedState = SUSPENDED_MARKER; + return nextProps; + } + pushPrimaryTreeSuspenseHandler(workInProgress); + return mountSuspensePrimaryChildren(workInProgress, didSuspend); + } + progressedPrimaryFragment = current.memoizedState; + if (null !== progressedPrimaryFragment) { + var dehydrated = progressedPrimaryFragment.dehydrated; + if (null !== dehydrated) + return updateDehydratedSuspenseComponent( current, workInProgress, + didSuspend, + JSCompiler_temp, + nextProps, + dehydrated, + progressedPrimaryFragment, renderLanes ); - } else - shim$1() - ? ((workInProgress.flags |= 128), - (workInProgress.child = current.child), - retryDehydratedSuspenseBoundary.bind(null, current), - shim$1(), - (workInProgress = null)) - : ((workInProgress = mountSuspensePrimaryChildren( - workInProgress, - nextProps.children - )), - (workInProgress.flags |= 4096)); - return workInProgress; } if (showFallback) { reuseSuspenseHandlerOnStack(workInProgress); - nextPrimaryChildren = nextProps.fallback; - showFallback = workInProgress.mode; - didSuspend = current.child; - var currentFallbackChildFragment = didSuspend.sibling, - primaryChildProps = { mode: "hidden", children: nextProps.children }; - 0 === (showFallback & 1) && workInProgress.child !== didSuspend + showFallback = nextProps.fallback; + didSuspend = workInProgress.mode; + progressedPrimaryFragment = current.child; + dehydrated = progressedPrimaryFragment.sibling; + var primaryChildProps = { mode: "hidden", children: nextProps.children }; + 0 === (didSuspend & 1) && workInProgress.child !== progressedPrimaryFragment ? ((nextProps = workInProgress.child), (nextProps.childLanes = 0), (nextProps.pendingProps = primaryChildProps), workInProgress.mode & 2 && ((nextProps.actualDuration = 0), (nextProps.actualStartTime = -1), - (nextProps.selfBaseDuration = didSuspend.selfBaseDuration), - (nextProps.treeBaseDuration = didSuspend.treeBaseDuration)), + (nextProps.selfBaseDuration = + progressedPrimaryFragment.selfBaseDuration), + (nextProps.treeBaseDuration = + progressedPrimaryFragment.treeBaseDuration)), (workInProgress.deletions = null)) - : ((nextProps = createWorkInProgress(didSuspend, primaryChildProps)), - (nextProps.subtreeFlags = didSuspend.subtreeFlags & 31457280)); - null !== currentFallbackChildFragment - ? (nextPrimaryChildren = createWorkInProgress( - currentFallbackChildFragment, - nextPrimaryChildren - )) - : ((nextPrimaryChildren = createFiberFromFragment( - nextPrimaryChildren, + : ((nextProps = createWorkInProgress( + progressedPrimaryFragment, + primaryChildProps + )), + (nextProps.subtreeFlags = + progressedPrimaryFragment.subtreeFlags & 31457280)); + null !== dehydrated + ? (showFallback = createWorkInProgress(dehydrated, showFallback)) + : ((showFallback = createFiberFromFragment( showFallback, + didSuspend, renderLanes, null )), - (nextPrimaryChildren.flags |= 2)); - nextPrimaryChildren.return = workInProgress; + (showFallback.flags |= 2)); + showFallback.return = workInProgress; nextProps.return = workInProgress; - nextProps.sibling = nextPrimaryChildren; + nextProps.sibling = showFallback; workInProgress.child = nextProps; - nextProps = nextPrimaryChildren; - nextPrimaryChildren = workInProgress.child; - showFallback = current.child.memoizedState; - null === showFallback - ? (showFallback = mountSuspenseOffscreenState(renderLanes)) - : ((didSuspend = showFallback.cachePool), - null !== didSuspend - ? ((currentFallbackChildFragment = CacheContext._currentValue), - (didSuspend = - didSuspend.parent !== currentFallbackChildFragment - ? { - parent: currentFallbackChildFragment, - pool: currentFallbackChildFragment - } - : didSuspend)) - : (didSuspend = getSuspendedCache()), - (showFallback = { - baseLanes: showFallback.baseLanes | renderLanes, - cachePool: didSuspend - })); - nextPrimaryChildren.memoizedState = showFallback; - nextPrimaryChildren.childLanes = getRemainingWorkInPrimaryTree( + nextProps = showFallback; + showFallback = workInProgress.child; + didSuspend = current.child.memoizedState; + didSuspend = + null === didSuspend + ? mountSuspenseOffscreenState(renderLanes) + : { baseLanes: didSuspend.baseLanes | renderLanes, cachePool: null }; + showFallback.memoizedState = didSuspend; + showFallback.childLanes = getRemainingWorkInPrimaryTree( current, JSCompiler_temp, renderLanes @@ -6160,8 +5316,13 @@ function mountSuspensePrimaryChildren(workInProgress, primaryChildren) { function retrySuspenseComponentWithoutHydrating( current, workInProgress, - renderLanes + renderLanes, + recoverableError ) { + null !== recoverableError && + (null === hydrationErrors + ? (hydrationErrors = [recoverableError]) + : hydrationErrors.push(recoverableError)); reconcileChildFibers(workInProgress, current.child, null, renderLanes); current = mountSuspensePrimaryChildren( workInProgress, @@ -6171,6 +5332,176 @@ function retrySuspenseComponentWithoutHydrating( workInProgress.memoizedState = null; return current; } +function updateDehydratedSuspenseComponent( + current, + workInProgress, + didSuspend, + didPrimaryChildrenDefer, + nextProps, + suspenseInstance, + suspenseState, + renderLanes +) { + if (didSuspend) { + if (workInProgress.flags & 256) + return ( + pushPrimaryTreeSuspenseHandler(workInProgress), + (workInProgress.flags &= -257), + (didPrimaryChildrenDefer = createCapturedValueFromError( + Error( + "There was an error while hydrating this Suspense boundary. Switched to client rendering." + ) + )), + retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + didPrimaryChildrenDefer + ) + ); + if (null !== workInProgress.memoizedState) + return ( + reuseSuspenseHandlerOnStack(workInProgress), + (workInProgress.child = current.child), + (workInProgress.flags |= 128), + null + ); + reuseSuspenseHandlerOnStack(workInProgress); + suspenseState = nextProps.fallback; + didSuspend = workInProgress.mode; + nextProps = createFiberFromOffscreen( + { mode: "visible", children: nextProps.children }, + didSuspend, + 0, + null + ); + suspenseState = createFiberFromFragment( + suspenseState, + didSuspend, + renderLanes, + null + ); + suspenseState.flags |= 2; + nextProps.return = workInProgress; + suspenseState.return = workInProgress; + nextProps.sibling = suspenseState; + workInProgress.child = nextProps; + 0 !== (workInProgress.mode & 1) && + reconcileChildFibers(workInProgress, current.child, null, renderLanes); + nextProps = workInProgress.child; + nextProps.memoizedState = mountSuspenseOffscreenState(renderLanes); + nextProps.childLanes = getRemainingWorkInPrimaryTree( + current, + didPrimaryChildrenDefer, + renderLanes + ); + workInProgress.memoizedState = SUSPENDED_MARKER; + return suspenseState; + } + pushPrimaryTreeSuspenseHandler(workInProgress); + if (0 === (workInProgress.mode & 1)) + return retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + null + ); + if (shim$1()) + return ( + (didPrimaryChildrenDefer = shim$1().digest), + (suspenseState = Error( + "The server could not finish this Suspense boundary, likely due to an error during server rendering. Switched to client rendering." + )), + (suspenseState.digest = didPrimaryChildrenDefer), + (didPrimaryChildrenDefer = createCapturedValueFromError( + suspenseState, + didPrimaryChildrenDefer, + void 0 + )), + retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + didPrimaryChildrenDefer + ) + ); + didPrimaryChildrenDefer = 0 !== (renderLanes & current.childLanes); + if (didReceiveUpdate || didPrimaryChildrenDefer) { + didPrimaryChildrenDefer = workInProgressRoot; + if (null !== didPrimaryChildrenDefer) { + nextProps = renderLanes & -renderLanes; + if (0 !== (nextProps & 42)) nextProps = 1; + else + switch (nextProps) { + case 2: + nextProps = 1; + break; + case 8: + nextProps = 4; + break; + case 32: + nextProps = 16; + break; + case 128: + case 256: + case 512: + case 1024: + case 2048: + case 4096: + case 8192: + case 16384: + case 32768: + case 65536: + case 131072: + case 262144: + case 524288: + case 1048576: + case 2097152: + case 4194304: + case 8388608: + case 16777216: + case 33554432: + nextProps = 64; + break; + case 268435456: + nextProps = 134217728; + break; + default: + nextProps = 0; + } + nextProps = + 0 !== + (nextProps & (didPrimaryChildrenDefer.suspendedLanes | renderLanes)) + ? 0 + : nextProps; + if (0 !== nextProps && nextProps !== suspenseState.retryLane) + throw ( + ((suspenseState.retryLane = nextProps), + enqueueConcurrentRenderForLane(current, nextProps), + scheduleUpdateOnFiber(didPrimaryChildrenDefer, current, nextProps), + SelectiveHydrationException) + ); + } + shim$1() || renderDidSuspendDelayIfPossible(); + return retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + null + ); + } + if (shim$1()) + return ( + (workInProgress.flags |= 128), + (workInProgress.child = current.child), + retryDehydratedSuspenseBoundary.bind(null, current), + shim$1(), + null + ); + current = mountSuspensePrimaryChildren(workInProgress, nextProps.children); + current.flags |= 4096; + return current; +} function scheduleSuspenseWorkOnFiber(fiber, renderLanes, propagationRoot) { fiber.lanes |= renderLanes; var alternate = fiber.alternate; @@ -6323,7 +5654,6 @@ function attemptEarlyBailoutIfNoScheduledUpdate( switch (workInProgress.tag) { case 3: pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); - pushProvider(workInProgress, CacheContext, current.memoizedState.cache); break; case 27: case 5: @@ -6333,23 +5663,22 @@ function attemptEarlyBailoutIfNoScheduledUpdate( pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); break; case 10: - pushProvider( - workInProgress, - workInProgress.type, - workInProgress.memoizedProps.value - ); + var newValue = workInProgress.memoizedProps.value, + context = workInProgress.type._context; + push(valueCursor, context._currentValue); + context._currentValue = newValue; break; case 12: 0 !== (renderLanes & workInProgress.childLanes) && (workInProgress.flags |= 4); - var stateNode = workInProgress.stateNode; - stateNode.effectDuration = 0; - stateNode.passiveEffectDuration = 0; + newValue = workInProgress.stateNode; + newValue.effectDuration = 0; + newValue.passiveEffectDuration = 0; break; case 13: - stateNode = workInProgress.memoizedState; - if (null !== stateNode) { - if (null !== stateNode.dehydrated) + newValue = workInProgress.memoizedState; + if (null !== newValue) { + if (null !== newValue.dehydrated) return ( pushPrimaryTreeSuspenseHandler(workInProgress), (workInProgress.flags |= 128), @@ -6368,9 +5697,9 @@ function attemptEarlyBailoutIfNoScheduledUpdate( pushPrimaryTreeSuspenseHandler(workInProgress); break; case 19: - stateNode = 0 !== (renderLanes & workInProgress.childLanes); + newValue = 0 !== (renderLanes & workInProgress.childLanes); if (0 !== (current.flags & 128)) { - if (stateNode) + if (newValue) return updateSuspenseListComponent( current, workInProgress, @@ -6378,13 +5707,13 @@ function attemptEarlyBailoutIfNoScheduledUpdate( ); workInProgress.flags |= 128; } - var renderState = workInProgress.memoizedState; - null !== renderState && - ((renderState.rendering = null), - (renderState.tail = null), - (renderState.lastEffect = null)); + context = workInProgress.memoizedState; + null !== context && + ((context.rendering = null), + (context.tail = null), + (context.lastEffect = null)); push(suspenseStackCursor, suspenseStackCursor.current); - if (stateNode) break; + if (newValue) break; else return null; case 22: case 23: @@ -6392,8 +5721,6 @@ function attemptEarlyBailoutIfNoScheduledUpdate( (workInProgress.lanes = 0), updateOffscreenComponent(current, workInProgress, renderLanes) ); - case 24: - pushProvider(workInProgress, CacheContext, current.memoizedState.cache); } return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); } @@ -6419,86 +5746,132 @@ function beginWork(current, workInProgress, renderLanes) { else didReceiveUpdate = !1; workInProgress.lanes = 0; switch (workInProgress.tag) { + case 2: + var Component = workInProgress.type; + resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress); + current = workInProgress.pendingProps; + prepareToReadContext(workInProgress, renderLanes); + var value = renderWithHooks( + null, + workInProgress, + Component, + current, + void 0, + renderLanes + ); + workInProgress.flags |= 1; + "object" === typeof value && + null !== value && + "function" === typeof value.render && + void 0 === value.$$typeof + ? ((workInProgress.tag = 1), + (workInProgress.memoizedState = null), + (workInProgress.updateQueue = null), + (workInProgress.memoizedState = + null !== value.state && void 0 !== value.state + ? value.state + : null), + initializeUpdateQueue(workInProgress), + (value.updater = classComponentUpdater), + (workInProgress.stateNode = value), + (value._reactInternals = workInProgress), + mountClassInstance(workInProgress, Component, current, renderLanes), + (workInProgress = finishClassComponent( + null, + workInProgress, + Component, + !0, + !1, + renderLanes + ))) + : ((workInProgress.tag = 0), + reconcileChildren(null, workInProgress, value, renderLanes), + (workInProgress = workInProgress.child)); + return workInProgress; case 16: - var elementType = workInProgress.elementType; + Component = workInProgress.elementType; a: { resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress); current = workInProgress.pendingProps; - var init = elementType._init; - elementType = init(elementType._payload); - workInProgress.type = elementType; - if ("function" === typeof elementType) - shouldConstruct(elementType) - ? ((current = resolveClassComponentProps(elementType, current)), - (workInProgress.tag = 1), - (workInProgress = updateClassComponent( - null, - workInProgress, - elementType, - current, - renderLanes - ))) - : ((workInProgress.tag = 0), - (workInProgress = updateFunctionComponent( - null, - workInProgress, - elementType, - current, - renderLanes - ))); - else { - if (void 0 !== elementType && null !== elementType) - if ( - ((init = elementType.$$typeof), init === REACT_FORWARD_REF_TYPE) - ) { - workInProgress.tag = 11; - workInProgress = updateForwardRef( - null, - workInProgress, - elementType, - current, - renderLanes - ); - break a; - } else if (init === REACT_MEMO_TYPE) { - workInProgress.tag = 14; - workInProgress = updateMemoComponent( - null, - workInProgress, - elementType, - current, - renderLanes - ); - break a; - } - throw Error( - "Element type is invalid. Received a promise that resolves to: " + - elementType + - ". Lazy element type must resolve to a class or function." - ); + value = Component._init; + Component = value(Component._payload); + workInProgress.type = Component; + value = workInProgress.tag = resolveLazyComponentTag(Component); + current = resolveDefaultProps(Component, current); + switch (value) { + case 0: + workInProgress = updateFunctionComponent( + null, + workInProgress, + Component, + current, + renderLanes + ); + break a; + case 1: + workInProgress = updateClassComponent( + null, + workInProgress, + Component, + current, + renderLanes + ); + break a; + case 11: + workInProgress = updateForwardRef( + null, + workInProgress, + Component, + current, + renderLanes + ); + break a; + case 14: + workInProgress = updateMemoComponent( + null, + workInProgress, + Component, + resolveDefaultProps(Component.type, current), + renderLanes + ); + break a; } + throw Error( + "Element type is invalid. Received a promise that resolves to: " + + Component + + ". Lazy element type must resolve to a class or function." + ); } return workInProgress; case 0: - return updateFunctionComponent( - current, - workInProgress, - workInProgress.type, - workInProgress.pendingProps, - renderLanes + return ( + (Component = workInProgress.type), + (value = workInProgress.pendingProps), + (value = + workInProgress.elementType === Component + ? value + : resolveDefaultProps(Component, value)), + updateFunctionComponent( + current, + workInProgress, + Component, + value, + renderLanes + ) ); case 1: return ( - (elementType = workInProgress.type), - (init = resolveClassComponentProps( - elementType, - workInProgress.pendingProps - )), + (Component = workInProgress.type), + (value = workInProgress.pendingProps), + (value = + workInProgress.elementType === Component + ? value + : resolveDefaultProps(Component, value)), updateClassComponent( current, workInProgress, - elementType, - init, + Component, + value, renderLanes ) ); @@ -6506,25 +5879,18 @@ function beginWork(current, workInProgress, renderLanes) { pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); if (null === current) throw Error("Should have a current fiber. This is a bug in React."); - var nextProps = workInProgress.pendingProps; - init = workInProgress.memoizedState; - elementType = init.element; + value = workInProgress.pendingProps; + Component = workInProgress.memoizedState.element; cloneUpdateQueue(current, workInProgress); - processUpdateQueue(workInProgress, nextProps, null, renderLanes); - nextProps = workInProgress.memoizedState; - var nextCache = nextProps.cache; - pushProvider(workInProgress, CacheContext, nextCache); - nextCache !== init.cache && - propagateContextChange(workInProgress, CacheContext, renderLanes); - suspendIfUpdateReadFromEntangledAsyncAction(); - init = nextProps.element; - init === elementType + processUpdateQueue(workInProgress, value, null, renderLanes); + value = workInProgress.memoizedState.element; + value === Component ? (workInProgress = bailoutOnAlreadyFinishedWork( current, workInProgress, renderLanes )) - : (reconcileChildren(current, workInProgress, init, renderLanes), + : (reconcileChildren(current, workInProgress, value, renderLanes), (workInProgress = workInProgress.child)); return workInProgress; case 26: @@ -6532,27 +5898,9 @@ function beginWork(current, workInProgress, renderLanes) { case 5: return ( pushHostContext(workInProgress), - (elementType = workInProgress.pendingProps.children), - null !== workInProgress.memoizedState && - ((init = renderWithHooks( - current, - workInProgress, - TransitionAwareHostComponent, - null, - null, - renderLanes - )), - (HostTransitionContext._currentValue = init), - didReceiveUpdate && - null !== current && - current.memoizedState.memoizedState !== init && - propagateContextChange( - workInProgress, - HostTransitionContext, - renderLanes - )), + (Component = workInProgress.pendingProps.children), markRef(current, workInProgress), - reconcileChildren(current, workInProgress, elementType, renderLanes), + reconcileChildren(current, workInProgress, Component, renderLanes), workInProgress.child ); case 6: @@ -6565,29 +5913,26 @@ function beginWork(current, workInProgress, renderLanes) { workInProgress, workInProgress.stateNode.containerInfo ), - (elementType = workInProgress.pendingProps), + (Component = workInProgress.pendingProps), null === current ? (workInProgress.child = reconcileChildFibers( workInProgress, null, - elementType, + Component, renderLanes )) - : reconcileChildren( - current, - workInProgress, - elementType, - renderLanes - ), + : reconcileChildren(current, workInProgress, Component, renderLanes), workInProgress.child ); case 11: - return updateForwardRef( - current, - workInProgress, - workInProgress.type, - workInProgress.pendingProps, - renderLanes + return ( + (Component = workInProgress.type), + (value = workInProgress.pendingProps), + (value = + workInProgress.elementType === Component + ? value + : resolveDefaultProps(Component, value)), + updateForwardRef(current, workInProgress, Component, value, renderLanes) ); case 7: return ( @@ -6612,9 +5957,9 @@ function beginWork(current, workInProgress, renderLanes) { case 12: return ( (workInProgress.flags |= 4), - (elementType = workInProgress.stateNode), - (elementType.effectDuration = 0), - (elementType.passiveEffectDuration = 0), + (Component = workInProgress.stateNode), + (Component.effectDuration = 0), + (Component.passiveEffectDuration = 0), reconcileChildren( current, workInProgress, @@ -6625,14 +5970,15 @@ function beginWork(current, workInProgress, renderLanes) { ); case 10: a: { - elementType = workInProgress.type; - init = workInProgress.pendingProps; - nextProps = workInProgress.memoizedProps; - nextCache = init.value; - pushProvider(workInProgress, elementType, nextCache); - if (null !== nextProps) - if (objectIs(nextProps.value, nextCache)) { - if (nextProps.children === init.children) { + Component = workInProgress.type._context; + value = workInProgress.pendingProps; + var oldProps = workInProgress.memoizedProps, + newValue = value.value; + push(valueCursor, Component._currentValue); + Component._currentValue = newValue; + if (null !== oldProps) + if (objectIs(oldProps.value, newValue)) { + if (oldProps.children === value.children) { workInProgress = bailoutOnAlreadyFinishedWork( current, workInProgress, @@ -6641,31 +5987,111 @@ function beginWork(current, workInProgress, renderLanes) { break a; } } else - propagateContextChange(workInProgress, elementType, renderLanes); - reconcileChildren(current, workInProgress, init.children, renderLanes); + for ( + oldProps = workInProgress.child, + null !== oldProps && (oldProps.return = workInProgress); + null !== oldProps; + + ) { + var list = oldProps.dependencies; + if (null !== list) { + newValue = oldProps.child; + for ( + var dependency = list.firstContext; + null !== dependency; + + ) { + if (dependency.context === Component) { + if (1 === oldProps.tag) { + dependency = createUpdate(renderLanes & -renderLanes); + dependency.tag = 2; + var updateQueue = oldProps.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; + } + } + oldProps.lanes |= renderLanes; + dependency = oldProps.alternate; + null !== dependency && (dependency.lanes |= renderLanes); + scheduleContextWorkOnParentPath( + oldProps.return, + renderLanes, + workInProgress + ); + list.lanes |= renderLanes; + break; + } + dependency = dependency.next; + } + } else if (10 === oldProps.tag) + newValue = + oldProps.type === workInProgress.type ? null : oldProps.child; + else if (18 === oldProps.tag) { + newValue = oldProps.return; + if (null === newValue) + throw Error( + "We just came from a parent so we must have had a parent. This is a bug in React." + ); + newValue.lanes |= renderLanes; + list = newValue.alternate; + null !== list && (list.lanes |= renderLanes); + scheduleContextWorkOnParentPath( + newValue, + renderLanes, + workInProgress + ); + newValue = oldProps.sibling; + } else newValue = oldProps.child; + if (null !== newValue) newValue.return = oldProps; + else + for (newValue = oldProps; null !== newValue; ) { + if (newValue === workInProgress) { + newValue = null; + break; + } + oldProps = newValue.sibling; + if (null !== oldProps) { + oldProps.return = newValue.return; + newValue = oldProps; + break; + } + newValue = newValue.return; + } + oldProps = newValue; + } + reconcileChildren(current, workInProgress, value.children, renderLanes); workInProgress = workInProgress.child; } return workInProgress; case 9: return ( - (init = workInProgress.type._context), - (elementType = workInProgress.pendingProps.children), + (value = workInProgress.type), + (Component = workInProgress.pendingProps.children), prepareToReadContext(workInProgress, renderLanes), - (init = readContext(init)), - markComponentRenderStarted(workInProgress), - (elementType = elementType(init)), - markComponentRenderStopped(), + (value = readContext(value)), + (Component = Component(value)), (workInProgress.flags |= 1), - reconcileChildren(current, workInProgress, elementType, renderLanes), + reconcileChildren(current, workInProgress, Component, renderLanes), workInProgress.child ); case 14: - return updateMemoComponent( - current, - workInProgress, - workInProgress.type, - workInProgress.pendingProps, - renderLanes + return ( + (Component = workInProgress.type), + (value = resolveDefaultProps(Component, workInProgress.pendingProps)), + (value = resolveDefaultProps(Component.type, value)), + updateMemoComponent( + current, + workInProgress, + Component, + value, + renderLanes + ) ); case 15: return updateSimpleMemoComponent( @@ -6677,97 +6103,30 @@ function beginWork(current, workInProgress, renderLanes) { ); case 17: return ( - (elementType = workInProgress.type), - (init = resolveClassComponentProps( - elementType, - workInProgress.pendingProps - )), + (Component = workInProgress.type), + (value = workInProgress.pendingProps), + (value = + workInProgress.elementType === Component + ? value + : resolveDefaultProps(Component, value)), resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress), (workInProgress.tag = 1), prepareToReadContext(workInProgress, renderLanes), - constructClassInstance(workInProgress, elementType, init), - mountClassInstance(workInProgress, elementType, init, renderLanes), + constructClassInstance(workInProgress, Component, value), + mountClassInstance(workInProgress, Component, value, renderLanes), finishClassComponent( null, workInProgress, - elementType, + Component, !0, !1, renderLanes ) ); - case 28: - return ( - (elementType = workInProgress.type), - (init = resolveClassComponentProps( - elementType, - workInProgress.pendingProps - )), - resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress), - (workInProgress.tag = 0), - updateFunctionComponent( - null, - workInProgress, - elementType, - init, - renderLanes - ) - ); case 19: return updateSuspenseListComponent(current, workInProgress, renderLanes); case 22: return updateOffscreenComponent(current, workInProgress, renderLanes); - case 24: - return ( - prepareToReadContext(workInProgress, renderLanes), - (elementType = readContext(CacheContext)), - null === current - ? ((init = peekCacheFromPool()), - null === init && - ((init = workInProgressRoot), - (nextProps = createCache()), - (init.pooledCache = nextProps), - nextProps.refCount++, - null !== nextProps && (init.pooledCacheLanes |= renderLanes), - (init = nextProps)), - (workInProgress.memoizedState = { - parent: elementType, - cache: init - }), - initializeUpdateQueue(workInProgress), - pushProvider(workInProgress, CacheContext, init)) - : (0 !== (current.lanes & renderLanes) && - (cloneUpdateQueue(current, workInProgress), - processUpdateQueue(workInProgress, null, null, renderLanes), - suspendIfUpdateReadFromEntangledAsyncAction()), - (init = current.memoizedState), - (nextProps = workInProgress.memoizedState), - init.parent !== elementType - ? ((init = { parent: elementType, cache: elementType }), - (workInProgress.memoizedState = init), - 0 === workInProgress.lanes && - (workInProgress.memoizedState = - workInProgress.updateQueue.baseState = - init), - pushProvider(workInProgress, CacheContext, elementType)) - : ((elementType = nextProps.cache), - pushProvider(workInProgress, CacheContext, elementType), - elementType !== init.cache && - propagateContextChange( - workInProgress, - CacheContext, - renderLanes - ))), - reconcileChildren( - current, - workInProgress, - workInProgress.pendingProps.children, - renderLanes - ), - workInProgress.child - ); - case 29: - throw workInProgress.pendingProps; } throw Error( "Unknown unit of work tag (" + @@ -6785,10 +6144,6 @@ function resetContextDependencies() { currentlyRenderingFiber = null; } -function pushProvider(providerFiber, context, nextValue) { - push(valueCursor, context._currentValue); - context._currentValue = nextValue; -} function popProvider(context) { context._currentValue = valueCursor.current; pop(valueCursor); @@ -6806,74 +6161,6 @@ function scheduleContextWorkOnParentPath(parent, renderLanes, propagationRoot) { parent = parent.return; } } -function propagateContextChange(workInProgress, context, renderLanes) { - var fiber = workInProgress.child; - null !== fiber && (fiber.return = workInProgress); - for (; null !== fiber; ) { - var list = fiber.dependencies; - if (null !== list) { - var nextFiber = fiber.child; - for (var dependency = list.firstContext; null !== dependency; ) { - if (dependency.context === context) { - if (1 === fiber.tag) { - dependency = createUpdate(renderLanes & -renderLanes); - dependency.tag = 2; - var updateQueue = fiber.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; - } - } - fiber.lanes |= renderLanes; - dependency = fiber.alternate; - null !== dependency && (dependency.lanes |= renderLanes); - scheduleContextWorkOnParentPath( - fiber.return, - renderLanes, - workInProgress - ); - list.lanes |= renderLanes; - break; - } - dependency = dependency.next; - } - } else if (10 === fiber.tag) - nextFiber = fiber.type === workInProgress.type ? null : fiber.child; - else if (18 === fiber.tag) { - nextFiber = fiber.return; - if (null === nextFiber) - throw Error( - "We just came from a parent so we must have had a parent. This is a bug in React." - ); - nextFiber.lanes |= renderLanes; - list = nextFiber.alternate; - null !== list && (list.lanes |= renderLanes); - scheduleContextWorkOnParentPath(nextFiber, renderLanes, workInProgress); - nextFiber = fiber.sibling; - } else nextFiber = fiber.child; - if (null !== nextFiber) nextFiber.return = fiber; - else - for (nextFiber = fiber; null !== nextFiber; ) { - if (nextFiber === workInProgress) { - nextFiber = null; - break; - } - fiber = nextFiber.sibling; - if (null !== fiber) { - fiber.return = nextFiber.return; - nextFiber = fiber; - break; - } - nextFiber = nextFiber.return; - } - fiber = nextFiber; - } -} function prepareToReadContext(workInProgress, renderLanes) { currentlyRenderingFiber = workInProgress; lastFullyObservedContext = lastContextDependency = null; @@ -6907,75 +6194,8 @@ function readContextForConsumer(consumer, context) { } else lastContextDependency = lastContextDependency.next = context; return value; } -var AbortControllerLocal = - "undefined" !== typeof AbortController - ? AbortController - : function () { - var listeners = [], - signal = (this.signal = { - aborted: !1, - addEventListener: function (type, listener) { - listeners.push(listener); - } - }); - this.abort = function () { - signal.aborted = !0; - listeners.forEach(function (listener) { - return listener(); - }); - }; - }, - scheduleCallback$1 = Scheduler.unstable_scheduleCallback, - NormalPriority = Scheduler.unstable_NormalPriority, - CacheContext = { - $$typeof: REACT_CONTEXT_TYPE, - Consumer: null, - Provider: null, - _currentValue: null, - _currentValue2: null, - _threadCount: 0 - }; -function createCache() { - return { - controller: new AbortControllerLocal(), - data: new Map(), - refCount: 0 - }; -} -function releaseCache(cache) { - cache.refCount--; - 0 === cache.refCount && - scheduleCallback$1(NormalPriority, function () { - cache.controller.abort(); - }); -} -var prevOnStartTransitionFinish = ReactSharedInternals.S; -ReactSharedInternals.S = function (transition, returnValue) { - "object" === typeof returnValue && - null !== returnValue && - "function" === typeof returnValue.then && - entangleAsyncAction(transition, returnValue); - null !== prevOnStartTransitionFinish && - prevOnStartTransitionFinish(transition, returnValue); -}; -var resumedCache = createCursor(null); -function peekCacheFromPool() { - var cacheResumedFromPreviousRender = resumedCache.current; - return null !== cacheResumedFromPreviousRender - ? cacheResumedFromPreviousRender - : workInProgressRoot.pooledCache; -} -function pushTransition(offscreenWorkInProgress, prevCachePool) { - null === prevCachePool - ? push(resumedCache, resumedCache.current) - : push(resumedCache, prevCachePool.pool); -} -function getSuspendedCache() { - var cacheFromPool = peekCacheFromPool(); - return null === cacheFromPool - ? null - : { parent: CacheContext._currentValue, pool: cacheFromPool }; -} +var ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig; +function handleAsyncAction() {} function scheduleRetryEffect(workInProgress, retryQueue) { null !== retryQueue ? (workInProgress.flags |= 4) @@ -6998,14 +6218,14 @@ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { break; case "collapsed": lastTailNode = renderState.tail; - for (var lastTailNode$92 = null; null !== lastTailNode; ) - null !== lastTailNode.alternate && (lastTailNode$92 = lastTailNode), + for (var lastTailNode$64 = null; null !== lastTailNode; ) + null !== lastTailNode.alternate && (lastTailNode$64 = lastTailNode), (lastTailNode = lastTailNode.sibling); - null === lastTailNode$92 + null === lastTailNode$64 ? hasRenderedATailFallback || null === renderState.tail ? (renderState.tail = null) : (renderState.tail.sibling = null) - : (lastTailNode$92.sibling = null); + : (lastTailNode$64.sibling = null); } } function bubbleProperties(completedWork) { @@ -7017,53 +6237,53 @@ function bubbleProperties(completedWork) { if (didBailout) if (0 !== (completedWork.mode & 2)) { for ( - var treeBaseDuration$94 = completedWork.selfBaseDuration, - child$95 = completedWork.child; - null !== child$95; + var treeBaseDuration$66 = completedWork.selfBaseDuration, + child$67 = completedWork.child; + null !== child$67; ) - (newChildLanes |= child$95.lanes | child$95.childLanes), - (subtreeFlags |= child$95.subtreeFlags & 31457280), - (subtreeFlags |= child$95.flags & 31457280), - (treeBaseDuration$94 += child$95.treeBaseDuration), - (child$95 = child$95.sibling); - completedWork.treeBaseDuration = treeBaseDuration$94; + (newChildLanes |= child$67.lanes | child$67.childLanes), + (subtreeFlags |= child$67.subtreeFlags & 31457280), + (subtreeFlags |= child$67.flags & 31457280), + (treeBaseDuration$66 += child$67.treeBaseDuration), + (child$67 = child$67.sibling); + completedWork.treeBaseDuration = treeBaseDuration$66; } else for ( - treeBaseDuration$94 = completedWork.child; - null !== treeBaseDuration$94; + treeBaseDuration$66 = completedWork.child; + null !== treeBaseDuration$66; ) (newChildLanes |= - treeBaseDuration$94.lanes | treeBaseDuration$94.childLanes), - (subtreeFlags |= treeBaseDuration$94.subtreeFlags & 31457280), - (subtreeFlags |= treeBaseDuration$94.flags & 31457280), - (treeBaseDuration$94.return = completedWork), - (treeBaseDuration$94 = treeBaseDuration$94.sibling); + treeBaseDuration$66.lanes | treeBaseDuration$66.childLanes), + (subtreeFlags |= treeBaseDuration$66.subtreeFlags & 31457280), + (subtreeFlags |= treeBaseDuration$66.flags & 31457280), + (treeBaseDuration$66.return = completedWork), + (treeBaseDuration$66 = treeBaseDuration$66.sibling); else if (0 !== (completedWork.mode & 2)) { - treeBaseDuration$94 = completedWork.actualDuration; - child$95 = completedWork.selfBaseDuration; + treeBaseDuration$66 = completedWork.actualDuration; + child$67 = completedWork.selfBaseDuration; for (var child = completedWork.child; null !== child; ) (newChildLanes |= child.lanes | child.childLanes), (subtreeFlags |= child.subtreeFlags), (subtreeFlags |= child.flags), - (treeBaseDuration$94 += child.actualDuration), - (child$95 += child.treeBaseDuration), + (treeBaseDuration$66 += child.actualDuration), + (child$67 += child.treeBaseDuration), (child = child.sibling); - completedWork.actualDuration = treeBaseDuration$94; - completedWork.treeBaseDuration = child$95; + completedWork.actualDuration = treeBaseDuration$66; + completedWork.treeBaseDuration = child$67; } else for ( - treeBaseDuration$94 = completedWork.child; - null !== treeBaseDuration$94; + treeBaseDuration$66 = completedWork.child; + null !== treeBaseDuration$66; ) (newChildLanes |= - treeBaseDuration$94.lanes | treeBaseDuration$94.childLanes), - (subtreeFlags |= treeBaseDuration$94.subtreeFlags), - (subtreeFlags |= treeBaseDuration$94.flags), - (treeBaseDuration$94.return = completedWork), - (treeBaseDuration$94 = treeBaseDuration$94.sibling); + treeBaseDuration$66.lanes | treeBaseDuration$66.childLanes), + (subtreeFlags |= treeBaseDuration$66.subtreeFlags), + (subtreeFlags |= treeBaseDuration$66.flags), + (treeBaseDuration$66.return = completedWork), + (treeBaseDuration$66 = treeBaseDuration$66.sibling); completedWork.subtreeFlags |= subtreeFlags; completedWork.childLanes = newChildLanes; return didBailout; @@ -7071,7 +6291,7 @@ function bubbleProperties(completedWork) { function completeWork(current, workInProgress, renderLanes) { var newProps = workInProgress.pendingProps; switch (workInProgress.tag) { - case 28: + case 2: case 16: case 15: case 0: @@ -7087,11 +6307,6 @@ function completeWork(current, workInProgress, renderLanes) { case 3: return ( (renderLanes = workInProgress.stateNode), - (newProps = null), - null !== current && (newProps = current.memoizedState.cache), - workInProgress.memoizedState.cache !== newProps && - (workInProgress.flags |= 2048), - popProvider(CacheContext), popHostContainer(), renderLanes.pendingContext && ((renderLanes.context = renderLanes.pendingContext), @@ -7123,8 +6338,8 @@ function completeWork(current, workInProgress, renderLanes) { bubbleProperties(workInProgress); return null; } - renderLanes = rootInstanceStackCursor.current; - current = allocateTag(); + current = rootInstanceStackCursor.current; + renderLanes = allocateTag(); type = getViewConfigForType(type); var updatePayload = diffProperties( null, @@ -7133,37 +6348,40 @@ function completeWork(current, workInProgress, renderLanes) { type.validAttributes ); ReactNativePrivateInterface.UIManager.createView( - current, - type.uiViewClassName, renderLanes, + type.uiViewClassName, + current, updatePayload ); - renderLanes = new ReactNativeFiberHostComponent( - current, + current = new ReactNativeFiberHostComponent( + renderLanes, type, workInProgress ); - instanceCache.set(current, workInProgress); - instanceProps.set(current, newProps); - a: for (current = workInProgress.child; null !== current; ) { - if (5 === current.tag || 6 === current.tag) - renderLanes._children.push(current.stateNode); - else if (4 !== current.tag && null !== current.child) { - current.child.return = current; - current = current.child; + instanceCache.set(renderLanes, workInProgress); + instanceProps.set(renderLanes, newProps); + a: for (renderLanes = workInProgress.child; null !== renderLanes; ) { + if (5 === renderLanes.tag || 6 === renderLanes.tag) + current._children.push(renderLanes.stateNode); + else if (4 !== renderLanes.tag && null !== renderLanes.child) { + renderLanes.child.return = renderLanes; + renderLanes = renderLanes.child; continue; } - if (current === workInProgress) break a; - for (; null === current.sibling; ) { - if (null === current.return || current.return === workInProgress) + if (renderLanes === workInProgress) break a; + for (; null === renderLanes.sibling; ) { + if ( + null === renderLanes.return || + renderLanes.return === workInProgress + ) break a; - current = current.return; + renderLanes = renderLanes.return; } - current.sibling.return = current.return; - current = current.sibling; + renderLanes.sibling.return = renderLanes.return; + renderLanes = renderLanes.sibling; } - workInProgress.stateNode = renderLanes; - finalizeInitialChildren(renderLanes) && (workInProgress.flags |= 4); + workInProgress.stateNode = current; + finalizeInitialChildren(current) && (workInProgress.flags |= 4); } bubbleProperties(workInProgress); workInProgress.flags &= -16777217; @@ -7176,20 +6394,20 @@ function completeWork(current, workInProgress, renderLanes) { throw Error( "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." ); - current = rootInstanceStackCursor.current; + renderLanes = rootInstanceStackCursor.current; if (!contextStackCursor.current.isInAParentText) throw Error( "Text strings must be rendered within a component." ); - renderLanes = allocateTag(); + current = allocateTag(); ReactNativePrivateInterface.UIManager.createView( - renderLanes, - "RCTRawText", current, + "RCTRawText", + renderLanes, { text: newProps } ); - instanceCache.set(renderLanes, workInProgress); - workInProgress.stateNode = renderLanes; + instanceCache.set(current, workInProgress); + workInProgress.stateNode = current; } bubbleProperties(workInProgress); return null; @@ -7239,35 +6457,24 @@ function completeWork(current, workInProgress, renderLanes) { workInProgress ); renderLanes = null !== newProps; - current = null !== current && null !== current.memoizedState; - renderLanes && - ((newProps = workInProgress.child), - (type = null), - null !== newProps.alternate && - null !== newProps.alternate.memoizedState && - null !== newProps.alternate.memoizedState.cachePool && - (type = newProps.alternate.memoizedState.cachePool.pool), - (updatePayload = null), - null !== newProps.memoizedState && - null !== newProps.memoizedState.cachePool && - (updatePayload = newProps.memoizedState.cachePool.pool), - updatePayload !== type && (newProps.flags |= 2048)); - renderLanes !== current && + renderLanes !== (null !== current && null !== current.memoizedState) && renderLanes && (workInProgress.child.flags |= 8192); scheduleRetryEffect(workInProgress, workInProgress.updateQueue); bubbleProperties(workInProgress); 0 !== (workInProgress.mode & 2) && renderLanes && - ((current = workInProgress.child), - null !== current && - (workInProgress.treeBaseDuration -= current.treeBaseDuration)); + ((renderLanes = workInProgress.child), + null !== renderLanes && + (workInProgress.treeBaseDuration -= renderLanes.treeBaseDuration)); return null; case 4: return popHostContainer(), bubbleProperties(workInProgress), null; case 10: return ( - popProvider(workInProgress.type), bubbleProperties(workInProgress), null + popProvider(workInProgress.type._context), + bubbleProperties(workInProgress), + null ); case 17: return bubbleProperties(workInProgress), null; @@ -7293,10 +6500,9 @@ function completeWork(current, workInProgress, renderLanes) { workInProgress.updateQueue = current; scheduleRetryEffect(workInProgress, current); workInProgress.subtreeFlags = 0; - current = renderLanes; - for (renderLanes = workInProgress.child; null !== renderLanes; ) - resetWorkInProgress(renderLanes, current), - (renderLanes = renderLanes.sibling); + for (current = workInProgress.child; null !== current; ) + resetWorkInProgress(current, renderLanes), + (current = current.sibling); push( suspenseStackCursor, (suspenseStackCursor.current & 1) | 2 @@ -7320,9 +6526,9 @@ function completeWork(current, workInProgress, renderLanes) { if ( ((workInProgress.flags |= 128), (newProps = !0), - (current = current.updateQueue), - (workInProgress.updateQueue = current), - scheduleRetryEffect(workInProgress, current), + (renderLanes = current.updateQueue), + (workInProgress.updateQueue = renderLanes), + scheduleRetryEffect(workInProgress, renderLanes), cutOffTailIfNeeded(type, !0), null === type.tail && "hidden" === type.tailMode && @@ -7340,9 +6546,9 @@ function completeWork(current, workInProgress, renderLanes) { type.isBackwards ? ((updatePayload.sibling = workInProgress.child), (workInProgress.child = updatePayload)) - : ((current = type.last), - null !== current - ? (current.sibling = updatePayload) + : ((renderLanes = type.last), + null !== renderLanes + ? (renderLanes.sibling = updatePayload) : (workInProgress.child = updatePayload), (type.last = updatePayload)); } @@ -7353,8 +6559,11 @@ function completeWork(current, workInProgress, renderLanes) { (type.tail = workInProgress.sibling), (type.renderingStartTime = now$1()), (workInProgress.sibling = null), - (current = suspenseStackCursor.current), - push(suspenseStackCursor, newProps ? (current & 1) | 2 : current & 1), + (renderLanes = suspenseStackCursor.current), + push( + suspenseStackCursor, + newProps ? (renderLanes & 1) | 2 : renderLanes & 1 + ), workInProgress ); bubbleProperties(workInProgress); @@ -7378,32 +6587,11 @@ function completeWork(current, workInProgress, renderLanes) { (renderLanes = workInProgress.updateQueue), null !== renderLanes && scheduleRetryEffect(workInProgress, renderLanes.retryQueue), - (renderLanes = null), - null !== current && - null !== current.memoizedState && - null !== current.memoizedState.cachePool && - (renderLanes = current.memoizedState.cachePool.pool), - (newProps = null), - null !== workInProgress.memoizedState && - null !== workInProgress.memoizedState.cachePool && - (newProps = workInProgress.memoizedState.cachePool.pool), - newProps !== renderLanes && (workInProgress.flags |= 2048), - null !== current && pop(resumedCache), null ); case 24: - return ( - (renderLanes = null), - null !== current && (renderLanes = current.memoizedState.cache), - workInProgress.memoizedState.cache !== renderLanes && - (workInProgress.flags |= 2048), - popProvider(CacheContext), - bubbleProperties(workInProgress), - null - ); - case 25: return null; - case 29: + case 25: return null; } throw Error( @@ -7426,7 +6614,6 @@ function unwindWork(current, workInProgress) { ); case 3: return ( - popProvider(CacheContext), popHostContainer(), (current = workInProgress.flags), 0 !== (current & 65536) && 0 === (current & 128) @@ -7460,13 +6647,12 @@ function unwindWork(current, workInProgress) { case 4: return popHostContainer(), null; case 10: - return popProvider(workInProgress.type), null; + return popProvider(workInProgress.type._context), null; case 22: case 23: return ( popSuspenseHandler(workInProgress), popHiddenContext(), - null !== current && pop(resumedCache), (current = workInProgress.flags), current & 65536 ? ((workInProgress.flags = (current & -65537) | 128), @@ -7476,7 +6662,7 @@ function unwindWork(current, workInProgress) { : null ); case 24: - return popProvider(CacheContext), null; + return null; case 25: return null; default: @@ -7486,7 +6672,6 @@ function unwindWork(current, workInProgress) { function unwindInterruptedWork(current, interruptedWork) { switch (interruptedWork.tag) { case 3: - popProvider(CacheContext); popHostContainer(); break; case 26: @@ -7504,16 +6689,11 @@ function unwindInterruptedWork(current, interruptedWork) { pop(suspenseStackCursor); break; case 10: - popProvider(interruptedWork.type); + popProvider(interruptedWork.type._context); break; case 22: case 23: - popSuspenseHandler(interruptedWork); - popHiddenContext(); - null !== current && pop(resumedCache); - break; - case 24: - popProvider(CacheContext); + popSuspenseHandler(interruptedWork), popHiddenContext(); } } var offscreenSubtreeIsHidden = !1, @@ -7526,10 +6706,7 @@ function shouldProfile(current) { return 0 !== (current.mode & 2) && 0 !== (executionContext & 4); } function callComponentWillUnmountWithTimer(current, instance) { - instance.props = resolveClassComponentProps( - current.type, - current.memoizedProps - ); + instance.props = current.memoizedProps; instance.state = current.memoizedState; if (shouldProfile(current)) try { @@ -7596,8 +6773,8 @@ function safelyDetachRef(current, nearestMountedAncestor) { recordLayoutEffectDuration(current); } else ref(null); - } catch (error$119) { - captureCommitPhaseError(current, nearestMountedAncestor, error$119); + } catch (error$84) { + captureCommitPhaseError(current, nearestMountedAncestor, error$84); } else ref.current = null; } @@ -7631,13 +6808,13 @@ function commitBeforeMutationEffects(root, firstChild) { break; case 1: if (0 !== (flags & 1024) && null !== current) { - var prevState = current.memoizedState, + var prevProps = current.memoizedProps, + prevState = current.memoizedState, instance = root.stateNode, snapshot = instance.getSnapshotBeforeUpdate( - resolveClassComponentProps( - root.type, - current.memoizedProps - ), + root.elementType === root.type + ? prevProps + : resolveDefaultProps(root.type, prevProps), prevState ); instance.__reactInternalSnapshotBeforeUpdate = snapshot; @@ -7688,65 +6865,26 @@ function commitHookEffectListUnmount( destroy = inst.destroy; void 0 !== destroy && ((inst.destroy = void 0), - 0 !== (flags & 8) - ? null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markComponentPassiveEffectUnmountStarted && - injectedProfilingHooks.markComponentPassiveEffectUnmountStarted( - finishedWork - ) - : 0 !== (flags & 4) && - markComponentLayoutEffectUnmountStarted(finishedWork), - safelyCallDestroy(finishedWork, nearestMountedAncestor, destroy), - 0 !== (flags & 8) - ? null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markComponentPassiveEffectUnmountStopped && - injectedProfilingHooks.markComponentPassiveEffectUnmountStopped() - : 0 !== (flags & 4) && markComponentLayoutEffectUnmountStopped()); + safelyCallDestroy(finishedWork, nearestMountedAncestor, destroy)); } effect = effect.next; } while (effect !== updateQueue); } } function commitHookEffectListMount(flags, finishedWork) { - var updateQueue = finishedWork.updateQueue; - updateQueue = null !== updateQueue ? updateQueue.lastEffect : null; - if (null !== updateQueue) { - var effect = (updateQueue = updateQueue.next); + finishedWork = finishedWork.updateQueue; + finishedWork = null !== finishedWork ? finishedWork.lastEffect : null; + if (null !== finishedWork) { + var effect = (finishedWork = finishedWork.next); do { if ((effect.tag & flags) === flags) { - 0 !== (flags & 8) - ? null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markComponentPassiveEffectMountStarted && - injectedProfilingHooks.markComponentPassiveEffectMountStarted( - finishedWork - ) - : 0 !== (flags & 4) && - null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markComponentLayoutEffectMountStarted && - injectedProfilingHooks.markComponentLayoutEffectMountStarted( - finishedWork - ); - var create$120 = effect.create, + var create$85 = effect.create, inst = effect.inst; - create$120 = create$120(); - inst.destroy = create$120; - 0 !== (flags & 8) - ? null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markComponentPassiveEffectMountStopped && - injectedProfilingHooks.markComponentPassiveEffectMountStopped() - : 0 !== (flags & 4) && - null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markComponentLayoutEffectMountStopped && - injectedProfilingHooks.markComponentLayoutEffectMountStopped(); + create$85 = create$85(); + inst.destroy = create$85; } effect = effect.next; - } while (effect !== updateQueue); + } while (effect !== finishedWork); } } function commitHookLayoutEffects(finishedWork, hookFlags) { @@ -7761,8 +6899,8 @@ function commitHookLayoutEffects(finishedWork, hookFlags) { } else try { commitHookEffectListMount(hookFlags, finishedWork); - } catch (error$122) { - captureCommitPhaseError(finishedWork, finishedWork.return, error$122); + } catch (error$87) { + captureCommitPhaseError(finishedWork, finishedWork.return, error$87); } } function commitClassCallbacks(finishedWork) { @@ -7842,18 +6980,18 @@ function commitLayoutEffectOnFiber(finishedRoot, current, finishedWork) { } else try { finishedRoot.componentDidMount(); - } catch (error$123) { + } catch (error$88) { captureCommitPhaseError( finishedWork, finishedWork.return, - error$123 + error$88 ); } else { - var prevProps = resolveClassComponentProps( - finishedWork.type, - current.memoizedProps - ); + var prevProps = + finishedWork.elementType === finishedWork.type + ? current.memoizedProps + : resolveDefaultProps(finishedWork.type, current.memoizedProps); current = current.memoizedState; if (shouldProfile(finishedWork)) { try { @@ -7863,11 +7001,11 @@ function commitLayoutEffectOnFiber(finishedRoot, current, finishedWork) { current, finishedRoot.__reactInternalSnapshotBeforeUpdate ); - } catch (error$124) { + } catch (error$89) { captureCommitPhaseError( finishedWork, finishedWork.return, - error$124 + error$89 ); } recordLayoutEffectDuration(finishedWork); @@ -7878,11 +7016,11 @@ function commitLayoutEffectOnFiber(finishedRoot, current, finishedWork) { current, finishedRoot.__reactInternalSnapshotBeforeUpdate ); - } catch (error$125) { + } catch (error$90) { captureCommitPhaseError( finishedWork, finishedWork.return, - error$125 + error$90 ); } } @@ -8181,8 +7319,7 @@ function commitDeletionEffectsOnFiber( destroy )) : 0 !== (tag & 4) && - (markComponentLayoutEffectUnmountStarted(deletedFiber), - shouldProfile(deletedFiber) + (shouldProfile(deletedFiber) ? (startLayoutEffectTimer(), (inst.destroy = void 0), safelyCallDestroy( @@ -8196,8 +7333,7 @@ function commitDeletionEffectsOnFiber( deletedFiber, nearestMountedAncestor, destroy - )), - markComponentLayoutEffectUnmountStopped())); + )))); prevHostParentIsContainer = prevHostParentIsContainer.next; } while (prevHostParentIsContainer !== prevHostParent); } @@ -8346,7 +7482,7 @@ function recursivelyTraverseMutationEffects(root$jscomp$0, parentFiber) { captureCommitPhaseError(childToDelete, parentFiber, error); } } - if (parentFiber.subtreeFlags & 13878) + if (parentFiber.subtreeFlags & 12854) for (parentFiber = parentFiber.child; null !== parentFiber; ) commitMutationEffectsOnFiber(parentFiber, root$jscomp$0), (parentFiber = parentFiber.sibling); @@ -8372,22 +7508,22 @@ function commitMutationEffectsOnFiber(finishedWork, root) { try { startLayoutEffectTimer(), commitHookEffectListUnmount(5, finishedWork, finishedWork.return); - } catch (error$134) { + } catch (error$99) { captureCommitPhaseError( finishedWork, finishedWork.return, - error$134 + error$99 ); } recordLayoutEffectDuration(finishedWork); } else try { commitHookEffectListUnmount(5, finishedWork, finishedWork.return); - } catch (error$135) { + } catch (error$100) { captureCommitPhaseError( finishedWork, finishedWork.return, - error$135 + error$100 ); } } @@ -8419,6 +7555,7 @@ function commitMutationEffectsOnFiber(finishedWork, root) { if (flags & 4 && ((flags = finishedWork.stateNode), null != flags)) { var newProps = finishedWork.memoizedProps; current = null !== current ? current.memoizedProps : newProps; + finishedWork.updateQueue = null; try { var viewConfig = flags.viewConfig; instanceProps.set(flags._nativeTag, newProps); @@ -8434,8 +7571,8 @@ function commitMutationEffectsOnFiber(finishedWork, root) { viewConfig.uiViewClassName, updatePayload ); - } catch (error$138) { - captureCommitPhaseError(finishedWork, finishedWork.return, error$138); + } catch (error$103) { + captureCommitPhaseError(finishedWork, finishedWork.return, error$103); } } break; @@ -8455,8 +7592,8 @@ function commitMutationEffectsOnFiber(finishedWork, root) { "RCTRawText", { text: current } ); - } catch (error$139) { - captureCommitPhaseError(finishedWork, finishedWork.return, error$139); + } catch (error$104) { + captureCommitPhaseError(finishedWork, finishedWork.return, error$104); } } break; @@ -8567,11 +7704,11 @@ function commitMutationEffectsOnFiber(finishedWork, root) { if (null === current) try { throw Error("Not yet implemented."); - } catch (error$128) { + } catch (error$93) { captureCommitPhaseError( finishedWork, finishedWork.return, - error$128 + error$93 ); } } else if ( @@ -8645,12 +7782,12 @@ function commitReconciliationEffects(finishedWork) { break; case 3: case 4: - var parent$129 = JSCompiler_inline_result.stateNode.containerInfo, - before$130 = getHostSibling(finishedWork); + var parent$94 = JSCompiler_inline_result.stateNode.containerInfo, + before$95 = getHostSibling(finishedWork); insertOrAppendPlacementNodeIntoContainer( finishedWork, - before$130, - parent$129 + before$95, + parent$94 ); break; default: @@ -8836,170 +7973,65 @@ function commitHookPassiveMountEffects(finishedWork, hookFlags) { } else try { commitHookEffectListMount(hookFlags, finishedWork); - } catch (error$143) { - captureCommitPhaseError(finishedWork, finishedWork.return, error$143); + } catch (error$108) { + captureCommitPhaseError(finishedWork, finishedWork.return, error$108); } } -function commitOffscreenPassiveMountEffects(current, finishedWork) { - var previousCache = null; - null !== current && - null !== current.memoizedState && - null !== current.memoizedState.cachePool && - (previousCache = current.memoizedState.cachePool.pool); - current = null; - null !== finishedWork.memoizedState && - null !== finishedWork.memoizedState.cachePool && - (current = finishedWork.memoizedState.cachePool.pool); - current !== previousCache && - (null != current && current.refCount++, - null != previousCache && releaseCache(previousCache)); -} -function commitCachePassiveMountEffect(current, finishedWork) { - current = null; - null !== finishedWork.alternate && - (current = finishedWork.alternate.memoizedState.cache); - finishedWork = finishedWork.memoizedState.cache; - finishedWork !== current && - (finishedWork.refCount++, null != current && releaseCache(current)); -} -function recursivelyTraversePassiveMountEffects( - root, - parentFiber, - committedLanes, - committedTransitions -) { +function recursivelyTraversePassiveMountEffects(root, parentFiber) { if (parentFiber.subtreeFlags & 10256) for (parentFiber = parentFiber.child; null !== parentFiber; ) - commitPassiveMountOnFiber( - root, - parentFiber, - committedLanes, - committedTransitions - ), + commitPassiveMountOnFiber(root, parentFiber), (parentFiber = parentFiber.sibling); } -function commitPassiveMountOnFiber( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions -) { +function commitPassiveMountOnFiber(finishedRoot, finishedWork) { var flags = finishedWork.flags; switch (finishedWork.tag) { case 0: case 11: case 15: - recursivelyTraversePassiveMountEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - ); + recursivelyTraversePassiveMountEffects(finishedRoot, finishedWork); flags & 2048 && commitHookPassiveMountEffects(finishedWork, 9); break; case 3: - recursivelyTraversePassiveMountEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - ); - flags & 2048 && - ((finishedRoot = null), - null !== finishedWork.alternate && - (finishedRoot = finishedWork.alternate.memoizedState.cache), - (finishedWork = finishedWork.memoizedState.cache), - finishedWork !== finishedRoot && - (finishedWork.refCount++, - null != finishedRoot && releaseCache(finishedRoot))); + recursivelyTraversePassiveMountEffects(finishedRoot, finishedWork); break; case 23: break; case 22: - var instance = finishedWork.stateNode; + flags = finishedWork.stateNode; null !== finishedWork.memoizedState - ? instance._visibility & 4 - ? recursivelyTraversePassiveMountEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - ) - : finishedWork.mode & 1 - ? recursivelyTraverseAtomicPassiveEffects(finishedRoot, finishedWork) - : ((instance._visibility |= 4), - recursivelyTraversePassiveMountEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - )) - : instance._visibility & 4 - ? recursivelyTraversePassiveMountEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - ) - : ((instance._visibility |= 4), + ? flags._visibility & 4 + ? recursivelyTraversePassiveMountEffects(finishedRoot, finishedWork) + : finishedWork.mode & 1 || + ((flags._visibility |= 4), + recursivelyTraversePassiveMountEffects(finishedRoot, finishedWork)) + : flags._visibility & 4 + ? recursivelyTraversePassiveMountEffects(finishedRoot, finishedWork) + : ((flags._visibility |= 4), recursivelyTraverseReconnectPassiveEffects( finishedRoot, - finishedWork, - committedLanes, - committedTransitions, - 0 !== (finishedWork.subtreeFlags & 10256) + finishedWork )); - flags & 2048 && - commitOffscreenPassiveMountEffects( - finishedWork.alternate, - finishedWork - ); break; case 24: - recursivelyTraversePassiveMountEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - ); - flags & 2048 && - commitCachePassiveMountEffect(finishedWork.alternate, finishedWork); + recursivelyTraversePassiveMountEffects(finishedRoot, finishedWork); break; default: - recursivelyTraversePassiveMountEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions - ); + recursivelyTraversePassiveMountEffects(finishedRoot, finishedWork); } } function recursivelyTraverseReconnectPassiveEffects( finishedRoot$jscomp$0, - parentFiber, - committedLanes$jscomp$0, - committedTransitions$jscomp$0, - includeWorkInProgressEffects + parentFiber ) { - includeWorkInProgressEffects = - includeWorkInProgressEffects && 0 !== (parentFiber.subtreeFlags & 10256); for (parentFiber = parentFiber.child; null !== parentFiber; ) { var finishedRoot = finishedRoot$jscomp$0, - finishedWork = parentFiber, - committedLanes = committedLanes$jscomp$0, - committedTransitions = committedTransitions$jscomp$0, - flags = finishedWork.flags; + finishedWork = parentFiber; switch (finishedWork.tag) { case 0: case 11: case 15: - recursivelyTraverseReconnectPassiveEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions, - includeWorkInProgressEffects - ); + recursivelyTraverseReconnectPassiveEffects(finishedRoot, finishedWork); commitHookPassiveMountEffects(finishedWork, 8); break; case 23: @@ -9009,93 +8041,30 @@ function recursivelyTraverseReconnectPassiveEffects( null !== finishedWork.memoizedState ? instance._visibility & 4 ? recursivelyTraverseReconnectPassiveEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions, - includeWorkInProgressEffects - ) - : finishedWork.mode & 1 - ? recursivelyTraverseAtomicPassiveEffects( finishedRoot, finishedWork ) - : ((instance._visibility |= 4), + : finishedWork.mode & 1 || + ((instance._visibility |= 4), recursivelyTraverseReconnectPassiveEffects( finishedRoot, - finishedWork, - committedLanes, - committedTransitions, - includeWorkInProgressEffects + finishedWork )) : ((instance._visibility |= 4), recursivelyTraverseReconnectPassiveEffects( finishedRoot, - finishedWork, - committedLanes, - committedTransitions, - includeWorkInProgressEffects + finishedWork )); - includeWorkInProgressEffects && - flags & 2048 && - commitOffscreenPassiveMountEffects( - finishedWork.alternate, - finishedWork - ); break; case 24: - recursivelyTraverseReconnectPassiveEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions, - includeWorkInProgressEffects - ); - includeWorkInProgressEffects && - flags & 2048 && - commitCachePassiveMountEffect(finishedWork.alternate, finishedWork); + recursivelyTraverseReconnectPassiveEffects(finishedRoot, finishedWork); break; default: - recursivelyTraverseReconnectPassiveEffects( - finishedRoot, - finishedWork, - committedLanes, - committedTransitions, - includeWorkInProgressEffects - ); + recursivelyTraverseReconnectPassiveEffects(finishedRoot, finishedWork); } parentFiber = parentFiber.sibling; } } -function recursivelyTraverseAtomicPassiveEffects( - finishedRoot$jscomp$0, - parentFiber -) { - if (parentFiber.subtreeFlags & 10256) - for (parentFiber = parentFiber.child; null !== parentFiber; ) { - var finishedRoot = finishedRoot$jscomp$0, - finishedWork = parentFiber, - flags = finishedWork.flags; - switch (finishedWork.tag) { - case 22: - recursivelyTraverseAtomicPassiveEffects(finishedRoot, finishedWork); - flags & 2048 && - commitOffscreenPassiveMountEffects( - finishedWork.alternate, - finishedWork - ); - break; - case 24: - recursivelyTraverseAtomicPassiveEffects(finishedRoot, finishedWork); - flags & 2048 && - commitCachePassiveMountEffect(finishedWork.alternate, finishedWork); - break; - default: - recursivelyTraverseAtomicPassiveEffects(finishedRoot, finishedWork); - } - parentFiber = parentFiber.sibling; - } -} var suspenseyCommitFlag = 8192; function recursivelyAccumulateSuspenseyCommit(parentFiber) { if (parentFiber.subtreeFlags & suspenseyCommitFlag) @@ -9107,9 +8076,10 @@ function accumulateSuspenseyCommitOnFiber(fiber) { switch (fiber.tag) { case 26: recursivelyAccumulateSuspenseyCommit(fiber); - fiber.flags & suspenseyCommitFlag && - null !== fiber.memoizedState && - shim(); + if (fiber.flags & suspenseyCommitFlag && null !== fiber.memoizedState) + throw Error( + "The current renderer does not support Resources. This error is likely caused by a bug in React. Please file an issue." + ); break; case 5: recursivelyAccumulateSuspenseyCommit(fiber); @@ -9253,29 +8223,16 @@ function commitPassiveUnmountEffectsInsideOfDeletedTree_begin( case 11: case 15: commitHookPassiveUnmountEffects(fiber, nearestMountedAncestor, 8); - break; - case 23: - case 22: - if ( - null !== fiber.memoizedState && - null !== fiber.memoizedState.cachePool - ) { - var cache = fiber.memoizedState.cachePool.pool; - null != cache && cache.refCount++; - } - break; - case 24: - releaseCache(fiber.memoizedState.cache); } - cache = fiber.child; - if (null !== cache) (cache.return = fiber), (nextEffect = cache); + var child = fiber.child; + if (null !== child) (child.return = fiber), (nextEffect = child); else a: for (fiber = deletedSubtreeRoot; null !== nextEffect; ) { - cache = nextEffect; - var sibling = cache.sibling, - returnFiber = cache.return; - detachFiberAfterEffects(cache); - if (cache === fiber) { + child = nextEffect; + var sibling = child.sibling, + returnFiber = child.return; + detachFiberAfterEffects(child); + if (child === fiber) { nextEffect = null; break a; } @@ -9288,17 +8245,10 @@ function commitPassiveUnmountEffectsInsideOfDeletedTree_begin( } } } -var DefaultAsyncDispatcher = { - getCacheForType: function (resourceType) { - var cache = readContext(CacheContext), - cacheForType = cache.data.get(resourceType); - void 0 === cacheForType && - ((cacheForType = resourceType()), - cache.data.set(resourceType, cacheForType)); - return cacheForType; - } - }, - PossiblyWeakMap = "function" === typeof WeakMap ? WeakMap : Map, +var PossiblyWeakMap = "function" === typeof WeakMap ? WeakMap : Map, + ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, + ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner, + ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig, executionContext = 0, workInProgressRoot = null, workInProgress = null, @@ -9308,6 +8258,7 @@ var DefaultAsyncDispatcher = { workInProgressRootDidAttachPingListener = !1, entangledRenderLanes = 0, workInProgressRootExitStatus = 0, + workInProgressRootFatalError = null, workInProgressRootSkippedLanes = 0, workInProgressRootInterleavedUpdatedLanes = 0, workInProgressRootPingedLanes = 0, @@ -9315,30 +8266,32 @@ var DefaultAsyncDispatcher = { workInProgressRootConcurrentErrors = null, workInProgressRootRecoverableErrors = null, workInProgressRootDidIncludeRecursiveRenderUpdate = !1, - didIncludeCommitPhaseUpdate = !1, globalMostRecentFallbackTime = 0, workInProgressRootRenderTargetTime = Infinity, workInProgressTransitions = null, + hasUncaughtError = !1, + firstUncaughtError = null, legacyErrorBoundariesThatAlreadyFailed = null, rootDoesHavePassiveEffects = !1, rootWithPendingPassiveEffects = null, pendingPassiveEffectsLanes = 0, pendingPassiveProfilerEffects = [], - pendingPassiveEffectsRemainingLanes = 0, - pendingPassiveTransitions = null, nestedUpdateCount = 0, rootWithNestedUpdates = null; function requestUpdateLane(fiber) { if (0 === (fiber.mode & 1)) return 2; if (0 !== (executionContext & 2) && 0 !== workInProgressRootRenderLanes) return workInProgressRootRenderLanes & -workInProgressRootRenderLanes; - if (null !== ReactSharedInternals.T) + fiber = ReactCurrentBatchConfig$1.transition; + null !== fiber && fiber._callbacks.add(handleAsyncAction); + if (null !== fiber) return ( - (fiber = currentEntangledLane), - 0 !== fiber ? fiber : requestTransitionLane() + 0 === currentEventTransitionLane && + (currentEventTransitionLane = claimNextTransitionLane()), + currentEventTransitionLane ); - fiber = 0 !== currentUpdatePriority ? currentUpdatePriority : 32; - return fiber; + fiber = currentUpdatePriority; + return 0 !== fiber ? fiber : 32; } function requestDeferredLane() { 0 === workInProgressDeferredLane && @@ -9361,7 +8314,7 @@ function scheduleUpdateOnFiber(root, fiber, lane) { workInProgressRootRenderLanes, workInProgressDeferredLane ); - markRootUpdated(root, lane); + markRootUpdated$1(root, lane); if (0 === (executionContext & 2) || root !== workInProgressRoot) isDevToolsPresent && addFiberToLanesMap(root, fiber, lane), root === workInProgressRoot && @@ -9416,24 +8369,22 @@ function performConcurrentWorkOnRoot(root, didTimeout) { root, renderWasConcurrent ); - if ( - 0 !== errorRetryLanes && + 0 !== errorRetryLanes && ((lanes = errorRetryLanes), (exitStatus = recoverFromConcurrentError( root, renderWasConcurrent, errorRetryLanes - )), - (renderWasConcurrent = !1), - 2 !== exitStatus) - ) - continue; - } - if (1 === exitStatus) { - prepareFreshStack(root, 0); - markRootSuspended(root, lanes, 0); - break; + ))); } + if (1 === exitStatus) + throw ( + ((originalCallbackNode = workInProgressRootFatalError), + prepareFreshStack(root, 0), + markRootSuspended(root, lanes, 0), + ensureRootIsScheduled(root), + originalCallbackNode) + ); root.finishedWork = didTimeout; root.finishedLanes = lanes; a: { @@ -9453,8 +8404,6 @@ function performConcurrentWorkOnRoot(root, didTimeout) { } break; case 2: - workInProgressRootRecoverableErrors = null; - break; case 3: case 5: break; @@ -9515,10 +8464,13 @@ function recoverFromConcurrentError( originallyAttemptedLanes, errorRetryLanes ) { - var errorsFromFirstAttempt = workInProgressRootConcurrentErrors; + var errorsFromFirstAttempt = workInProgressRootConcurrentErrors, + JSCompiler_inline_result; + (JSCompiler_inline_result = root.current.memoizedState.isDehydrated) && + (prepareFreshStack(root, errorRetryLanes).flags |= 256); errorRetryLanes = renderRootSync(root, errorRetryLanes); if (2 !== errorRetryLanes) { - if (workInProgressRootDidAttachPingListener) + if (workInProgressRootDidAttachPingListener && !JSCompiler_inline_result) return ( (root.errorRecoveryDisabledLanes |= originallyAttemptedLanes), (workInProgressRootInterleavedUpdatedLanes |= originallyAttemptedLanes), @@ -9547,9 +8499,7 @@ function commitRootWhenReady( lanes, spawnedLane ) { - lanes = finishedWork.subtreeFlags; - (lanes & 8192 || 16785408 === (lanes & 16785408)) && - accumulateSuspenseyCommitOnFiber(finishedWork); + 0 === (lanes & 42) && accumulateSuspenseyCommitOnFiber(finishedWork); commitRoot( root, recoverableErrors, @@ -9592,15 +8542,6 @@ function isRenderConsistentWithExternalStores(finishedWork) { } return !0; } -function markRootUpdated(root, updatedLanes) { - root.pendingLanes |= updatedLanes; - 268435456 !== updatedLanes && - ((root.suspendedLanes = 0), (root.pingedLanes = 0)); - executionContext & 2 - ? (workInProgressRootDidIncludeRecursiveRenderUpdate = !0) - : executionContext & 4 && (didIncludeCommitPhaseUpdate = !0); - throwIfInfiniteUpdateLoopDetected(); -} function markRootSuspended(root, suspendedLanes, spawnedLane) { suspendedLanes &= ~workInProgressRootPingedLanes; suspendedLanes &= ~workInProgressRootInterleavedUpdatedLanes; @@ -9611,60 +8552,14 @@ function markRootSuspended(root, suspendedLanes, spawnedLane) { 0 < lanes; ) { - var index$11 = 31 - clz32(lanes), - lane = 1 << index$11; - expirationTimes[index$11] = -1; + var index$6 = 31 - clz32(lanes), + lane = 1 << index$6; + expirationTimes[index$6] = -1; lanes &= ~lane; } 0 !== spawnedLane && markSpawnedDeferredLane(root, spawnedLane, suspendedLanes); } -function performSyncWorkOnRoot(root, lanes) { - if (0 !== (executionContext & 6)) - throw Error("Should not already be working."); - if (flushPassiveEffects()) return ensureRootIsScheduled(root), null; - currentUpdateIsNested = nestedUpdateScheduled; - nestedUpdateScheduled = !1; - var exitStatus = renderRootSync(root, lanes); - if (0 !== root.tag && 2 === exitStatus) { - var originallyAttemptedLanes = lanes, - errorRetryLanes = getLanesToRetrySynchronouslyOnError( - root, - originallyAttemptedLanes - ); - 0 !== errorRetryLanes && - ((lanes = errorRetryLanes), - (exitStatus = recoverFromConcurrentError( - root, - originallyAttemptedLanes, - errorRetryLanes - ))); - } - if (1 === exitStatus) - return ( - prepareFreshStack(root, 0), - markRootSuspended(root, lanes, 0), - ensureRootIsScheduled(root), - null - ); - if (6 === exitStatus) - return ( - markRootSuspended(root, lanes, workInProgressDeferredLane), - ensureRootIsScheduled(root), - null - ); - root.finishedWork = root.current.alternate; - root.finishedLanes = lanes; - commitRoot( - root, - workInProgressRootRecoverableErrors, - workInProgressTransitions, - workInProgressRootDidIncludeRecursiveRenderUpdate, - workInProgressDeferredLane - ); - ensureRootIsScheduled(root); - return null; -} function resetWorkInProgressStack() { if (null !== workInProgress) { if (0 === workInProgressSuspendedReason) @@ -9698,11 +8593,12 @@ function prepareFreshStack(root, lanes) { workInProgressSuspendedReason = 0; workInProgressThrownValue = null; workInProgressRootDidAttachPingListener = !1; + workInProgressRootExitStatus = 0; + workInProgressRootFatalError = null; workInProgressDeferredLane = workInProgressRootPingedLanes = workInProgressRootInterleavedUpdatedLanes = workInProgressRootSkippedLanes = - workInProgressRootExitStatus = 0; workInProgressRootRecoverableErrors = workInProgressRootConcurrentErrors = null; @@ -9715,9 +8611,9 @@ function prepareFreshStack(root, lanes) { 0 < allEntangledLanes; ) { - var index$9 = 31 - clz32(allEntangledLanes), - lane = 1 << index$9; - lanes |= root[index$9]; + var index$4 = 31 - clz32(allEntangledLanes), + lane = 1 << index$4; + lanes |= root[index$4]; allEntangledLanes &= ~lane; } entangledRenderLanes = lanes; @@ -9726,82 +8622,47 @@ function prepareFreshStack(root, lanes) { } function handleThrow(root, thrownValue) { currentlyRenderingFiber$1 = null; - ReactSharedInternals.H = ContextOnlyDispatcher; - if (thrownValue === SuspenseException) { - thrownValue = getSuspendedThenable(); - var handler = suspenseHandlerStackCursor.current; - workInProgressSuspendedReason = - (null !== handler && - ((workInProgressRootRenderLanes & 4194176) === - workInProgressRootRenderLanes - ? null !== shellBoundary - : ((workInProgressRootRenderLanes & 62914560) !== - workInProgressRootRenderLanes && - 0 === (workInProgressRootRenderLanes & 536870912)) || - handler !== shellBoundary)) || - 0 !== (workInProgressRootSkippedLanes & 134217727) || - 0 !== (workInProgressRootInterleavedUpdatedLanes & 134217727) - ? 3 - : 2; - } else - thrownValue === SuspenseyCommitException - ? ((thrownValue = getSuspendedThenable()), - (workInProgressSuspendedReason = 4)) - : (workInProgressSuspendedReason = - thrownValue === SelectiveHydrationException - ? 8 - : null !== thrownValue && - "object" === typeof thrownValue && - "function" === typeof thrownValue.then - ? 6 - : 1); + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + ReactCurrentOwner.current = null; + thrownValue === SuspenseException + ? ((thrownValue = getSuspendedThenable()), + (root = suspenseHandlerStackCursor.current), + (workInProgressSuspendedReason = + (null !== root && + ((workInProgressRootRenderLanes & 4194176) === + workInProgressRootRenderLanes + ? null !== shellBoundary + : ((workInProgressRootRenderLanes & 62914560) !== + workInProgressRootRenderLanes && + 0 === (workInProgressRootRenderLanes & 536870912)) || + root !== shellBoundary)) || + 0 !== (workInProgressRootSkippedLanes & 134217727) || + 0 !== (workInProgressRootInterleavedUpdatedLanes & 134217727) + ? 3 + : 2)) + : thrownValue === SuspenseyCommitException + ? ((thrownValue = getSuspendedThenable()), + (workInProgressSuspendedReason = 4)) + : (workInProgressSuspendedReason = + thrownValue === SelectiveHydrationException + ? 8 + : null !== thrownValue && + "object" === typeof thrownValue && + "function" === typeof thrownValue.then + ? 6 + : 1); workInProgressThrownValue = thrownValue; - handler = workInProgress; - if (null === handler) - (workInProgressRootExitStatus = 1), - logUncaughtError( - root, - createCapturedValueAtFiber(thrownValue, root.current) - ); - else - switch ( - (handler.mode & 2 && - stopProfilerTimerIfRunningAndRecordDelta(handler, !0), - markComponentRenderStopped(), - workInProgressSuspendedReason) - ) { - case 1: - null !== injectedProfilingHooks && - "function" === typeof injectedProfilingHooks.markComponentErrored && - injectedProfilingHooks.markComponentErrored( - handler, - thrownValue, - workInProgressRootRenderLanes - ); - break; - case 2: - case 3: - case 6: - case 7: - null !== injectedProfilingHooks && - "function" === typeof injectedProfilingHooks.markComponentSuspended && - injectedProfilingHooks.markComponentSuspended( - handler, - thrownValue, - workInProgressRootRenderLanes - ); - } + root = workInProgress; + null === root + ? ((workInProgressRootExitStatus = 1), + (workInProgressRootFatalError = thrownValue)) + : root.mode & 2 && stopProfilerTimerIfRunningAndRecordDelta(root, !0); } function pushDispatcher() { - var prevDispatcher = ReactSharedInternals.H; - ReactSharedInternals.H = ContextOnlyDispatcher; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = ContextOnlyDispatcher; return null === prevDispatcher ? ContextOnlyDispatcher : prevDispatcher; } -function pushAsyncDispatcher() { - var prevAsyncDispatcher = ReactSharedInternals.A; - ReactSharedInternals.A = DefaultAsyncDispatcher; - return prevAsyncDispatcher; -} function renderDidSuspendDelayIfPossible() { workInProgressRootExitStatus = 4; (0 === (workInProgressRootSkippedLanes & 134217727) && @@ -9816,8 +8677,7 @@ function renderDidSuspendDelayIfPossible() { function renderRootSync(root, lanes) { var prevExecutionContext = executionContext; executionContext |= 2; - var prevDispatcher = pushDispatcher(), - prevAsyncDispatcher = pushAsyncDispatcher(); + var prevDispatcher = pushDispatcher(); if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) { if (isDevToolsPresent) { var memoizedUpdaters = root.memoizedUpdaters; @@ -9829,7 +8689,6 @@ function renderRootSync(root, lanes) { workInProgressTransitions = null; prepareFreshStack(root, lanes); } - markRenderStarted(lanes); lanes = !1; a: do try { @@ -9854,20 +8713,18 @@ function renderRootSync(root, lanes) { } workLoopSync(); break; - } catch (thrownValue$148) { - handleThrow(root, thrownValue$148); + } catch (thrownValue$109) { + handleThrow(root, thrownValue$109); } while (1); lanes && root.shellSuspendCounter++; resetContextDependencies(); executionContext = prevExecutionContext; - ReactSharedInternals.H = prevDispatcher; - ReactSharedInternals.A = prevAsyncDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; if (null !== workInProgress) throw Error( "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." ); - markRenderStopped(); workInProgressRoot = null; workInProgressRootRenderLanes = 0; finishQueueingConcurrentUpdates(); @@ -9879,8 +8736,7 @@ function workLoopSync() { function renderRootConcurrent(root, lanes) { var prevExecutionContext = executionContext; executionContext |= 2; - var prevDispatcher = pushDispatcher(), - prevAsyncDispatcher = pushAsyncDispatcher(); + var prevDispatcher = pushDispatcher(); if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) { if (isDevToolsPresent) { var memoizedUpdaters = root.memoizedUpdaters; @@ -9893,7 +8749,6 @@ function renderRootConcurrent(root, lanes) { workInProgressRootRenderTargetTime = now$1() + 500; prepareFreshStack(root, lanes); } - markRenderStarted(lanes); a: do try { if (0 !== workInProgressSuspendedReason && null !== workInProgress) @@ -9938,27 +8793,23 @@ function renderRootConcurrent(root, lanes) { throwAndUnwindWorkLoop(root, lanes, memoizedUpdaters)); break; case 5: - var resource = null; switch (workInProgress.tag) { - case 26: - resource = workInProgress.memoizedState; case 5: + case 26: case 27: - var hostFiber = workInProgress; - if (resource ? shim(resource) : 1) { - workInProgressSuspendedReason = 0; - workInProgressThrownValue = null; - var sibling = hostFiber.sibling; - if (null !== sibling) workInProgress = sibling; - else { - var returnFiber = hostFiber.return; - null !== returnFiber - ? ((workInProgress = returnFiber), - completeUnitOfWork(returnFiber)) - : (workInProgress = null); - } - break b; + lanes = workInProgress; + workInProgressSuspendedReason = 0; + workInProgressThrownValue = null; + var sibling = lanes.sibling; + if (null !== sibling) workInProgress = sibling; + else { + var returnFiber = lanes.return; + null !== returnFiber + ? ((workInProgress = returnFiber), + completeUnitOfWork(returnFiber)) + : (workInProgress = null); } + break b; } workInProgressSuspendedReason = 0; workInProgressThrownValue = null; @@ -9978,22 +8829,14 @@ function renderRootConcurrent(root, lanes) { } workLoopConcurrent(); break; - } catch (thrownValue$150) { - handleThrow(root, thrownValue$150); + } catch (thrownValue$111) { + handleThrow(root, thrownValue$111); } while (1); resetContextDependencies(); - ReactSharedInternals.H = prevDispatcher; - ReactSharedInternals.A = prevAsyncDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; executionContext = prevExecutionContext; - if (null !== workInProgress) - return ( - null !== injectedProfilingHooks && - "function" === typeof injectedProfilingHooks.markRenderYielded && - injectedProfilingHooks.markRenderYielded(), - 0 - ); - markRenderStopped(); + if (null !== workInProgress) return 0; workInProgressRoot = null; workInProgressRootRenderLanes = 0; finishQueueingConcurrentUpdates(); @@ -10014,46 +8857,62 @@ function performUnitOfWork(unitOfWork) { null === current ? completeUnitOfWork(unitOfWork) : (workInProgress = current); + ReactCurrentOwner.current = null; } function replaySuspendedUnitOfWork(unitOfWork) { - var next = unitOfWork; - var current = next.alternate, - isProfilingMode = 0 !== (next.mode & 2); - isProfilingMode && startProfilerTimer(next); - switch (next.tag) { + var current = unitOfWork.alternate, + isProfilingMode = 0 !== (unitOfWork.mode & 2); + isProfilingMode && startProfilerTimer(unitOfWork); + switch (unitOfWork.tag) { + case 2: + unitOfWork.tag = 0; case 15: case 0: + var Component = unitOfWork.type, + unresolvedProps = unitOfWork.pendingProps; + unresolvedProps = + unitOfWork.elementType === Component + ? unresolvedProps + : resolveDefaultProps(Component, unresolvedProps); current = replayFunctionComponent( current, - next, - next.pendingProps, - next.type, + unitOfWork, + unresolvedProps, + Component, void 0, workInProgressRootRenderLanes ); break; case 11: + Component = unitOfWork.type.render; + unresolvedProps = unitOfWork.pendingProps; + unresolvedProps = + unitOfWork.elementType === Component + ? unresolvedProps + : resolveDefaultProps(Component, unresolvedProps); current = replayFunctionComponent( current, - next, - next.pendingProps, - next.type.render, - next.ref, + unitOfWork, + unresolvedProps, + Component, + unitOfWork.ref, workInProgressRootRenderLanes ); break; case 5: - resetHooksOnUnwind(next); + resetHooksOnUnwind(unitOfWork); default: - unwindInterruptedWork(current, next), - (next = workInProgress = - resetWorkInProgress(next, entangledRenderLanes)), - (current = beginWork(current, next, entangledRenderLanes)); + unwindInterruptedWork(current, unitOfWork), + (unitOfWork = workInProgress = + resetWorkInProgress(unitOfWork, entangledRenderLanes)), + (current = beginWork(current, unitOfWork, entangledRenderLanes)); } - isProfilingMode && stopProfilerTimerIfRunningAndRecordDelta(next, !0); - next = current; + isProfilingMode && stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, !0); unitOfWork.memoizedProps = unitOfWork.pendingProps; - null === next ? completeUnitOfWork(unitOfWork) : (workInProgress = next); + null === current + ? completeUnitOfWork(unitOfWork) + : (workInProgress = current); + ReactCurrentOwner.current = null; } function throwAndUnwindWorkLoop(root, unitOfWork, thrownValue) { resetContextDependencies(); @@ -10072,20 +8931,14 @@ function throwAndUnwindWorkLoop(root, unitOfWork, thrownValue) { ) ) { workInProgressRootExitStatus = 1; - logUncaughtError( - root, - createCapturedValueAtFiber(thrownValue, root.current) - ); + workInProgressRootFatalError = thrownValue; workInProgress = null; return; } } catch (error) { if (null !== returnFiber) throw ((workInProgress = returnFiber), error); workInProgressRootExitStatus = 1; - logUncaughtError( - root, - createCapturedValueAtFiber(thrownValue, root.current) - ); + workInProgressRootFatalError = thrownValue; workInProgress = null; return; } @@ -10149,11 +9002,11 @@ function commitRoot( didIncludeRenderPhaseUpdate, spawnedLane ) { - var prevTransition = ReactSharedInternals.T, - previousUpdateLanePriority = currentUpdatePriority; + var previousUpdateLanePriority = currentUpdatePriority, + prevTransition = ReactCurrentBatchConfig.transition; try { - (currentUpdatePriority = 2), - (ReactSharedInternals.T = null), + (ReactCurrentBatchConfig.transition = null), + (currentUpdatePriority = 2), commitRootImpl( root, recoverableErrors, @@ -10163,7 +9016,7 @@ function commitRoot( spawnedLane ); } finally { - (ReactSharedInternals.T = prevTransition), + (ReactCurrentBatchConfig.transition = prevTransition), (currentUpdatePriority = previousUpdateLanePriority); } return null; @@ -10180,143 +9033,118 @@ function commitRootImpl( while (null !== rootWithPendingPassiveEffects); if (0 !== (executionContext & 6)) throw Error("Should not already be working."); - var finishedWork = root.finishedWork, - lanes = root.finishedLanes; - null !== injectedProfilingHooks && - "function" === typeof injectedProfilingHooks.markCommitStarted && - injectedProfilingHooks.markCommitStarted(lanes); - if (null === finishedWork) return markCommitStopped(), null; + didIncludeRenderPhaseUpdate = root.finishedWork; + transitions = root.finishedLanes; + if (null === didIncludeRenderPhaseUpdate) return null; root.finishedWork = null; root.finishedLanes = 0; - if (finishedWork === root.current) + if (didIncludeRenderPhaseUpdate === root.current) throw Error( "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." ); root.callbackNode = null; root.callbackPriority = 0; root.cancelPendingCommit = null; - var remainingLanes = finishedWork.lanes | finishedWork.childLanes; + var remainingLanes = + didIncludeRenderPhaseUpdate.lanes | didIncludeRenderPhaseUpdate.childLanes; remainingLanes |= concurrentlyUpdatedLanes; markRootFinished(root, remainingLanes, spawnedLane); - didIncludeCommitPhaseUpdate = !1; root === workInProgressRoot && ((workInProgress = workInProgressRoot = null), (workInProgressRootRenderLanes = 0)); - (0 === (finishedWork.subtreeFlags & 10256) && - 0 === (finishedWork.flags & 10256)) || + (0 === (didIncludeRenderPhaseUpdate.subtreeFlags & 10256) && + 0 === (didIncludeRenderPhaseUpdate.flags & 10256)) || rootDoesHavePassiveEffects || ((rootDoesHavePassiveEffects = !0), - (pendingPassiveEffectsRemainingLanes = remainingLanes), - (pendingPassiveTransitions = transitions), - scheduleCallback(NormalPriority$1, function () { + scheduleCallback(NormalPriority, function () { flushPassiveEffects(); return null; })); - transitions = 0 !== (finishedWork.flags & 15990); - if (0 !== (finishedWork.subtreeFlags & 15990) || transitions) { - transitions = ReactSharedInternals.T; - ReactSharedInternals.T = null; - spawnedLane = currentUpdatePriority; + spawnedLane = 0 !== (didIncludeRenderPhaseUpdate.flags & 15990); + if (0 !== (didIncludeRenderPhaseUpdate.subtreeFlags & 15990) || spawnedLane) { + spawnedLane = ReactCurrentBatchConfig.transition; + ReactCurrentBatchConfig.transition = null; + remainingLanes = currentUpdatePriority; currentUpdatePriority = 2; var prevExecutionContext = executionContext; executionContext |= 4; - commitBeforeMutationEffects(root, finishedWork); + ReactCurrentOwner.current = null; + commitBeforeMutationEffects(root, didIncludeRenderPhaseUpdate); commitTime = now(); - commitMutationEffects(root, finishedWork, lanes); - root.current = finishedWork; - null !== injectedProfilingHooks && - "function" === typeof injectedProfilingHooks.markLayoutEffectsStarted && - injectedProfilingHooks.markLayoutEffectsStarted(lanes); - commitLayoutEffects(finishedWork, root, lanes); - null !== injectedProfilingHooks && - "function" === typeof injectedProfilingHooks.markLayoutEffectsStopped && - injectedProfilingHooks.markLayoutEffectsStopped(); + commitMutationEffects(root, didIncludeRenderPhaseUpdate, transitions); + root.current = didIncludeRenderPhaseUpdate; + commitLayoutEffects(didIncludeRenderPhaseUpdate, root, transitions); requestPaint(); executionContext = prevExecutionContext; - currentUpdatePriority = spawnedLane; - ReactSharedInternals.T = transitions; - } else (root.current = finishedWork), (commitTime = now()); - rootDoesHavePassiveEffects - ? ((rootDoesHavePassiveEffects = !1), - (rootWithPendingPassiveEffects = root), - (pendingPassiveEffectsLanes = lanes)) - : releaseRootPooledCache(root, remainingLanes); + currentUpdatePriority = remainingLanes; + ReactCurrentBatchConfig.transition = spawnedLane; + } else (root.current = didIncludeRenderPhaseUpdate), (commitTime = now()); + rootDoesHavePassiveEffects && + ((rootDoesHavePassiveEffects = !1), + (rootWithPendingPassiveEffects = root), + (pendingPassiveEffectsLanes = transitions)); remainingLanes = root.pendingLanes; 0 === remainingLanes && (legacyErrorBoundariesThatAlreadyFailed = null); - onCommitRoot(finishedWork.stateNode, renderPriorityLevel); + onCommitRoot(didIncludeRenderPhaseUpdate.stateNode, renderPriorityLevel); isDevToolsPresent && root.memoizedUpdaters.clear(); ensureRootIsScheduled(root); if (null !== recoverableErrors) for ( - renderPriorityLevel = root.onRecoverableError, finishedWork = 0; - finishedWork < recoverableErrors.length; - finishedWork++ + renderPriorityLevel = root.onRecoverableError, + didIncludeRenderPhaseUpdate = 0; + didIncludeRenderPhaseUpdate < recoverableErrors.length; + didIncludeRenderPhaseUpdate++ ) - (remainingLanes = recoverableErrors[finishedWork]), - renderPriorityLevel(remainingLanes.value, { - componentStack: remainingLanes.stack - }); + (spawnedLane = recoverableErrors[didIncludeRenderPhaseUpdate]), + (remainingLanes = { + digest: spawnedLane.digest, + componentStack: spawnedLane.stack + }), + renderPriorityLevel(spawnedLane.value, remainingLanes); + if (hasUncaughtError) + throw ( + ((hasUncaughtError = !1), + (root = firstUncaughtError), + (firstUncaughtError = null), + root) + ); 0 !== (pendingPassiveEffectsLanes & 3) && 0 !== root.tag && flushPassiveEffects(); remainingLanes = root.pendingLanes; - didIncludeRenderPhaseUpdate || - didIncludeCommitPhaseUpdate || - (0 !== (lanes & 4194218) && 0 !== (remainingLanes & 42)) + 0 !== (transitions & 4194218) && 0 !== (remainingLanes & 42) ? ((nestedUpdateScheduled = !0), root === rootWithNestedUpdates ? nestedUpdateCount++ : ((nestedUpdateCount = 0), (rootWithNestedUpdates = root))) : (nestedUpdateCount = 0); flushSyncWorkAcrossRoots_impl(!1); - markCommitStopped(); return null; } -function releaseRootPooledCache(root, remainingLanes) { - 0 === (root.pooledCacheLanes &= remainingLanes) && - ((remainingLanes = root.pooledCache), - null != remainingLanes && - ((root.pooledCache = null), releaseCache(remainingLanes))); -} function flushPassiveEffects() { if (null !== rootWithPendingPassiveEffects) { - var root = rootWithPendingPassiveEffects, - remainingLanes = pendingPassiveEffectsRemainingLanes; - pendingPassiveEffectsRemainingLanes = 0; var renderPriority = lanesToEventPriority(pendingPassiveEffectsLanes), - prevTransition = ReactSharedInternals.T, + prevTransition = ReactCurrentBatchConfig.transition, previousPriority = currentUpdatePriority; try { + ReactCurrentBatchConfig.transition = null; currentUpdatePriority = 32 > renderPriority ? 32 : renderPriority; - ReactSharedInternals.T = null; if (null === rootWithPendingPassiveEffects) var JSCompiler_inline_result = !1; else { - var transitions = pendingPassiveTransitions; - pendingPassiveTransitions = null; renderPriority = rootWithPendingPassiveEffects; - var lanes = pendingPassiveEffectsLanes; rootWithPendingPassiveEffects = null; pendingPassiveEffectsLanes = 0; if (0 !== (executionContext & 6)) throw Error("Cannot flush passive effects while already rendering."); - null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markPassiveEffectsStarted && - injectedProfilingHooks.markPassiveEffectsStarted(lanes); var prevExecutionContext = executionContext; executionContext |= 4; commitPassiveUnmountOnFiber(renderPriority.current); - commitPassiveMountOnFiber( - renderPriority, - renderPriority.current, - lanes, - transitions - ); - transitions = pendingPassiveProfilerEffects; + commitPassiveMountOnFiber(renderPriority, renderPriority.current); + var profilerEffects = pendingPassiveProfilerEffects; pendingPassiveProfilerEffects = []; - for (lanes = 0; lanes < transitions.length; lanes++) { - var finishedWork = transitions[lanes]; + for (var i = 0; i < profilerEffects.length; i++) { + var finishedWork = profilerEffects[i]; if (executionContext & 4 && 0 !== (finishedWork.flags & 4)) switch (finishedWork.tag) { case 12: @@ -10325,16 +9153,11 @@ function flushPassiveEffects() { _finishedWork$memoize = finishedWork.memoizedProps, id = _finishedWork$memoize.id, onPostCommit = _finishedWork$memoize.onPostCommit, - commitTime$121 = commitTime, + commitTime$86 = commitTime, phase = null === finishedWork.alternate ? "mount" : "update"; currentUpdateIsNested && (phase = "nested-update"); "function" === typeof onPostCommit && - onPostCommit( - id, - phase, - passiveEffectDuration, - commitTime$121 - ); + onPostCommit(id, phase, passiveEffectDuration, commitTime$86); var parentFiber = finishedWork.return; b: for (; null !== parentFiber; ) { switch (parentFiber.tag) { @@ -10351,10 +9174,6 @@ function flushPassiveEffects() { } } } - null !== injectedProfilingHooks && - "function" === - typeof injectedProfilingHooks.markPassiveEffectsStopped && - injectedProfilingHooks.markPassiveEffectsStopped(); executionContext = prevExecutionContext; flushSyncWorkAcrossRoots_impl(!1); if ( @@ -10372,8 +9191,7 @@ function flushPassiveEffects() { return JSCompiler_inline_result; } finally { (currentUpdatePriority = previousPriority), - (ReactSharedInternals.T = prevTransition), - releaseRootPooledCache(root, remainingLanes); + (ReactCurrentBatchConfig.transition = prevTransition); } } return !1; @@ -10382,17 +9200,17 @@ function enqueuePendingPassiveProfilerEffect(fiber) { pendingPassiveProfilerEffects.push(fiber); rootDoesHavePassiveEffects || ((rootDoesHavePassiveEffects = !0), - scheduleCallback(NormalPriority$1, function () { + scheduleCallback(NormalPriority, function () { flushPassiveEffects(); return null; })); } function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { sourceFiber = createCapturedValueAtFiber(error, sourceFiber); - sourceFiber = createRootErrorUpdate(rootFiber.stateNode, sourceFiber, 2); + sourceFiber = createRootErrorUpdate(rootFiber, sourceFiber, 2); rootFiber = enqueueUpdate(rootFiber, sourceFiber, 2); null !== rootFiber && - (markRootUpdated(rootFiber, 2), ensureRootIsScheduled(rootFiber)); + (markRootUpdated$1(rootFiber, 2), ensureRootIsScheduled(rootFiber)); } function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error) { if (3 === sourceFiber.tag) @@ -10416,17 +9234,19 @@ function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error) { !legacyErrorBoundariesThatAlreadyFailed.has(instance))) ) { sourceFiber = createCapturedValueAtFiber(error, sourceFiber); - error = createClassErrorUpdate(2); - instance = enqueueUpdate(nearestMountedAncestor, error, 2); - null !== instance && - (initializeClassErrorUpdate( - error, - instance, - nearestMountedAncestor, - sourceFiber - ), - markRootUpdated(instance, 2), - ensureRootIsScheduled(instance)); + sourceFiber = createClassErrorUpdate( + nearestMountedAncestor, + sourceFiber, + 2 + ); + nearestMountedAncestor = enqueueUpdate( + nearestMountedAncestor, + sourceFiber, + 2 + ); + null !== nearestMountedAncestor && + (markRootUpdated$1(nearestMountedAncestor, 2), + ensureRootIsScheduled(nearestMountedAncestor)); break; } } @@ -10454,10 +9274,6 @@ function pingSuspendedRoot(root, wakeable, pingedLanes) { var pingCache = root.pingCache; null !== pingCache && pingCache.delete(wakeable); root.pingedLanes |= root.suspendedLanes & pingedLanes; - executionContext & 2 - ? (workInProgressRootDidIncludeRecursiveRenderUpdate = !0) - : executionContext & 4 && (didIncludeCommitPhaseUpdate = !0); - throwIfInfiniteUpdateLoopDetected(); workInProgressRoot === root && (workInProgressRootRenderLanes & pingedLanes) === pingedLanes && (4 === workInProgressRootExitStatus || @@ -10474,7 +9290,7 @@ function retryTimedOutBoundary(boundaryFiber, retryLane) { (retryLane = 0 === (boundaryFiber.mode & 1) ? 2 : claimNextRetryLane()); boundaryFiber = enqueueConcurrentRenderForLane(boundaryFiber, retryLane); null !== boundaryFiber && - (markRootUpdated(boundaryFiber, retryLane), + (markRootUpdated$1(boundaryFiber, retryLane), ensureRootIsScheduled(boundaryFiber)); } function retryDehydratedSuspenseBoundary(boundaryFiber) { @@ -10505,20 +9321,6 @@ function resolveRetryWakeable(boundaryFiber, wakeable) { null !== retryCache && retryCache.delete(wakeable); retryTimedOutBoundary(boundaryFiber, retryLane); } -function throwIfInfiniteUpdateLoopDetected() { - if (50 < nestedUpdateCount) - throw ( - ((nestedUpdateCount = 0), - (rootWithNestedUpdates = null), - executionContext & 2 && - null !== workInProgressRoot && - (workInProgressRoot.errorRecoveryDisabledLanes |= - workInProgressRootRenderLanes), - Error( - "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." - )) - ); -} function restorePendingUpdaters(root, lanes) { isDevToolsPresent && root.memoizedUpdaters.forEach(function (schedulingFiber) { @@ -10526,7 +9328,7 @@ function restorePendingUpdaters(root, lanes) { }); } function scheduleCallback(priorityLevel, callback) { - return scheduleCallback$3(priorityLevel, callback); + return scheduleCallback$2(priorityLevel, callback); } function FiberNode(tag, pendingProps, key, mode) { this.tag = tag; @@ -10562,6 +9364,16 @@ function shouldConstruct(Component) { Component = Component.prototype; return !(!Component || !Component.isReactComponent); } +function resolveLazyComponentTag(Component) { + if ("function" === typeof Component) + return shouldConstruct(Component) ? 1 : 0; + if (void 0 !== Component && null !== Component) { + Component = Component.$$typeof; + if (Component === REACT_FORWARD_REF_TYPE) return 11; + if (Component === REACT_MEMO_TYPE) return 14; + } + return 2; +} function createWorkInProgress(current, pendingProps) { var workInProgress = current.alternate; null === workInProgress @@ -10647,7 +9459,7 @@ function createFiberFromTypeAndProps( mode, lanes ) { - var fiberTag = 0; + var fiberTag = 2; owner = type; if ("function" === typeof type) shouldConstruct(type) && (fiberTag = 1); else if ("string" === typeof type) fiberTag = 5; @@ -10688,12 +9500,12 @@ function createFiberFromTypeAndProps( if ("object" === typeof type && null !== type) switch (type.$$typeof) { case REACT_PROVIDER_TYPE: - case REACT_CONTEXT_TYPE: fiberTag = 10; break a; - case REACT_CONSUMER_TYPE: + case REACT_CONTEXT_TYPE: fiberTag = 9; break a; + case REACT_CONSUMER_TYPE: case REACT_FORWARD_REF_TYPE: fiberTag = 11; break a; @@ -10707,7 +9519,7 @@ function createFiberFromTypeAndProps( } throw Error( "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + - ((null === type ? "null" : typeof type) + ".") + ((null == type ? type : typeof type) + ".") ); } key = createFiber(fiberTag, pendingProps, key, mode); @@ -10787,8 +9599,6 @@ function FiberRootNode( tag, hydrate, identifierPrefix, - onUncaughtError, - onCaughtError, onRecoverableError, formState ) { @@ -10820,11 +9630,7 @@ function FiberRootNode( this.entanglements = createLaneMap(0); this.hiddenUpdates = createLaneMap(null); this.identifierPrefix = identifierPrefix; - this.onUncaughtError = onUncaughtError; - this.onCaughtError = onCaughtError; this.onRecoverableError = onRecoverableError; - this.pooledCache = null; - this.pooledCacheLanes = 0; this.formState = formState; this.incompleteTransitions = new Map(); this.passiveEffectDuration = this.effectDuration = 0; @@ -10859,9 +9665,6 @@ function findHostInstance(component) { function updateContainer(element, container, parentComponent, callback) { parentComponent = container.current; var lane = requestUpdateLane(parentComponent); - null !== injectedProfilingHooks && - "function" === typeof injectedProfilingHooks.markRenderScheduled && - injectedProfilingHooks.markRenderScheduled(lane); null === container.context ? (container.context = emptyContextObject) : (container.pendingContext = emptyContextObject); @@ -10904,37 +9707,8 @@ function findNodeHandle(componentOrHandle) { function getInspectorDataForInstance() { throw Error("getInspectorDataForInstance() is not available in production"); } -var isomorphicReactPackageVersion = React.version; -if ("19.0.0-rc-fb9a90fa48-20240614" !== isomorphicReactPackageVersion) - throw Error( - 'Incompatible React versions: The "react" and "react-native-renderer" packages must have the exact same version. Instead got:\n - react: ' + - (isomorphicReactPackageVersion + - "\n - react-native-renderer: 19.0.0-rc-fb9a90fa48-20240614\nLearn more: https://react.dev/warnings/version-mismatch") - ); -if ( - "function" !== - typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog -) - throw Error( - "Expected ReactFiberErrorDialog.showErrorDialog to be a function." - ); -function nativeOnUncaughtError(error, errorInfo) { - !1 !== - ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog({ - errorBoundary: null, - error: error, - componentStack: - null != errorInfo.componentStack ? errorInfo.componentStack : "" - }) && reportGlobalError(error); -} -function nativeOnCaughtError(error, errorInfo) { - !1 !== - ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog({ - errorBoundary: errorInfo.errorBoundary, - error: error, - componentStack: - null != errorInfo.componentStack ? errorInfo.componentStack : "" - }) && console.error(error); +function onRecoverableError(error) { + console.error(error); } function unmountComponentAtNode(containerTag) { var root = roots.get(containerTag); @@ -10956,10 +9730,10 @@ batchedUpdatesImpl = function (fn, a) { } }; var roots = new Map(), - devToolsConfig$jscomp$inline_1261 = { + devToolsConfig$jscomp$inline_1140 = { findFiberByHostInstance: getInstanceFromTag, bundleType: 0, - version: "19.0.0-rc-fb9a90fa48-20240614", + version: "18.3.0-canary-9372c6311-20240315", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForInstance: getInspectorDataForInstance, @@ -10975,24 +9749,11 @@ var roots = new Map(), }.bind(null, findNodeHandle) } }; -(function (internals) { - if ("undefined" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) return !1; - var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; - if (hook.isDisabled || !hook.supportsFiber) return !0; - try { - (internals = assign({}, internals, { - getLaneLabelMap: getLaneLabelMap, - injectProfilingHooks: injectProfilingHooks - })), - (rendererID = hook.inject(internals)), - (injectedHook = hook); - } catch (err) {} - return hook.checkDCE ? !0 : !1; -})({ - bundleType: devToolsConfig$jscomp$inline_1261.bundleType, - version: devToolsConfig$jscomp$inline_1261.version, - rendererPackageName: devToolsConfig$jscomp$inline_1261.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_1261.rendererConfig, +var internals$jscomp$inline_1378 = { + bundleType: devToolsConfig$jscomp$inline_1140.bundleType, + version: devToolsConfig$jscomp$inline_1140.version, + rendererPackageName: devToolsConfig$jscomp$inline_1140.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_1140.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -11002,21 +9763,34 @@ var roots = new Map(), setErrorHandler: null, setSuspenseHandler: null, scheduleUpdate: null, - currentDispatcherRef: ReactSharedInternals, + currentDispatcherRef: ReactSharedInternals.ReactCurrentDispatcher, findHostInstanceByFiber: function (fiber) { fiber = findCurrentHostFiber(fiber); return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_1261.findFiberByHostInstance || + devToolsConfig$jscomp$inline_1140.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "19.0.0-rc-fb9a90fa48-20240614" -}); + reconcilerVersion: "18.3.0-canary-9372c6311-20240315" +}; +if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { + var hook$jscomp$inline_1379 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + if ( + !hook$jscomp$inline_1379.isDisabled && + hook$jscomp$inline_1379.supportsFiber + ) + try { + (rendererID = hook$jscomp$inline_1379.inject( + internals$jscomp$inline_1378 + )), + (injectedHook = hook$jscomp$inline_1379); + } catch (err) {} +} exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = { computeComponentStackForErrorReporting: function (reactTag) { return (reactTag = getInstanceFromTag(reactTag)) @@ -11061,47 +9835,26 @@ exports.getInspectorDataForInstance = getInspectorDataForInstance; exports.isChildPublicInstance = function () { throw Error("isChildPublicInstance() is not available in production."); }; -exports.render = function (element, containerTag, callback, options) { +exports.render = function (element, containerTag, callback) { var root = roots.get(containerTag); if (!root) { - root = nativeOnUncaughtError; - var onCaughtError = nativeOnCaughtError, - onRecoverableError = defaultOnRecoverableError; - options && - void 0 !== options.onUncaughtError && - (root = options.onUncaughtError); - options && - void 0 !== options.onCaughtError && - (onCaughtError = options.onCaughtError); - options && - void 0 !== options.onRecoverableError && - (onRecoverableError = options.onRecoverableError); - options = new FiberRootNode( - containerTag, - 0, - !1, - "", - root, - onCaughtError, - onRecoverableError, - null + root = new FiberRootNode(containerTag, 0, !1, "", onRecoverableError, null); + var JSCompiler_inline_result = 0; + isDevToolsPresent && (JSCompiler_inline_result |= 2); + JSCompiler_inline_result = createFiber( + 3, + null, + null, + JSCompiler_inline_result ); - root = 0; - isDevToolsPresent && (root |= 2); - root = createFiber(3, null, null, root); - options.current = root; - root.stateNode = options; - onCaughtError = createCache(); - onCaughtError.refCount++; - options.pooledCache = onCaughtError; - onCaughtError.refCount++; - root.memoizedState = { + root.current = JSCompiler_inline_result; + JSCompiler_inline_result.stateNode = root; + JSCompiler_inline_result.memoizedState = { element: null, isDehydrated: !1, - cache: onCaughtError + cache: null }; - initializeUpdateQueue(root); - root = options; + initializeUpdateQueue(JSCompiler_inline_result); roots.set(containerTag, root); } updateContainer(element, root, null, callback); diff --git a/packages/react-native/package.json b/packages/react-native/package.json index dd7cb6850ca46e..94c346669df8f3 100644 --- a/packages/react-native/package.json +++ b/packages/react-native/package.json @@ -99,7 +99,7 @@ }, "peerDependencies": { "@types/react": "^18.2.6", - "react": "^19.0.0-rc-fb9a90fa48-20240614" + "react": "^18.2.0" }, "peerDependenciesMeta": { "@types/react": { @@ -138,7 +138,7 @@ "react-devtools-core": "^6.0.1", "react-refresh": "^0.14.0", "regenerator-runtime": "^0.13.2", - "scheduler": "0.25.0-rc-fb9a90fa48-20240614", + "scheduler": "0.24.0-canary-efb381bbf-20230505", "semver": "^7.1.3", "stacktrace-parser": "^0.1.10", "whatwg-fetch": "^3.0.0", diff --git a/packages/react-native/scripts/cocoapods/__tests__/new_architecture-test.rb b/packages/react-native/scripts/cocoapods/__tests__/new_architecture-test.rb index 677fe99d185c3b..6a7d5f7cb8b6d6 100644 --- a/packages/react-native/scripts/cocoapods/__tests__/new_architecture-test.rb +++ b/packages/react-native/scripts/cocoapods/__tests__/new_architecture-test.rb @@ -40,27 +40,15 @@ def test_setClangCxxLanguageStandardIfNeeded_whenReactCoreIsPresent assert_equal(installer.aggregate_targets[0].user_project.build_configurations[0].build_settings["CLANG_CXX_LANGUAGE_STANDARD"], "c++20") assert_equal(installer.aggregate_targets[1].user_project.build_configurations[0].build_settings["CLANG_CXX_LANGUAGE_STANDARD"], "c++20") - assert_equal(installer.pods_project.targets[1].received_resolved_build_setting_parameters, [ReceivedCommonResolvedBuildSettings.new("CLANG_CXX_LANGUAGE_STANDARD", true)]) assert_equal(Pod::UI.collected_messages, ["Setting CLANG_CXX_LANGUAGE_STANDARD to c++20 on /test/path.xcproj", "Setting CLANG_CXX_LANGUAGE_STANDARD to c++20 on /test/path2.xcproj"]) end - def test_setClangCxxLanguageStandardIfNeeded_whenReactCoreIsNotPresent - installer = prepare_mocked_installer_without_react_core - NewArchitectureHelper.set_clang_cxx_language_standard_if_needed(installer) - - assert_equal(installer.aggregate_targets[0].user_project.build_configurations[0].build_settings["CLANG_CXX_LANGUAGE_STANDARD"], nil) - assert_equal(installer.aggregate_targets[1].user_project.build_configurations[0].build_settings["CLANG_CXX_LANGUAGE_STANDARD"], nil) - assert_equal(installer.pods_project.targets[0].received_resolved_build_setting_parameters, []) - assert_equal(Pod::UI.collected_messages, []) - end - def test_setClangCxxLanguageStandardIfNeeded_whenThereAreDifferentValuesForLanguageStandard_takesTheFirstValue installer = prepare_mocked_installer_with_react_core_and_different_language_standards NewArchitectureHelper.set_clang_cxx_language_standard_if_needed(installer) assert_equal(installer.aggregate_targets[0].user_project.build_configurations[0].build_settings["CLANG_CXX_LANGUAGE_STANDARD"], "c++20") assert_equal(installer.aggregate_targets[1].user_project.build_configurations[0].build_settings["CLANG_CXX_LANGUAGE_STANDARD"], "c++20") - assert_equal(installer.pods_project.targets[1].received_resolved_build_setting_parameters, [ReceivedCommonResolvedBuildSettings.new("CLANG_CXX_LANGUAGE_STANDARD", true)]) assert_equal(Pod::UI.collected_messages, ["Setting CLANG_CXX_LANGUAGE_STANDARD to c++20 on /test/path.xcproj", "Setting CLANG_CXX_LANGUAGE_STANDARD to c++20 on /test/path2.xcproj"]) end diff --git a/packages/react-native/scripts/cocoapods/__tests__/utils-test.rb b/packages/react-native/scripts/cocoapods/__tests__/utils-test.rb index 4ddc0c60b8024c..f73df42f13871e 100644 --- a/packages/react-native/scripts/cocoapods/__tests__/utils-test.rb +++ b/packages/react-native/scripts/cocoapods/__tests__/utils-test.rb @@ -701,9 +701,6 @@ def test_createXcodeEnvIfMissing_whenTheyAreNotPresent_createsThem # Assert assert_equal(FileMock.exist_invocation_params, ["/.xcode.env", "/.xcode.env.local"]) assert_equal($collected_commands[0], "echo 'export NODE_BINARY=$(command -v node)' > /.xcode.env") - - assert_true($collected_commands[1].start_with? "echo 'export NODE_BINARY=") - assert_true($collected_commands[1].end_with? "' > /.xcode.env.local") end # ============================ # diff --git a/packages/rn-tester/package.json b/packages/rn-tester/package.json index 34a6ef4fc49d04..51ff079c14ab0e 100644 --- a/packages/rn-tester/package.json +++ b/packages/rn-tester/package.json @@ -34,7 +34,7 @@ "nullthrows": "^1.1.1" }, "peerDependencies": { - "react": "19.0.0-rc-fb9a90fa48-20240614", + "react": "18.3.1", "react-native": "*" }, "codegenConfig": { diff --git a/packages/virtualized-lists/package.json b/packages/virtualized-lists/package.json index 048ec8edeff37f..ce522709544d9a 100644 --- a/packages/virtualized-lists/package.json +++ b/packages/virtualized-lists/package.json @@ -24,7 +24,7 @@ "nullthrows": "^1.1.1" }, "devDependencies": { - "react-test-renderer": "19.0.0-rc-fb9a90fa48-20240614" + "react-test-renderer": "18.3.1" }, "peerDependencies": { "@types/react": "^18.2.6", diff --git a/scripts/releases/__tests__/__fixtures__/set-version/packages/react-native/template/package.json b/scripts/releases/__tests__/__fixtures__/set-version/packages/react-native/template/package.json index 0fb8477978126c..5472402ec93fa6 100644 --- a/scripts/releases/__tests__/__fixtures__/set-version/packages/react-native/template/package.json +++ b/scripts/releases/__tests__/__fixtures__/set-version/packages/react-native/template/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": true, "dependencies": { - "react": "19.0.0-rc-fb9a90fa48-20240614", + "react": "18.3.1", "react-native": "1000.0.0" }, "devDependencies": { diff --git a/yarn.lock b/yarn.lock index 41d4b38fa823ca..f4da56fe2074bc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6283,7 +6283,7 @@ logkitty@^0.7.1: dayjs "^1.8.15" yargs "^15.1.0" -loose-envify@^1.0.0, loose-envify@^1.4.0: +loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== @@ -7366,28 +7366,39 @@ react-devtools-core@^6.0.1: shell-quote "^1.6.1" ws "^7" -react-is@19.0.0-rc-fb9a90fa48-20240614, react-is@^16.13.1, react-is@^16.8.4, react-is@^17.0.1, react-is@^18.0.0: - version "19.0.0-rc-fb9a90fa48-20240614" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-19.0.0-rc-fb9a90fa48-20240614.tgz#6987893799abdedf2e9929e31541cb6d7dc8285a" - integrity sha512-60qI7v1B9RhmZwjTCnAgzcuABOQsIH20vTbETQPaze96s1lY2lSawv9dvXAfF8Z1MIqOppWSKLNOshF0WsZ3OA== +react-is@18.3.1, "react-is@^16.12.0 || ^17.0.0 || ^18.0.0", react-is@^16.13.1, react-is@^16.8.4, react-is@^17.0.1, react-is@^18.0.0, react-is@^18.3.1: + version "18.3.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.3.1.tgz#e83557dc12eae63a99e003a46388b1dcbb44db7e" + integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg== react-refresh@^0.14.0: version "0.14.2" resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.14.2.tgz#3833da01ce32da470f1f936b9d477da5c7028bf9" integrity sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA== -react-test-renderer@19.0.0-rc-fb9a90fa48-20240614: - version "19.0.0-rc-fb9a90fa48-20240614" - resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-19.0.0-rc-fb9a90fa48-20240614.tgz#6657b3d05a533afad5ea0516f9ed29cadf72334f" - integrity sha512-cV3mGgsKTJCB8f4tZxWIp0ot4PMgx791XTkwpapf06ZlUk5BCP3C1CbIqRXcKeiQODvFJClZX26TFTPAklTq7A== +react-shallow-renderer@^16.15.0: + version "16.15.0" + resolved "https://registry.yarnpkg.com/react-shallow-renderer/-/react-shallow-renderer-16.15.0.tgz#48fb2cf9b23d23cde96708fe5273a7d3446f4457" + integrity sha512-oScf2FqQ9LFVQgA73vr86xl2NaOIX73rh+YFqcOp68CWj56tSfgtGKrEbyhCj0rSijyG9M1CYprTh39fBi5hzA== dependencies: - react-is "19.0.0-rc-fb9a90fa48-20240614" - scheduler "0.25.0-rc-fb9a90fa48-20240614" + object-assign "^4.1.1" + react-is "^16.12.0 || ^17.0.0 || ^18.0.0" + +react-test-renderer@18.3.1: + version "18.3.1" + resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-18.3.1.tgz#e693608a1f96283400d4a3afead6893f958b80b4" + integrity sha512-KkAgygexHUkQqtvvx/otwxtuFu5cVjfzTCtjXLH9boS19/Nbtg84zS7wIQn39G8IlrhThBpQsMKkq5ZHZIYFXA== + dependencies: + react-is "^18.3.1" + react-shallow-renderer "^16.15.0" + scheduler "^0.23.2" -react@19.0.0-rc-fb9a90fa48-20240614: - version "19.0.0-rc-fb9a90fa48-20240614" - resolved "https://registry.yarnpkg.com/react/-/react-19.0.0-rc-fb9a90fa48-20240614.tgz#90eb43a0b005e8cc3cbf0d801c14816d01df1b08" - integrity sha512-nvE3Gy+IOIfH/DXhkyxFVQSrITarFcQz4+shzC/McxQXEUSonpw2oDy/Wi9hdDtV3hlP12VYuDL95iiBREedNQ== +react@18.3.1: + version "18.3.1" + resolved "https://registry.yarnpkg.com/react/-/react-18.3.1.tgz#49ab892009c53933625bd16b2533fc754cab2891" + integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ== + dependencies: + loose-envify "^1.1.0" readable-stream@^2.0.6, readable-stream@~2.3.6: version "2.3.8" @@ -7737,10 +7748,19 @@ safe-regex-test@^1.0.3: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -scheduler@0.25.0-rc-fb9a90fa48-20240614: - version "0.25.0-rc-fb9a90fa48-20240614" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.25.0-rc-fb9a90fa48-20240614.tgz#9ee11063b7c0f47aef3fea53d9f1be3f13794dce" - integrity sha512-HHqQ/SqbeiDfXXVKgNxTpbQTD4n7IUb4hZATvHjp03jr3TF7igehCyHdOjeYTrzIseLO93cTTfSb5f4qWcirMQ== +scheduler@0.24.0-canary-efb381bbf-20230505: + version "0.24.0-canary-efb381bbf-20230505" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.24.0-canary-efb381bbf-20230505.tgz#5dddc60e29f91cd7f8b983d7ce4a99c2202d178f" + integrity sha512-ABvovCDe/k9IluqSh4/ISoq8tIJnW8euVAWYt5j/bg6dRnqwQwiGO1F/V4AyK96NGF/FB04FhOUDuWj8IKfABA== + dependencies: + loose-envify "^1.1.0" + +scheduler@^0.23.2: + version "0.23.2" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.2.tgz#414ba64a3b282892e944cf2108ecc078d115cdc3" + integrity sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ== + dependencies: + loose-envify "^1.1.0" selfsigned@^2.4.1: version "2.4.1" From f5d7df6672b7282c9fdfe5673983da0ed86257b7 Mon Sep 17 00:00:00 2001 From: Sam Zhou Date: Fri, 8 Nov 2024 08:39:06 -0800 Subject: [PATCH 133/220] Pre-suppress errors to prepare for flow typing changes Summary: Changelog: [Internal] Reviewed By: cyan33 Differential Revision: D65633359 fbshipit-source-id: 7aaee2cab2d61b61eb5e1317d6b4ce58b6191fb8 --- .../src/generators/modules/__test_fixtures__/fixtures.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/react-native-codegen/src/generators/modules/__test_fixtures__/fixtures.js b/packages/react-native-codegen/src/generators/modules/__test_fixtures__/fixtures.js index a31493780327f8..c507530b28a389 100644 --- a/packages/react-native-codegen/src/generators/modules/__test_fixtures__/fixtures.js +++ b/packages/react-native-codegen/src/generators/modules/__test_fixtures__/fixtures.js @@ -1717,6 +1717,7 @@ const REAL_MODULE_EXAMPLE: SchemaType = { const CXX_ONLY_NATIVE_MODULES: SchemaType = { modules: { + // $FlowFixMe[incompatible-type] NativeSampleTurboModule: { type: 'NativeModule', aliasMap: { From 63ec67c5917c68633e174b3d59bde077dd9de8c4 Mon Sep 17 00:00:00 2001 From: Alex Hunt Date: Fri, 8 Nov 2024 09:16:21 -0800 Subject: [PATCH 134/220] Exclude Libraries/ReactPrivate/ from public-api-test Summary: As titled. This API is legacy / Meta-only. Changelog: [Internal] Reviewed By: cortinico Differential Revision: D65666574 fbshipit-source-id: f9700486aec0306b305910bff14ae7f3df3fab7f --- .../__snapshots__/public-api-test.js.snap | 31 ------------------- .../Libraries/__tests__/public-api-test.js | 2 ++ 2 files changed, 2 insertions(+), 31 deletions(-) diff --git a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap index d6551c65fc20bb..fccdab05e017a4 100644 --- a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap +++ b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap @@ -7755,37 +7755,6 @@ declare export default typeof requireNativeComponent; " `; -exports[`public API should not change unintentionally Libraries/ReactPrivate/ReactNativePrivateInitializeCore.js 1`] = `""`; - -exports[`public API should not change unintentionally Libraries/ReactPrivate/ReactNativePrivateInterface.js 1`] = ` -"declare module.exports: { - get BatchedBridge(): BatchedBridge, - get ExceptionsManager(): ExceptionsManager, - get Platform(): Platform, - get RCTEventEmitter(): RCTEventEmitter, - get ReactNativeViewConfigRegistry(): ReactNativeViewConfigRegistry, - get TextInputState(): TextInputState, - get UIManager(): UIManager, - get deepDiffer(): deepDiffer, - get deepFreezeAndThrowOnMutationInDev(): deepFreezeAndThrowOnMutationInDev< - { ... } | Array, - >, - get flattenStyle(): flattenStyle, - get ReactFiberErrorDialog(): ReactFiberErrorDialog, - get legacySendAccessibilityEvent(): legacySendAccessibilityEvent, - get RawEventEmitter(): RawEventEmitter, - get CustomEvent(): CustomEvent, - get createAttributePayload(): createAttributePayload, - get diffAttributePayloads(): diffAttributePayloads, - get createPublicInstance(): createPublicInstance, - get createPublicTextInstance(): createPublicTextInstance, - get getNativeTagFromPublicInstance(): getNativeTagFromPublicInstance, - get getNodeFromPublicInstance(): getNodeFromPublicInstance, - get getInternalInstanceHandleFromPublicInstance(): getInternalInstanceHandleFromPublicInstance, -}; -" -`; - exports[`public API should not change unintentionally Libraries/Settings/NativeSettingsManager.js 1`] = ` "export * from \\"../../src/private/specs/modules/NativeSettingsManager\\"; declare export default typeof NativeSettingsManager; diff --git a/packages/react-native/Libraries/__tests__/public-api-test.js b/packages/react-native/Libraries/__tests__/public-api-test.js index 08cdde71acf5ae..e9a499b709802e 100644 --- a/packages/react-native/Libraries/__tests__/public-api-test.js +++ b/packages/react-native/Libraries/__tests__/public-api-test.js @@ -29,6 +29,8 @@ const IGNORE_PATTERNS = [ // Non source files 'Libraries/Renderer/implementations/**', 'Libraries/Renderer/shims/**', + // ReactNativePrivateInterface + 'Libraries/ReactPrivate/**', ]; const sourceFiles = [ From 105f5f60001036b7494497432d342d284f4f1404 Mon Sep 17 00:00:00 2001 From: Pieter De Baets Date: Fri, 8 Nov 2024 09:31:12 -0800 Subject: [PATCH 135/220] Convert exceptions in com.facebook.react.bridge to Kotlin (#47493) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47493 Changelog: [Internal] Reviewed By: tdn120 Differential Revision: D65597240 fbshipit-source-id: 8014c756d7730bea617f6d27eb1e56d75c9156cf --- .../ReactAndroid/api/ReactAndroid.api | 25 ++++++------- .../react/bridge/AssertionException.java | 20 ----------- .../react/bridge/AssertionException.kt | 14 ++++++++ ...ption.java => InvalidIteratorException.kt} | 13 +++---- ... => JSApplicationCausedNativeException.kt} | 23 ++++-------- ...JSApplicationIllegalArgumentException.java | 20 ----------- .../JSApplicationIllegalArgumentException.kt | 16 +++++++++ .../bridge/NativeArgumentsParseException.java | 22 ------------ .../bridge/NativeArgumentsParseException.kt | 16 +++++++++ .../react/bridge/NoSuchKeyException.java | 20 ----------- .../react/bridge/NoSuchKeyException.kt | 14 ++++++++ ...java => ObjectAlreadyConsumedException.kt} | 13 +++---- .../ReactIgnorableMountingException.java | 36 ------------------- .../bridge/ReactIgnorableMountingException.kt | 35 ++++++++++++++++++ ...tNoCrashBridgeNotAllowedSoftException.java | 27 -------------- ...actNoCrashBridgeNotAllowedSoftException.kt | 17 +++++++++ .../bridge/ReactNoCrashSoftException.java | 29 --------------- .../react/bridge/ReactNoCrashSoftException.kt | 22 ++++++++++++ ...ava => RetryableMountingLayerException.kt} | 17 ++++----- 19 files changed, 168 insertions(+), 231 deletions(-) delete mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/AssertionException.java create mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/AssertionException.kt rename packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/{InvalidIteratorException.java => InvalidIteratorException.kt} (60%) rename packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/{JSApplicationCausedNativeException.java => JSApplicationCausedNativeException.kt} (61%) delete mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JSApplicationIllegalArgumentException.java create mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JSApplicationIllegalArgumentException.kt delete mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/NativeArgumentsParseException.java create mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/NativeArgumentsParseException.kt delete mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/NoSuchKeyException.java create mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/NoSuchKeyException.kt rename packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/{ObjectAlreadyConsumedException.java => ObjectAlreadyConsumedException.kt} (64%) delete mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactIgnorableMountingException.java create mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactIgnorableMountingException.kt delete mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactNoCrashBridgeNotAllowedSoftException.java create mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactNoCrashBridgeNotAllowedSoftException.kt delete mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactNoCrashSoftException.java create mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactNoCrashSoftException.kt rename packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/{RetryableMountingLayerException.java => RetryableMountingLayerException.kt} (52%) diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 1585de5f1e42c9..79fc6198a3301a 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -576,7 +576,7 @@ public class com/facebook/react/bridge/Arguments { public static fun toList (Lcom/facebook/react/bridge/ReadableArray;)Ljava/util/ArrayList; } -public class com/facebook/react/bridge/AssertionException : java/lang/RuntimeException { +public final class com/facebook/react/bridge/AssertionException : java/lang/RuntimeException { public fun (Ljava/lang/String;)V } @@ -833,7 +833,7 @@ public abstract interface class com/facebook/react/bridge/Inspector$RemoteConnec public abstract fun onMessage (Ljava/lang/String;)V } -public class com/facebook/react/bridge/InvalidIteratorException : java/lang/RuntimeException { +public final class com/facebook/react/bridge/InvalidIteratorException : java/lang/RuntimeException { public fun (Ljava/lang/String;)V } @@ -842,7 +842,7 @@ public class com/facebook/react/bridge/JSApplicationCausedNativeException : java public fun (Ljava/lang/String;Ljava/lang/Throwable;)V } -public class com/facebook/react/bridge/JSApplicationIllegalArgumentException : com/facebook/react/bridge/JSApplicationCausedNativeException { +public final class com/facebook/react/bridge/JSApplicationIllegalArgumentException : com/facebook/react/bridge/JSApplicationCausedNativeException { public fun (Ljava/lang/String;)V public fun (Ljava/lang/String;Ljava/lang/Throwable;)V } @@ -1082,7 +1082,7 @@ public class com/facebook/react/bridge/NativeModuleRegistry { public fun onBatchComplete ()V } -public class com/facebook/react/bridge/NoSuchKeyException : java/lang/RuntimeException { +public final class com/facebook/react/bridge/NoSuchKeyException : java/lang/RuntimeException { public fun (Ljava/lang/String;)V } @@ -1092,10 +1092,6 @@ public abstract interface class com/facebook/react/bridge/NotThreadSafeBridgeIdl public abstract fun onTransitionToBridgeIdle ()V } -public class com/facebook/react/bridge/ObjectAlreadyConsumedException : java/lang/RuntimeException { - public fun (Ljava/lang/String;)V -} - public abstract interface class com/facebook/react/bridge/OnBatchCompleteListener { public abstract fun onBatchComplete ()V } @@ -1244,11 +1240,16 @@ public class com/facebook/react/bridge/ReactCxxErrorHandler { public static fun setHandleErrorFunc (Ljava/lang/Object;Ljava/lang/reflect/Method;)V } -public class com/facebook/react/bridge/ReactIgnorableMountingException : java/lang/RuntimeException { +public final class com/facebook/react/bridge/ReactIgnorableMountingException : java/lang/RuntimeException { + public static final field Companion Lcom/facebook/react/bridge/ReactIgnorableMountingException$Companion; public fun (Ljava/lang/String;)V public fun (Ljava/lang/String;Ljava/lang/Throwable;)V public fun (Ljava/lang/Throwable;)V - public static fun isIgnorable (Ljava/lang/Throwable;)Z + public static final fun isIgnorable (Ljava/lang/Throwable;)Z +} + +public final class com/facebook/react/bridge/ReactIgnorableMountingException$Companion { + public final fun isIgnorable (Ljava/lang/Throwable;)Z } public class com/facebook/react/bridge/ReactInstanceManagerInspectorTarget : java/lang/AutoCloseable { @@ -1425,7 +1426,7 @@ public abstract interface annotation class com/facebook/react/bridge/ReactMethod public abstract interface class com/facebook/react/bridge/ReactModuleWithSpec { } -public class com/facebook/react/bridge/ReactNoCrashBridgeNotAllowedSoftException : com/facebook/react/bridge/ReactNoCrashSoftException { +public final class com/facebook/react/bridge/ReactNoCrashBridgeNotAllowedSoftException : com/facebook/react/bridge/ReactNoCrashSoftException { public fun (Ljava/lang/String;)V public fun (Ljava/lang/String;Ljava/lang/Throwable;)V public fun (Ljava/lang/Throwable;)V @@ -1542,7 +1543,7 @@ public final class com/facebook/react/bridge/ReadableType : java/lang/Enum { public static fun values ()[Lcom/facebook/react/bridge/ReadableType; } -public class com/facebook/react/bridge/RetryableMountingLayerException : java/lang/RuntimeException { +public final class com/facebook/react/bridge/RetryableMountingLayerException : java/lang/RuntimeException { public fun (Ljava/lang/String;)V public fun (Ljava/lang/String;Ljava/lang/Throwable;)V public fun (Ljava/lang/Throwable;)V diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/AssertionException.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/AssertionException.java deleted file mode 100644 index 5b39dd854c4a8d..00000000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/AssertionException.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and 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.bridge; - -/** - * Like {@link AssertionError} but extends RuntimeException so that it may be caught by a {@link - * JSExceptionHandler}. See that class for more details. Used in conjunction with {@link - * SoftAssertions}. - */ -public class AssertionException extends RuntimeException { - - public AssertionException(String detailMessage) { - super(detailMessage); - } -} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/AssertionException.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/AssertionException.kt new file mode 100644 index 00000000000000..fb9e153419fa72 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/AssertionException.kt @@ -0,0 +1,14 @@ +/* + * Copyright (c) Meta Platforms, Inc. and 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.bridge + +/** + * Like [AssertionError] but extends RuntimeException so that it may be caught by a + * [JSExceptionHandler]. See that class for more details. Used in conjunction with [SoftAssertions]. + */ +public class AssertionException(message: String) : RuntimeException(message) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/InvalidIteratorException.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/InvalidIteratorException.kt similarity index 60% rename from packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/InvalidIteratorException.java rename to packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/InvalidIteratorException.kt index 310c3862d60f94..4bcf98454d148e 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/InvalidIteratorException.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/InvalidIteratorException.kt @@ -5,19 +5,14 @@ * LICENSE file in the root directory of this source tree. */ -package com.facebook.react.bridge; +package com.facebook.react.bridge -import com.facebook.proguard.annotations.DoNotStrip; +import com.facebook.proguard.annotations.DoNotStrip /** * Exception thrown by {@link ReadableMapKeySetIterator#nextKey()} when the iterator tries to * iterate over elements after the end of the key set. */ @DoNotStrip -public class InvalidIteratorException extends RuntimeException { - - @DoNotStrip - public InvalidIteratorException(String msg) { - super(msg); - } -} +public class InvalidIteratorException public @DoNotStrip constructor(msg: String) : + RuntimeException(msg) {} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JSApplicationCausedNativeException.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JSApplicationCausedNativeException.kt similarity index 61% rename from packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JSApplicationCausedNativeException.java rename to packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JSApplicationCausedNativeException.kt index 4805dc855cb197..5ed7eb34d7fc7c 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JSApplicationCausedNativeException.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JSApplicationCausedNativeException.kt @@ -5,9 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -package com.facebook.react.bridge; - -import androidx.annotation.Nullable; +package com.facebook.react.bridge /** * A special RuntimeException that should be thrown by native code if it has reached an exceptional @@ -19,25 +17,18 @@ * this catalyst instance? * *

Examples where this class is appropriate to throw: - * *

    - *
  • JS tries to update a view with a tag that hasn't been created yet - *
  • JS tries to show a static image that isn't in resources - *
  • JS tries to use an unsupported view class + *
  • JS tries to update a view with a tag that hasn't been created yet + *
  • JS tries to show a static image that isn't in resources + *
  • JS tries to use an unsupported view class *
* *

Examples where this class **isn't** appropriate to throw: - Failed to write to localStorage * because disk is full - Assertions about internal state (e.g. that * child.getParent().indexOf(child) != -1) */ -public class JSApplicationCausedNativeException extends RuntimeException { - - public JSApplicationCausedNativeException(String detailMessage) { - super(detailMessage); - } +public open class JSApplicationCausedNativeException : RuntimeException { + public constructor(detailMessage: String) : super(detailMessage) - public JSApplicationCausedNativeException( - @Nullable String detailMessage, @Nullable Throwable throwable) { - super(detailMessage, throwable); - } + public constructor(detailMessage: String, throwable: Throwable?) : super(detailMessage, throwable) } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JSApplicationIllegalArgumentException.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JSApplicationIllegalArgumentException.java deleted file mode 100644 index 47d4a94129f102..00000000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JSApplicationIllegalArgumentException.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and 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.bridge; - -/** An illegal argument Exception caused by an argument passed from JS. */ -public class JSApplicationIllegalArgumentException extends JSApplicationCausedNativeException { - - public JSApplicationIllegalArgumentException(String detailMessage) { - super(detailMessage); - } - - public JSApplicationIllegalArgumentException(String detailMessage, Throwable t) { - super(detailMessage, t); - } -} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JSApplicationIllegalArgumentException.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JSApplicationIllegalArgumentException.kt new file mode 100644 index 00000000000000..2fe3d505a68cd2 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JSApplicationIllegalArgumentException.kt @@ -0,0 +1,16 @@ +/* + * Copyright (c) Meta Platforms, Inc. and 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.bridge + +/** An illegal argument Exception caused by an argument passed from JS. */ +public class JSApplicationIllegalArgumentException : JSApplicationCausedNativeException { + + public constructor(detailMessage: String) : super(detailMessage) + + public constructor(detailMessage: String, t: Throwable) : super(detailMessage, t) +} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/NativeArgumentsParseException.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/NativeArgumentsParseException.java deleted file mode 100644 index 974fcfc944926e..00000000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/NativeArgumentsParseException.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and 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.bridge; - -import androidx.annotation.Nullable; - -/** Exception thrown when a native module method call receives unexpected arguments from JS. */ -class NativeArgumentsParseException extends JSApplicationCausedNativeException { - - public NativeArgumentsParseException(String detailMessage) { - super(detailMessage); - } - - public NativeArgumentsParseException(@Nullable String detailMessage, @Nullable Throwable t) { - super(detailMessage, t); - } -} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/NativeArgumentsParseException.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/NativeArgumentsParseException.kt new file mode 100644 index 00000000000000..6fb3d735e0b437 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/NativeArgumentsParseException.kt @@ -0,0 +1,16 @@ +/* + * Copyright (c) Meta Platforms, Inc. and 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.bridge + +/** Exception thrown when a native module method call receives unexpected arguments from JS. */ +internal class NativeArgumentsParseException : JSApplicationCausedNativeException { + + public constructor(detailMessage: String) : super(detailMessage) + + public constructor(detailMessage: String, throwable: Throwable?) : super(detailMessage, throwable) +} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/NoSuchKeyException.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/NoSuchKeyException.java deleted file mode 100644 index 7e8c2cae409da4..00000000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/NoSuchKeyException.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and 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.bridge; - -import com.facebook.proguard.annotations.DoNotStrip; - -/** Exception thrown by {@link ReadableNativeMap} when a key that does not exist is requested. */ -@DoNotStrip -public class NoSuchKeyException extends RuntimeException { - - @DoNotStrip - public NoSuchKeyException(String msg) { - super(msg); - } -} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/NoSuchKeyException.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/NoSuchKeyException.kt new file mode 100644 index 00000000000000..76d17cf927a823 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/NoSuchKeyException.kt @@ -0,0 +1,14 @@ +/* + * Copyright (c) Meta Platforms, Inc. and 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.bridge + +import com.facebook.proguard.annotations.DoNotStrip + +/** Exception thrown by [ReadableNativeMap] when a key that does not exist is requested. */ +@DoNotStrip +public class NoSuchKeyException @DoNotStrip constructor(msg: String) : RuntimeException(msg) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ObjectAlreadyConsumedException.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ObjectAlreadyConsumedException.kt similarity index 64% rename from packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ObjectAlreadyConsumedException.java rename to packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ObjectAlreadyConsumedException.kt index ef8cc78303384b..34cd394fafa636 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ObjectAlreadyConsumedException.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ObjectAlreadyConsumedException.kt @@ -5,9 +5,9 @@ * LICENSE file in the root directory of this source tree. */ -package com.facebook.react.bridge; +package com.facebook.react.bridge -import com.facebook.proguard.annotations.DoNotStrip; +import com.facebook.proguard.annotations.DoNotStrip /** * Exception thrown when a caller attempts to modify or use a {@link WritableNativeArray} or {@link @@ -15,10 +15,5 @@ * we reuse the native memory so the underlying array/map is no longer valid. */ @DoNotStrip -public class ObjectAlreadyConsumedException extends RuntimeException { - - @DoNotStrip - public ObjectAlreadyConsumedException(String detailMessage) { - super(detailMessage); - } -} +internal class ObjectAlreadyConsumedException +public @DoNotStrip constructor(detailMessage: String) : RuntimeException(detailMessage) {} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactIgnorableMountingException.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactIgnorableMountingException.java deleted file mode 100644 index b77c7eed46fca9..00000000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactIgnorableMountingException.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and 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.bridge; - -/** - * If thrown during a MountItem execution, FabricUIManager will print diagnostics and ignore the - * error. Use this carefully and sparingly! - */ -public class ReactIgnorableMountingException extends RuntimeException { - public ReactIgnorableMountingException(String m) { - super(m); - } - - public ReactIgnorableMountingException(String m, Throwable e) { - super(m, e); - } - - public ReactIgnorableMountingException(Throwable e) { - super(e); - } - - public static boolean isIgnorable(Throwable e) { - while (e != null) { - if (e instanceof ReactIgnorableMountingException) { - return true; - } - e = e.getCause(); - } - return false; - } -} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactIgnorableMountingException.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactIgnorableMountingException.kt new file mode 100644 index 00000000000000..37a6f743bfddc7 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactIgnorableMountingException.kt @@ -0,0 +1,35 @@ +/* + * Copyright (c) Meta Platforms, Inc. and 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.bridge + +/** + * If thrown during a MountItem execution, FabricUIManager will print diagnostics and ignore the + * error. Use this carefully and sparingly! + */ +public class ReactIgnorableMountingException : RuntimeException { + + public constructor(m: String) : super(m) + + public constructor(e: Throwable) : super(e) + + public constructor(m: String, e: Throwable) : super(m, e) + + public companion object { + @JvmStatic + public fun isIgnorable(e: Throwable): Boolean { + var cause: Throwable? = e + while (cause != null) { + if (cause is ReactIgnorableMountingException) { + return true + } + cause = cause.cause + } + return false + } + } +} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactNoCrashBridgeNotAllowedSoftException.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactNoCrashBridgeNotAllowedSoftException.java deleted file mode 100644 index d4264167e6c4e1..00000000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactNoCrashBridgeNotAllowedSoftException.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and 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.bridge; - -/** - * Extends RuntimeException so that it may be caught by a {@link ReactSoftExceptionListener}. Any - * {@link ReactSoftExceptionListener} that catches a ReactNoCrashBridgeNotAllowedSoftException - * should log it only and not crash, no matter what. - */ -public class ReactNoCrashBridgeNotAllowedSoftException extends ReactNoCrashSoftException { - public ReactNoCrashBridgeNotAllowedSoftException(String m) { - super(m); - } - - public ReactNoCrashBridgeNotAllowedSoftException(Throwable e) { - super(e); - } - - public ReactNoCrashBridgeNotAllowedSoftException(String m, Throwable e) { - super(m, e); - } -} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactNoCrashBridgeNotAllowedSoftException.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactNoCrashBridgeNotAllowedSoftException.kt new file mode 100644 index 00000000000000..3e22f0c8211c67 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactNoCrashBridgeNotAllowedSoftException.kt @@ -0,0 +1,17 @@ +/* + * Copyright (c) Meta Platforms, Inc. and 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.bridge + +public class ReactNoCrashBridgeNotAllowedSoftException : ReactNoCrashSoftException { + + public constructor(m: String) : super(m) + + public constructor(e: Throwable) : super(e) + + public constructor(m: String, e: Throwable) : super(m, e) +} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactNoCrashSoftException.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactNoCrashSoftException.java deleted file mode 100644 index eef596686d5b70..00000000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactNoCrashSoftException.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and 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.bridge; - -import javax.annotation.Nullable; - -/** - * Extends RuntimeException so that it may be caught by a {@link ReactSoftExceptionListener}. Any - * {@link ReactSoftExceptionListener} that catches a ReactNoCrashSoftException should log it only - * and not crash, no matter what. - */ -public class ReactNoCrashSoftException extends RuntimeException { - public ReactNoCrashSoftException(String m) { - super(m); - } - - public ReactNoCrashSoftException(Throwable e) { - super(e); - } - - public ReactNoCrashSoftException(String m, @Nullable Throwable e) { - super(m, e); - } -} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactNoCrashSoftException.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactNoCrashSoftException.kt new file mode 100644 index 00000000000000..5ed13bd9fa3ce2 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactNoCrashSoftException.kt @@ -0,0 +1,22 @@ +/* + * Copyright (c) Meta Platforms, Inc. and 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.bridge + +/** + * Extends RuntimeException so that it may be caught by a [ReactSoftExceptionListener]. Any + * [ReactSoftExceptionListener] that catches a ReactNoCrashSoftException should log it only and not + * crash, no matter what. + */ +public open class ReactNoCrashSoftException : RuntimeException { + + public constructor(m: String) : super(m) + + public constructor(e: Throwable) : super(e) + + public constructor(m: String, e: Throwable?) : super(m, e) +} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/RetryableMountingLayerException.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/RetryableMountingLayerException.kt similarity index 52% rename from packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/RetryableMountingLayerException.java rename to packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/RetryableMountingLayerException.kt index fbb9856ddeba11..3759fffa6d9ea5 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/RetryableMountingLayerException.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/RetryableMountingLayerException.kt @@ -5,22 +5,17 @@ * LICENSE file in the root directory of this source tree. */ -package com.facebook.react.bridge; +package com.facebook.react.bridge /** * ViewCommands can throw this Exception. If this is caught during the execution of a ViewCommand * mounting instruction, it indicates that the mount item can be safely retried. */ -public class RetryableMountingLayerException extends RuntimeException { - public RetryableMountingLayerException(String msg, Throwable e) { - super(msg, e); - } +public class RetryableMountingLayerException : RuntimeException { - public RetryableMountingLayerException(Throwable e) { - super(e); - } + public constructor(msg: String) : super(msg) - public RetryableMountingLayerException(String msg) { - super(msg); - } + public constructor(e: Throwable) : super(e) + + public constructor(msg: String, e: Throwable?) : super(msg, e) } From 090501d26d83be5c5d2df885c60d05ec133d7a54 Mon Sep 17 00:00:00 2001 From: Tim Yung Date: Fri, 8 Nov 2024 10:22:12 -0800 Subject: [PATCH 136/220] RN: Enable `scheduleAnimatedEndCallbackInMicrotask` (#47503) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47503 Enables the `scheduleAnimatedEndCallbackInMicrotask` feature flag that was introduced in https://github.com/facebook/react-native/pull/46714. Changelog: [General][Changed] - Callbacks passed to `animation.start()` will be scheduled for execution in a microtask. Previously, there were certain scenarios in which the callback could be synchronously executed by `start`. Reviewed By: javache Differential Revision: D65645981 fbshipit-source-id: ac159208b7c1df60549baa52704bb0e704da0acf --- .../Libraries/Animated/__tests__/Animated-test.js | 9 +++++++-- .../Libraries/Animated/animations/Animation.js | 6 +----- .../featureflags/ReactNativeFeatureFlags.config.js | 9 --------- .../src/private/featureflags/ReactNativeFeatureFlags.js | 8 +------- 4 files changed, 9 insertions(+), 23 deletions(-) diff --git a/packages/react-native/Libraries/Animated/__tests__/Animated-test.js b/packages/react-native/Libraries/Animated/__tests__/Animated-test.js index ba471e03a12f60..fde378c260b879 100644 --- a/packages/react-native/Libraries/Animated/__tests__/Animated-test.js +++ b/packages/react-native/Libraries/Animated/__tests__/Animated-test.js @@ -121,10 +121,12 @@ describe('Animated', () => { await unmount(root); + expect(callback).not.toBeCalled(); + await jest.runOnlyPendingTimersAsync(); expect(callback).toBeCalledWith({finished: false}); }); - it('triggers callback when spring is at rest', () => { + it('triggers callback when spring is at rest', async () => { const anim = new Animated.Value(0); const callback = jest.fn(); Animated.spring(anim, { @@ -132,7 +134,10 @@ describe('Animated', () => { velocity: 0, useNativeDriver: false, }).start(callback); - expect(callback).toBeCalled(); + + expect(callback).not.toBeCalled(); + await jest.runOnlyPendingTimersAsync(); + expect(callback).toBeCalledWith({finished: true}); }); it('send toValue when a critically damped spring stops', () => { diff --git a/packages/react-native/Libraries/Animated/animations/Animation.js b/packages/react-native/Libraries/Animated/animations/Animation.js index ad5163b8ab4101..7d26ce2617bfec 100644 --- a/packages/react-native/Libraries/Animated/animations/Animation.js +++ b/packages/react-native/Libraries/Animated/animations/Animation.js @@ -165,11 +165,7 @@ export default class Animation { const callback = this.#onEnd; if (callback != null) { this.#onEnd = null; - if (ReactNativeFeatureFlags.scheduleAnimatedEndCallbackInMicrotask()) { - queueMicrotask(() => callback(result)); - } else { - callback(result); - } + queueMicrotask(() => callback(result)); } } } diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index 0aa841bcaafa21..e6e7a5a2a710be 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -560,15 +560,6 @@ const definitions: FeatureFlagDefinitions = { purpose: 'release', }, }, - scheduleAnimatedEndCallbackInMicrotask: { - defaultValue: false, - metadata: { - dateAdded: '2024-09-27', - description: - 'Changes the completion callback supplied via `Animation#start` to be scheduled in a microtask instead of synchronously executed.', - purpose: 'experimentation', - }, - }, shouldSkipStateUpdatesForLoopingAnimations: { defaultValue: false, metadata: { diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index 7d796d7984642b..10977d3603e4fd 100644 --- a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<650ba11a0ac49b9779c6c98f57f7369f>> + * @generated SignedSource<<716c4507093099c254b57d744366bd05>> * @flow strict */ @@ -37,7 +37,6 @@ export type ReactNativeFeatureFlagsJsOnly = { enableAnimatedPropsMemo: Getter, enableOptimisedVirtualizedCells: Getter, isLayoutAnimationEnabled: Getter, - scheduleAnimatedEndCallbackInMicrotask: Getter, shouldSkipStateUpdatesForLoopingAnimations: Getter, shouldUseAnimatedObjectForTransform: Getter, shouldUseRemoveClippedSubviewsAsDefaultOnIOS: Getter, @@ -154,11 +153,6 @@ export const enableOptimisedVirtualizedCells: Getter = createJavaScript */ export const isLayoutAnimationEnabled: Getter = createJavaScriptFlagGetter('isLayoutAnimationEnabled', true); -/** - * Changes the completion callback supplied via `Animation#start` to be scheduled in a microtask instead of synchronously executed. - */ -export const scheduleAnimatedEndCallbackInMicrotask: Getter = createJavaScriptFlagGetter('scheduleAnimatedEndCallbackInMicrotask', false); - /** * If the animation is within Animated.loop, we do not send state updates to React. */ From 2ec547ad28ca914c17e276abb91174dfa0dc87b2 Mon Sep 17 00:00:00 2001 From: Pieter De Baets Date: Fri, 8 Nov 2024 10:26:50 -0800 Subject: [PATCH 137/220] Remove concurrentRoot from initialProps (#47512) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47512 As can be seen in `renderApplication`, `useConcurrentRoot` is no longer used to decide whether to run the application in concurrent mode, as we default all Fabric-users to concurrent root. Changelog: [General][Removed] Removed type for useConcurrentRoot from AppRegistry, as it was already ignored Reviewed By: sammy-SC, fabriziocucci Differential Revision: D65660681 fbshipit-source-id: c99e5ae14d515015709908ed21a854c780f628e0 --- .../AppDelegate/RCTRootViewFactory.mm | 27 +++++-------------- .../Libraries/ReactNative/AppRegistry.js | 6 ----- .../ReactNative/renderApplication.js | 7 +++-- .../__snapshots__/public-api-test.js.snap | 2 -- 4 files changed, 9 insertions(+), 33 deletions(-) diff --git a/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.mm b/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.mm index a92596cb67cc9c..d0f5379c919db5 100644 --- a/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.mm +++ b/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.mm @@ -38,17 +38,6 @@ #import #import -static NSString *const kRNConcurrentRoot = @"concurrentRoot"; - -static NSDictionary *updateInitialProps(NSDictionary *initialProps, BOOL isFabricEnabled) -{ - NSMutableDictionary *mutableProps = initialProps != NULL ? [initialProps mutableCopy] : [NSMutableDictionary new]; - // Hardcoding the Concurrent Root as it it not recommended to - // have the concurrentRoot turned off when Fabric is enabled. - mutableProps[kRNConcurrentRoot] = @(isFabricEnabled); - return mutableProps; -} - @implementation RCTRootViewFactoryConfiguration - (instancetype)initWithBundleURL:(NSURL *)bundleURL newArchEnabled:(BOOL)newArchEnabled @@ -149,11 +138,9 @@ - (UIView *)viewWithModuleName:(NSString *)moduleName } - (UIView *)viewWithModuleName:(NSString *)moduleName - initialProperties:(NSDictionary *)initialProperties + initialProperties:(NSDictionary *)initProps launchOptions:(NSDictionary *)launchOptions { - NSDictionary *initProps = updateInitialProps(initialProperties, _configuration.fabricEnabled); - if (_configuration.bridgelessEnabled) { // Enable TurboModule interop by default in Bridgeless mode RCTEnableTurboModuleInterop(YES); @@ -167,8 +154,8 @@ - (UIView *)viewWithModuleName:(NSString *)moduleName [[RCTSurfaceHostingProxyRootView alloc] initWithSurface:surface]; surfaceHostingProxyRootView.backgroundColor = [UIColor systemBackgroundColor]; - if (self->_configuration.customizeRootView != nil) { - self->_configuration.customizeRootView(surfaceHostingProxyRootView); + if (_configuration.customizeRootView != nil) { + _configuration.customizeRootView(surfaceHostingProxyRootView); } return surfaceHostingProxyRootView; } @@ -182,8 +169,8 @@ - (UIView *)viewWithModuleName:(NSString *)moduleName } else { rootView = [self createRootViewWithBridge:self.bridge moduleName:moduleName initProps:initProps]; } - if (self->_configuration.customizeRootView != nil) { - self->_configuration.customizeRootView(rootView); + if (_configuration.customizeRootView != nil) { + _configuration.customizeRootView(rootView); } return rootView; } @@ -197,11 +184,9 @@ - (UIView *)createRootViewWithBridge:(RCTBridge *)bridge moduleName:(NSString *)moduleName initProps:(NSDictionary *)initProps { - BOOL enableFabric = self->_configuration.fabricEnabled; + BOOL enableFabric = _configuration.fabricEnabled; UIView *rootView = RCTAppSetupDefaultRootView(bridge, moduleName, initProps, enableFabric); - rootView.backgroundColor = [UIColor systemBackgroundColor]; - return rootView; } diff --git a/packages/react-native/Libraries/ReactNative/AppRegistry.js b/packages/react-native/Libraries/ReactNative/AppRegistry.js index 79e2bdc97d50ae..6c18c8d6170a9c 100644 --- a/packages/react-native/Libraries/ReactNative/AppRegistry.js +++ b/packages/react-native/Libraries/ReactNative/AppRegistry.js @@ -46,7 +46,6 @@ type AppParameters = { initialProps: $ReadOnly<{[string]: mixed, ...}>, rootTag: RootTag, fabric?: boolean, - concurrentRoot?: boolean, }; export type Runnable = ( appParameters: AppParameters, @@ -120,10 +119,6 @@ const AppRegistry = { ): string { const scopedPerformanceLogger = createPerformanceLogger(); runnables[appKey] = (appParameters, displayMode) => { - const concurrentRootEnabled = Boolean( - appParameters.initialProps?.concurrentRoot || - appParameters.concurrentRoot, - ); renderApplication( componentProviderInstrumentationHook( componentProvider, @@ -138,7 +133,6 @@ const AppRegistry = { appKey === 'LogBox', // is logbox appKey, displayMode, - concurrentRootEnabled, ); }; if (section) { diff --git a/packages/react-native/Libraries/ReactNative/renderApplication.js b/packages/react-native/Libraries/ReactNative/renderApplication.js index 782014a52dd584..de0f46108e35c7 100644 --- a/packages/react-native/Libraries/ReactNative/renderApplication.js +++ b/packages/react-native/Libraries/ReactNative/renderApplication.js @@ -41,7 +41,6 @@ export default function renderApplication( isLogBox?: boolean, debugName?: string, displayMode?: ?DisplayModeType, - useConcurrentRoot?: boolean, useOffscreen?: boolean, ) { invariant(rootTag, 'Expect to have a valid rootTag, instead got ', rootTag); @@ -87,12 +86,12 @@ export default function renderApplication( } // We want to have concurrentRoot always enabled when you're on Fabric. - const useConcurrentRootOverride = fabric; + const useConcurrentRoot = Boolean(fabric); performanceLogger.startTimespan('renderApplication_React_render'); performanceLogger.setExtra( 'usedReactConcurrentRoot', - useConcurrentRootOverride ? '1' : '0', + useConcurrentRoot ? '1' : '0', ); performanceLogger.setExtra('usedReactFabric', fabric ? '1' : '0'); performanceLogger.setExtra( @@ -103,7 +102,7 @@ export default function renderApplication( element: renderable, rootTag, useFabric: Boolean(fabric), - useConcurrentRoot: Boolean(useConcurrentRootOverride), + useConcurrentRoot, }); performanceLogger.stopTimespan('renderApplication_React_render'); } diff --git a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap index fccdab05e017a4..53b141bdc6d442 100644 --- a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap +++ b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap @@ -7381,7 +7381,6 @@ type AppParameters = { initialProps: $ReadOnly<{ [string]: mixed, ... }>, rootTag: RootTag, fabric?: boolean, - concurrentRoot?: boolean, }; export type Runnable = ( appParameters: AppParameters, @@ -7741,7 +7740,6 @@ exports[`public API should not change unintentionally Libraries/ReactNative/rend isLogBox?: boolean, debugName?: string, displayMode?: ?DisplayModeType, - useConcurrentRoot?: boolean, useOffscreen?: boolean ): void; " From e3c3a0c8a7c052ecd47eece92063a7fda33bc55c Mon Sep 17 00:00:00 2001 From: Pieter De Baets Date: Fri, 8 Nov 2024 10:37:37 -0800 Subject: [PATCH 138/220] Migrate NativeModuleRegistryBuilder to Kotlin (#47508) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47508 Changelog: [Internal] Reviewed By: tdn120 Differential Revision: D60037204 fbshipit-source-id: 2b405e492520e075b83a075009d25fb7b7fa8925 --- .../ReactAndroid/api/ReactAndroid.api | 7 +- .../react/NativeModuleRegistryBuilder.java | 69 ------------------- .../react/NativeModuleRegistryBuilder.kt | 61 ++++++++++++++++ .../facebook/react/ReactInstanceManager.java | 2 +- 4 files changed, 66 insertions(+), 73 deletions(-) delete mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/NativeModuleRegistryBuilder.java create mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/NativeModuleRegistryBuilder.kt diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 79fc6198a3301a..c0294c6d8e4287 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -68,10 +68,11 @@ public class com/facebook/react/MemoryPressureRouter : android/content/Component public fun removeMemoryPressureListener (Lcom/facebook/react/bridge/MemoryPressureListener;)V } -public class com/facebook/react/NativeModuleRegistryBuilder { +public final class com/facebook/react/NativeModuleRegistryBuilder { + public fun (Lcom/facebook/react/bridge/ReactApplicationContext;)V public fun (Lcom/facebook/react/bridge/ReactApplicationContext;Lcom/facebook/react/ReactInstanceManager;)V - public fun build ()Lcom/facebook/react/bridge/NativeModuleRegistry; - public fun processPackage (Lcom/facebook/react/ReactPackage;)V + public final fun build ()Lcom/facebook/react/bridge/NativeModuleRegistry; + public final fun processPackage (Lcom/facebook/react/ReactPackage;)V } public abstract class com/facebook/react/ReactActivity : androidx/appcompat/app/AppCompatActivity, com/facebook/react/modules/core/DefaultHardwareBackBtnHandler, com/facebook/react/modules/core/PermissionAwareActivity { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/NativeModuleRegistryBuilder.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/NativeModuleRegistryBuilder.java deleted file mode 100644 index a33bc6e732b563..00000000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/NativeModuleRegistryBuilder.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and 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; - -import com.facebook.react.bridge.ModuleHolder; -import com.facebook.react.bridge.NativeModuleRegistry; -import com.facebook.react.bridge.ReactApplicationContext; -import java.util.HashMap; -import java.util.Map; - -/** Helper class to build NativeModuleRegistry. */ -public class NativeModuleRegistryBuilder { - - private final ReactApplicationContext mReactApplicationContext; - - private final Map mModules = new HashMap<>(); - - public NativeModuleRegistryBuilder( - ReactApplicationContext reactApplicationContext, ReactInstanceManager reactInstanceManager) { - mReactApplicationContext = reactApplicationContext; - } - - public void processPackage(ReactPackage reactPackage) { - // We use an iterable instead of an iterator here to ensure thread safety, and that this list - // cannot be modified - Iterable moduleHolders; - if (reactPackage instanceof LazyReactPackage) { - moduleHolders = - ((LazyReactPackage) reactPackage).getNativeModuleIterator(mReactApplicationContext); - } else if (reactPackage instanceof BaseReactPackage) { - moduleHolders = - ((BaseReactPackage) reactPackage).getNativeModuleIterator(mReactApplicationContext); - } else { - moduleHolders = - ReactPackageHelper.getNativeModuleIterator(reactPackage, mReactApplicationContext); - } - - for (ModuleHolder moduleHolder : moduleHolders) { - String name = moduleHolder.getName(); - if (mModules.containsKey(name)) { - ModuleHolder existingNativeModule = mModules.get(name); - if (!moduleHolder.getCanOverrideExistingModule()) { - throw new IllegalStateException( - "Native module " - + name - + " tried to override " - + existingNativeModule.getClassName() - + ". Check the getPackages() method in MainApplication.java, it might be that" - + " module is being created twice. If this was your intention, set" - + " canOverrideExistingModule=true. This error may also be present if the package" - + " is present only once in getPackages() but is also automatically added later" - + " during build time by autolinking. Try removing the existing entry and" - + " rebuild."); - } - mModules.remove(existingNativeModule); - } - mModules.put(name, moduleHolder); - } - } - - public NativeModuleRegistry build() { - return new NativeModuleRegistry(mReactApplicationContext, mModules); - } -} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/NativeModuleRegistryBuilder.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/NativeModuleRegistryBuilder.kt new file mode 100644 index 00000000000000..b50070c3d175a8 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/NativeModuleRegistryBuilder.kt @@ -0,0 +1,61 @@ +/* + * Copyright (c) Meta Platforms, Inc. and 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 + +import com.facebook.react.bridge.ModuleHolder +import com.facebook.react.bridge.NativeModuleRegistry +import com.facebook.react.bridge.ReactApplicationContext + +/** Helper class to build NativeModuleRegistry. */ +public class NativeModuleRegistryBuilder( + private val reactApplicationContext: ReactApplicationContext, +) { + + private val modules = HashMap() + + @Deprecated( + "ReactInstanceManager is not used", + ReplaceWith("NativeModuleRegistryBuilder(reactApplicationContext)")) + public constructor( + reactApplicationContext: ReactApplicationContext, + @Suppress("UNUSED_PARAMETER") reactInstanceManager: ReactInstanceManager + ) : this(reactApplicationContext) {} + + public fun processPackage(reactPackage: ReactPackage) { + // We use an iterable instead of an iterator here to ensure thread safety, and that this list + // cannot be modified + val moduleHolders = + @Suppress("DEPRECATION") + if (reactPackage is LazyReactPackage) { + reactPackage.getNativeModuleIterator(reactApplicationContext) + } else if (reactPackage is BaseReactPackage) { + reactPackage.getNativeModuleIterator(reactApplicationContext) + } else { + ReactPackageHelper.getNativeModuleIterator(reactPackage, reactApplicationContext) + } + for (moduleHolder in moduleHolders) { + val name = moduleHolder.name + val existingNativeModule = modules[name] + if (existingNativeModule != null) { + check(moduleHolder.canOverrideExistingModule) { + """ +Native module $name tried to override ${existingNativeModule.className}. + +Check the getPackages() method in MainApplication.java, it might be that module is being created twice. +If this was your intention, set canOverrideExistingModule=true. This error may also be present if the +package is present only once in getPackages() but is also automatically added later during build time +by autolinking. Try removing the existing entry and rebuild. +""" + } + } + modules[name] = moduleHolder + } + } + + public fun build(): NativeModuleRegistry = NativeModuleRegistry(reactApplicationContext, modules) +} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java index dc07b2bfaaf093..1ba517b3075851 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java @@ -1536,7 +1536,7 @@ private ReactApplicationContext createReactContext( private NativeModuleRegistry processPackages( ReactApplicationContext reactContext, List packages) { NativeModuleRegistryBuilder nativeModuleRegistryBuilder = - new NativeModuleRegistryBuilder(reactContext, this); + new NativeModuleRegistryBuilder(reactContext); ReactMarker.logMarker(PROCESS_PACKAGES_START); From ee7b4e276355146be53958b402bfb2d5af2dd1bc Mon Sep 17 00:00:00 2001 From: Jakub Piasecki Date: Fri, 8 Nov 2024 11:07:26 -0800 Subject: [PATCH 139/220] Fix timers in headless tasks on bridgeless mode (#47496) Summary: Fixes https://github.com/facebook/react-native/issues/47495 `JavaTimerManager` is being registered to receive headless tasks events in the [`TimingModule`](https://github.com/facebook/react-native/blob/0ee963ea65bcc88122044d51027511e611bde584/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/core/TimingModule.kt#L28-L29). This module is not used on bridgeless: [1](https://github.com/facebook/react-native/blob/0ee963ea65bcc88122044d51027511e611bde584/packages/react-native/Libraries/Core/setUpTimers.js#L44-L61), [2](https://github.com/facebook/react-native/blob/0ee963ea65bcc88122044d51027511e611bde584/packages/react-native/Libraries/Core/setUpTimers.js#L123-L132) and since it's loaded lazily, the event listener is never registered. This PR moves registration to the constructor of `JavaTimerManager` and deregistration to the `onInstanceDestroy` method. This way the event listener is always registered when an instance of the timer manager exists. ## Changelog: [ANDROID] [FIXED] - Fix timers in headless tasks on bridgeless mode Pull Request resolved: https://github.com/facebook/react-native/pull/47496 Test Plan: See the reproducer from the issue Reviewed By: javache Differential Revision: D65615601 Pulled By: alanleedev fbshipit-source-id: 6e1d36f8783e813065f79730a928b99c3e385718 --- packages/react-native/ReactAndroid/api/ReactAndroid.api | 1 - .../com/facebook/react/modules/core/JavaTimerManager.kt | 2 ++ .../java/com/facebook/react/modules/core/TimingModule.kt | 8 -------- 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index c0294c6d8e4287..803129424c9b6d 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -3182,7 +3182,6 @@ public final class com/facebook/react/modules/core/TimingModule : com/facebook/f public fun createTimer (DDDZ)V public fun deleteTimer (D)V public fun emitTimeDriftWarning (Ljava/lang/String;)V - public fun initialize ()V public fun invalidate ()V public fun setSendIdleEvents (Z)V } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/core/JavaTimerManager.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/core/JavaTimerManager.kt index ecce67478dd9d0..8b6571698fc5dd 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/core/JavaTimerManager.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/core/JavaTimerManager.kt @@ -65,6 +65,7 @@ public open class JavaTimerManager( init { reactApplicationContext.addLifecycleEventListener(this) + HeadlessJsTaskContext.getInstance(reactApplicationContext).addTaskEventListener(this) } override fun onHostPause() { @@ -103,6 +104,7 @@ public open class JavaTimerManager( } public open fun onInstanceDestroy() { + HeadlessJsTaskContext.getInstance(reactApplicationContext).removeTaskEventListener(this) reactApplicationContext.removeLifecycleEventListener(this) clearFrameCallback() clearChoreographerIdleCallback() diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/core/TimingModule.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/core/TimingModule.kt index bfa0219acf2454..caf7846a322d86 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/core/TimingModule.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/core/TimingModule.kt @@ -12,7 +12,6 @@ import com.facebook.react.bridge.ReactApplicationContext import com.facebook.react.bridge.WritableArray import com.facebook.react.common.annotations.VisibleForTesting import com.facebook.react.devsupport.interfaces.DevSupportManager -import com.facebook.react.jstasks.HeadlessJsTaskContext import com.facebook.react.module.annotations.ReactModule /** Native module for JS timer execution. Timers fire on frame boundaries. */ @@ -24,11 +23,6 @@ public class TimingModule( private val javaTimerManager: JavaTimerManager = JavaTimerManager(reactContext, this, ReactChoreographer.getInstance(), devSupportManager) - override fun initialize() { - HeadlessJsTaskContext.getInstance(getReactApplicationContext()) - .addTaskEventListener(javaTimerManager) - } - override fun createTimer( callbackIDDouble: Double, durationDouble: Double, @@ -68,8 +62,6 @@ public class TimingModule( } override fun invalidate() { - val headlessJsTaskContext = HeadlessJsTaskContext.getInstance(getReactApplicationContext()) - headlessJsTaskContext.removeTaskEventListener(javaTimerManager) javaTimerManager.onInstanceDestroy() } From 2f7957f2fd424fdaa980d99a4ff05eb3237d662e Mon Sep 17 00:00:00 2001 From: Pieter De Baets Date: Fri, 8 Nov 2024 11:32:51 -0800 Subject: [PATCH 140/220] Merge RawText sequences (#47278) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47278 When we have multiple spans of text inside a element, React will emit these as separate RawText ShadowNodes. RawText shadow nodes cannot have any properties beyond the text they contain, yet our current AttributedText logic will generate a separate span for each and duplicate all the relevant properties. This can be particularly inefficient when JSX is used to interpolate strings, e.g. `Example {i}/{count}` results in 4 raw text elements with duplicated properties. Changelog: [General][Changed] Improved AttributedText generation for raw text nodes. Reviewed By: NickGerleman Differential Revision: D65134912 fbshipit-source-id: dba4296ebe9987e989760cdee66f1e076fbb7a98 --- .../components/text/BaseTextShadowNode.cpp | 27 ++++-- .../text/tests/BaseTextShadowNodeTest.cpp | 93 +++++++++++++++++++ 2 files changed, 111 insertions(+), 9 deletions(-) create mode 100644 packages/react-native/ReactCommon/react/renderer/components/text/tests/BaseTextShadowNodeTest.cpp diff --git a/packages/react-native/ReactCommon/react/renderer/components/text/BaseTextShadowNode.cpp b/packages/react-native/ReactCommon/react/renderer/components/text/BaseTextShadowNode.cpp index 2ff46e65dc879e..77ede813aedd3a 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/text/BaseTextShadowNode.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/text/BaseTextShadowNode.cpp @@ -29,24 +29,33 @@ void BaseTextShadowNode::buildAttributedString( const ShadowNode& parentNode, AttributedString& outAttributedString, Attachments& outAttachments) { + bool lastFragmentWasRawText = false; for (const auto& childNode : parentNode.getChildren()) { // RawShadowNode auto rawTextShadowNode = dynamic_cast(childNode.get()); if (rawTextShadowNode != nullptr) { - auto fragment = AttributedString::Fragment{}; - fragment.string = rawTextShadowNode->getConcreteProps().text; - fragment.textAttributes = baseTextAttributes; + const auto& rawText = rawTextShadowNode->getConcreteProps().text; + if (lastFragmentWasRawText) { + outAttributedString.getFragments().back().string += rawText; + } else { + auto fragment = AttributedString::Fragment{}; + fragment.string = rawText; + fragment.textAttributes = baseTextAttributes; - // Storing a retaining pointer to `ParagraphShadowNode` inside - // `attributedString` causes a retain cycle (besides that fact that we - // don't need it at all). Storing a `ShadowView` instance instead of - // `ShadowNode` should properly fix this problem. - fragment.parentShadowView = shadowViewFromShadowNode(parentNode); - outAttributedString.appendFragment(fragment); + // Storing a retaining pointer to `ParagraphShadowNode` inside + // `attributedString` causes a retain cycle (besides that fact that we + // don't need it at all). Storing a `ShadowView` instance instead of + // `ShadowNode` should properly fix this problem. + fragment.parentShadowView = shadowViewFromShadowNode(parentNode); + outAttributedString.appendFragment(fragment); + lastFragmentWasRawText = true; + } continue; } + lastFragmentWasRawText = false; + // TextShadowNode auto textShadowNode = dynamic_cast(childNode.get()); if (textShadowNode != nullptr) { diff --git a/packages/react-native/ReactCommon/react/renderer/components/text/tests/BaseTextShadowNodeTest.cpp b/packages/react-native/ReactCommon/react/renderer/components/text/tests/BaseTextShadowNodeTest.cpp new file mode 100644 index 00000000000000..6a9e4858d1f4e3 --- /dev/null +++ b/packages/react-native/ReactCommon/react/renderer/components/text/tests/BaseTextShadowNodeTest.cpp @@ -0,0 +1,93 @@ +/* + * Copyright (c) Meta Platforms, Inc. and 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 + +namespace facebook::react { + +namespace { + +Element rawTextElement(const char* text) { + auto rawTextProps = std::make_shared(); + rawTextProps->text = text; + return Element().props(rawTextProps); +} + +} // namespace + +TEST(BaseTextShadowNodeTest, fragmentsWithDifferentAttributes) { + ContextContainer contextContainer{}; + PropsParserContext parserContext{-1, contextContainer}; + + auto builder = simpleComponentBuilder(); + auto shadowNode = builder.build(Element().children({ + Element() + .props([]() { + auto props = std::make_shared(); + props->textAttributes.fontSize = 12; + return props; + }) + .children({ + rawTextElement("First fragment. "), + }), + Element() + .props([]() { + auto props = std::make_shared(); + props->textAttributes.fontSize = 24; + return props; + }) + .children({ + rawTextElement("Second fragment"), + }), + })); + + auto baseTextAttributes = TextAttributes::defaultTextAttributes(); + AttributedString output; + BaseTextShadowNode::Attachments attachments; + BaseTextShadowNode::buildAttributedString( + baseTextAttributes, *shadowNode, output, attachments); + + EXPECT_EQ(output.getString(), "First fragment. Second fragment"); + + const auto& fragments = output.getFragments(); + EXPECT_EQ(fragments.size(), 2); + EXPECT_EQ(fragments[0].textAttributes.fontSize, 12); + EXPECT_EQ( + fragments[0].parentShadowView.tag, + shadowNode->getChildren()[0]->getTag()); + EXPECT_EQ(fragments[1].textAttributes.fontSize, 24); + EXPECT_EQ( + fragments[1].parentShadowView.tag, + shadowNode->getChildren()[1]->getTag()); +} + +TEST(BaseTextShadowNodeTest, rawTextIsMerged) { + ContextContainer contextContainer{}; + PropsParserContext parserContext{-1, contextContainer}; + + auto builder = simpleComponentBuilder(); + auto shadowNode = builder.build(Element().children({ + rawTextElement("Hello "), + rawTextElement("World"), + })); + + auto baseTextAttributes = TextAttributes::defaultTextAttributes(); + AttributedString output; + BaseTextShadowNode::Attachments attachments; + BaseTextShadowNode::buildAttributedString( + baseTextAttributes, *shadowNode, output, attachments); + + EXPECT_EQ(output.getString(), "Hello World"); + EXPECT_EQ(output.getFragments().size(), 1); +} + +} // namespace facebook::react From 84bfeec9b8fc745f5673ea92dd4c0cdb27ba3b55 Mon Sep 17 00:00:00 2001 From: "Alex Taylor (alta)" Date: Fri, 8 Nov 2024 12:27:49 -0800 Subject: [PATCH 141/220] Deploy 0.252.0 to xplat + www (#47523) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47523 Changelog: [Internal] Reviewed By: SamChou19815 Differential Revision: D65666666 fbshipit-source-id: 19f75611805777115febfca79d0945d31b7ea522 --- .flowconfig | 2 +- package.json | 2 +- yarn.lock | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.flowconfig b/.flowconfig index 8eb6023d7ade54..d8ab20ce9cc6a9 100644 --- a/.flowconfig +++ b/.flowconfig @@ -93,4 +93,4 @@ untyped-import untyped-type-import [version] -^0.251.1 +^0.252.0 diff --git a/package.json b/package.json index e76423582e2462..d335260a705e93 100644 --- a/package.json +++ b/package.json @@ -77,7 +77,7 @@ "eslint-plugin-redundant-undefined": "^0.4.0", "eslint-plugin-relay": "^1.8.3", "flow-api-translator": "0.24.0", - "flow-bin": "^0.251.1", + "flow-bin": "^0.252.0", "glob": "^7.1.1", "hermes-eslint": "0.24.0", "hermes-transform": "0.24.0", diff --git a/yarn.lock b/yarn.lock index f4da56fe2074bc..7fcc487ef4f9d2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4451,10 +4451,10 @@ flow-api-translator@0.24.0: hermes-transform "0.24.0" typescript "5.3.2" -flow-bin@^0.251.1: - version "0.251.1" - resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.251.1.tgz#d8dc360b865edaa6e76b3b9edd545f5730e1b520" - integrity sha512-zp8NsURU1hY2drz0p5MEVRrUg+0oXNbzD7od3ExOEBqMZsM6oX5ixp8j4U2sv+4v2dJWLgi9wQS4xJ5dnq2Q+Q== +flow-bin@^0.252.0: + version "0.252.0" + resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.252.0.tgz#a312b8e131391efe2864aab62de241b36f65b47b" + integrity sha512-DjWbg5FwSZy+9hO3zzwrxjoak7Fld4pQC0paVji1lF2e8aIqCYvjA2c1Kd4iv3uDmzVDg0MfRSXNKfhR2ql7JQ== flow-enums-runtime@^0.0.6: version "0.0.6" From cd9ece0553a820a1a3363ba76541a7dd4bcd8f16 Mon Sep 17 00:00:00 2001 From: Sam Zhou Date: Fri, 8 Nov 2024 13:52:27 -0800 Subject: [PATCH 142/220] Pre-suppress errors ahead of turn on partial react 19 ref-as-prop support Summary: `react.ref_as_prop=experimental.partial_support` will expose errors where a ref prop is passed to a function component without ref prop. This diff pre-suppresses the newly exposed errors. Changelog: [Internal] Reviewed By: gkz Differential Revision: D65686695 fbshipit-source-id: f241cc40f3ac414a2960dec60d9ba4633e5f93c0 --- .../rn-tester/js/examples/Accessibility/AccessibilityExample.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/rn-tester/js/examples/Accessibility/AccessibilityExample.js b/packages/rn-tester/js/examples/Accessibility/AccessibilityExample.js index 7bbe1c5d8c9e86..49090ce83658de 100644 --- a/packages/rn-tester/js/examples/Accessibility/AccessibilityExample.js +++ b/packages/rn-tester/js/examples/Accessibility/AccessibilityExample.js @@ -1314,6 +1314,7 @@ function SetAccessibilityFocusExample(props: {}): React.Node { return ( + {/* $FlowFixMe[prop-missing] */} SetAccessibilityFocus on native element. This should get focus after clicking the button! From 34c157f6b3c975189bf1e630849a9f1b7ad02abe Mon Sep 17 00:00:00 2001 From: David Vacca Date: Fri, 8 Nov 2024 16:13:17 -0800 Subject: [PATCH 143/220] Undeprecate UIManagerProvider in the new architecture (#47386) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47386 UIManagerProvider is actually useful to decouple client code from the FabricUIManagerClass that's why I'm removing the DeprecatedInNewArchitecture annotation changelog: [internal] internal Reviewed By: cortinico Differential Revision: D65430644 fbshipit-source-id: 46e95b9e40e99dd9ec6df9f2d51b1fa3d3d77d27 --- .../java/com/facebook/react/bridge/UIManagerProvider.kt | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/UIManagerProvider.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/UIManagerProvider.kt index 1c39113ca13866..b9932726aca5a5 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/UIManagerProvider.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/UIManagerProvider.kt @@ -7,14 +7,10 @@ package com.facebook.react.bridge -import com.facebook.react.common.annotations.DeprecatedInNewArchitecture - /** * {@link UIManagerProvider} is used to create UIManager objects during the initialization of React - * Native. This was introduced as a temporary interface to enable the new renderer of React Native - * in isolation of others part of the new architecture of React Native. + * Native. */ -@DeprecatedInNewArchitecture public fun interface UIManagerProvider { /* Provides a {@link com.facebook.react.bridge.UIManager} for the context received as a parameter. */ From 7794d7af43b90b581574361af102f67ad7961a5e Mon Sep 17 00:00:00 2001 From: Thomas Nardone Date: Fri, 8 Nov 2024 16:14:37 -0800 Subject: [PATCH 144/220] Add TextTransform KTX (#47525) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47525 This API is awkward for nullsafe code. Adding an extension allows Kotlin code to use `applyTextTransform()` on either nullable or non-null strings: ``` val a: String = string.applyTextTransform(...) val b: String? = nullableString?.applyTextTransform(...) ``` Changelog: [Android][Added] TextTransform ktx Reviewed By: javache Differential Revision: D65618709 fbshipit-source-id: 28a0fe61a0eaf27aa9677af39d932982f3b694b2 --- .../ReactAndroid/api/ReactAndroid.api | 4 +++ .../react/views/text/TextTransform.kt | 35 ++++++++----------- 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 803129424c9b6d..3af665e8bb60c1 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -7598,6 +7598,10 @@ public final class com/facebook/react/views/text/TextTransform$Companion { public final fun apply (Ljava/lang/String;Lcom/facebook/react/views/text/TextTransform;)Ljava/lang/String; } +public final class com/facebook/react/views/text/TextTransformKt { + public static final fun applyTextTransform (Ljava/lang/String;Lcom/facebook/react/views/text/TextTransform;)Ljava/lang/String; +} + public class com/facebook/react/views/text/frescosupport/FrescoBasedReactTextInlineImageViewManager : com/facebook/react/uimanager/BaseViewManager { public static final field REACT_CLASS Ljava/lang/String; public fun ()V diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextTransform.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextTransform.kt index 7da115539bbf7b..f095711592da12 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextTransform.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextTransform.kt @@ -21,35 +21,28 @@ public enum class TextTransform { public companion object { @JvmStatic - public fun apply(text: String?, textTransform: TextTransform?): String? { - if (text == null) { - return null - } - val transformed: String = - when (textTransform) { - UPPERCASE -> text.uppercase(Locale.getDefault()) - LOWERCASE -> text.lowercase(Locale.getDefault()) - CAPITALIZE -> capitalize(text) - else -> text - } - return transformed - } + public fun apply(text: String?, textTransform: TextTransform?): String? = + text?.applyTextTransform(textTransform) + } +} - private fun capitalize(text: String): String { +public fun String.applyTextTransform(textTransform: TextTransform?): String { + return when (textTransform) { + TextTransform.UPPERCASE -> uppercase(Locale.getDefault()) + TextTransform.LOWERCASE -> lowercase(Locale.getDefault()) + TextTransform.CAPITALIZE -> { val wordIterator = BreakIterator.getWordInstance() - wordIterator.setText(text) - - val res = StringBuilder(text.length) + wordIterator.setText(this) + val res = StringBuilder(length) var start = wordIterator.first() var end = wordIterator.next() while (end != BreakIterator.DONE) { - res.append(text[start].uppercaseChar()) - res.append(text.substring(start + 1, end)) + res.append(substring(start, end).replaceFirstChar { it.uppercaseChar() }) start = end end = wordIterator.next() } - - return res.toString() + res.toString() } + else -> this } } From 3e27ef1f6e024bba8725a3bd64e2648ffd6af496 Mon Sep 17 00:00:00 2001 From: David Vacca Date: Fri, 8 Nov 2024 20:40:18 -0800 Subject: [PATCH 145/220] Deprecate CatalystInstance in old architecture (#47383) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47383 CatalystInstance is deprecated and will be removed in new architecture changelog: [Android][Changed] Deprecate CatalystInstance in old architecture Reviewed By: cortinico Differential Revision: D65430643 fbshipit-source-id: 96ba91c45760ead8155f9f28b6fad523be75929e --- .../facebook/react/bridge/CatalystInstance.kt | 19 +++++++++---------- .../runtime/BridgelessCatalystInstance.kt | 4 ++++ .../facebook/react/bridge/ReactTestHelper.kt | 4 ++++ .../modules/network/NetworkingModuleTest.kt | 4 ++++ .../react/modules/timing/TimingModuleTest.kt | 4 ++++ .../react/uimanager/SimpleViewPropertyTest.kt | 4 ++++ .../views/image/ReactImagePropertyTest.kt | 4 ++++ .../textinput/ReactTextInputPropertyTest.kt | 4 ++++ 8 files changed, 37 insertions(+), 10 deletions(-) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstance.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstance.kt index a2325c6b95c6cd..b6c763689a073f 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstance.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstance.kt @@ -9,7 +9,6 @@ package com.facebook.react.bridge import com.facebook.proguard.annotations.DoNotStrip import com.facebook.react.bridge.queue.ReactQueueConfiguration -import com.facebook.react.common.annotations.DeprecatedInNewArchitecture import com.facebook.react.common.annotations.VisibleForTesting import com.facebook.react.internal.turbomodule.core.interfaces.TurboModuleRegistry import com.facebook.react.turbomodule.core.interfaces.CallInvokerHolder @@ -20,6 +19,9 @@ import com.facebook.react.turbomodule.core.interfaces.NativeMethodCallInvokerHol * the invocation of JavaScript methods and lets a set of Java APIs be invocable from JavaScript as * well. */ +@Deprecated( + message = + "This class is deprecated, please to migrate to new architecture using [com.facebook.react.defaults.DefaultReactHost] instead.") @DoNotStrip public interface CatalystInstance : MemoryPressureListener, JSInstance, JSBundleLoaderDelegate { public fun runJSBundle() @@ -117,21 +119,18 @@ public interface CatalystInstance : MemoryPressureListener, JSInstance, JSBundle */ public val nativeMethodCallInvokerHolder: NativeMethodCallInvokerHolder - @DeprecatedInNewArchitecture( + @Deprecated( message = - "This method will be deprecated later as part of Stable APIs with bridge removal and not" + - " encouraged usage.") + "This method is deprecated, please to migrate to new architecture using [com.facebook.react.defaults.DefaultReactHost] instead.") public fun setTurboModuleRegistry(turboModuleRegistry: TurboModuleRegistry) - @DeprecatedInNewArchitecture( + @Deprecated( message = - "This method will be deprecated later as part of Stable APIs with bridge removal and not" + - " encouraged usage.") + "This method is deprecated, please to migrate to new architecture using [com.facebook.react.defaults.DefaultReactHost] instead.") public fun setFabricUIManager(fabricUIManager: UIManager) - @DeprecatedInNewArchitecture( + @Deprecated( message = - "This method will be deprecated later as part of Stable APIs with bridge removal and not" + - " encouraged usage.") + "This method is deprecated, please to migrate to new architecture using [com.facebook.react.defaults.DefaultReactHost] instead.") public fun getFabricUIManager(): UIManager? } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/BridgelessCatalystInstance.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/BridgelessCatalystInstance.kt index 99c3296c5e7a14..07279d4806c9e1 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/BridgelessCatalystInstance.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/BridgelessCatalystInstance.kt @@ -5,6 +5,10 @@ * LICENSE file in the root directory of this source tree. */ +// TODO T207169925: Migrate CatalystInstance to Reacthost and remove the Suppress("DEPRECATION") +// annotation +@file:Suppress("DEPRECATION") + package com.facebook.react.runtime import android.content.res.AssetManager diff --git a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/bridge/ReactTestHelper.kt b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/bridge/ReactTestHelper.kt index 8de19b6fd58818..e82a9d8db9c52f 100644 --- a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/bridge/ReactTestHelper.kt +++ b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/bridge/ReactTestHelper.kt @@ -5,6 +5,10 @@ * LICENSE file in the root directory of this source tree. */ +// TODO T207169925: Migrate CatalystInstance to Reacthost and remove the Suppress("DEPRECATION") +// annotation +@file:Suppress("DEPRECATION") + package com.facebook.react.bridge import com.facebook.react.bridge.queue.MessageQueueThreadSpec diff --git a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/modules/network/NetworkingModuleTest.kt b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/modules/network/NetworkingModuleTest.kt index 683f52ad3f62d0..cadc66401d0358 100644 --- a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/modules/network/NetworkingModuleTest.kt +++ b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/modules/network/NetworkingModuleTest.kt @@ -5,6 +5,10 @@ * LICENSE file in the root directory of this source tree. */ +// TODO T207169925: Migrate CatalystInstance to Reacthost and remove the Suppress("DEPRECATION") +// annotation +@file:Suppress("DEPRECATION") + package com.facebook.react.modules.network import com.facebook.react.bridge.Arguments diff --git a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/modules/timing/TimingModuleTest.kt b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/modules/timing/TimingModuleTest.kt index 2d36284234bfd5..7faa5085e22a33 100644 --- a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/modules/timing/TimingModuleTest.kt +++ b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/modules/timing/TimingModuleTest.kt @@ -5,6 +5,10 @@ * LICENSE file in the root directory of this source tree. */ +// TODO T207169925: Migrate CatalystInstance to Reacthost and remove the Suppress("DEPRECATION") +// annotation +@file:Suppress("DEPRECATION") + package com.facebook.react.modules.timing import android.content.Context diff --git a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/uimanager/SimpleViewPropertyTest.kt b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/uimanager/SimpleViewPropertyTest.kt index 749e523a84699e..f6922883f506c7 100644 --- a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/uimanager/SimpleViewPropertyTest.kt +++ b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/uimanager/SimpleViewPropertyTest.kt @@ -5,6 +5,10 @@ * LICENSE file in the root directory of this source tree. */ +// TODO T207169925: Migrate CatalystInstance to Reacthost and remove the Suppress("DEPRECATION") +// annotation +@file:Suppress("DEPRECATION") + package com.facebook.react.uimanager import android.view.View diff --git a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/image/ReactImagePropertyTest.kt b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/image/ReactImagePropertyTest.kt index faa427a52dd2e3..6704f4755ac7fd 100644 --- a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/image/ReactImagePropertyTest.kt +++ b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/image/ReactImagePropertyTest.kt @@ -5,6 +5,10 @@ * LICENSE file in the root directory of this source tree. */ +// TODO T207169925: Migrate CatalystInstance to Reacthost and remove the Suppress("DEPRECATION") +// annotation +@file:Suppress("DEPRECATION") + package com.facebook.react.views.image import android.graphics.Color diff --git a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/textinput/ReactTextInputPropertyTest.kt b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/textinput/ReactTextInputPropertyTest.kt index 109bcd6d91fb56..91aabb17f3b80a 100644 --- a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/textinput/ReactTextInputPropertyTest.kt +++ b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/textinput/ReactTextInputPropertyTest.kt @@ -5,6 +5,10 @@ * LICENSE file in the root directory of this source tree. */ +// TODO T207169925: Migrate CatalystInstance to Reacthost and remove the Suppress("DEPRECATION") +// annotation +@file:Suppress("DEPRECATION") + package com.facebook.react.views.textinput import android.graphics.Color From 44d619414c1de3dbf17a421afa8dbcec7cdab025 Mon Sep 17 00:00:00 2001 From: D N <4661784+retyui@users.noreply.github.com> Date: Sat, 9 Nov 2024 15:56:44 -0800 Subject: [PATCH 146/220] fix: Remove `BackHandler.removeEventListener` (#45892) Summary: All `removeEventListener` methods was removed https://github.com/facebook/react-native/commit/2596b2f6954362d2cd34a1be870810ab90cbb916 perviously but seems a `BackHandler` was missed This can be a breaking change for some third-party modules. **Migration**: Use `remove` on the EventSubscription from `addEventListener`: ```diff useEffect(()=>{ + const subscription = NativeModule.removeListener(name, listener); + return ()=>subscription.remove(); },[]) ``` ## Changelog: [GENERAL] [REMOVED] - Remove `BackHandler.removeEventListener` Pull Request resolved: https://github.com/facebook/react-native/pull/45892 Test Plan: ... Reviewed By: huntie Differential Revision: D65663591 Pulled By: javache fbshipit-source-id: 01b804cd6ec77ea4916a0ced7fee551d045f1684 --- .../Utilities/BackHandler.android.js | 24 +++++-------------- .../Libraries/Utilities/BackHandler.d.ts | 4 ---- .../Libraries/Utilities/BackHandler.ios.js | 5 ---- .../Libraries/Utilities/BackHandler.js.flow | 4 ---- .../Utilities/__mocks__/BackHandler.js | 11 +++------ .../__snapshots__/public-api-test.js.snap | 4 ---- packages/rn-tester/js/RNTesterAppShared.js | 13 ++++------ 7 files changed, 14 insertions(+), 51 deletions(-) diff --git a/packages/react-native/Libraries/Utilities/BackHandler.android.js b/packages/react-native/Libraries/Utilities/BackHandler.android.js index 74519f78193482..6105a5341dee06 100644 --- a/packages/react-native/Libraries/Utilities/BackHandler.android.js +++ b/packages/react-native/Libraries/Utilities/BackHandler.android.js @@ -59,10 +59,6 @@ type TBackHandler = {| eventName: BackPressEventName, handler: () => ?boolean, ) => {remove: () => void, ...}, - +removeEventListener: ( - eventName: BackPressEventName, - handler: () => ?boolean, - ) => void, |}; const BackHandler: TBackHandler = { exitApp: function (): void { @@ -86,22 +82,14 @@ const BackHandler: TBackHandler = { _backPressSubscriptions.push(handler); } return { - remove: (): void => BackHandler.removeEventListener(eventName, handler), + remove: (): void => { + const index = _backPressSubscriptions.indexOf(handler); + if (index !== -1) { + _backPressSubscriptions.splice(index, 1); + } + }, }; }, - - /** - * Removes the event handler. - */ - removeEventListener: function ( - eventName: BackPressEventName, - handler: () => ?boolean, - ): void { - const index = _backPressSubscriptions.indexOf(handler); - if (index !== -1) { - _backPressSubscriptions.splice(index, 1); - } - }, }; module.exports = BackHandler; diff --git a/packages/react-native/Libraries/Utilities/BackHandler.d.ts b/packages/react-native/Libraries/Utilities/BackHandler.d.ts index 72400aeb1c3420..8ca8e1743d193c 100644 --- a/packages/react-native/Libraries/Utilities/BackHandler.d.ts +++ b/packages/react-native/Libraries/Utilities/BackHandler.d.ts @@ -28,10 +28,6 @@ export interface BackHandlerStatic { eventName: BackPressEventName, handler: () => boolean | null | undefined, ): NativeEventSubscription; - removeEventListener( - eventName: BackPressEventName, - handler: () => boolean | null | undefined, - ): void; } export const BackHandler: BackHandlerStatic; diff --git a/packages/react-native/Libraries/Utilities/BackHandler.ios.js b/packages/react-native/Libraries/Utilities/BackHandler.ios.js index 49bd876d817a9b..f024cdb9d35eb7 100644 --- a/packages/react-native/Libraries/Utilities/BackHandler.ios.js +++ b/packages/react-native/Libraries/Utilities/BackHandler.ios.js @@ -20,10 +20,6 @@ type TBackHandler = {| eventName: BackPressEventName, handler: () => ?boolean, ) => {remove: () => void, ...}, - +removeEventListener: ( - eventName: BackPressEventName, - handler: () => ?boolean, - ) => void, |}; let BackHandler: TBackHandler = { @@ -33,7 +29,6 @@ let BackHandler: TBackHandler = { remove: emptyFunction, }; }, - removeEventListener(_eventName: BackPressEventName, _handler: Function) {}, }; module.exports = BackHandler; diff --git a/packages/react-native/Libraries/Utilities/BackHandler.js.flow b/packages/react-native/Libraries/Utilities/BackHandler.js.flow index a966ffd6183694..aec78e1697004b 100644 --- a/packages/react-native/Libraries/Utilities/BackHandler.js.flow +++ b/packages/react-native/Libraries/Utilities/BackHandler.js.flow @@ -18,10 +18,6 @@ type TBackHandler = {| eventName: BackPressEventName, handler: () => ?boolean, ) => {remove: () => void, ...}, - +removeEventListener: ( - eventName: BackPressEventName, - handler: () => ?boolean, - ) => void, |}; declare module.exports: TBackHandler; diff --git a/packages/react-native/Libraries/Utilities/__mocks__/BackHandler.js b/packages/react-native/Libraries/Utilities/__mocks__/BackHandler.js index f0c6a12d13a5eb..bc5bc62dfea064 100644 --- a/packages/react-native/Libraries/Utilities/__mocks__/BackHandler.js +++ b/packages/react-native/Libraries/Utilities/__mocks__/BackHandler.js @@ -20,17 +20,12 @@ const BackHandler = { ): {remove: () => void} { _backPressSubscriptions.add(handler); return { - remove: () => BackHandler.removeEventListener(eventName, handler), + remove: () => { + _backPressSubscriptions.delete(handler); + }, }; }, - removeEventListener: function ( - eventName: BackPressEventName, - handler: () => ?boolean, - ): void { - _backPressSubscriptions.delete(handler); - }, - mockPressBack: function () { let invokeDefault = true; const subscriptions = [..._backPressSubscriptions].reverse(); diff --git a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap index 53b141bdc6d442..01ea39f9f6062d 100644 --- a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap +++ b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap @@ -8897,10 +8897,6 @@ type TBackHandler = {| eventName: BackPressEventName, handler: () => ?boolean ) => { remove: () => void, ... }, - +removeEventListener: ( - eventName: BackPressEventName, - handler: () => ?boolean - ) => void, |}; declare module.exports: TBackHandler; " diff --git a/packages/rn-tester/js/RNTesterAppShared.js b/packages/rn-tester/js/RNTesterAppShared.js index d1dfdc900cb36d..e41e6cd640d30f 100644 --- a/packages/rn-tester/js/RNTesterAppShared.js +++ b/packages/rn-tester/js/RNTesterAppShared.js @@ -97,14 +97,11 @@ const RNTesterApp = ({ return false; }; - BackHandler.addEventListener('hardwareBackPress', handleHardwareBackPress); - - return () => { - BackHandler.removeEventListener( - 'hardwareBackPress', - handleHardwareBackPress, - ); - }; + const subscription = BackHandler.addEventListener( + 'hardwareBackPress', + handleHardwareBackPress, + ); + return () => subscription.remove(); }, [activeModuleKey, handleBackPress]); const handleModuleCardPress = React.useCallback( From ae4341100828069ea58abf1af0078ebc94848b72 Mon Sep 17 00:00:00 2001 From: Yedidya Feldblum Date: Sun, 10 Nov 2024 02:42:41 -0800 Subject: [PATCH 147/220] let Value be nothrow-move-constructible (#47422) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47422 Reviewed By: Gownta Differential Revision: D65273055 fbshipit-source-id: 6fda316137b1f797b8b4041521555e46e1098e7c --- packages/react-native/ReactCommon/jsi/jsi/jsi.cpp | 2 +- packages/react-native/ReactCommon/jsi/jsi/jsi.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/react-native/ReactCommon/jsi/jsi/jsi.cpp b/packages/react-native/ReactCommon/jsi/jsi/jsi.cpp index 13588e1d04bcef..e11ef30d77ed65 100644 --- a/packages/react-native/ReactCommon/jsi/jsi/jsi.cpp +++ b/packages/react-native/ReactCommon/jsi/jsi/jsi.cpp @@ -333,7 +333,7 @@ Function Object::asFunction(Runtime& runtime) && { return std::move(*this).getFunction(runtime); } -Value::Value(Value&& other) : Value(other.kind_) { +Value::Value(Value&& other) noexcept : Value(other.kind_) { if (kind_ == BooleanKind) { data_.boolean = other.data_.boolean; } else if (kind_ == NumberKind) { diff --git a/packages/react-native/ReactCommon/jsi/jsi/jsi.h b/packages/react-native/ReactCommon/jsi/jsi/jsi.h index a826923a6401d8..be48bb82474352 100644 --- a/packages/react-native/ReactCommon/jsi/jsi/jsi.h +++ b/packages/react-native/ReactCommon/jsi/jsi/jsi.h @@ -1121,7 +1121,7 @@ class JSI_EXPORT Function : public Object { class JSI_EXPORT Value { public: /// Default ctor creates an \c undefined JS value. - Value() : Value(UndefinedKind) {} + Value() noexcept : Value(UndefinedKind) {} /// Creates a \c null JS value. /* implicit */ Value(std::nullptr_t) : kind_(NullKind) {} @@ -1162,7 +1162,7 @@ class JSI_EXPORT Value { "Value cannot be constructed directly from const char*"); } - Value(Value&& value); + Value(Value&& other) noexcept; /// Copies a Symbol lvalue into a new JS value. Value(Runtime& runtime, const Symbol& sym) : Value(SymbolKind) { @@ -1217,7 +1217,7 @@ class JSI_EXPORT Value { /// https://262.ecma-international.org/11.0/#sec-strict-equality-comparison static bool strictEquals(Runtime& runtime, const Value& a, const Value& b); - Value& operator=(Value&& other) { + Value& operator=(Value&& other) noexcept { this->~Value(); new (this) Value(std::move(other)); return *this; From b60e36390c6b32c4d54f9ae25c812ef9dee3e30b Mon Sep 17 00:00:00 2001 From: David Vacca Date: Sun, 10 Nov 2024 09:30:58 -0800 Subject: [PATCH 148/220] Introduce ReactHost.destroy() method to notifies when the React instance is destroyed (#47534) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47534 This diff is introducing a new method to destroy React instance that allows the caller to be notified when the destroy finishes This is necessary for apps to act upon destroy of the react instance changelog: [internal] internal Reviewed By: shwanton Differential Revision: D65721107 fbshipit-source-id: 2d3d9755db38461ba381b86c72df5869c542379b --- .../ReactAndroid/api/ReactAndroid.api | 3 +++ .../main/java/com/facebook/react/ReactHost.kt | 21 ++++++++++++++++++- .../facebook/react/runtime/ReactHostImpl.java | 20 ++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 3af665e8bb60c1..70e3de5e55dafc 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -205,6 +205,8 @@ public abstract interface class com/facebook/react/ReactHost { public abstract fun addReactInstanceEventListener (Lcom/facebook/react/ReactInstanceEventListener;)V public abstract fun createSurface (Landroid/content/Context;Ljava/lang/String;Landroid/os/Bundle;)Lcom/facebook/react/interfaces/fabric/ReactSurface; public abstract fun destroy (Ljava/lang/String;Ljava/lang/Exception;)Lcom/facebook/react/interfaces/TaskInterface; + public abstract fun destroy (Ljava/lang/String;Ljava/lang/Exception;Lkotlin/jvm/functions/Function1;)Lcom/facebook/react/interfaces/TaskInterface; + public static synthetic fun destroy$default (Lcom/facebook/react/ReactHost;Ljava/lang/String;Ljava/lang/Exception;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lcom/facebook/react/interfaces/TaskInterface; public abstract fun getCurrentReactContext ()Lcom/facebook/react/bridge/ReactContext; public abstract fun getDevSupportManager ()Lcom/facebook/react/devsupport/interfaces/DevSupportManager; public abstract fun getLifecycleState ()Lcom/facebook/react/common/LifecycleState; @@ -3789,6 +3791,7 @@ public class com/facebook/react/runtime/ReactHostImpl : com/facebook/react/React public fun addReactInstanceEventListener (Lcom/facebook/react/ReactInstanceEventListener;)V public fun createSurface (Landroid/content/Context;Ljava/lang/String;Landroid/os/Bundle;)Lcom/facebook/react/interfaces/fabric/ReactSurface; public fun destroy (Ljava/lang/String;Ljava/lang/Exception;)Lcom/facebook/react/interfaces/TaskInterface; + public fun destroy (Ljava/lang/String;Ljava/lang/Exception;Lkotlin/jvm/functions/Function1;)Lcom/facebook/react/interfaces/TaskInterface; public fun getCurrentReactContext ()Lcom/facebook/react/bridge/ReactContext; public fun getDevSupportManager ()Lcom/facebook/react/devsupport/interfaces/DevSupportManager; public fun getLifecycleState ()Lcom/facebook/react/common/LifecycleState; diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactHost.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactHost.kt index b5a88b70574272..86409ba182a868 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactHost.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactHost.kt @@ -116,7 +116,26 @@ public interface ReactHost { * be used to log properly the cause of destroy operation. * @return A task that completes when React Native gets destroyed. */ - public fun destroy(reason: String, ex: Exception?): TaskInterface + public fun destroy( + reason: String, + ex: Exception?, + ): TaskInterface + + /** + * Entrypoint to destroy the ReactInstance. If the ReactInstance is reloading, will wait until + * reload is finished, before destroying. + * + * @param reason describing why ReactHost is being destroyed (e.g. memmory pressure) + * @param ex exception that caused the trigger to destroy ReactHost (or null) This exception will + * be used to log properly the cause of destroy operation. + * @param onDestroyFinished callback that will be called when React Native gets destroyed. + * @return A task that completes when React Native gets destroyed. + */ + public fun destroy( + reason: String, + ex: Exception?, + onDestroyFinished: (instanceDestroyedSuccessfully: Boolean) -> Unit = {} + ): TaskInterface /** * Permanently destroys the ReactHost, including the ReactInstance (if any). The application MUST diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.java index c0988129387519..dd82980846632e 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.java @@ -86,6 +86,7 @@ import java.util.concurrent.atomic.AtomicReference; import kotlin.Unit; import kotlin.jvm.functions.Function0; +import kotlin.jvm.functions.Function1; /** * A ReactHost is an object that manages a single {@link ReactInstance}. A ReactHost can be @@ -542,6 +543,25 @@ private void loadNetworkResource(String url, InspectorNetworkRequestListener lis InspectorNetworkHelper.loadNetworkResource(url, listener); } + @NonNull + @Override + public TaskInterface destroy( + @NonNull String reason, + @Nullable Exception ex, + @NonNull Function1 onDestroyFinished) { + Task task = (Task) destroy(reason, ex); + return task.continueWith( + new Continuation() { + @Nullable + @Override + public Void then(@NonNull Task task) throws Exception { + boolean instanceDestroyedSuccessfully = task.isCompleted() && !task.isFaulted(); + onDestroyFinished.invoke(instanceDestroyedSuccessfully); + return null; + } + }); + } + /** * Entrypoint to destroy the ReactInstance. If the ReactInstance is reloading, will wait until * reload is finished, before destroying. From a9a1c86a927fc6e3854a9b4ad44d38bd3c8db588 Mon Sep 17 00:00:00 2001 From: Pieter De Baets Date: Sun, 10 Nov 2024 14:08:35 -0800 Subject: [PATCH 149/220] Convert com.facebook.react.bridge.ReactSoftExceptionLogger to Kotlin (#47513) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47513 Changelog: [Internal] Reviewed By: tdn120 Differential Revision: D65602362 fbshipit-source-id: 95e63bd04480c1c8a364fcf93d24f71f94057d65 --- .../ReactAndroid/api/ReactAndroid.api | 14 ++-- .../bridge/ReactSoftExceptionLogger.java | 66 ------------------- .../react/bridge/ReactSoftExceptionLogger.kt | 65 ++++++++++++++++++ 3 files changed, 72 insertions(+), 73 deletions(-) delete mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactSoftExceptionLogger.java create mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactSoftExceptionLogger.kt diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 70e3de5e55dafc..415b96566b430e 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -1441,13 +1441,13 @@ public class com/facebook/react/bridge/ReactNoCrashSoftException : java/lang/Run public fun (Ljava/lang/Throwable;)V } -public class com/facebook/react/bridge/ReactSoftExceptionLogger { - public fun ()V - public static fun addListener (Lcom/facebook/react/bridge/ReactSoftExceptionLogger$ReactSoftExceptionListener;)V - public static fun clearListeners ()V - public static fun logSoftException (Ljava/lang/String;Ljava/lang/Throwable;)V - public static fun logSoftExceptionVerbose (Ljava/lang/String;Ljava/lang/Throwable;)V - public static fun removeListener (Lcom/facebook/react/bridge/ReactSoftExceptionLogger$ReactSoftExceptionListener;)V +public final class com/facebook/react/bridge/ReactSoftExceptionLogger { + public static final field INSTANCE Lcom/facebook/react/bridge/ReactSoftExceptionLogger; + public static final fun addListener (Lcom/facebook/react/bridge/ReactSoftExceptionLogger$ReactSoftExceptionListener;)V + public static final fun clearListeners ()V + public static final fun logSoftException (Ljava/lang/String;Ljava/lang/Throwable;)V + public static final fun logSoftExceptionVerbose (Ljava/lang/String;Ljava/lang/Throwable;)V + public static final fun removeListener (Lcom/facebook/react/bridge/ReactSoftExceptionLogger$ReactSoftExceptionListener;)V } public abstract interface class com/facebook/react/bridge/ReactSoftExceptionLogger$ReactSoftExceptionListener { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactSoftExceptionLogger.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactSoftExceptionLogger.java deleted file mode 100644 index 74aee9148f80f8..00000000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactSoftExceptionLogger.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and 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.bridge; - -import com.facebook.common.logging.FLog; -import com.facebook.proguard.annotations.DoNotStrip; -import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; - -@DoNotStrip -public class ReactSoftExceptionLogger { - public interface ReactSoftExceptionListener { - void logSoftException(final String category, final Throwable cause); - } - - // Use a list instead of a set here because we expect the number of listeners - // to be very small, and we want listeners to be called in a deterministic - // order. - private static final List sListeners = new CopyOnWriteArrayList<>(); - - @DoNotStrip - public static void addListener(ReactSoftExceptionListener listener) { - if (!sListeners.contains(listener)) { - sListeners.add(listener); - } - } - - @DoNotStrip - public static void removeListener(ReactSoftExceptionListener listener) { - sListeners.remove(listener); - } - - @DoNotStrip - public static void clearListeners() { - sListeners.clear(); - } - - @DoNotStrip - public static void logSoftExceptionVerbose(final String category, final Throwable cause) { - logSoftException( - category + "|" + cause.getClass().getSimpleName() + ":" + cause.getMessage(), cause); - } - - @DoNotStrip - public static void logSoftException(final String category, final Throwable cause) { - if (sListeners.size() > 0) { - for (ReactSoftExceptionListener listener : sListeners) { - listener.logSoftException(category, cause); - } - } else { - FLog.e(category, "Unhandled SoftException", cause); - } - } - - @DoNotStrip - // For use from within the C++ JReactSoftExceptionLogger - private static void logNoThrowSoftExceptionWithMessage( - final String category, final String message) { - logSoftException(category, new ReactNoCrashSoftException(message)); - } -} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactSoftExceptionLogger.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactSoftExceptionLogger.kt new file mode 100644 index 00000000000000..1a17fa8994c0a4 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactSoftExceptionLogger.kt @@ -0,0 +1,65 @@ +/* + * Copyright (c) Meta Platforms, Inc. and 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.bridge + +import com.facebook.common.logging.FLog +import com.facebook.proguard.annotations.DoNotStrip +import java.util.concurrent.CopyOnWriteArrayList +import kotlin.jvm.JvmStatic + +@DoNotStrip +public object ReactSoftExceptionLogger { + + // Use a list instead of a set here because we expect the number of listeners + // to be very small, and we want listeners to be called in a deterministic + // order. + private val listeners: MutableList = CopyOnWriteArrayList() + + @JvmStatic + public fun addListener(listener: ReactSoftExceptionListener): Unit { + if (!listeners.contains(listener)) { + listeners.add(listener) + } + } + + @JvmStatic + public fun removeListener(listener: ReactSoftExceptionListener): Unit { + listeners.remove(listener) + } + + @JvmStatic + public fun clearListeners(): Unit { + listeners.clear() + } + + @JvmStatic + public fun logSoftExceptionVerbose(category: String, cause: Throwable): Unit { + logSoftException("${category}|${cause.javaClass.simpleName}:${cause.message}", cause) + } + + @JvmStatic + public fun logSoftException(category: String, cause: Throwable): Unit { + if (!listeners.isEmpty()) { + for (listener in listeners) { + listener.logSoftException(category, cause) + } + } else { + FLog.e(category, "Unhandled SoftException", cause) + } + } + + @JvmStatic + @DoNotStrip + private fun logNoThrowSoftExceptionWithMessage(category: String, message: String) { + logSoftException(category, ReactNoCrashSoftException(message)) + } + + public fun interface ReactSoftExceptionListener { + public fun logSoftException(category: String, cause: Throwable) + } +} From 9db28834e27819ac13d8c81df48c0b5dbe3ef54b Mon Sep 17 00:00:00 2001 From: Fabrizio Cucci Date: Mon, 11 Nov 2024 02:49:09 -0800 Subject: [PATCH 150/220] Migrate com.facebook.react.views.text.ReactTextViewManagerCallback to Kotlin (#47516) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47516 As per title. Changelog: [Internal] Reviewed By: javache Differential Revision: D65598258 fbshipit-source-id: 0ef7e9a4aefcb021bc55698eaf43c2a69bbb4f63 --- .../text/ReactTextViewManagerCallback.java | 25 ------------------- .../text/ReactTextViewManagerCallback.kt | 25 +++++++++++++++++++ 2 files changed, 25 insertions(+), 25 deletions(-) delete mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextViewManagerCallback.java create mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextViewManagerCallback.kt diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextViewManagerCallback.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextViewManagerCallback.java deleted file mode 100644 index 22bb7b29fa224c..00000000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextViewManagerCallback.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and 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.views.text; - -import android.text.Spannable; - -/** - * This interface allows clients of {@link ReactTextViewManager} to customize or prepare {@link - * Spannable} object that represent text that will be rendered on the screen. - */ -public interface ReactTextViewManagerCallback { - - /** - * Callback executed right after the {@link Spannable} object is created by React. - * - *

This callback can be used by different implementations of ReactTextViewManager to customize - * Spannable or extend managed created by React. - */ - void onPostProcessSpannable(Spannable text); -} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextViewManagerCallback.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextViewManagerCallback.kt new file mode 100644 index 00000000000000..556aebba1f9e25 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextViewManagerCallback.kt @@ -0,0 +1,25 @@ +/* + * Copyright (c) Meta Platforms, Inc. and 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.views.text + +import android.text.Spannable + +/** + * This interface allows clients of [ReactTextViewManager] to customize or prepare [Spannable] + * object that represent text that will be rendered on the screen. + */ +public fun interface ReactTextViewManagerCallback { + + /** + * Callback executed right after the [Spannable] object is created by React. + * + * This callback can be used by different implementations of ReactTextViewManager to customize or + * extend the [Spannable] created by React. + */ + public fun onPostProcessSpannable(text: Spannable) +} From 97a4234b6e51b3c35c82095029ef00270ad02e29 Mon Sep 17 00:00:00 2001 From: Riccardo Cipolleschi Date: Mon, 11 Nov 2024 04:55:23 -0800 Subject: [PATCH 151/220] Fix Typo and skip generation of app-specific component registration (#47547) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47547 In [#47176](https://github.com/facebook/react-native/pull/47176) we disabled the generation of the component registration for app specific components as it was creating a circular dependency between the app and React Native. However, we made a couple of typos that make it not work as expected and users picked up those typos soon. This change fixes them for good. ## Changelog [iOS][Fixed] - Properly stop generating component registration for components defined in app. Reviewed By: blakef Differential Revision: D65750433 fbshipit-source-id: 1a879c5be014905558b9fd05e6f16ac36b784ed6 --- .../scripts/codegen/generate-artifacts-executor.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/react-native/scripts/codegen/generate-artifacts-executor.js b/packages/react-native/scripts/codegen/generate-artifacts-executor.js index f50288816f38bb..b76d2d4e6153bb 100644 --- a/packages/react-native/scripts/codegen/generate-artifacts-executor.js +++ b/packages/react-native/scripts/codegen/generate-artifacts-executor.js @@ -548,7 +548,7 @@ function rootCodegenTargetNeedsThirdPartyComponentProvider(pkgJson, platform) { function dependencyNeedsThirdPartyComponentProvider( schemaInfo, platform, - appCondegenConfigSpec, + appCodegenConfigSpec, ) { // Filter the react native core library out. // In the future, core library and third party library should @@ -559,7 +559,7 @@ function dependencyNeedsThirdPartyComponentProvider( // the symbols defined in the app. return ( !isReactNativeCoreLibrary(schemaInfo.library.config.name, platform) && - schemaInfo.library.config.name !== appCondegenConfigSpec + schemaInfo.library.config.name !== appCodegenConfigSpec ); } @@ -792,7 +792,7 @@ function execute(projectRoot, targetPlatform, baseOutputPath) { dependencyNeedsThirdPartyComponentProvider( schemaInfo, platform, - pkgJson.codegenConfig?.appCondegenConfigSpec, + pkgJson.codegenConfig?.name, ), ); const schemas = filteredSchemas.map(schemaInfo => schemaInfo.schema); From 6c577e96db911b31e5eac0cb1c9fa7d42abc9e10 Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Mon, 11 Nov 2024 05:27:44 -0800 Subject: [PATCH 152/220] remove unused import and declaration in EventQueue (#47545) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47545 changelog: [internal] Reviewed By: javache Differential Revision: D65663098 fbshipit-source-id: b0a848de9ef01e2915a945a58a08e2e9c666a116 --- .../react-native/ReactCommon/react/renderer/core/EventQueue.cpp | 1 - .../react-native/ReactCommon/react/renderer/core/EventQueue.h | 2 -- 2 files changed, 3 deletions(-) diff --git a/packages/react-native/ReactCommon/react/renderer/core/EventQueue.cpp b/packages/react-native/ReactCommon/react/renderer/core/EventQueue.cpp index 9290bcc106c88b..6eee3cd102f0a8 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/EventQueue.cpp +++ b/packages/react-native/ReactCommon/react/renderer/core/EventQueue.cpp @@ -7,7 +7,6 @@ #include "EventQueue.h" -#include #include "EventEmitter.h" #include "ShadowNodeFamily.h" diff --git a/packages/react-native/ReactCommon/react/renderer/core/EventQueue.h b/packages/react-native/ReactCommon/react/renderer/core/EventQueue.h index 3578473b76634e..74525c6971a3a4 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/EventQueue.h +++ b/packages/react-native/ReactCommon/react/renderer/core/EventQueue.h @@ -19,8 +19,6 @@ namespace facebook::react { -class RuntimeScheduler; - /* * Event Queue synchronized with given Event Beat and dispatching event * using given Event Pipe. From d7cb6d95a8324666539fe276625fcc36401f290e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Norte?= Date: Mon, 11 Nov 2024 06:05:28 -0800 Subject: [PATCH 153/220] Clean up `forceBatchingMountItemsOnAndroid` feature flag (#47546) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47546 Changelog: [internal] Cleaning up the feature flag as we've tested it's safe to land. Reviewed By: javache Differential Revision: D65749504 fbshipit-source-id: 964db7e9c31ebb8d7e4f7e2703a3040709c6ed6e --- .../fabric/mounting/MountItemDispatcher.java | 4 +- .../mounting/SurfaceMountingManager.java | 16 ++---- .../featureflags/ReactNativeFeatureFlags.kt | 8 +-- .../ReactNativeFeatureFlagsCxxAccessor.kt | 12 +---- .../ReactNativeFeatureFlagsCxxInterop.kt | 4 +- .../ReactNativeFeatureFlagsDefaults.kt | 4 +- .../ReactNativeFeatureFlagsLocalAccessor.kt | 13 +---- .../ReactNativeFeatureFlagsProvider.kt | 4 +- .../JReactNativeFeatureFlagsCxxInterop.cpp | 16 +----- .../JReactNativeFeatureFlagsCxxInterop.h | 5 +- .../featureflags/ReactNativeFeatureFlags.cpp | 6 +-- .../featureflags/ReactNativeFeatureFlags.h | 7 +-- .../ReactNativeFeatureFlagsAccessor.cpp | 52 ++++++------------- .../ReactNativeFeatureFlagsAccessor.h | 6 +-- .../ReactNativeFeatureFlagsDefaults.h | 6 +-- .../ReactNativeFeatureFlagsProvider.h | 3 +- .../NativeReactNativeFeatureFlags.cpp | 7 +-- .../NativeReactNativeFeatureFlags.h | 4 +- .../ReactNativeFeatureFlags.config.js | 9 ---- .../featureflags/ReactNativeFeatureFlags.js | 7 +-- .../specs/NativeReactNativeFeatureFlags.js | 3 +- 21 files changed, 41 insertions(+), 155 deletions(-) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountItemDispatcher.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountItemDispatcher.java index 617530307d1c81..53a5539eec9331 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountItemDispatcher.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountItemDispatcher.java @@ -116,9 +116,7 @@ public void tryDispatchMountItems() { return; } - if (ReactNativeFeatureFlags.forceBatchingMountItemsOnAndroid()) { - mInDispatch = true; - } + mInDispatch = true; try { dispatchMountItems(); diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/SurfaceMountingManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/SurfaceMountingManager.java index d85716c6f0bee4..2bfb30be9044e7 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/SurfaceMountingManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/SurfaceMountingManager.java @@ -232,19 +232,13 @@ private void addRootView(@NonNull final View rootView) { ((ReactRoot) rootView).setRootViewTag(mSurfaceId); } - if (!ReactNativeFeatureFlags.forceBatchingMountItemsOnAndroid()) { - mRootViewAttached = true; - } - executeMountItemsOnViewAttach(); - if (ReactNativeFeatureFlags.forceBatchingMountItemsOnAndroid()) { - // By doing this after `executeMountItemsOnViewAttach`, we ensure - // that any operations scheduled while processing this queue are - // also added to the queue, instead of being processed immediately - // through the queue in `MountItemDispatcher`. - mRootViewAttached = true; - } + // By doing this after `executeMountItemsOnViewAttach`, we ensure + // that any operations scheduled while processing this queue are + // also added to the queue, instead of being processed immediately + // through the queue in `MountItemDispatcher`. + mRootViewAttached = true; }; if (UiThreadUtil.isOnUiThread()) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt index 22663e6de70c38..43a0790ca273ce 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> */ /** @@ -208,12 +208,6 @@ public object ReactNativeFeatureFlags { @JvmStatic public fun fixMountingCoordinatorReportedPendingTransactionsOnAndroid(): Boolean = accessor.fixMountingCoordinatorReportedPendingTransactionsOnAndroid() - /** - * Forces the mounting layer on Android to always batch mount items instead of dispatching them immediately. This might fix some crashes related to synchronous state updates, where some views dispatch state updates during mount. - */ - @JvmStatic - public fun forceBatchingMountItemsOnAndroid(): Boolean = accessor.forceBatchingMountItemsOnAndroid() - /** * Flag determining if the React Native DevTools (Fusebox) CDP backend should be enabled in debug builds. This flag is global and should not be changed across React Host lifetimes. */ diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt index fd7615b07442e9..b494443cbd08ec 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<1fa2a94ddb1563952c457e098f0deed7>> + * @generated SignedSource<<2a25e30cbee2548ee5538ecbc4b92fdc>> */ /** @@ -50,7 +50,6 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso private var excludeYogaFromRawPropsCache: Boolean? = null private var fixMappingOfEventPrioritiesBetweenFabricAndReactCache: Boolean? = null private var fixMountingCoordinatorReportedPendingTransactionsOnAndroidCache: Boolean? = null - private var forceBatchingMountItemsOnAndroidCache: Boolean? = null private var fuseboxEnabledDebugCache: Boolean? = null private var fuseboxEnabledReleaseCache: Boolean? = null private var initEagerTurboModulesOnNativeModulesQueueAndroidCache: Boolean? = null @@ -338,15 +337,6 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso return cached } - override fun forceBatchingMountItemsOnAndroid(): Boolean { - var cached = forceBatchingMountItemsOnAndroidCache - if (cached == null) { - cached = ReactNativeFeatureFlagsCxxInterop.forceBatchingMountItemsOnAndroid() - forceBatchingMountItemsOnAndroidCache = cached - } - return cached - } - override fun fuseboxEnabledDebug(): Boolean { var cached = fuseboxEnabledDebugCache if (cached == null) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt index a2f271f67470fe..3ce01e133fc8c8 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<0656ed5b5317e6caf85605bba62d08d1>> */ /** @@ -88,8 +88,6 @@ public object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic public external fun fixMountingCoordinatorReportedPendingTransactionsOnAndroid(): Boolean - @DoNotStrip @JvmStatic public external fun forceBatchingMountItemsOnAndroid(): Boolean - @DoNotStrip @JvmStatic public external fun fuseboxEnabledDebug(): Boolean @DoNotStrip @JvmStatic public external fun fuseboxEnabledRelease(): Boolean diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt index 8d6b0dcb1b4b19..fac7b1ecedc65c 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<09dd6fb517b7b965c5cc554a075e5590>> + * @generated SignedSource<<43c2b02a67fea9ad6d36e7716cb81ccc>> */ /** @@ -83,8 +83,6 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun fixMountingCoordinatorReportedPendingTransactionsOnAndroid(): Boolean = false - override fun forceBatchingMountItemsOnAndroid(): Boolean = false - override fun fuseboxEnabledDebug(): Boolean = true override fun fuseboxEnabledRelease(): Boolean = false diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt index 825f1e9bb2edc6..6b2f7d028daf75 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<7e78a7ec91d557297f869b964cc91eac>> + * @generated SignedSource<<71dcfc3812f442a35ae2c24621c05605>> */ /** @@ -54,7 +54,6 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces private var excludeYogaFromRawPropsCache: Boolean? = null private var fixMappingOfEventPrioritiesBetweenFabricAndReactCache: Boolean? = null private var fixMountingCoordinatorReportedPendingTransactionsOnAndroidCache: Boolean? = null - private var forceBatchingMountItemsOnAndroidCache: Boolean? = null private var fuseboxEnabledDebugCache: Boolean? = null private var fuseboxEnabledReleaseCache: Boolean? = null private var initEagerTurboModulesOnNativeModulesQueueAndroidCache: Boolean? = null @@ -372,16 +371,6 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces return cached } - override fun forceBatchingMountItemsOnAndroid(): Boolean { - var cached = forceBatchingMountItemsOnAndroidCache - if (cached == null) { - cached = currentProvider.forceBatchingMountItemsOnAndroid() - accessedFeatureFlags.add("forceBatchingMountItemsOnAndroid") - forceBatchingMountItemsOnAndroidCache = cached - } - return cached - } - override fun fuseboxEnabledDebug(): Boolean { var cached = fuseboxEnabledDebugCache if (cached == null) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt index 044953d58b2b5a..13d7ca329ee1f8 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<0c6450697814b66ae910d66f278213ef>> + * @generated SignedSource<<2dd3e32b571ae171bd5621424116188b>> */ /** @@ -83,8 +83,6 @@ public interface ReactNativeFeatureFlagsProvider { @DoNotStrip public fun fixMountingCoordinatorReportedPendingTransactionsOnAndroid(): Boolean - @DoNotStrip public fun forceBatchingMountItemsOnAndroid(): Boolean - @DoNotStrip public fun fuseboxEnabledDebug(): Boolean @DoNotStrip public fun fuseboxEnabledRelease(): Boolean diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp index cea8404ce0ee34..9338814c888063 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<869d22f5b2b35741b171a7257e91f114>> + * @generated SignedSource<<62bd0386265d0fa4bdccab1faf22d25c>> */ /** @@ -219,12 +219,6 @@ class ReactNativeFeatureFlagsProviderHolder return method(javaProvider_); } - bool forceBatchingMountItemsOnAndroid() override { - static const auto method = - getReactNativeFeatureFlagsProviderJavaClass()->getMethod("forceBatchingMountItemsOnAndroid"); - return method(javaProvider_); - } - bool fuseboxEnabledDebug() override { static const auto method = getReactNativeFeatureFlagsProviderJavaClass()->getMethod("fuseboxEnabledDebug"); @@ -475,11 +469,6 @@ bool JReactNativeFeatureFlagsCxxInterop::fixMountingCoordinatorReportedPendingTr return ReactNativeFeatureFlags::fixMountingCoordinatorReportedPendingTransactionsOnAndroid(); } -bool JReactNativeFeatureFlagsCxxInterop::forceBatchingMountItemsOnAndroid( - facebook::jni::alias_ref /*unused*/) { - return ReactNativeFeatureFlags::forceBatchingMountItemsOnAndroid(); -} - bool JReactNativeFeatureFlagsCxxInterop::fuseboxEnabledDebug( facebook::jni::alias_ref /*unused*/) { return ReactNativeFeatureFlags::fuseboxEnabledDebug(); @@ -681,9 +670,6 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "fixMountingCoordinatorReportedPendingTransactionsOnAndroid", JReactNativeFeatureFlagsCxxInterop::fixMountingCoordinatorReportedPendingTransactionsOnAndroid), - makeNativeMethod( - "forceBatchingMountItemsOnAndroid", - JReactNativeFeatureFlagsCxxInterop::forceBatchingMountItemsOnAndroid), makeNativeMethod( "fuseboxEnabledDebug", JReactNativeFeatureFlagsCxxInterop::fuseboxEnabledDebug), diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h index db65b1df62818d..b74fa4ab351ce2 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<344f9c1de8883c4b72c124dd626f6489>> + * @generated SignedSource<<00e9f2368ec7745d960e8671b0e58d19>> */ /** @@ -120,9 +120,6 @@ class JReactNativeFeatureFlagsCxxInterop static bool fixMountingCoordinatorReportedPendingTransactionsOnAndroid( facebook::jni::alias_ref); - static bool forceBatchingMountItemsOnAndroid( - facebook::jni::alias_ref); - static bool fuseboxEnabledDebug( facebook::jni::alias_ref); diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp index a8ece83edfccc5..b9962928aa3f49 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> */ /** @@ -146,10 +146,6 @@ bool ReactNativeFeatureFlags::fixMountingCoordinatorReportedPendingTransactionsO return getAccessor().fixMountingCoordinatorReportedPendingTransactionsOnAndroid(); } -bool ReactNativeFeatureFlags::forceBatchingMountItemsOnAndroid() { - return getAccessor().forceBatchingMountItemsOnAndroid(); -} - bool ReactNativeFeatureFlags::fuseboxEnabledDebug() { return getAccessor().fuseboxEnabledDebug(); } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h index 26d9c5353ad327..5b5b4f8a4b3325 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<079c1e8cd65a004c1b26f1a2517e9042>> */ /** @@ -189,11 +189,6 @@ class ReactNativeFeatureFlags { */ RN_EXPORT static bool fixMountingCoordinatorReportedPendingTransactionsOnAndroid(); - /** - * Forces the mounting layer on Android to always batch mount items instead of dispatching them immediately. This might fix some crashes related to synchronous state updates, where some views dispatch state updates during mount. - */ - RN_EXPORT static bool forceBatchingMountItemsOnAndroid(); - /** * Flag determining if the React Native DevTools (Fusebox) CDP backend should be enabled in debug builds. This flag is global and should not be changed across React Host lifetimes. */ diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp index 47899365761e96..8e03edeecc4745 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<331139167971b86c56d29f8ef914c6d1>> + * @generated SignedSource<<8f2e12ef2ddfb1e49b0cdfed8e695e54>> */ /** @@ -569,24 +569,6 @@ bool ReactNativeFeatureFlagsAccessor::fixMountingCoordinatorReportedPendingTrans return flagValue.value(); } -bool ReactNativeFeatureFlagsAccessor::forceBatchingMountItemsOnAndroid() { - auto flagValue = forceBatchingMountItemsOnAndroid_.load(); - - if (!flagValue.has_value()) { - // This block is not exclusive but it is not necessary. - // If multiple threads try to initialize the feature flag, we would only - // be accessing the provider multiple times but the end state of this - // instance and the returned flag value would be the same. - - markFlagAsAccessed(30, "forceBatchingMountItemsOnAndroid"); - - flagValue = currentProvider_->forceBatchingMountItemsOnAndroid(); - forceBatchingMountItemsOnAndroid_ = flagValue; - } - - return flagValue.value(); -} - bool ReactNativeFeatureFlagsAccessor::fuseboxEnabledDebug() { auto flagValue = fuseboxEnabledDebug_.load(); @@ -596,7 +578,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxEnabledDebug() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(31, "fuseboxEnabledDebug"); + markFlagAsAccessed(30, "fuseboxEnabledDebug"); flagValue = currentProvider_->fuseboxEnabledDebug(); fuseboxEnabledDebug_ = flagValue; @@ -614,7 +596,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxEnabledRelease() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(32, "fuseboxEnabledRelease"); + markFlagAsAccessed(31, "fuseboxEnabledRelease"); flagValue = currentProvider_->fuseboxEnabledRelease(); fuseboxEnabledRelease_ = flagValue; @@ -632,7 +614,7 @@ bool ReactNativeFeatureFlagsAccessor::initEagerTurboModulesOnNativeModulesQueueA // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(33, "initEagerTurboModulesOnNativeModulesQueueAndroid"); + markFlagAsAccessed(32, "initEagerTurboModulesOnNativeModulesQueueAndroid"); flagValue = currentProvider_->initEagerTurboModulesOnNativeModulesQueueAndroid(); initEagerTurboModulesOnNativeModulesQueueAndroid_ = flagValue; @@ -650,7 +632,7 @@ bool ReactNativeFeatureFlagsAccessor::lazyAnimationCallbacks() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(34, "lazyAnimationCallbacks"); + markFlagAsAccessed(33, "lazyAnimationCallbacks"); flagValue = currentProvider_->lazyAnimationCallbacks(); lazyAnimationCallbacks_ = flagValue; @@ -668,7 +650,7 @@ bool ReactNativeFeatureFlagsAccessor::loadVectorDrawablesOnImages() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(35, "loadVectorDrawablesOnImages"); + markFlagAsAccessed(34, "loadVectorDrawablesOnImages"); flagValue = currentProvider_->loadVectorDrawablesOnImages(); loadVectorDrawablesOnImages_ = flagValue; @@ -686,7 +668,7 @@ bool ReactNativeFeatureFlagsAccessor::setAndroidLayoutDirection() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(36, "setAndroidLayoutDirection"); + markFlagAsAccessed(35, "setAndroidLayoutDirection"); flagValue = currentProvider_->setAndroidLayoutDirection(); setAndroidLayoutDirection_ = flagValue; @@ -704,7 +686,7 @@ bool ReactNativeFeatureFlagsAccessor::traceTurboModulePromiseRejectionsOnAndroid // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(37, "traceTurboModulePromiseRejectionsOnAndroid"); + markFlagAsAccessed(36, "traceTurboModulePromiseRejectionsOnAndroid"); flagValue = currentProvider_->traceTurboModulePromiseRejectionsOnAndroid(); traceTurboModulePromiseRejectionsOnAndroid_ = flagValue; @@ -722,7 +704,7 @@ bool ReactNativeFeatureFlagsAccessor::useAlwaysAvailableJSErrorHandling() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(38, "useAlwaysAvailableJSErrorHandling"); + markFlagAsAccessed(37, "useAlwaysAvailableJSErrorHandling"); flagValue = currentProvider_->useAlwaysAvailableJSErrorHandling(); useAlwaysAvailableJSErrorHandling_ = flagValue; @@ -740,7 +722,7 @@ bool ReactNativeFeatureFlagsAccessor::useFabricInterop() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(39, "useFabricInterop"); + markFlagAsAccessed(38, "useFabricInterop"); flagValue = currentProvider_->useFabricInterop(); useFabricInterop_ = flagValue; @@ -758,7 +740,7 @@ bool ReactNativeFeatureFlagsAccessor::useImmediateExecutorInAndroidBridgeless() // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(40, "useImmediateExecutorInAndroidBridgeless"); + markFlagAsAccessed(39, "useImmediateExecutorInAndroidBridgeless"); flagValue = currentProvider_->useImmediateExecutorInAndroidBridgeless(); useImmediateExecutorInAndroidBridgeless_ = flagValue; @@ -776,7 +758,7 @@ bool ReactNativeFeatureFlagsAccessor::useNativeViewConfigsInBridgelessMode() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(41, "useNativeViewConfigsInBridgelessMode"); + markFlagAsAccessed(40, "useNativeViewConfigsInBridgelessMode"); flagValue = currentProvider_->useNativeViewConfigsInBridgelessMode(); useNativeViewConfigsInBridgelessMode_ = flagValue; @@ -794,7 +776,7 @@ bool ReactNativeFeatureFlagsAccessor::useOptimisedViewPreallocationOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(42, "useOptimisedViewPreallocationOnAndroid"); + markFlagAsAccessed(41, "useOptimisedViewPreallocationOnAndroid"); flagValue = currentProvider_->useOptimisedViewPreallocationOnAndroid(); useOptimisedViewPreallocationOnAndroid_ = flagValue; @@ -812,7 +794,7 @@ bool ReactNativeFeatureFlagsAccessor::useOptimizedEventBatchingOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(43, "useOptimizedEventBatchingOnAndroid"); + markFlagAsAccessed(42, "useOptimizedEventBatchingOnAndroid"); flagValue = currentProvider_->useOptimizedEventBatchingOnAndroid(); useOptimizedEventBatchingOnAndroid_ = flagValue; @@ -830,7 +812,7 @@ bool ReactNativeFeatureFlagsAccessor::useRuntimeShadowNodeReferenceUpdate() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(44, "useRuntimeShadowNodeReferenceUpdate"); + markFlagAsAccessed(43, "useRuntimeShadowNodeReferenceUpdate"); flagValue = currentProvider_->useRuntimeShadowNodeReferenceUpdate(); useRuntimeShadowNodeReferenceUpdate_ = flagValue; @@ -848,7 +830,7 @@ bool ReactNativeFeatureFlagsAccessor::useTurboModuleInterop() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(45, "useTurboModuleInterop"); + markFlagAsAccessed(44, "useTurboModuleInterop"); flagValue = currentProvider_->useTurboModuleInterop(); useTurboModuleInterop_ = flagValue; @@ -866,7 +848,7 @@ bool ReactNativeFeatureFlagsAccessor::useTurboModules() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(46, "useTurboModules"); + markFlagAsAccessed(45, "useTurboModules"); flagValue = currentProvider_->useTurboModules(); useTurboModules_ = flagValue; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h index 76dd7914093f05..4121373011cdfa 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<1efdbd02124b25d6599e4867f08c69c9>> */ /** @@ -62,7 +62,6 @@ class ReactNativeFeatureFlagsAccessor { bool excludeYogaFromRawProps(); bool fixMappingOfEventPrioritiesBetweenFabricAndReact(); bool fixMountingCoordinatorReportedPendingTransactionsOnAndroid(); - bool forceBatchingMountItemsOnAndroid(); bool fuseboxEnabledDebug(); bool fuseboxEnabledRelease(); bool initEagerTurboModulesOnNativeModulesQueueAndroid(); @@ -90,7 +89,7 @@ class ReactNativeFeatureFlagsAccessor { std::unique_ptr currentProvider_; bool wasOverridden_; - std::array, 47> accessedFeatureFlags_; + std::array, 46> accessedFeatureFlags_; std::atomic> commonTestFlag_; std::atomic> allowRecursiveCommitsWithSynchronousMountOnAndroid_; @@ -122,7 +121,6 @@ class ReactNativeFeatureFlagsAccessor { std::atomic> excludeYogaFromRawProps_; std::atomic> fixMappingOfEventPrioritiesBetweenFabricAndReact_; std::atomic> fixMountingCoordinatorReportedPendingTransactionsOnAndroid_; - std::atomic> forceBatchingMountItemsOnAndroid_; std::atomic> fuseboxEnabledDebug_; std::atomic> fuseboxEnabledRelease_; std::atomic> initEagerTurboModulesOnNativeModulesQueueAndroid_; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h index 9eb9a479dab0b8..7a07337b537a9f 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<2964ff45378547dd40a9b0df440f8869>> + * @generated SignedSource<> */ /** @@ -147,10 +147,6 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { return false; } - bool forceBatchingMountItemsOnAndroid() override { - return false; - } - bool fuseboxEnabledDebug() override { return true; } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h index 1b7ee55376a7dc..39bf0acbc9e183 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<5e45e15376ce8426cb5d4ddbfe599066>> + * @generated SignedSource<<9038e8340a349ed8f4abee66555e98d3>> */ /** @@ -55,7 +55,6 @@ class ReactNativeFeatureFlagsProvider { virtual bool excludeYogaFromRawProps() = 0; virtual bool fixMappingOfEventPrioritiesBetweenFabricAndReact() = 0; virtual bool fixMountingCoordinatorReportedPendingTransactionsOnAndroid() = 0; - virtual bool forceBatchingMountItemsOnAndroid() = 0; virtual bool fuseboxEnabledDebug() = 0; virtual bool fuseboxEnabledRelease() = 0; virtual bool initEagerTurboModulesOnNativeModulesQueueAndroid() = 0; diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp index 7473a90a7303eb..8839a22e053289 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp +++ b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<3a530491b7f90f1c0a1e75a6d618f586>> + * @generated SignedSource<<1626340cbb5cc8958d6b16c9b717e91e>> */ /** @@ -208,11 +208,6 @@ bool NativeReactNativeFeatureFlags::fixMountingCoordinatorReportedPendingTransac return ReactNativeFeatureFlags::fixMountingCoordinatorReportedPendingTransactionsOnAndroid(); } -bool NativeReactNativeFeatureFlags::forceBatchingMountItemsOnAndroid( - jsi::Runtime& /*runtime*/) { - return ReactNativeFeatureFlags::forceBatchingMountItemsOnAndroid(); -} - bool NativeReactNativeFeatureFlags::fuseboxEnabledDebug( jsi::Runtime& /*runtime*/) { return ReactNativeFeatureFlags::fuseboxEnabledDebug(); diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h index a6ea7723be643e..d9d4802f936b8c 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h +++ b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<4c476d0f5a9657387dd5f49db4ebde2c>> + * @generated SignedSource<> */ /** @@ -101,8 +101,6 @@ class NativeReactNativeFeatureFlags bool fixMountingCoordinatorReportedPendingTransactionsOnAndroid(jsi::Runtime& runtime); - bool forceBatchingMountItemsOnAndroid(jsi::Runtime& runtime); - bool fuseboxEnabledDebug(jsi::Runtime& runtime); bool fuseboxEnabledRelease(jsi::Runtime& runtime); diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index e6e7a5a2a710be..5659ae20929fc5 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -322,15 +322,6 @@ const definitions: FeatureFlagDefinitions = { purpose: 'experimentation', }, }, - forceBatchingMountItemsOnAndroid: { - defaultValue: false, - metadata: { - dateAdded: '2024-04-10', - description: - 'Forces the mounting layer on Android to always batch mount items instead of dispatching them immediately. This might fix some crashes related to synchronous state updates, where some views dispatch state updates during mount.', - purpose: 'experimentation', - }, - }, fuseboxEnabledDebug: { defaultValue: true, metadata: { diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index 10977d3603e4fd..90fbc2f5b3be40 100644 --- a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<716c4507093099c254b57d744366bd05>> + * @generated SignedSource<> * @flow strict */ @@ -83,7 +83,6 @@ export type ReactNativeFeatureFlags = { excludeYogaFromRawProps: Getter, fixMappingOfEventPrioritiesBetweenFabricAndReact: Getter, fixMountingCoordinatorReportedPendingTransactionsOnAndroid: Getter, - forceBatchingMountItemsOnAndroid: Getter, fuseboxEnabledDebug: Getter, fuseboxEnabledRelease: Getter, initEagerTurboModulesOnNativeModulesQueueAndroid: Getter, @@ -320,10 +319,6 @@ export const fixMappingOfEventPrioritiesBetweenFabricAndReact: Getter = * Fixes a limitation on Android where the mounting coordinator would report there are no pending transactions but some of them were actually not processed due to the use of the push model. */ export const fixMountingCoordinatorReportedPendingTransactionsOnAndroid: Getter = createNativeFlagGetter('fixMountingCoordinatorReportedPendingTransactionsOnAndroid', false); -/** - * Forces the mounting layer on Android to always batch mount items instead of dispatching them immediately. This might fix some crashes related to synchronous state updates, where some views dispatch state updates during mount. - */ -export const forceBatchingMountItemsOnAndroid: Getter = createNativeFlagGetter('forceBatchingMountItemsOnAndroid', false); /** * Flag determining if the React Native DevTools (Fusebox) CDP backend should be enabled in debug builds. This flag is global and should not be changed across React Host lifetimes. */ diff --git a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js index bc26c3a86faa71..8dbecefffb6b51 100644 --- a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<53510b80964a952f0fc4ed97a6d59386>> * @flow strict */ @@ -56,7 +56,6 @@ export interface Spec extends TurboModule { +excludeYogaFromRawProps?: () => boolean; +fixMappingOfEventPrioritiesBetweenFabricAndReact?: () => boolean; +fixMountingCoordinatorReportedPendingTransactionsOnAndroid?: () => boolean; - +forceBatchingMountItemsOnAndroid?: () => boolean; +fuseboxEnabledDebug?: () => boolean; +fuseboxEnabledRelease?: () => boolean; +initEagerTurboModulesOnNativeModulesQueueAndroid?: () => boolean; From 685facfd53460136c649f6b303346b6d1de0b68a Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Mon, 11 Nov 2024 07:01:53 -0800 Subject: [PATCH 154/220] fix race condition in EventBeat (#47548) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47548 changelog: [internal] This race condition only shows itself with flag `useOptimizedEventBatchingOnAndroid` # Problem EventBeat assumes method `induce` will be called repeatedly on every UI tick. This is true for iOS and existing implementation of event beat on Android. The first early exist inside of `induce` method is built with this assumption. `useOptimizedEventBatchingOnAndroid` on Android changes this. `induce` will only be called after FabricUIManager.onRequestEventBeat is invoked and then it will stop. For one `FabricUIManager.onRequestEventBeat` call, `EventBeat::induce` is called once. And there is a chance for race condition. Here is a simplified implementation of `induce`. This method may be called many times in sequence. The caller will set [isRequested_](https://github.com/facebook/react-native/blob/main/packages/react-native/ReactCommon/react/renderer/core/EventBeat.cpp#L25) and then invoke [FabricUIManager.onRequestEventBeat](https://github.com/facebook/react-native/blob/main/packages/react-native/ReactAndroid/src/main/jni/react/fabric/AndroidEventBeat.cpp#L43). Notice how `FabricUIManager.onRequestEventBeat` is debounced if `isRequested_` flag is true. ``` void EventBeat::induce() const { if (!isRequested_ || isBeatCallbackScheduled_) { // isRequested_ is not set to false in case isBeatCallbackScheduled_) is true. return; } isRequested_ = false; isBeatCallbackScheduled_ = true; auto beat = std::function( // on JS queue isBeatCallbackScheduled_ = false; // beatCallback_(runtime) } runtimeScheduler_.scheduleWork(std::move(beat)); } ``` This can get into a state where `isRequested_` is not reset back to false even though `EventBeat::induce` is called when `isBeatCallbackScheduled_` is true. `AndroidEventBeat::request` -> `isRequested_` is set to true -> `FabricUIManager::onRequestEventBeat` -> `EventBeat::induce` -> `isRequested_` is set to false -> `isBeatCallbackScheduled_` is set to true -> `AndroidEventBeat::request` -> `FabricUIManager::onRequestEventBeat` -> `EventBeat::induce` (early exit because `isBeatCallbackScheduled_` is true) -> `beat` is executed on the JS thread. From this point on, subsequent calls to `AndroidEventBeat::request` are always debounced because flag `isRequested_` is true. Any subsequent event on Android will end up calling `EventBeat::induce` and the mechanism gets unstuck. # The fix The fix is simple, any time `EventBeat::induce` is called, make sure `request_` flag is set to false. This then satisfied the expectation of `useOptimizedEventBatchingOnAndroid` optimisation. Reviewed By: rubennorte Differential Revision: D65566258 fbshipit-source-id: 5f15da8f5cb722b329f9f72b9ddca8e2cac04144 --- .../src/main/jni/react/fabric/AndroidEventBeat.cpp | 2 +- .../ReactCommon/react/renderer/core/EventBeat.cpp | 11 ++++++++--- .../ReactCommon/react/renderer/core/EventBeat.h | 6 +++++- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/AndroidEventBeat.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/AndroidEventBeat.cpp index 9c63329613d5aa..f8171553ca1add 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/AndroidEventBeat.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/AndroidEventBeat.cpp @@ -33,7 +33,7 @@ void AndroidEventBeat::tick() const { } void AndroidEventBeat::request() const { - bool alreadyRequested = isRequested_; + bool alreadyRequested = isEventBeatRequested_; EventBeat::request(); if (!alreadyRequested) { // Notifies java side that an event will be dispatched (e.g. LayoutEvent) diff --git a/packages/react-native/ReactCommon/react/renderer/core/EventBeat.cpp b/packages/react-native/ReactCommon/react/renderer/core/EventBeat.cpp index 82f18533a9d8dd..a7fe0cd7f003e6 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/EventBeat.cpp +++ b/packages/react-native/ReactCommon/react/renderer/core/EventBeat.cpp @@ -22,7 +22,7 @@ void EventBeat::request() const { react_native_assert( beatCallback_ && "Unexpected state: EventBeat::setBeatCallback was not called before EventBeat::request."); - isRequested_ = true; + isEventBeatRequested_ = true; } void EventBeat::requestSynchronous() const { @@ -38,11 +38,16 @@ void EventBeat::setBeatCallback(BeatCallback beatCallback) { } void EventBeat::induce() const { - if (!isRequested_ || isBeatCallbackScheduled_) { + if (!isEventBeatRequested_) { + return; + } + + isEventBeatRequested_ = false; + + if (isBeatCallbackScheduled_) { return; } - isRequested_ = false; isBeatCallbackScheduled_ = true; auto beat = std::function( diff --git a/packages/react-native/ReactCommon/react/renderer/core/EventBeat.h b/packages/react-native/ReactCommon/react/renderer/core/EventBeat.h index 02a0499427e0ed..ae88c8a5f517a2 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/EventBeat.h +++ b/packages/react-native/ReactCommon/react/renderer/core/EventBeat.h @@ -130,7 +130,11 @@ class EventBeat { BeatCallback beatCallback_; std::shared_ptr ownerBox_; - mutable std::atomic isRequested_{false}; + + /* + * Indicates if event beat was requested to avoid redundant requests. + */ + mutable std::atomic isEventBeatRequested_{false}; private: RuntimeScheduler& runtimeScheduler_; From 443bc32dc49a86534fce1d6ec0e31c97b8f33053 Mon Sep 17 00:00:00 2001 From: David Vacca Date: Mon, 11 Nov 2024 07:03:00 -0800 Subject: [PATCH 155/220] Update KDocs for ReactHost.destroy() methods (#47536) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47536 I'm updating KDoc for ReactHost.destroy() methods to warn about potential deadlock when waiting for completion changelog: [Android][Changed] update documentation for ReactHost.destroy() APIs Reviewed By: shwanton Differential Revision: D65734396 fbshipit-source-id: b7924cafce2fd58e2633736f922d303c61f6ad14 --- .../main/java/com/facebook/react/ReactHost.kt | 16 ++++++++++++-- .../facebook/react/runtime/ReactHostImpl.java | 21 +++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactHost.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactHost.kt index 86409ba182a868..04a83dff30629a 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactHost.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactHost.kt @@ -111,7 +111,13 @@ public interface ReactHost { * Entrypoint to destroy the ReactInstance. If the ReactInstance is reloading, will wait until * reload is finished, before destroying. * - * @param reason describing why ReactHost is being destroyed (e.g. memmory pressure) + * The destroy operation is asynchronous and the task returned by this method will complete when + * React Native gets destroyed. Note that the destroy operation will execute in multiple threads, + * in particular some of the sub-tasks will run in the UIThread. Calling + * [TaskInterface.waitForCompletion] from the UIThread will lead into a deadlock. Use [destroy] + * passing the onDestroyFinished callback to be notified when React Native gets destroyed. + * + * @param reason describing why ReactHost is being destroyed (e.g. memory pressure) * @param ex exception that caused the trigger to destroy ReactHost (or null) This exception will * be used to log properly the cause of destroy operation. * @return A task that completes when React Native gets destroyed. @@ -125,7 +131,13 @@ public interface ReactHost { * Entrypoint to destroy the ReactInstance. If the ReactInstance is reloading, will wait until * reload is finished, before destroying. * - * @param reason describing why ReactHost is being destroyed (e.g. memmory pressure) + * The destroy operation is asynchronous and the task returned by this method will complete when + * React Native gets destroyed. Note that the destroy operation will execute in multiple threads, + * in particular some of the sub-tasks will run in the UIThread. Calling + * [TaskInterface.waitForCompletion] from the UIThread will lead into a deadlock. Use + * onDestroyFinished callback to be notified when React Native gets destroyed. + * + * @param reason describing why ReactHost is being destroyed (e.g. memory pressure) * @param ex exception that caused the trigger to destroy ReactHost (or null) This exception will * be used to log properly the cause of destroy operation. * @param onDestroyFinished callback that will be called when React Native gets destroyed. diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.java index dd82980846632e..1e06f6abb7b340 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.java @@ -543,6 +543,22 @@ private void loadNetworkResource(String url, InspectorNetworkRequestListener lis InspectorNetworkHelper.loadNetworkResource(url, listener); } + /** + * Entrypoint to destroy the ReactInstance. If the ReactInstance is reloading, will wait until + * reload is finished, before destroying. + * + *

The destroy operation is asynchronous and the task returned by this method will complete + * when React Native gets destroyed. Note that the destroy operation will execute in multiple + * threads, in particular some of the sub-tasks will run in the UIThread. Calling {@link + * TaskInterface#waitForCompletion()} from the UIThread will lead into a deadlock. Use + * onDestroyFinished callback to be notified when React Native gets destroyed. + * + * @param reason describing why ReactHost is being destroyed (e.g. memory pressure) + * @param ex exception that caused the trigger to destroy ReactHost (or null) This exception will + * be used to log properly the cause of destroy operation. + * @param onDestroyFinished callback that will be called when React Native gets destroyed. + * @return A task that completes when React Native gets destroyed. + */ @NonNull @Override public TaskInterface destroy( @@ -566,6 +582,11 @@ public Void then(@NonNull Task task) throws Exception { * Entrypoint to destroy the ReactInstance. If the ReactInstance is reloading, will wait until * reload is finished, before destroying. * + *

The destroy operation is asynchronous and the task returned by this method will complete + * when React Native gets destroyed. Note that the destroy operation will execute in multiple + * threads, in particular some of the sub-tasks will run in the UIThread. Calling {@link + * TaskInterface#waitForCompletion()} from the UIThread will lead into a deadlock. + * * @param reason {@link String} describing why ReactHost is being destroyed (e.g. memory pressure) * @param ex {@link Exception} exception that caused the trigger to destroy ReactHost (or null) * This exception will be used to log properly the cause of destroy operation. From 17b69795c3d7b68de27c818e9f4e26f5e1a920a7 Mon Sep 17 00:00:00 2001 From: David Vacca Date: Mon, 11 Nov 2024 07:03:00 -0800 Subject: [PATCH 156/220] Migrate ExecutorException to kotlin (#47539) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47539 Migrate ExecutorException to kotlin changelog: [internal] internal Reviewed By: javache Differential Revision: D65738325 fbshipit-source-id: 0ae6adedf0f80d57426ebc749fd77c31942b3b47 --- .../{ExecutorException.java => ExecutorException.kt} | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) rename packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/{ExecutorException.java => ExecutorException.kt} (56%) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/ExecutorException.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/ExecutorException.kt similarity index 56% rename from packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/ExecutorException.java rename to packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/ExecutorException.kt index 57c0a4e817d26d..9748991897414e 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/ExecutorException.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/ExecutorException.kt @@ -5,17 +5,11 @@ * LICENSE file in the root directory of this source tree. */ -package com.facebook.react.runtime.internal.bolts; - -import androidx.annotation.Nullable; +package com.facebook.react.runtime.internal.bolts /** * This is a wrapper class for emphasizing that task failed due to bad {@code Executor}, rather than * the continuation block it self. */ -class ExecutorException extends RuntimeException { - - public ExecutorException(@Nullable Exception e) { - super("An exception was thrown by an Executor", e); - } -} +internal class ExecutorException(e: Exception?) : + RuntimeException("An exception was thrown by an Executor", e) {} From b8337ebf97149448ec1e0db602c8b77971d84f8d Mon Sep 17 00:00:00 2001 From: David Vacca Date: Mon, 11 Nov 2024 07:03:00 -0800 Subject: [PATCH 157/220] Migrate Continuation to kotlin (#47537) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47537 Migrate Continuation interface to kotlin changelog: [internal] internal Reviewed By: javache Differential Revision: D65738326 fbshipit-source-id: 1a119f6d349101951dc528583f3dbaf5441da91e --- .../bolts/{Continuation.java => Continuation.kt} | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) rename packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/{Continuation.java => Continuation.kt} (59%) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/Continuation.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/Continuation.kt similarity index 59% rename from packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/Continuation.java rename to packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/Continuation.kt index 216747122516c7..c71dfa20872123 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/Continuation.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/Continuation.kt @@ -5,20 +5,16 @@ * LICENSE file in the root directory of this source tree. */ -package com.facebook.react.runtime.internal.bolts; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; +package com.facebook.react.runtime.internal.bolts /** * A function to be called after a task completes. * *

If you wish to have the Task from a Continuation that does not return a Task be cancelled then - * throw a {@link java.util.concurrent.CancellationException} from the Continuation. + * throw a [java.util.concurrent.CancellationException] from the Continuation. * * @see Task */ public interface Continuation { - @Nullable - TContinuationResult then(@NonNull Task task) throws Exception; + @Throws(Exception::class) public fun then(task: Task): TContinuationResult? } From 7b21b9e69c6176c7f66af0e479623ed1c2be0d62 Mon Sep 17 00:00:00 2001 From: David Vacca Date: Mon, 11 Nov 2024 07:03:00 -0800 Subject: [PATCH 158/220] Internalize Continuation (#47540) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47540 Continuation is only used inside RN, we should make it internal changelog: [Android][Changed] Reduce visibility of Continuation to internal, although this interface wasn't being exposed in any public API Reviewed By: javache Differential Revision: D65738329 fbshipit-source-id: 6fb1b9e9a253eafad0f6eb1e4c1363d6254846da --- packages/react-native/ReactAndroid/api/ReactAndroid.api | 4 ---- .../com/facebook/react/runtime/internal/bolts/Continuation.kt | 4 ++-- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 415b96566b430e..bc1155d43a40d3 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -3862,10 +3862,6 @@ public final class com/facebook/react/runtime/hermes/HermesInstance : com/facebo public final class com/facebook/react/runtime/hermes/HermesInstance$Companion { } -public abstract interface class com/facebook/react/runtime/internal/bolts/Continuation { - public abstract fun then (Lcom/facebook/react/runtime/internal/bolts/Task;)Ljava/lang/Object; -} - public class com/facebook/react/runtime/internal/bolts/Task : com/facebook/react/interfaces/TaskInterface { public static final field IMMEDIATE_EXECUTOR Ljava/util/concurrent/Executor; public static final field UI_THREAD_EXECUTOR Ljava/util/concurrent/Executor; diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/Continuation.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/Continuation.kt index c71dfa20872123..d19b016b1703af 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/Continuation.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/Continuation.kt @@ -15,6 +15,6 @@ package com.facebook.react.runtime.internal.bolts * * @see Task */ -public interface Continuation { - @Throws(Exception::class) public fun then(task: Task): TContinuationResult? +internal interface Continuation { + @Throws(Exception::class) fun then(task: Task): TContinuationResult? } From a4eb5794ccae4a4d54cd20d6105a84bacf91a786 Mon Sep 17 00:00:00 2001 From: David Vacca Date: Mon, 11 Nov 2024 07:03:00 -0800 Subject: [PATCH 159/220] Migrate TaskCompletionSource to kotlin (#47541) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47541 Migrate TaskCompletionSource to kotlin changelog: [internal] internal Reviewed By: javache Differential Revision: D65738330 fbshipit-source-id: 34963ae4a95dbea2fcebbdaa33436e22a7ca4751 --- .../ReactAndroid/api/ReactAndroid.api | 16 ++-- .../internal/bolts/TaskCompletionSource.java | 73 ------------------- .../internal/bolts/TaskCompletionSource.kt | 50 +++++++++++++ 3 files changed, 58 insertions(+), 81 deletions(-) delete mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/TaskCompletionSource.java create mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/TaskCompletionSource.kt diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index bc1155d43a40d3..14331ddd94dfbf 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -3895,15 +3895,15 @@ public abstract interface class com/facebook/react/runtime/internal/bolts/Task$U public abstract fun unobservedException (Lcom/facebook/react/runtime/internal/bolts/Task;Lcom/facebook/react/runtime/internal/bolts/UnobservedTaskException;)V } -public class com/facebook/react/runtime/internal/bolts/TaskCompletionSource { +public final class com/facebook/react/runtime/internal/bolts/TaskCompletionSource { public fun ()V - public fun getTask ()Lcom/facebook/react/runtime/internal/bolts/Task; - public fun setCancelled ()V - public fun setError (Ljava/lang/Exception;)V - public fun setResult (Ljava/lang/Object;)V - public fun trySetCancelled ()Z - public fun trySetError (Ljava/lang/Exception;)Z - public fun trySetResult (Ljava/lang/Object;)Z + public final fun getTask ()Lcom/facebook/react/runtime/internal/bolts/Task; + public final fun setCancelled ()V + public final fun setError (Ljava/lang/Exception;)V + public final fun setResult (Ljava/lang/Object;)V + public final fun trySetCancelled ()Z + public final fun trySetError (Ljava/lang/Exception;)Z + public final fun trySetResult (Ljava/lang/Object;)Z } public final class com/facebook/react/shell/MainPackageConfig { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/TaskCompletionSource.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/TaskCompletionSource.java deleted file mode 100644 index 080c6c43a231f2..00000000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/TaskCompletionSource.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and 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.runtime.internal.bolts; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -/** - * Allows safe orchestration of a task's completion, preventing the consumer from prematurely - * completing the task. Essentially, it represents the producer side of a Task, providing - * access to the consumer side through the getTask() method while isolating the Task's completion - * mechanisms from the consumer. - */ -public class TaskCompletionSource { - - @NonNull private final Task task; - - /** - * Creates a TaskCompletionSource that orchestrates a Task. This allows the creator of a task to - * be solely responsible for its completion. - */ - public TaskCompletionSource() { - task = new Task<>(); - } - - /** - * @return the Task associated with this TaskCompletionSource. - */ - public @NonNull Task getTask() { - return task; - } - - /** Sets the cancelled flag on the Task if the Task hasn't already been completed. */ - public boolean trySetCancelled() { - return task.trySetCancelled(); - } - - /** Sets the result on the Task if the Task hasn't already been completed. */ - public boolean trySetResult(@Nullable TResult result) { - return task.trySetResult(result); - } - - /** Sets the error on the Task if the Task hasn't already been completed. */ - public boolean trySetError(@Nullable Exception error) { - return task.trySetError(error); - } - - /** Sets the cancelled flag on the task, throwing if the Task has already been completed. */ - public void setCancelled() { - if (!trySetCancelled()) { - throw new IllegalStateException("Cannot cancel a completed task."); - } - } - - /** Sets the result of the Task, throwing if the Task has already been completed. */ - public void setResult(@Nullable TResult result) { - if (!trySetResult(result)) { - throw new IllegalStateException("Cannot set the result of a completed task."); - } - } - - /** Sets the error of the Task, throwing if the Task has already been completed. */ - public void setError(@Nullable Exception error) { - if (!trySetError(error)) { - throw new IllegalStateException("Cannot set the error on a completed task."); - } - } -} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/TaskCompletionSource.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/TaskCompletionSource.kt new file mode 100644 index 00000000000000..ca4d9b7319f0f0 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/TaskCompletionSource.kt @@ -0,0 +1,50 @@ +/* + * Copyright (c) Meta Platforms, Inc. and 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.runtime.internal.bolts + +/** + * Allows safe orchestration of a task's completion, preventing the consumer from prematurely + * completing the task. Essentially, it represents the producer side of a Task, providing + * access to the consumer side through the getTask() method while isolating the Task's completion + * mechanisms from the consumer. + */ +public class TaskCompletionSource() { + + /** @return the Task associated with this TaskCompletionSource. */ + public val task: Task = Task() + + /** Sets the cancelled flag on the Task if the Task hasn't already been completed. */ + public fun trySetCancelled(): Boolean = task.trySetCancelled() + + /** Sets the result on the Task if the Task hasn't already been completed. */ + public fun trySetResult(result: TResult?): Boolean = task.trySetResult(result) + + /** Sets the error on the Task if the Task hasn't already been completed. */ + public fun trySetError(error: Exception?): Boolean = task.trySetError(error) + + /** Sets the cancelled flag on the task, throwing if the Task has already been completed. */ + public fun setCancelled(): Unit { + if (!trySetCancelled()) { + throw IllegalStateException("Cannot cancel a completed task.") + } + } + + /** Sets the result of the Task, throwing if the Task has already been completed. */ + public fun setResult(result: TResult?): Unit { + if (!trySetResult(result)) { + throw IllegalStateException("Cannot set the result of a completed task.") + } + } + + /** Sets the error of the Task, throwing if the Task has already been completed. */ + public fun setError(error: Exception?): Unit { + if (!trySetError(error)) { + throw IllegalStateException("Cannot set the error on a completed task.") + } + } +} From 4f551611326d63b6fb5cd53e63d536c2c6f04647 Mon Sep 17 00:00:00 2001 From: David Vacca Date: Mon, 11 Nov 2024 07:03:00 -0800 Subject: [PATCH 160/220] Internalize TaskCompletionSource class (#47543) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47543 TaskCompletionSource is public but it shouldn't, in this diff I'm making it intenral changelog: [Android][Breaking] Reduce visibility of TaskCompletionSource class Reviewed By: javache Differential Revision: D65738324 fbshipit-source-id: 61db35a408162c53398b20e45a52f3eb46de1eae --- .../react-native/ReactAndroid/api/ReactAndroid.api | 11 ----------- .../runtime/internal/bolts/TaskCompletionSource.kt | 2 +- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 14331ddd94dfbf..969a7a5a8b3706 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -3895,17 +3895,6 @@ public abstract interface class com/facebook/react/runtime/internal/bolts/Task$U public abstract fun unobservedException (Lcom/facebook/react/runtime/internal/bolts/Task;Lcom/facebook/react/runtime/internal/bolts/UnobservedTaskException;)V } -public final class com/facebook/react/runtime/internal/bolts/TaskCompletionSource { - public fun ()V - public final fun getTask ()Lcom/facebook/react/runtime/internal/bolts/Task; - public final fun setCancelled ()V - public final fun setError (Ljava/lang/Exception;)V - public final fun setResult (Ljava/lang/Object;)V - public final fun trySetCancelled ()Z - public final fun trySetError (Ljava/lang/Exception;)Z - public final fun trySetResult (Ljava/lang/Object;)Z -} - public final class com/facebook/react/shell/MainPackageConfig { public fun (Lcom/facebook/imagepipeline/core/ImagePipelineConfig;)V public final fun getFrescoConfig ()Lcom/facebook/imagepipeline/core/ImagePipelineConfig; diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/TaskCompletionSource.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/TaskCompletionSource.kt index ca4d9b7319f0f0..4964d0a88b644f 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/TaskCompletionSource.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/TaskCompletionSource.kt @@ -13,7 +13,7 @@ package com.facebook.react.runtime.internal.bolts * access to the consumer side through the getTask() method while isolating the Task's completion * mechanisms from the consumer. */ -public class TaskCompletionSource() { +internal class TaskCompletionSource() { /** @return the Task associated with this TaskCompletionSource. */ public val task: Task = Task() From 94839ed174f27cc9f29615a83fede680a50b7261 Mon Sep 17 00:00:00 2001 From: David Vacca Date: Mon, 11 Nov 2024 07:03:00 -0800 Subject: [PATCH 161/220] Migrate UnobservedTaskException to kotlin (#47542) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47542 Migrate UnobservedTaskException to kotlin changelog: [internal] internal Reviewed By: javache Differential Revision: D65738327 fbshipit-source-id: 251f8ee55497328212ce3facab7a4686fa1a29c8 --- ...edTaskException.java => UnobservedTaskException.kt} | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) rename packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/{UnobservedTaskException.java => UnobservedTaskException.kt} (52%) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/UnobservedTaskException.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/UnobservedTaskException.kt similarity index 52% rename from packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/UnobservedTaskException.java rename to packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/UnobservedTaskException.kt index a0013d84914918..3566ba02fa9e79 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/UnobservedTaskException.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/UnobservedTaskException.kt @@ -5,13 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -package com.facebook.react.runtime.internal.bolts; - -import androidx.annotation.Nullable; +package com.facebook.react.runtime.internal.bolts /** Used to signify that a Task's error went unobserved. */ -class UnobservedTaskException extends RuntimeException { - public UnobservedTaskException(@Nullable Throwable cause) { - super(cause); - } -} +internal class UnobservedTaskException(cause: Throwable?) : RuntimeException(cause) {} From 3a4493f4c4a70492c6d50eca3d604111a285e887 Mon Sep 17 00:00:00 2001 From: David Vacca Date: Mon, 11 Nov 2024 07:03:00 -0800 Subject: [PATCH 162/220] Migrate UnobservedErrorNotifier to kotlin (#47538) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47538 Migrate UnobservedErrorNotifier to kotlin changelog: [internal] internal Reviewed By: javache Differential Revision: D65738328 fbshipit-source-id: 651caecfbbe01d52aeac371f4427665c34b85107 --- .../react/runtime/internal/bolts/Task.java | 2 +- .../bolts/UnobservedErrorNotifier.java | 42 ------------------- .../internal/bolts/UnobservedErrorNotifier.kt | 27 ++++++++++++ 3 files changed, 28 insertions(+), 43 deletions(-) delete mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/UnobservedErrorNotifier.java create mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/UnobservedErrorNotifier.kt diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/Task.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/Task.java index 840d582a7b1743..dd21653372779b 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/Task.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/Task.java @@ -58,7 +58,7 @@ public interface UnobservedExceptionHandler { private static volatile UnobservedExceptionHandler unobservedExceptionHandler; /** Returns the handler invoked when a task has an unobserved exception or {@code null}. */ - public static UnobservedExceptionHandler getUnobservedExceptionHandler() { + public static @Nullable UnobservedExceptionHandler getUnobservedExceptionHandler() { return unobservedExceptionHandler; } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/UnobservedErrorNotifier.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/UnobservedErrorNotifier.java deleted file mode 100644 index 5ddf687ad10d5a..00000000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/UnobservedErrorNotifier.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and 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.runtime.internal.bolts; - -import androidx.annotation.Nullable; - -/** - * This class is used to retain a faulted task until either its error is observed or it is - * finalized. If it is finalized with a task, then the uncaught exception handler is exected with an - * UnobservedTaskException. - */ -class UnobservedErrorNotifier { - @Nullable private Task task; - - public UnobservedErrorNotifier(@Nullable Task task) { - this.task = task; - } - - @Override - protected void finalize() throws Throwable { - try { - Task faultedTask = task; - if (faultedTask != null) { - Task.UnobservedExceptionHandler ueh = Task.getUnobservedExceptionHandler(); - if (ueh != null) { - ueh.unobservedException(faultedTask, new UnobservedTaskException(faultedTask.getError())); - } - } - } finally { - super.finalize(); - } - } - - public void setObserved() { - task = null; - } -} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/UnobservedErrorNotifier.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/UnobservedErrorNotifier.kt new file mode 100644 index 00000000000000..1f4422eb57d304 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/UnobservedErrorNotifier.kt @@ -0,0 +1,27 @@ +/* + * Copyright (c) Meta Platforms, Inc. and 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.runtime.internal.bolts + +/** + * This class is used to retain a faulted task until either its error is observed or it is + * finalized. If it is finalized with a task, then the uncaught exception handler is executed with + * an UnobservedTaskException. + */ +internal class UnobservedErrorNotifier(private var task: Task<*>?) { + + protected fun finalize() { + task?.let { faultedTask -> + Task.getUnobservedExceptionHandler() + ?.unobservedException(faultedTask, UnobservedTaskException(faultedTask.getError())) + } + } + + public fun setObserved(): Unit { + task = null + } +} From 2c31fe99e1cc5bfdb393d4f5c70231a042ea67ef Mon Sep 17 00:00:00 2001 From: Pieter De Baets Date: Mon, 11 Nov 2024 07:35:20 -0800 Subject: [PATCH 163/220] Use rval for AttributedString::Fragment changes (#47494) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47494 Changelog: [General][Changed] AttributedString `appendFragment` and `prependFragment` take an rval instead of a const ref; append/prependAttributedString have been removed Reviewed By: mdvacca Differential Revision: D65603864 fbshipit-source-id: 1160a9e2064470f826bea66736b4fce13caa3a73 --- .../attributedstring/AttributedString.cpp | 36 ++++--------------- .../attributedstring/AttributedString.h | 11 ++---- .../tests/AttributedStringBoxTest.cpp | 6 ++-- .../components/text/BaseTextShadowNode.cpp | 4 +-- .../AndroidTextInputShadowNode.cpp | 4 +-- 5 files changed, 15 insertions(+), 46 deletions(-) diff --git a/packages/react-native/ReactCommon/react/renderer/attributedstring/AttributedString.cpp b/packages/react-native/ReactCommon/react/renderer/attributedstring/AttributedString.cpp index 6ce203b415c520..f5c0a1c020db9e 100644 --- a/packages/react-native/ReactCommon/react/renderer/attributedstring/AttributedString.cpp +++ b/packages/react-native/ReactCommon/react/renderer/attributedstring/AttributedString.cpp @@ -53,42 +53,18 @@ bool Fragment::operator!=(const Fragment& rhs) const { #pragma mark - AttributedString -void AttributedString::appendFragment(const Fragment& fragment) { +void AttributedString::appendFragment(Fragment&& fragment) { ensureUnsealed(); - - if (fragment.string.empty()) { - return; + if (!fragment.string.empty()) { + fragments_.push_back(std::move(fragment)); } - - fragments_.push_back(fragment); } -void AttributedString::prependFragment(const Fragment& fragment) { +void AttributedString::prependFragment(Fragment&& fragment) { ensureUnsealed(); - - if (fragment.string.empty()) { - return; + if (!fragment.string.empty()) { + fragments_.insert(fragments_.begin(), std::move(fragment)); } - - fragments_.insert(fragments_.begin(), fragment); -} - -void AttributedString::appendAttributedString( - const AttributedString& attributedString) { - ensureUnsealed(); - fragments_.insert( - fragments_.end(), - attributedString.fragments_.begin(), - attributedString.fragments_.end()); -} - -void AttributedString::prependAttributedString( - const AttributedString& attributedString) { - ensureUnsealed(); - fragments_.insert( - fragments_.begin(), - attributedString.fragments_.begin(), - attributedString.fragments_.end()); } void AttributedString::setBaseTextAttributes( diff --git a/packages/react-native/ReactCommon/react/renderer/attributedstring/AttributedString.h b/packages/react-native/ReactCommon/react/renderer/attributedstring/AttributedString.h index 4499aefad453ed..7bd57b37c13a8a 100644 --- a/packages/react-native/ReactCommon/react/renderer/attributedstring/AttributedString.h +++ b/packages/react-native/ReactCommon/react/renderer/attributedstring/AttributedString.h @@ -65,15 +65,8 @@ class AttributedString : public Sealable, public DebugStringConvertible { /* * Appends and prepends a `fragment` to the string. */ - void appendFragment(const Fragment& fragment); - void prependFragment(const Fragment& fragment); - - /* - * Appends and prepends an `attributedString` (all its fragments) to - * the string. - */ - void appendAttributedString(const AttributedString& attributedString); - void prependAttributedString(const AttributedString& attributedString); + void appendFragment(Fragment&& fragment); + void prependFragment(Fragment&& fragment); /* * Sets attributes which would apply to hypothetical text not included in the diff --git a/packages/react-native/ReactCommon/react/renderer/attributedstring/tests/AttributedStringBoxTest.cpp b/packages/react-native/ReactCommon/react/renderer/attributedstring/tests/AttributedStringBoxTest.cpp index b9ddd65ef8668f..b6774b36f4d537 100644 --- a/packages/react-native/ReactCommon/react/renderer/attributedstring/tests/AttributedStringBoxTest.cpp +++ b/packages/react-native/ReactCommon/react/renderer/attributedstring/tests/AttributedStringBoxTest.cpp @@ -23,7 +23,7 @@ TEST(AttributedStringBoxTest, testValueConstructor) { auto attributedString = AttributedString{}; auto fragment = AttributedString::Fragment{}; fragment.string = "test string"; - attributedString.appendFragment(fragment); + attributedString.appendFragment(std::move(fragment)); auto attributedStringBox = AttributedStringBox{attributedString}; EXPECT_EQ(attributedStringBox.getMode(), AttributedStringBox::Mode::Value); @@ -58,7 +58,7 @@ TEST(AttributedStringBoxTest, testMoveConstructor) { auto attributedString = AttributedString{}; auto fragment = AttributedString::Fragment{}; fragment.string = "test string"; - attributedString.appendFragment(fragment); + attributedString.appendFragment(std::move(fragment)); auto movedFromAttributedStringBox = AttributedStringBox{attributedString}; auto moveToAttributedStringBox = @@ -88,7 +88,7 @@ TEST(AttributedStringBoxTest, testMoveAssignment) { auto attributedString = AttributedString{}; auto fragment = AttributedString::Fragment{}; fragment.string = "test string"; - attributedString.appendFragment(fragment); + attributedString.appendFragment(std::move(fragment)); auto movedFromAttributedStringBox = AttributedStringBox{attributedString}; auto moveToAttributedStringBox = AttributedStringBox{}; diff --git a/packages/react-native/ReactCommon/react/renderer/components/text/BaseTextShadowNode.cpp b/packages/react-native/ReactCommon/react/renderer/components/text/BaseTextShadowNode.cpp index 77ede813aedd3a..1d0bd67846cf19 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/text/BaseTextShadowNode.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/text/BaseTextShadowNode.cpp @@ -48,7 +48,7 @@ void BaseTextShadowNode::buildAttributedString( // don't need it at all). Storing a `ShadowView` instance instead of // `ShadowNode` should properly fix this problem. fragment.parentShadowView = shadowViewFromShadowNode(parentNode); - outAttributedString.appendFragment(fragment); + outAttributedString.appendFragment(std::move(fragment)); lastFragmentWasRawText = true; } continue; @@ -75,7 +75,7 @@ void BaseTextShadowNode::buildAttributedString( fragment.string = AttributedString::Fragment::AttachmentCharacter(); fragment.parentShadowView = shadowViewFromShadowNode(*childNode); fragment.textAttributes = baseTextAttributes; - outAttributedString.appendFragment(fragment); + outAttributedString.appendFragment(std::move(fragment)); outAttachments.push_back(Attachment{ childNode.get(), outAttributedString.getFragments().size() - 1}); } diff --git a/packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputShadowNode.cpp b/packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputShadowNode.cpp index 2d19e6daecf6fe..e45bca14842a6a 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputShadowNode.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputShadowNode.cpp @@ -61,7 +61,7 @@ AttributedString AndroidTextInputShadowNode::getAttributedString() const { // that effect. fragment.textAttributes.backgroundColor = clearColor(); fragment.parentShadowView = ShadowView(*this); - attributedString.prependFragment(fragment); + attributedString.prependFragment(std::move(fragment)); } return attributedString; @@ -91,7 +91,7 @@ AttributedString AndroidTextInputShadowNode::getPlaceholderAttributedString() // appended to the AttributedString (see implementation of appendFragment) fragment.textAttributes = textAttributes; fragment.parentShadowView = ShadowView(*this); - textAttributedString.appendFragment(fragment); + textAttributedString.appendFragment(std::move(fragment)); return textAttributedString; } From e70202e606be3101da33d28f5403443c3e84749e Mon Sep 17 00:00:00 2001 From: oddlyspaced Date: Mon, 11 Nov 2024 07:38:21 -0800 Subject: [PATCH 164/220] feat(Android): add support for detecting grayscale mode enabled on android (#47497) Summary: On android the isGrayScaleEnabled method of AccessibilityInfo always returns false due to missing implementation. This PR fills the gap by providing the native module logic for checking grayscale mode. ## Changelog: - Added native module code to check for grayscale mode on android - Updated js accessibility info module to return the correct promise instead of default false for isGrayScaleEnabled() - Moved the test for isGrayScaleEnabled() out of ios scope to common Android and iOS scope [ANDROID] [ADDED] - logic to check for grayscale mode on android Pull Request resolved: https://github.com/facebook/react-native/pull/47497 Test Plan: Tested on : - Google Pixel 7 Pro (Android 14) - OnePlus 12 (Android 14) - Pixel 6 (Android 15) Reviewed By: cortinico Differential Revision: D65662583 Pulled By: javache fbshipit-source-id: 39f9ce37c9375b5380257847395393045eedbadc --- .../AccessibilityInfo/AccessibilityInfo.js | 9 ++++- .../AccessibilityInfoModule.kt | 34 +++++++++++++++++++ .../specs/modules/NativeAccessibilityInfo.js | 3 ++ .../Accessibility/AccessibilityExample.js | 9 ++--- 4 files changed, 48 insertions(+), 7 deletions(-) diff --git a/packages/react-native/Libraries/Components/AccessibilityInfo/AccessibilityInfo.js b/packages/react-native/Libraries/Components/AccessibilityInfo/AccessibilityInfo.js index 1e7c70d265a628..ccae5960ac2106 100644 --- a/packages/react-native/Libraries/Components/AccessibilityInfo/AccessibilityInfo.js +++ b/packages/react-native/Libraries/Components/AccessibilityInfo/AccessibilityInfo.js @@ -56,6 +56,7 @@ const EventNames: Map< ['screenReaderChanged', 'touchExplorationDidChange'], ['accessibilityServiceChanged', 'accessibilityServiceDidChange'], ['invertColorsChanged', 'invertColorDidChange'], + ['grayscaleChanged', 'grayscaleModeDidChange'], ]) : new Map([ ['announcementFinished', 'announcementFinished'], @@ -114,7 +115,13 @@ const AccessibilityInfo = { */ isGrayscaleEnabled(): Promise { if (Platform.OS === 'android') { - return Promise.resolve(false); + return new Promise((resolve, reject) => { + if (NativeAccessibilityInfoAndroid?.isGrayscaleEnabled != null) { + NativeAccessibilityInfoAndroid.isGrayscaleEnabled(resolve); + } else { + reject(null); + } + }); } else { return new Promise((resolve, reject) => { if (NativeAccessibilityManagerIOS != null) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/accessibilityinfo/AccessibilityInfoModule.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/accessibilityinfo/AccessibilityInfoModule.kt index 4f8ed62c7cdf51..9c835f1e9b43f1 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/accessibilityinfo/AccessibilityInfoModule.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/accessibilityinfo/AccessibilityInfoModule.kt @@ -87,6 +87,7 @@ internal class AccessibilityInfoModule(context: ReactApplicationContext) : private var accessibilityServiceEnabled = false private var recommendedTimeout = 0 private var invertColorsEnabled = false + private var grayscaleModeEnabled = false init { val appContext = context.applicationContext @@ -97,6 +98,7 @@ internal class AccessibilityInfoModule(context: ReactApplicationContext) : accessibilityServiceEnabled = accessibilityManager.isEnabled reduceMotionEnabled = isReduceMotionEnabledValue highTextContrastEnabled = isHighTextContrastEnabledValue + grayscaleModeEnabled = isGrayscaleEnabledValue } @get:TargetApi(Build.VERSION_CODES.LOLLIPOP) @@ -123,6 +125,21 @@ internal class AccessibilityInfoModule(context: ReactApplicationContext) : } } + @get:TargetApi(Build.VERSION_CODES.LOLLIPOP) + private val isGrayscaleEnabledValue: Boolean + get() { + try { + val colorCorrectionSettingKey = "accessibility_display_daltonizer_enabled" + val colorModeSettingKey = "accessibility_display_daltonizer" + // for grayscale mode to be detected, the color correction accessibility setting should be + // on and the color correction mode should be set to grayscale (0) + return Settings.Secure.getInt(contentResolver, colorCorrectionSettingKey) == 1 && + Settings.Secure.getInt(contentResolver, colorModeSettingKey) == 0 + } catch (e: Settings.SettingNotFoundException) { + return false + } + } + @get:TargetApi(Build.VERSION_CODES.LOLLIPOP) private val isHighTextContrastEnabledValue: Boolean get() { @@ -141,6 +158,10 @@ internal class AccessibilityInfoModule(context: ReactApplicationContext) : successCallback.invoke(invertColorsEnabled) } + override fun isGrayscaleEnabled(successCallback: Callback) { + successCallback.invoke(grayscaleModeEnabled) + } + override fun isHighTextContrastEnabled(successCallback: Callback) { successCallback.invoke(highTextContrastEnabled) } @@ -211,6 +232,17 @@ internal class AccessibilityInfoModule(context: ReactApplicationContext) : } } + private fun updateAndSendGrayscaleModeChangeEvent() { + val isGrayscaleModeEnabled = isGrayscaleEnabledValue + if (grayscaleModeEnabled != isGrayscaleModeEnabled) { + grayscaleModeEnabled = isGrayscaleModeEnabled + val reactApplicationContext = getReactApplicationContextIfActiveOrWarn() + if (reactApplicationContext != null) { + reactApplicationContext.emitDeviceEvent(GRAYSCALE_MODE_EVENT_NAME, grayscaleModeEnabled) + } + } + } + @TargetApi(Build.VERSION_CODES.LOLLIPOP) override fun onHostResume() { accessibilityManager?.addTouchExplorationStateChangeListener( @@ -227,6 +259,7 @@ internal class AccessibilityInfoModule(context: ReactApplicationContext) : updateAndSendReduceMotionChangeEvent() updateAndSendHighTextContrastChangeEvent() updateAndSendInvertColorsChangeEvent() + updateAndSendGrayscaleModeChangeEvent() } @TargetApi(Build.VERSION_CODES.LOLLIPOP) @@ -292,5 +325,6 @@ internal class AccessibilityInfoModule(context: ReactApplicationContext) : private const val ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED_CONSTANT = "high_text_contrast_enabled" // constant is marked with @hide private const val INVERT_COLOR_EVENT_NAME = "invertColorDidChange" + private const val GRAYSCALE_MODE_EVENT_NAME = "grayscaleModeDidChange" } } diff --git a/packages/react-native/src/private/specs/modules/NativeAccessibilityInfo.js b/packages/react-native/src/private/specs/modules/NativeAccessibilityInfo.js index 07b4b17622abe4..358134c9ed1bdb 100644 --- a/packages/react-native/src/private/specs/modules/NativeAccessibilityInfo.js +++ b/packages/react-native/src/private/specs/modules/NativeAccessibilityInfo.js @@ -34,6 +34,9 @@ export interface Spec extends TurboModule { mSec: number, onSuccess: (recommendedTimeoutMillis: number) => void, ) => void; + +isGrayscaleEnabled?: ( + onSuccess: (isGrayscaleEnabled: boolean) => void, + ) => void; } export default (TurboModuleRegistry.get('AccessibilityInfo'): ?Spec); diff --git a/packages/rn-tester/js/examples/Accessibility/AccessibilityExample.js b/packages/rn-tester/js/examples/Accessibility/AccessibilityExample.js index 49090ce83658de..576f82ce201672 100644 --- a/packages/rn-tester/js/examples/Accessibility/AccessibilityExample.js +++ b/packages/rn-tester/js/examples/Accessibility/AccessibilityExample.js @@ -1336,12 +1336,6 @@ class EnabledExamples extends React.Component<{}> { eventListener="boldTextChanged" /> - - - { eventListener="screenReaderChanged" /> + + + ); } From 6295b81e79f14a1670e3417e76d569603962ab1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Guzm=C3=A1n?= Date: Mon, 11 Nov 2024 07:38:59 -0800 Subject: [PATCH 165/220] test(image): [android] adding missing image resize mode test cases (#47527) Summary: Follow up from https://github.com/facebook/react-native/issues/47433, adding some missing scenarios in the unit tests for the image component in Android. ## Changelog: [INTERNAL] [ADDED] - Improving Android `ImageResizeMode` unit tests Pull Request resolved: https://github.com/facebook/react-native/pull/47527 Test Plan: ```bash yarn test-android ``` Reviewed By: fabriziocucci Differential Revision: D65735794 Pulled By: Abbondanzo fbshipit-source-id: a420274c78d9eadf0439870cfaae4d16247c6034 --- .../react/views/image/ImageResizeModeTest.kt | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/image/ImageResizeModeTest.kt b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/image/ImageResizeModeTest.kt index c3c589986af95b..a00ea2e5a691b2 100644 --- a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/image/ImageResizeModeTest.kt +++ b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/image/ImageResizeModeTest.kt @@ -7,6 +7,7 @@ package com.facebook.react.views.image +import android.graphics.Shader.TileMode import com.facebook.drawee.drawable.ScalingUtils import org.assertj.core.api.Assertions import org.junit.Test @@ -17,7 +18,7 @@ import org.robolectric.RobolectricTestRunner class ImageResizeModeTest { @Test - fun testImageResizeMode() { + fun testScaleType() { Assertions.assertThat(ImageResizeMode.toScaleType(null)) .isEqualTo(ScalingUtils.ScaleType.CENTER_CROP) Assertions.assertThat(ImageResizeMode.toScaleType("contain")) @@ -28,6 +29,8 @@ class ImageResizeModeTest { .isEqualTo(ScalingUtils.ScaleType.FIT_XY) Assertions.assertThat(ImageResizeMode.toScaleType("center")) .isEqualTo(ScalingUtils.ScaleType.CENTER_INSIDE) + Assertions.assertThat(ImageResizeMode.toScaleType("repeat")) + .isEqualTo(ScaleTypeStartInside.INSTANCE) Assertions.assertThat(ImageResizeMode.toScaleType("none")) .isEqualTo(ScaleTypeStartInside.INSTANCE) @@ -35,4 +38,18 @@ class ImageResizeModeTest { Assertions.assertThat(ImageResizeMode.defaultValue()) .isEqualTo(ScalingUtils.ScaleType.CENTER_CROP) } + + @Test + fun testTileMode() { + Assertions.assertThat(ImageResizeMode.toTileMode(null)).isEqualTo(TileMode.CLAMP) + Assertions.assertThat(ImageResizeMode.toTileMode("contain")).isEqualTo(TileMode.CLAMP) + Assertions.assertThat(ImageResizeMode.toTileMode("cover")).isEqualTo(TileMode.CLAMP) + Assertions.assertThat(ImageResizeMode.toTileMode("stretch")).isEqualTo(TileMode.CLAMP) + Assertions.assertThat(ImageResizeMode.toTileMode("center")).isEqualTo(TileMode.CLAMP) + Assertions.assertThat(ImageResizeMode.toTileMode("none")).isEqualTo(TileMode.CLAMP) + Assertions.assertThat(ImageResizeMode.toTileMode("repeat")).isEqualTo(TileMode.REPEAT) + + // No resizeMode set + Assertions.assertThat(ImageResizeMode.defaultTileMode()).isEqualTo(TileMode.CLAMP) + } } From 5b609cca099b3b0d4fc66d4cf50f69d3c5b7fc8e Mon Sep 17 00:00:00 2001 From: Peter Abbondanzo Date: Mon, 11 Nov 2024 10:12:33 -0800 Subject: [PATCH 166/220] Fix onMomentumScrollBegin not dispatching from animations (#47468) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47468 Across our scroll view implementations on iOS, we fire `onMomentumScrollEnd` whenever the scroll view finishes decelerating, whether it comes from a user's touch or call to `setContentOffset` with animations. But we omit dispatching the `onMomentumScrollBegin` event in the latter cases. This change updates both old and new architecture to dispatch `onMomentumScrollBegin` when a view-command-driven scroll occurs with animation, like `scrollTo` or `scrollToEnd`. Changelog: [iOS][Fixed] - Fixed `onMomentumScrollBegin` event not firing on command-driven scroll events Reviewed By: javache Differential Revision: D65556000 fbshipit-source-id: bc4b778c63d8a032e1d8e00b9d4d5f83a5d651d6 --- .../ScrollView/RCTScrollViewComponentView.mm | 2 ++ .../React/Views/ScrollView/RCTScrollView.m | 6 ++++++ .../js/examples/ScrollView/ScrollViewExample.js | 12 +++++++++++- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm b/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm index 95f38d95fac3d4..48cdc2de8da46a 100644 --- a/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm +++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm @@ -903,6 +903,8 @@ - (void)scrollToOffset:(CGPoint)offset animated:(BOOL)animated // When not animated, the expected workflow in ``scrollViewDidEndScrollingAnimation`` after scrolling is not going // to get triggered. We will need to manually execute here. [self _handleFinishedScrolling:_scrollView]; + } else if (_eventEmitter) { + static_cast(*_eventEmitter).onMomentumScrollBegin([self _scrollViewMetrics]); } } diff --git a/packages/react-native/React/Views/ScrollView/RCTScrollView.m b/packages/react-native/React/Views/ScrollView/RCTScrollView.m index e83b91de6756fa..3fc9a47f3edd9a 100644 --- a/packages/react-native/React/Views/ScrollView/RCTScrollView.m +++ b/packages/react-native/React/Views/ScrollView/RCTScrollView.m @@ -600,6 +600,9 @@ - (void)scrollToOffset:(CGPoint)offset animated:(BOOL)animated offset = CGPointMake(x, y); } [_scrollView setContentOffset:offset animated:animated]; + if (animated) { + [self sendScrollEventWithName:@"onMomentumScrollBegin" scrollView:_scrollView userData:nil]; + } } } @@ -622,6 +625,9 @@ - (void)scrollToEnd:(BOOL)animated // Ensure at least one scroll event will fire _allowNextScrollNoMatterWhat = YES; [_scrollView setContentOffset:offset animated:animated]; + if (animated) { + [self sendScrollEventWithName:@"onMomentumScrollBegin" scrollView:_scrollView userData:nil]; + } } } diff --git a/packages/rn-tester/js/examples/ScrollView/ScrollViewExample.js b/packages/rn-tester/js/examples/ScrollView/ScrollViewExample.js index ae0b34365c5675..074cd7130e3af4 100644 --- a/packages/rn-tester/js/examples/ScrollView/ScrollViewExample.js +++ b/packages/rn-tester/js/examples/ScrollView/ScrollViewExample.js @@ -15,7 +15,7 @@ import RNTesterText from '../../components/RNTesterText'; import ScrollViewPressableStickyHeaderExample from './ScrollViewPressableStickyHeaderExample'; import nullthrows from 'nullthrows'; import * as React from 'react'; -import {useCallback, useState} from 'react'; +import {useCallback, useRef, useState} from 'react'; import { Platform, RefreshControl, @@ -855,11 +855,21 @@ const OnScrollOptions = () => { }; const OnMomentumScroll = () => { + const ref = useRef>(null); const [scroll, setScroll] = useState('none'); return ( Scroll State: {scroll} +