diff --git a/packages/react-native/Libraries/AppDelegate/RCTReactNativeFactory.mm b/packages/react-native/Libraries/AppDelegate/RCTReactNativeFactory.mm index 8de52a870e2..232a354bbef 100644 --- a/packages/react-native/Libraries/AppDelegate/RCTReactNativeFactory.mm +++ b/packages/react-native/Libraries/AppDelegate/RCTReactNativeFactory.mm @@ -314,6 +314,14 @@ class RCTAppDelegateBridgelessFeatureFlags : public ReactNativeFeatureFlagsDefau { return true; } + bool updateRuntimeShadowNodeReferencesOnCommit() override + { + return true; + } + bool useShadowNodeStateOnClone() override + { + return true; + } }; - (void)_setUpFeatureFlags 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 177a5f9dc77..19b3394dbd4 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<<5e27f8a6852293234595697743315ff8>> + * @generated SignedSource<> */ /** @@ -238,6 +238,12 @@ public object ReactNativeFeatureFlags { @JvmStatic public fun traceTurboModulePromiseRejectionsOnAndroid(): Boolean = accessor.traceTurboModulePromiseRejectionsOnAndroid() + /** + * When enabled, runtime shadow node references will be updated during the commit. This allows running RSNRU from any thread without corrupting the renderer state. + */ + @JvmStatic + public fun updateRuntimeShadowNodeReferencesOnCommit(): Boolean = accessor.updateRuntimeShadowNodeReferencesOnCommit() + /** * In Bridgeless mode, use the always available javascript error reporting pipeline. */ @@ -274,6 +280,12 @@ public object ReactNativeFeatureFlags { @JvmStatic public fun useRawPropsJsiValue(): Boolean = accessor.useRawPropsJsiValue() + /** + * Use the state stored on the source shadow node when cloning it instead of reading in the most recent state on the shadow node family. + */ + @JvmStatic + public fun useShadowNodeStateOnClone(): Boolean = accessor.useShadowNodeStateOnClone() + /** * In Bridgeless mode, should legacy NativeModules use the TurboModule system? */ 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 a31d4ac1138..3e2792c8d08 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<> + * @generated SignedSource<<0496ecf3d1e5d8a2e6d4d594aca806d0>> */ /** @@ -55,12 +55,14 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces private var removeTurboModuleManagerDelegateMutexCache: Boolean? = null private var throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOSCache: Boolean? = null private var traceTurboModulePromiseRejectionsOnAndroidCache: Boolean? = null + private var updateRuntimeShadowNodeReferencesOnCommitCache: Boolean? = null private var useAlwaysAvailableJSErrorHandlingCache: Boolean? = null private var useEditTextStockAndroidFocusBehaviorCache: Boolean? = null private var useFabricInteropCache: Boolean? = null private var useNativeViewConfigsInBridgelessModeCache: Boolean? = null private var useOptimizedEventBatchingOnAndroidCache: Boolean? = null private var useRawPropsJsiValueCache: Boolean? = null + private var useShadowNodeStateOnCloneCache: Boolean? = null private var useTurboModuleInteropCache: Boolean? = null private var useTurboModulesCache: Boolean? = null @@ -379,6 +381,15 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces return cached } + override fun updateRuntimeShadowNodeReferencesOnCommit(): Boolean { + var cached = updateRuntimeShadowNodeReferencesOnCommitCache + if (cached == null) { + cached = ReactNativeFeatureFlagsCxxInterop.updateRuntimeShadowNodeReferencesOnCommit() + updateRuntimeShadowNodeReferencesOnCommitCache = cached + } + return cached + } + override fun useAlwaysAvailableJSErrorHandling(): Boolean { var cached = useAlwaysAvailableJSErrorHandlingCache if (cached == null) { @@ -433,6 +444,15 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces return cached } + override fun useShadowNodeStateOnClone(): Boolean { + var cached = useShadowNodeStateOnCloneCache + if (cached == null) { + cached = ReactNativeFeatureFlagsCxxInterop.useShadowNodeStateOnClone() + useShadowNodeStateOnCloneCache = cached + } + return cached + } + override fun useTurboModuleInterop(): Boolean { var cached = useTurboModuleInteropCache 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 c34ada1a498..c1a6f42f24f 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<<08b51adfc7c09f0f26f2b3c8351cda01>> + * @generated SignedSource<> */ /** @@ -98,6 +98,8 @@ public object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic public external fun traceTurboModulePromiseRejectionsOnAndroid(): Boolean + @DoNotStrip @JvmStatic public external fun updateRuntimeShadowNodeReferencesOnCommit(): Boolean + @DoNotStrip @JvmStatic public external fun useAlwaysAvailableJSErrorHandling(): Boolean @DoNotStrip @JvmStatic public external fun useEditTextStockAndroidFocusBehavior(): Boolean @@ -110,6 +112,8 @@ public object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic public external fun useRawPropsJsiValue(): Boolean + @DoNotStrip @JvmStatic public external fun useShadowNodeStateOnClone(): Boolean + @DoNotStrip @JvmStatic public external fun useTurboModuleInterop(): Boolean @DoNotStrip @JvmStatic public external fun useTurboModules(): 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 6ebcda8985d..8f33f72f796 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<<0041e37961e68474a6d092dc0f8a4903>> + * @generated SignedSource<> */ /** @@ -93,6 +93,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun traceTurboModulePromiseRejectionsOnAndroid(): Boolean = false + override fun updateRuntimeShadowNodeReferencesOnCommit(): Boolean = false + override fun useAlwaysAvailableJSErrorHandling(): Boolean = false override fun useEditTextStockAndroidFocusBehavior(): Boolean = true @@ -105,6 +107,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun useRawPropsJsiValue(): Boolean = false + override fun useShadowNodeStateOnClone(): Boolean = false + override fun useTurboModuleInterop(): Boolean = false override fun useTurboModules(): 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 b8e40dd8a05..399a1788f74 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<> + * @generated SignedSource<<8f5180a0ef154c083ac38d28e650ee11>> */ /** @@ -59,12 +59,14 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc private var removeTurboModuleManagerDelegateMutexCache: Boolean? = null private var throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOSCache: Boolean? = null private var traceTurboModulePromiseRejectionsOnAndroidCache: Boolean? = null + private var updateRuntimeShadowNodeReferencesOnCommitCache: Boolean? = null private var useAlwaysAvailableJSErrorHandlingCache: Boolean? = null private var useEditTextStockAndroidFocusBehaviorCache: Boolean? = null private var useFabricInteropCache: Boolean? = null private var useNativeViewConfigsInBridgelessModeCache: Boolean? = null private var useOptimizedEventBatchingOnAndroidCache: Boolean? = null private var useRawPropsJsiValueCache: Boolean? = null + private var useShadowNodeStateOnCloneCache: Boolean? = null private var useTurboModuleInteropCache: Boolean? = null private var useTurboModulesCache: Boolean? = null @@ -418,6 +420,16 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc return cached } + override fun updateRuntimeShadowNodeReferencesOnCommit(): Boolean { + var cached = updateRuntimeShadowNodeReferencesOnCommitCache + if (cached == null) { + cached = currentProvider.updateRuntimeShadowNodeReferencesOnCommit() + accessedFeatureFlags.add("updateRuntimeShadowNodeReferencesOnCommit") + updateRuntimeShadowNodeReferencesOnCommitCache = cached + } + return cached + } + override fun useAlwaysAvailableJSErrorHandling(): Boolean { var cached = useAlwaysAvailableJSErrorHandlingCache if (cached == null) { @@ -478,6 +490,16 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc return cached } + override fun useShadowNodeStateOnClone(): Boolean { + var cached = useShadowNodeStateOnCloneCache + if (cached == null) { + cached = currentProvider.useShadowNodeStateOnClone() + accessedFeatureFlags.add("useShadowNodeStateOnClone") + useShadowNodeStateOnCloneCache = cached + } + return cached + } + override fun useTurboModuleInterop(): Boolean { var cached = useTurboModuleInteropCache if (cached == null) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsOverrides_RNOSS_Stable_Android.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsOverrides_RNOSS_Stable_Android.kt index 4e28893fd22..50282190296 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsOverrides_RNOSS_Stable_Android.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsOverrides_RNOSS_Stable_Android.kt @@ -17,4 +17,8 @@ public class ReactNativeFeatureFlagsOverrides_RNOSS_Stable_Android( override fun enableFabricRenderer(): Boolean = bridgelessEnabled || fabricEnabled override fun useTurboModules(): Boolean = bridgelessEnabled || turboModulesEnabled + + override fun updateRuntimeShadowNodeReferencesOnCommit(): Boolean = true + + override fun useShadowNodeStateOnClone(): Boolean = true } 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 bb5525fab60..79b76152ea5 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<<9a223b4f79e4612eb193036256bfebc5>> + * @generated SignedSource<<33571f99b1f78fbc62cecfca5f8351fa>> */ /** @@ -93,6 +93,8 @@ public interface ReactNativeFeatureFlagsProvider { @DoNotStrip public fun traceTurboModulePromiseRejectionsOnAndroid(): Boolean + @DoNotStrip public fun updateRuntimeShadowNodeReferencesOnCommit(): Boolean + @DoNotStrip public fun useAlwaysAvailableJSErrorHandling(): Boolean @DoNotStrip public fun useEditTextStockAndroidFocusBehavior(): Boolean @@ -105,6 +107,8 @@ public interface ReactNativeFeatureFlagsProvider { @DoNotStrip public fun useRawPropsJsiValue(): Boolean + @DoNotStrip public fun useShadowNodeStateOnClone(): Boolean + @DoNotStrip public fun useTurboModuleInterop(): Boolean @DoNotStrip public fun useTurboModules(): 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 1d441b6687d..6c6bff13419 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<<91c1a65790aa5946a354ab8a1966a5f4>> + * @generated SignedSource<<83b23039ed9fff5109ff3b532648baac>> */ /** @@ -249,6 +249,12 @@ class ReactNativeFeatureFlagsProviderHolder return method(javaProvider_); } + bool updateRuntimeShadowNodeReferencesOnCommit() override { + static const auto method = + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("updateRuntimeShadowNodeReferencesOnCommit"); + return method(javaProvider_); + } + bool useAlwaysAvailableJSErrorHandling() override { static const auto method = getReactNativeFeatureFlagsProviderJavaClass()->getMethod("useAlwaysAvailableJSErrorHandling"); @@ -285,6 +291,12 @@ class ReactNativeFeatureFlagsProviderHolder return method(javaProvider_); } + bool useShadowNodeStateOnClone() override { + static const auto method = + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("useShadowNodeStateOnClone"); + return method(javaProvider_); + } + bool useTurboModuleInterop() override { static const auto method = getReactNativeFeatureFlagsProviderJavaClass()->getMethod("useTurboModuleInterop"); @@ -476,6 +488,11 @@ bool JReactNativeFeatureFlagsCxxInterop::traceTurboModulePromiseRejectionsOnAndr return ReactNativeFeatureFlags::traceTurboModulePromiseRejectionsOnAndroid(); } +bool JReactNativeFeatureFlagsCxxInterop::updateRuntimeShadowNodeReferencesOnCommit( + facebook::jni::alias_ref /*unused*/) { + return ReactNativeFeatureFlags::updateRuntimeShadowNodeReferencesOnCommit(); +} + bool JReactNativeFeatureFlagsCxxInterop::useAlwaysAvailableJSErrorHandling( facebook::jni::alias_ref /*unused*/) { return ReactNativeFeatureFlags::useAlwaysAvailableJSErrorHandling(); @@ -506,6 +523,11 @@ bool JReactNativeFeatureFlagsCxxInterop::useRawPropsJsiValue( return ReactNativeFeatureFlags::useRawPropsJsiValue(); } +bool JReactNativeFeatureFlagsCxxInterop::useShadowNodeStateOnClone( + facebook::jni::alias_ref /*unused*/) { + return ReactNativeFeatureFlags::useShadowNodeStateOnClone(); +} + bool JReactNativeFeatureFlagsCxxInterop::useTurboModuleInterop( facebook::jni::alias_ref /*unused*/) { return ReactNativeFeatureFlags::useTurboModuleInterop(); @@ -652,6 +674,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "traceTurboModulePromiseRejectionsOnAndroid", JReactNativeFeatureFlagsCxxInterop::traceTurboModulePromiseRejectionsOnAndroid), + makeNativeMethod( + "updateRuntimeShadowNodeReferencesOnCommit", + JReactNativeFeatureFlagsCxxInterop::updateRuntimeShadowNodeReferencesOnCommit), makeNativeMethod( "useAlwaysAvailableJSErrorHandling", JReactNativeFeatureFlagsCxxInterop::useAlwaysAvailableJSErrorHandling), @@ -670,6 +695,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "useRawPropsJsiValue", JReactNativeFeatureFlagsCxxInterop::useRawPropsJsiValue), + makeNativeMethod( + "useShadowNodeStateOnClone", + JReactNativeFeatureFlagsCxxInterop::useShadowNodeStateOnClone), makeNativeMethod( "useTurboModuleInterop", JReactNativeFeatureFlagsCxxInterop::useTurboModuleInterop), 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 21e9f35f648..925a31a7166 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<<610104213a5eba23b797e27377d71b52>> + * @generated SignedSource<> */ /** @@ -135,6 +135,9 @@ class JReactNativeFeatureFlagsCxxInterop static bool traceTurboModulePromiseRejectionsOnAndroid( facebook::jni::alias_ref); + static bool updateRuntimeShadowNodeReferencesOnCommit( + facebook::jni::alias_ref); + static bool useAlwaysAvailableJSErrorHandling( facebook::jni::alias_ref); @@ -153,6 +156,9 @@ class JReactNativeFeatureFlagsCxxInterop static bool useRawPropsJsiValue( facebook::jni::alias_ref); + static bool useShadowNodeStateOnClone( + facebook::jni::alias_ref); + static bool useTurboModuleInterop( 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 ab4a6045f1a..f0efac973d0 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<<3d4eefc7af1e9d594ade8339c261ca01>> + * @generated SignedSource<<661a4193f9ba7af0c963bc13751deb15>> */ /** @@ -166,6 +166,10 @@ bool ReactNativeFeatureFlags::traceTurboModulePromiseRejectionsOnAndroid() { return getAccessor().traceTurboModulePromiseRejectionsOnAndroid(); } +bool ReactNativeFeatureFlags::updateRuntimeShadowNodeReferencesOnCommit() { + return getAccessor().updateRuntimeShadowNodeReferencesOnCommit(); +} + bool ReactNativeFeatureFlags::useAlwaysAvailableJSErrorHandling() { return getAccessor().useAlwaysAvailableJSErrorHandling(); } @@ -190,6 +194,10 @@ bool ReactNativeFeatureFlags::useRawPropsJsiValue() { return getAccessor().useRawPropsJsiValue(); } +bool ReactNativeFeatureFlags::useShadowNodeStateOnClone() { + return getAccessor().useShadowNodeStateOnClone(); +} + bool ReactNativeFeatureFlags::useTurboModuleInterop() { return getAccessor().useTurboModuleInterop(); } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h index b2712e08288..35afb5835d8 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<<55a526204b386d34058c86183d5b97ac>> + * @generated SignedSource<<53e965423f2957b37e0470c607cc45a4>> */ /** @@ -214,6 +214,11 @@ class ReactNativeFeatureFlags { */ RN_EXPORT static bool traceTurboModulePromiseRejectionsOnAndroid(); + /** + * When enabled, runtime shadow node references will be updated during the commit. This allows running RSNRU from any thread without corrupting the renderer state. + */ + RN_EXPORT static bool updateRuntimeShadowNodeReferencesOnCommit(); + /** * In Bridgeless mode, use the always available javascript error reporting pipeline. */ @@ -244,6 +249,11 @@ class ReactNativeFeatureFlags { */ RN_EXPORT static bool useRawPropsJsiValue(); + /** + * Use the state stored on the source shadow node when cloning it instead of reading in the most recent state on the shadow node family. + */ + RN_EXPORT static bool useShadowNodeStateOnClone(); + /** * In Bridgeless mode, should legacy NativeModules use the TurboModule system? */ diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp index db14f08282c..6c494257b4d 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<> + * @generated SignedSource<<5ff3ac57eb17d9b6642d98f2fc35bd9d>> */ /** @@ -659,6 +659,24 @@ bool ReactNativeFeatureFlagsAccessor::traceTurboModulePromiseRejectionsOnAndroid return flagValue.value(); } +bool ReactNativeFeatureFlagsAccessor::updateRuntimeShadowNodeReferencesOnCommit() { + auto flagValue = updateRuntimeShadowNodeReferencesOnCommit_.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(35, "updateRuntimeShadowNodeReferencesOnCommit"); + + flagValue = currentProvider_->updateRuntimeShadowNodeReferencesOnCommit(); + updateRuntimeShadowNodeReferencesOnCommit_ = flagValue; + } + + return flagValue.value(); +} + bool ReactNativeFeatureFlagsAccessor::useAlwaysAvailableJSErrorHandling() { auto flagValue = useAlwaysAvailableJSErrorHandling_.load(); @@ -668,7 +686,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(35, "useAlwaysAvailableJSErrorHandling"); + markFlagAsAccessed(36, "useAlwaysAvailableJSErrorHandling"); flagValue = currentProvider_->useAlwaysAvailableJSErrorHandling(); useAlwaysAvailableJSErrorHandling_ = flagValue; @@ -686,7 +704,7 @@ bool ReactNativeFeatureFlagsAccessor::useEditTextStockAndroidFocusBehavior() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(36, "useEditTextStockAndroidFocusBehavior"); + markFlagAsAccessed(37, "useEditTextStockAndroidFocusBehavior"); flagValue = currentProvider_->useEditTextStockAndroidFocusBehavior(); useEditTextStockAndroidFocusBehavior_ = flagValue; @@ -704,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(37, "useFabricInterop"); + markFlagAsAccessed(38, "useFabricInterop"); flagValue = currentProvider_->useFabricInterop(); useFabricInterop_ = flagValue; @@ -722,7 +740,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(38, "useNativeViewConfigsInBridgelessMode"); + markFlagAsAccessed(39, "useNativeViewConfigsInBridgelessMode"); flagValue = currentProvider_->useNativeViewConfigsInBridgelessMode(); useNativeViewConfigsInBridgelessMode_ = flagValue; @@ -740,7 +758,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(39, "useOptimizedEventBatchingOnAndroid"); + markFlagAsAccessed(40, "useOptimizedEventBatchingOnAndroid"); flagValue = currentProvider_->useOptimizedEventBatchingOnAndroid(); useOptimizedEventBatchingOnAndroid_ = flagValue; @@ -758,7 +776,7 @@ bool ReactNativeFeatureFlagsAccessor::useRawPropsJsiValue() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(40, "useRawPropsJsiValue"); + markFlagAsAccessed(41, "useRawPropsJsiValue"); flagValue = currentProvider_->useRawPropsJsiValue(); useRawPropsJsiValue_ = flagValue; @@ -767,6 +785,24 @@ bool ReactNativeFeatureFlagsAccessor::useRawPropsJsiValue() { return flagValue.value(); } +bool ReactNativeFeatureFlagsAccessor::useShadowNodeStateOnClone() { + auto flagValue = useShadowNodeStateOnClone_.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(42, "useShadowNodeStateOnClone"); + + flagValue = currentProvider_->useShadowNodeStateOnClone(); + useShadowNodeStateOnClone_ = flagValue; + } + + return flagValue.value(); +} + bool ReactNativeFeatureFlagsAccessor::useTurboModuleInterop() { auto flagValue = useTurboModuleInterop_.load(); @@ -776,7 +812,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(41, "useTurboModuleInterop"); + markFlagAsAccessed(43, "useTurboModuleInterop"); flagValue = currentProvider_->useTurboModuleInterop(); useTurboModuleInterop_ = flagValue; @@ -794,7 +830,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(42, "useTurboModules"); + markFlagAsAccessed(44, "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 9459bfe7de7..48e75d266b0 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<<95aa4a8b8859f26b901112df1517b1f1>> + * @generated SignedSource<<267385c8df88a5d1eb7f1e2478209d39>> */ /** @@ -67,12 +67,14 @@ class ReactNativeFeatureFlagsAccessor { bool removeTurboModuleManagerDelegateMutex(); bool throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS(); bool traceTurboModulePromiseRejectionsOnAndroid(); + bool updateRuntimeShadowNodeReferencesOnCommit(); bool useAlwaysAvailableJSErrorHandling(); bool useEditTextStockAndroidFocusBehavior(); bool useFabricInterop(); bool useNativeViewConfigsInBridgelessMode(); bool useOptimizedEventBatchingOnAndroid(); bool useRawPropsJsiValue(); + bool useShadowNodeStateOnClone(); bool useTurboModuleInterop(); bool useTurboModules(); @@ -86,7 +88,7 @@ class ReactNativeFeatureFlagsAccessor { std::unique_ptr currentProvider_; bool wasOverridden_; - std::array, 43> accessedFeatureFlags_; + std::array, 45> accessedFeatureFlags_; std::atomic> commonTestFlag_; std::atomic> disableMountItemReorderingAndroid_; @@ -123,12 +125,14 @@ class ReactNativeFeatureFlagsAccessor { std::atomic> removeTurboModuleManagerDelegateMutex_; std::atomic> throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS_; std::atomic> traceTurboModulePromiseRejectionsOnAndroid_; + std::atomic> updateRuntimeShadowNodeReferencesOnCommit_; std::atomic> useAlwaysAvailableJSErrorHandling_; std::atomic> useEditTextStockAndroidFocusBehavior_; std::atomic> useFabricInterop_; std::atomic> useNativeViewConfigsInBridgelessMode_; std::atomic> useOptimizedEventBatchingOnAndroid_; std::atomic> useRawPropsJsiValue_; + std::atomic> useShadowNodeStateOnClone_; std::atomic> useTurboModuleInterop_; std::atomic> useTurboModules_; }; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h index 329de9bbe3b..e81708e657d 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<> + * @generated SignedSource<<48bb4ea50c42676aee161ea1594a6aec>> */ /** @@ -167,6 +167,10 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { return false; } + bool updateRuntimeShadowNodeReferencesOnCommit() override { + return false; + } + bool useAlwaysAvailableJSErrorHandling() override { return false; } @@ -191,6 +195,10 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { return false; } + bool useShadowNodeStateOnClone() override { + return false; + } + bool useTurboModuleInterop() override { return false; } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h index 38a04a32dc9..cfd48f0bf4f 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.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<<21aeeeaa1a402f91b616180114887a58>> + * @generated SignedSource<> */ /** @@ -360,6 +360,15 @@ class ReactNativeFeatureFlagsDynamicProvider : public ReactNativeFeatureFlagsDef return ReactNativeFeatureFlagsDefaults::traceTurboModulePromiseRejectionsOnAndroid(); } + bool updateRuntimeShadowNodeReferencesOnCommit() override { + auto value = values_["updateRuntimeShadowNodeReferencesOnCommit"]; + if (!value.isNull()) { + return value.getBool(); + } + + return ReactNativeFeatureFlagsDefaults::updateRuntimeShadowNodeReferencesOnCommit(); + } + bool useAlwaysAvailableJSErrorHandling() override { auto value = values_["useAlwaysAvailableJSErrorHandling"]; if (!value.isNull()) { @@ -414,6 +423,15 @@ class ReactNativeFeatureFlagsDynamicProvider : public ReactNativeFeatureFlagsDef return ReactNativeFeatureFlagsDefaults::useRawPropsJsiValue(); } + bool useShadowNodeStateOnClone() override { + auto value = values_["useShadowNodeStateOnClone"]; + if (!value.isNull()) { + return value.getBool(); + } + + return ReactNativeFeatureFlagsDefaults::useShadowNodeStateOnClone(); + } + bool useTurboModuleInterop() override { auto value = values_["useTurboModuleInterop"]; if (!value.isNull()) { diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h index b0f52f4644e..8efd2e70070 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<> + * @generated SignedSource<> */ /** @@ -60,12 +60,14 @@ class ReactNativeFeatureFlagsProvider { virtual bool removeTurboModuleManagerDelegateMutex() = 0; virtual bool throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS() = 0; virtual bool traceTurboModulePromiseRejectionsOnAndroid() = 0; + virtual bool updateRuntimeShadowNodeReferencesOnCommit() = 0; virtual bool useAlwaysAvailableJSErrorHandling() = 0; virtual bool useEditTextStockAndroidFocusBehavior() = 0; virtual bool useFabricInterop() = 0; virtual bool useNativeViewConfigsInBridgelessMode() = 0; virtual bool useOptimizedEventBatchingOnAndroid() = 0; virtual bool useRawPropsJsiValue() = 0; + virtual bool useShadowNodeStateOnClone() = 0; virtual bool useTurboModuleInterop() = 0; virtual bool useTurboModules() = 0; }; diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp index 0ea524de1b7..cf4b98fd8c0 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<<651dc228bd4959a90c82de905a8b6c40>> + * @generated SignedSource<<76f1f689940817c1df6ace2f8dd062e7>> */ /** @@ -219,6 +219,11 @@ bool NativeReactNativeFeatureFlags::traceTurboModulePromiseRejectionsOnAndroid( return ReactNativeFeatureFlags::traceTurboModulePromiseRejectionsOnAndroid(); } +bool NativeReactNativeFeatureFlags::updateRuntimeShadowNodeReferencesOnCommit( + jsi::Runtime& /*runtime*/) { + return ReactNativeFeatureFlags::updateRuntimeShadowNodeReferencesOnCommit(); +} + bool NativeReactNativeFeatureFlags::useAlwaysAvailableJSErrorHandling( jsi::Runtime& /*runtime*/) { return ReactNativeFeatureFlags::useAlwaysAvailableJSErrorHandling(); @@ -249,6 +254,11 @@ bool NativeReactNativeFeatureFlags::useRawPropsJsiValue( return ReactNativeFeatureFlags::useRawPropsJsiValue(); } +bool NativeReactNativeFeatureFlags::useShadowNodeStateOnClone( + jsi::Runtime& /*runtime*/) { + return ReactNativeFeatureFlags::useShadowNodeStateOnClone(); +} + bool NativeReactNativeFeatureFlags::useTurboModuleInterop( jsi::Runtime& /*runtime*/) { return ReactNativeFeatureFlags::useTurboModuleInterop(); diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h index f21c5bd3d9c..2c6765db1f1 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<<1a082675338773d1a6259fabfd2f652f>> + * @generated SignedSource<> */ /** @@ -107,6 +107,8 @@ class NativeReactNativeFeatureFlags bool traceTurboModulePromiseRejectionsOnAndroid(jsi::Runtime& runtime); + bool updateRuntimeShadowNodeReferencesOnCommit(jsi::Runtime& runtime); + bool useAlwaysAvailableJSErrorHandling(jsi::Runtime& runtime); bool useEditTextStockAndroidFocusBehavior(jsi::Runtime& runtime); @@ -119,6 +121,8 @@ class NativeReactNativeFeatureFlags bool useRawPropsJsiValue(jsi::Runtime& runtime); + bool useShadowNodeStateOnClone(jsi::Runtime& runtime); + bool useTurboModuleInterop(jsi::Runtime& runtime); bool useTurboModules(jsi::Runtime& runtime); diff --git a/packages/react-native/ReactCommon/react/renderer/core/ShadowNode.cpp b/packages/react-native/ReactCommon/react/renderer/core/ShadowNode.cpp index dc54f04c5c3..d762d8b00d4 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/ShadowNode.cpp +++ b/packages/react-native/ReactCommon/react/renderer/core/ShadowNode.cpp @@ -112,7 +112,9 @@ ShadowNode::ShadowNode( fragment.children ? fragment.children : sourceShadowNode.children_), state_( fragment.state ? fragment.state - : sourceShadowNode.getMostRecentState()), + : (ReactNativeFeatureFlags::useShadowNodeStateOnClone() + ? sourceShadowNode.state_ + : sourceShadowNode.getMostRecentState())), orderIndex_(sourceShadowNode.orderIndex_), family_(sourceShadowNode.family_), traits_(sourceShadowNode.traits_) { @@ -308,20 +310,28 @@ void ShadowNode::setRuntimeShadowNodeReference( runtimeShadowNodeReference_ = runtimeShadowNodeReference; } -void ShadowNode::transferRuntimeShadowNodeReference( +void ShadowNode::updateRuntimeShadowNodeReference( const Shared& destinationShadowNode) const { - destinationShadowNode->runtimeShadowNodeReference_ = - runtimeShadowNodeReference_; - if (auto reference = runtimeShadowNodeReference_.lock()) { reference->shadowNode = destinationShadowNode; } } +void ShadowNode::transferRuntimeShadowNodeReference( + const Shared& destinationShadowNode) const { + destinationShadowNode->runtimeShadowNodeReference_ = + runtimeShadowNodeReference_; + + if (!ReactNativeFeatureFlags::updateRuntimeShadowNodeReferencesOnCommit()) { + updateRuntimeShadowNodeReference(destinationShadowNode); + } +} + void ShadowNode::transferRuntimeShadowNodeReference( const Shared& destinationShadowNode, const ShadowNodeFragment& fragment) const { - if (useRuntimeShadowNodeReferenceUpdateOnThread && + if ((ReactNativeFeatureFlags::updateRuntimeShadowNodeReferencesOnCommit() || + useRuntimeShadowNodeReferenceUpdateOnThread) && fragment.runtimeShadowNodeReference) { transferRuntimeShadowNodeReference(destinationShadowNode); } diff --git a/packages/react-native/ReactCommon/react/renderer/core/ShadowNode.h b/packages/react-native/ReactCommon/react/renderer/core/ShadowNode.h index 7a3ad9cbc1b..ae648988875 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/ShadowNode.h +++ b/packages/react-native/ReactCommon/react/renderer/core/ShadowNode.h @@ -187,6 +187,12 @@ class ShadowNode : public Sealable, void setRuntimeShadowNodeReference(const std::shared_ptr& runtimeShadowNodeReference) const; + /* + * Update the runtime reference to point to the provided shadow node. + */ + void updateRuntimeShadowNodeReference( + const Shared& destinationShadowNode) const; + /* * Transfer the runtime reference to this `ShadowNode` to a new instance, * updating the reference to point to the new `ShadowNode` referencing it. diff --git a/packages/react-native/ReactCommon/react/renderer/mounting/updateMountedFlag.cpp b/packages/react-native/ReactCommon/react/renderer/mounting/updateMountedFlag.cpp index 4b501294144..77d038bb1cd 100644 --- a/packages/react-native/ReactCommon/react/renderer/mounting/updateMountedFlag.cpp +++ b/packages/react-native/ReactCommon/react/renderer/mounting/updateMountedFlag.cpp @@ -7,6 +7,8 @@ #include "updateMountedFlag.h" +#include + namespace facebook::react { void updateMountedFlag( const ShadowNode::ListOfShared& oldChildren, @@ -47,6 +49,10 @@ void updateMountedFlag( newChild->setMounted(true); oldChild->setMounted(false); + if (ReactNativeFeatureFlags::updateRuntimeShadowNodeReferencesOnCommit()) { + newChild->updateRuntimeShadowNodeReference(newChild); + } + updateMountedFlag(oldChild->getChildren(), newChild->getChildren()); } diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index 611e2e0b599..2403266d4a8 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -419,6 +419,17 @@ const definitions: FeatureFlagDefinitions = { }, ossReleaseStage: 'none', }, + updateRuntimeShadowNodeReferencesOnCommit: { + defaultValue: false, + metadata: { + dateAdded: '2025-04-15', + description: + 'When enabled, runtime shadow node references will be updated during the commit. This allows running RSNRU from any thread without corrupting the renderer state.', + expectedReleaseValue: true, + purpose: 'experimentation', + }, + ossReleaseStage: 'none', + }, useAlwaysAvailableJSErrorHandling: { defaultValue: false, metadata: { @@ -482,6 +493,17 @@ const definitions: FeatureFlagDefinitions = { }, ossReleaseStage: 'none', }, + useShadowNodeStateOnClone: { + defaultValue: false, + metadata: { + dateAdded: '2025-04-16', + description: + 'Use the state stored on the source shadow node when cloning it instead of reading in the most recent state on the shadow node family.', + expectedReleaseValue: true, + purpose: 'experimentation', + }, + ossReleaseStage: 'none', + }, useTurboModuleInterop: { defaultValue: false, metadata: { diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index 4625001cf6e..3b4b290483a 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<<3e68d888bf4d8ac71b63571a639d265b>> + * @generated SignedSource<<5b1d3ba6712de7a927eeeb8602ee2a8f>> * @flow strict */ @@ -84,12 +84,14 @@ export type ReactNativeFeatureFlags = $ReadOnly<{ removeTurboModuleManagerDelegateMutex: Getter, throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS: Getter, traceTurboModulePromiseRejectionsOnAndroid: Getter, + updateRuntimeShadowNodeReferencesOnCommit: Getter, useAlwaysAvailableJSErrorHandling: Getter, useEditTextStockAndroidFocusBehavior: Getter, useFabricInterop: Getter, useNativeViewConfigsInBridgelessMode: Getter, useOptimizedEventBatchingOnAndroid: Getter, useRawPropsJsiValue: Getter, + useShadowNodeStateOnClone: Getter, useTurboModuleInterop: Getter, useTurboModules: Getter, }>; @@ -313,6 +315,10 @@ export const throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIO * Enables storing js caller stack when creating promise in native module. This is useful in case of Promise rejection and tracing the cause. */ export const traceTurboModulePromiseRejectionsOnAndroid: Getter = createNativeFlagGetter('traceTurboModulePromiseRejectionsOnAndroid', false); +/** + * When enabled, runtime shadow node references will be updated during the commit. This allows running RSNRU from any thread without corrupting the renderer state. + */ +export const updateRuntimeShadowNodeReferencesOnCommit: Getter = createNativeFlagGetter('updateRuntimeShadowNodeReferencesOnCommit', false); /** * In Bridgeless mode, use the always available javascript error reporting pipeline. */ @@ -337,6 +343,10 @@ export const useOptimizedEventBatchingOnAndroid: Getter = createNativeF * Instead of using folly::dynamic as internal representation in RawProps and RawValue, use jsi::Value */ export const useRawPropsJsiValue: Getter = createNativeFlagGetter('useRawPropsJsiValue', false); +/** + * Use the state stored on the source shadow node when cloning it instead of reading in the most recent state on the shadow node family. + */ +export const useShadowNodeStateOnClone: Getter = createNativeFlagGetter('useShadowNodeStateOnClone', false); /** * In Bridgeless mode, should legacy NativeModules use the TurboModule system? */ diff --git a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js index 2fc24f69b71..f61e2c7d42d 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<<0d611c17d522627c59a68d083eb6b6dc>> + * @generated SignedSource<> * @flow strict */ @@ -59,12 +59,14 @@ export interface Spec extends TurboModule { +removeTurboModuleManagerDelegateMutex?: () => boolean; +throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS?: () => boolean; +traceTurboModulePromiseRejectionsOnAndroid?: () => boolean; + +updateRuntimeShadowNodeReferencesOnCommit?: () => boolean; +useAlwaysAvailableJSErrorHandling?: () => boolean; +useEditTextStockAndroidFocusBehavior?: () => boolean; +useFabricInterop?: () => boolean; +useNativeViewConfigsInBridgelessMode?: () => boolean; +useOptimizedEventBatchingOnAndroid?: () => boolean; +useRawPropsJsiValue?: () => boolean; + +useShadowNodeStateOnClone?: () => boolean; +useTurboModuleInterop?: () => boolean; +useTurboModules?: () => boolean; }