From 03d2186ace2cb17c676b7763d5a545759a658b77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hanno=20J=2E=20G=C3=B6decke?= Date: Wed, 11 Dec 2024 08:38:12 -0800 Subject: [PATCH] Construct `RawValue` directly from `jsi::Value` (#48047) Summary: ### Motivation: We are looking for a way to access the "raw" jsi value in our fabric view components, so that we can pass complex types like `HostObjects` or `jsi::Object` with `NativeState` attached to our components directly. Currently the props are converted from `jsi::Object` to `folly::dynamic`, which prevents us from accessing these values directly. ### Changes This PR is a implementation of the proposal discussed here: - https://github.com/facebook/react-native/pull/44966#issuecomment-2503915245 These changes extend `RawValue` so that it can be directly constructed from `RawValue(Runtime*, jsi::Value&)` (not just from `folly::dynamic`). `RawValue`s are created by the `RawPropParser.cpp`. By default it will use the `RawValue(folly::dynamic)` constructor, but we added a feature flag called `useRawPropsJsiValue`, which will sue the JSI constructor. This enables to test this feature at runtime incrementally. This change might also be tested on a component basis, by setting a flag in the component descriptor to enable JSI prop parsing for the RawPropParser, as outlined in this PR: - https://github.com/hannojg/react-native/pull/2 ## Changelog: [General] [Added] - Add `useRawPropsJsiValue` feature flag to represent props internally as `jsi::Value`s instead of converting them to `folly::dynamic` [General] [Added] - Added `RawValue(Runtime*, jsi::Value&)` constructor to make a `RawValue` from a `jsi::Value`. Pull Request resolved: https://github.com/facebook/react-native/pull/48047 Test Plan: Enable the `useRawPropsJsiValue` feature flag and test the rn-tester app on android and iOS. Make sure you get no new errors / warnings in the native console. Reviewed By: NickGerleman Differential Revision: D66877093 Pulled By: javache fbshipit-source-id: 7342e5f86d2492ad63a9ccf5508f04e7eb252def --- .../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 | 26 +- .../ReactNativeFeatureFlagsAccessor.h | 6 +- .../ReactNativeFeatureFlagsDefaults.h | 6 +- .../ReactNativeFeatureFlagsDynamicProvider.h | 11 +- .../ReactNativeFeatureFlagsProvider.h | 3 +- .../NativeReactNativeFeatureFlags.cpp | 7 +- .../NativeReactNativeFeatureFlags.h | 4 +- .../react/renderer/core/RawPropsParser.cpp | 10 +- .../react/renderer/core/RawValue.h | 337 ++++++++++++++++-- .../renderer/graphics/React-graphics.podspec | 6 + .../ReactNativeFeatureFlags.config.js | 9 + .../featureflags/ReactNativeFeatureFlags.js | 7 +- .../specs/NativeReactNativeFeatureFlags.js | 3 +- packages/rn-tester/Podfile.lock | 1 + 24 files changed, 468 insertions(+), 47 deletions(-) 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 81ed253e303..d0ee2ef4338 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<<124d445f029ae3e23652f355cbd28765>> + * @generated SignedSource<<609b55df15ac72da5a3c14dde18a4814>> */ /** @@ -286,6 +286,12 @@ public object ReactNativeFeatureFlags { @JvmStatic public fun useOptimizedEventBatchingOnAndroid(): Boolean = accessor.useOptimizedEventBatchingOnAndroid() + /** + * Instead of using folly::dynamic as internal representation in RawProps and RawValue, use jsi::Value + */ + @JvmStatic + public fun useRawPropsJsiValue(): Boolean = accessor.useRawPropsJsiValue() + /** * When enabled, cloning shadow nodes within react native will update the reference held by the current JS fiber tree. */ 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 ad998c6fb51..7e87b950dc8 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<<08711c50ae5a1ffabcc561bbfe05896e>> + * @generated SignedSource<<0be0090ba864cd4fe0bd2c22e419923c>> */ /** @@ -63,6 +63,7 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso private var useNativeViewConfigsInBridgelessModeCache: Boolean? = null private var useOptimisedViewPreallocationOnAndroidCache: Boolean? = null private var useOptimizedEventBatchingOnAndroidCache: Boolean? = null + private var useRawPropsJsiValueCache: Boolean? = null private var useRuntimeShadowNodeReferenceUpdateCache: Boolean? = null private var useTurboModuleInteropCache: Boolean? = null private var useTurboModulesCache: Boolean? = null @@ -454,6 +455,15 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso return cached } + override fun useRawPropsJsiValue(): Boolean { + var cached = useRawPropsJsiValueCache + if (cached == null) { + cached = ReactNativeFeatureFlagsCxxInterop.useRawPropsJsiValue() + useRawPropsJsiValueCache = cached + } + return cached + } + override fun useRuntimeShadowNodeReferenceUpdate(): Boolean { var cached = useRuntimeShadowNodeReferenceUpdateCache 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 7f893474e80..c92b0c68a33 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<<1079b38c8b5c0c16e658fa1a4ff0b619>> + * @generated SignedSource<> */ /** @@ -114,6 +114,8 @@ public object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic public external fun useOptimizedEventBatchingOnAndroid(): Boolean + @DoNotStrip @JvmStatic public external fun useRawPropsJsiValue(): Boolean + @DoNotStrip @JvmStatic public external fun useRuntimeShadowNodeReferenceUpdate(): Boolean @DoNotStrip @JvmStatic public external fun useTurboModuleInterop(): 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 739f88f3c54..f44cdadae12 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<> + * @generated SignedSource<<04ac11c085b2880db40d44e431db42f2>> */ /** @@ -109,6 +109,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun useOptimizedEventBatchingOnAndroid(): Boolean = false + override fun useRawPropsJsiValue(): Boolean = false + override fun useRuntimeShadowNodeReferenceUpdate(): Boolean = true override fun useTurboModuleInterop(): 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 15d150bf386..348e334c34f 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<<0f7a852c7c44b4074bf618252fecb2f6>> */ /** @@ -67,6 +67,7 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces private var useNativeViewConfigsInBridgelessModeCache: Boolean? = null private var useOptimisedViewPreallocationOnAndroidCache: Boolean? = null private var useOptimizedEventBatchingOnAndroidCache: Boolean? = null + private var useRawPropsJsiValueCache: Boolean? = null private var useRuntimeShadowNodeReferenceUpdateCache: Boolean? = null private var useTurboModuleInteropCache: Boolean? = null private var useTurboModulesCache: Boolean? = null @@ -501,6 +502,16 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces return cached } + override fun useRawPropsJsiValue(): Boolean { + var cached = useRawPropsJsiValueCache + if (cached == null) { + cached = currentProvider.useRawPropsJsiValue() + accessedFeatureFlags.add("useRawPropsJsiValue") + useRawPropsJsiValueCache = cached + } + return cached + } + override fun useRuntimeShadowNodeReferenceUpdate(): Boolean { var cached = useRuntimeShadowNodeReferenceUpdateCache 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 0d7b4013437..cd32e8b71b5 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<> + * @generated SignedSource<<190f00e954f343b076cfe5ef75ee4539>> */ /** @@ -109,6 +109,8 @@ public interface ReactNativeFeatureFlagsProvider { @DoNotStrip public fun useOptimizedEventBatchingOnAndroid(): Boolean + @DoNotStrip public fun useRawPropsJsiValue(): Boolean + @DoNotStrip public fun useRuntimeShadowNodeReferenceUpdate(): Boolean @DoNotStrip public fun useTurboModuleInterop(): 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 6ff7afe01b5..d576fc3d71b 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<<0f603eaf15eb01cb23a2485d5a525275>> + * @generated SignedSource<<8a9673f2f81917b3466fb955d5641720>> */ /** @@ -297,6 +297,12 @@ class ReactNativeFeatureFlagsProviderHolder return method(javaProvider_); } + bool useRawPropsJsiValue() override { + static const auto method = + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("useRawPropsJsiValue"); + return method(javaProvider_); + } + bool useRuntimeShadowNodeReferenceUpdate() override { static const auto method = getReactNativeFeatureFlagsProviderJavaClass()->getMethod("useRuntimeShadowNodeReferenceUpdate"); @@ -534,6 +540,11 @@ bool JReactNativeFeatureFlagsCxxInterop::useOptimizedEventBatchingOnAndroid( return ReactNativeFeatureFlags::useOptimizedEventBatchingOnAndroid(); } +bool JReactNativeFeatureFlagsCxxInterop::useRawPropsJsiValue( + facebook::jni::alias_ref /*unused*/) { + return ReactNativeFeatureFlags::useRawPropsJsiValue(); +} + bool JReactNativeFeatureFlagsCxxInterop::useRuntimeShadowNodeReferenceUpdate( facebook::jni::alias_ref /*unused*/) { return ReactNativeFeatureFlags::useRuntimeShadowNodeReferenceUpdate(); @@ -709,6 +720,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "useOptimizedEventBatchingOnAndroid", JReactNativeFeatureFlagsCxxInterop::useOptimizedEventBatchingOnAndroid), + makeNativeMethod( + "useRawPropsJsiValue", + JReactNativeFeatureFlagsCxxInterop::useRawPropsJsiValue), makeNativeMethod( "useRuntimeShadowNodeReferenceUpdate", JReactNativeFeatureFlagsCxxInterop::useRuntimeShadowNodeReferenceUpdate), 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 8f50302cb4c..df9ef850a5a 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<> + * @generated SignedSource<> */ /** @@ -159,6 +159,9 @@ class JReactNativeFeatureFlagsCxxInterop static bool useOptimizedEventBatchingOnAndroid( facebook::jni::alias_ref); + static bool useRawPropsJsiValue( + facebook::jni::alias_ref); + static bool useRuntimeShadowNodeReferenceUpdate( 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 4903401eca8..564b1ca5698 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<<88103b9e29549d8bc3971f254a3529b6>> + * @generated SignedSource<> */ /** @@ -198,6 +198,10 @@ bool ReactNativeFeatureFlags::useOptimizedEventBatchingOnAndroid() { return getAccessor().useOptimizedEventBatchingOnAndroid(); } +bool ReactNativeFeatureFlags::useRawPropsJsiValue() { + return getAccessor().useRawPropsJsiValue(); +} + bool ReactNativeFeatureFlags::useRuntimeShadowNodeReferenceUpdate() { return getAccessor().useRuntimeShadowNodeReferenceUpdate(); } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h index 5a92eb8d16e..c14b2cff642 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<<9657126869d2fb6edb9074d71c0989ac>> + * @generated SignedSource<> */ /** @@ -254,6 +254,11 @@ class ReactNativeFeatureFlags { */ RN_EXPORT static bool useOptimizedEventBatchingOnAndroid(); + /** + * Instead of using folly::dynamic as internal representation in RawProps and RawValue, use jsi::Value + */ + RN_EXPORT static bool useRawPropsJsiValue(); + /** * When enabled, cloning shadow nodes within react native will update the reference held by the current JS fiber tree. */ diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp index 1387f6d035b..e2e528c86fe 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<<01cf526d22b18b9f43f715a84db8422f>> + * @generated SignedSource<<1cd2586e0118ba4a828fd99fdda97187>> */ /** @@ -803,6 +803,24 @@ bool ReactNativeFeatureFlagsAccessor::useOptimizedEventBatchingOnAndroid() { return flagValue.value(); } +bool ReactNativeFeatureFlagsAccessor::useRawPropsJsiValue() { + auto flagValue = useRawPropsJsiValue_.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(43, "useRawPropsJsiValue"); + + flagValue = currentProvider_->useRawPropsJsiValue(); + useRawPropsJsiValue_ = flagValue; + } + + return flagValue.value(); +} + bool ReactNativeFeatureFlagsAccessor::useRuntimeShadowNodeReferenceUpdate() { auto flagValue = useRuntimeShadowNodeReferenceUpdate_.load(); @@ -812,7 +830,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(43, "useRuntimeShadowNodeReferenceUpdate"); + markFlagAsAccessed(44, "useRuntimeShadowNodeReferenceUpdate"); flagValue = currentProvider_->useRuntimeShadowNodeReferenceUpdate(); useRuntimeShadowNodeReferenceUpdate_ = flagValue; @@ -830,7 +848,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(44, "useTurboModuleInterop"); + markFlagAsAccessed(45, "useTurboModuleInterop"); flagValue = currentProvider_->useTurboModuleInterop(); useTurboModuleInterop_ = flagValue; @@ -848,7 +866,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(45, "useTurboModules"); + markFlagAsAccessed(46, "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 56944778d8c..5f0177c50ed 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<<485a7e88ec81935a6c45b1ce5de0cbf2>> + * @generated SignedSource<<6be37ce8729f305b92161c7263366c7b>> */ /** @@ -75,6 +75,7 @@ class ReactNativeFeatureFlagsAccessor { bool useNativeViewConfigsInBridgelessMode(); bool useOptimisedViewPreallocationOnAndroid(); bool useOptimizedEventBatchingOnAndroid(); + bool useRawPropsJsiValue(); bool useRuntimeShadowNodeReferenceUpdate(); bool useTurboModuleInterop(); bool useTurboModules(); @@ -89,7 +90,7 @@ class ReactNativeFeatureFlagsAccessor { std::unique_ptr currentProvider_; bool wasOverridden_; - std::array, 46> accessedFeatureFlags_; + std::array, 47> accessedFeatureFlags_; std::atomic> commonTestFlag_; std::atomic> completeReactInstanceCreationOnBgThreadOnAndroid_; @@ -134,6 +135,7 @@ class ReactNativeFeatureFlagsAccessor { std::atomic> useNativeViewConfigsInBridgelessMode_; std::atomic> useOptimisedViewPreallocationOnAndroid_; std::atomic> useOptimizedEventBatchingOnAndroid_; + std::atomic> useRawPropsJsiValue_; std::atomic> useRuntimeShadowNodeReferenceUpdate_; 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 5d0c50f9018..4aedd08b058 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<<3a027e8944a9d20b04f16f99e8097c65>> + * @generated SignedSource<<93d8b298331642e4dfc7aa0ebf0978c2>> */ /** @@ -199,6 +199,10 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { return false; } + bool useRawPropsJsiValue() override { + return false; + } + bool useRuntimeShadowNodeReferenceUpdate() override { return true; } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h index cabea3ad9d2..faa8fea40bd 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<<5b91c17d725f3a6a140e9fd4a9849707>> + * @generated SignedSource<> */ /** @@ -432,6 +432,15 @@ class ReactNativeFeatureFlagsDynamicProvider : public ReactNativeFeatureFlagsDef return ReactNativeFeatureFlagsDefaults::useOptimizedEventBatchingOnAndroid(); } + bool useRawPropsJsiValue() override { + auto value = values_["useRawPropsJsiValue"]; + if (!value.isNull()) { + return value.getBool(); + } + + return ReactNativeFeatureFlagsDefaults::useRawPropsJsiValue(); + } + bool useRuntimeShadowNodeReferenceUpdate() override { auto value = values_["useRuntimeShadowNodeReferenceUpdate"]; if (!value.isNull()) { diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h index 8e1be74ea17..717db8694a0 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<<8e43cf80f518df24cf78180c83bdb2cc>> */ /** @@ -68,6 +68,7 @@ class ReactNativeFeatureFlagsProvider { virtual bool useNativeViewConfigsInBridgelessMode() = 0; virtual bool useOptimisedViewPreallocationOnAndroid() = 0; virtual bool useOptimizedEventBatchingOnAndroid() = 0; + virtual bool useRawPropsJsiValue() = 0; virtual bool useRuntimeShadowNodeReferenceUpdate() = 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 e7fc2e3412a..ffbf68b6208 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<> + * @generated SignedSource<<2bc4bcbe92476dd7de97e804a1e20440>> */ /** @@ -259,6 +259,11 @@ bool NativeReactNativeFeatureFlags::useOptimizedEventBatchingOnAndroid( return ReactNativeFeatureFlags::useOptimizedEventBatchingOnAndroid(); } +bool NativeReactNativeFeatureFlags::useRawPropsJsiValue( + jsi::Runtime& /*runtime*/) { + return ReactNativeFeatureFlags::useRawPropsJsiValue(); +} + bool NativeReactNativeFeatureFlags::useRuntimeShadowNodeReferenceUpdate( jsi::Runtime& /*runtime*/) { return ReactNativeFeatureFlags::useRuntimeShadowNodeReferenceUpdate(); diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h index c36f690b23b..59c72d29111 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<<7f993bf54033abc75c79e719489b8127>> + * @generated SignedSource<<21e01d73d525a42650c97107fb7ed7ae>> */ /** @@ -123,6 +123,8 @@ class NativeReactNativeFeatureFlags bool useOptimizedEventBatchingOnAndroid(jsi::Runtime& runtime); + bool useRawPropsJsiValue(jsi::Runtime& runtime); + bool useRuntimeShadowNodeReferenceUpdate(jsi::Runtime& runtime); bool useTurboModuleInterop(jsi::Runtime& runtime); diff --git a/packages/react-native/ReactCommon/react/renderer/core/RawPropsParser.cpp b/packages/react-native/ReactCommon/react/renderer/core/RawPropsParser.cpp index 122956d33c7..e739efbff29 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/RawPropsParser.cpp +++ b/packages/react-native/ReactCommon/react/renderer/core/RawPropsParser.cpp @@ -8,6 +8,7 @@ #include "RawPropsParser.h" #include +#include #include #include @@ -136,8 +137,13 @@ void RawPropsParser::preparse(const RawProps& rawProps) const noexcept { rawProps.keyIndexToValueIndex_[keyIndex] = valueIndex; auto value = object.getProperty(runtime, nameValue); - rawProps.values_.push_back( - RawValue(jsi::dynamicFromValue(runtime, value))); + RawValue rawValue; + if (ReactNativeFeatureFlags::useRawPropsJsiValue()) { + rawValue = RawValue(runtime, std::move(value)); + } else { + rawValue = RawValue(jsi::dynamicFromValue(runtime, value)); + } + rawProps.values_.push_back(std::move(rawValue)); valueIndex++; } diff --git a/packages/react-native/ReactCommon/react/renderer/core/RawValue.h b/packages/react-native/ReactCommon/react/renderer/core/RawValue.h index 59ea6e0124b..d888c59e595 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/RawValue.h +++ b/packages/react-native/ReactCommon/react/renderer/core/RawValue.h @@ -8,6 +8,7 @@ #pragma once #include +#include #include #include @@ -54,38 +55,52 @@ class RawValue { /* * Constructors. */ - RawValue() noexcept : dynamic_(nullptr) {} + RawValue() noexcept : value_(folly::dynamic(nullptr)) {} - RawValue(RawValue&& other) noexcept : dynamic_(std::move(other.dynamic_)) {} + RawValue(RawValue&& other) noexcept : value_(std::move(other.value_)) {} RawValue& operator=(RawValue&& other) noexcept { if (this != &other) { - dynamic_ = std::move(other.dynamic_); + value_ = std::move(other.value_); } return *this; } - explicit RawValue(const folly::dynamic& dynamic) noexcept - : dynamic_(dynamic) {} + explicit RawValue(jsi::Runtime& runtime, const jsi::Value& value) noexcept + : value_(std::make_pair(&runtime, jsi::Value(runtime, value))) {} + + explicit RawValue(jsi::Runtime& runtime, jsi::Value&& value) noexcept + : value_(std::make_pair(&runtime, std::move(value))) {} + + explicit RawValue(const folly::dynamic& dynamic) noexcept : value_(dynamic) {} explicit RawValue(folly::dynamic&& dynamic) noexcept - : dynamic_(std::move(dynamic)) {} + : value_(std::move(dynamic)) {} private: friend class RawProps; friend class RawPropsParser; friend class UIManagerBinding; - /* - * Copy constructor and copy assignment operator would be private and only for - * internal use, but it's needed for user-code that does `auto val = - * (butter::map)rawVal;` - */ - RawValue(const RawValue& other) noexcept : dynamic_(other.dynamic_) {} + RawValue(const RawValue& other) { + if (std::holds_alternative(other.value_)) { + auto& dynamic = std::get(other.value_); + value_ = dynamic; + } else { + const auto& [runtime, value] = std::get(other.value_); + value_ = std::make_pair(runtime, jsi::Value(*runtime, value)); + } + } - RawValue& operator=(const RawValue& other) noexcept { + RawValue& operator=(const RawValue& other) { if (this != &other) { - dynamic_ = other.dynamic_; + if (std::holds_alternative(other.value_)) { + auto& dynamic = std::get(other.value_); + value_ = dynamic; + } else { + const auto& [runtime, value] = std::get(other.value_); + value_ = std::make_pair(runtime, jsi::Value(*runtime, value)); + } } return *this; } @@ -96,30 +111,54 @@ class RawValue { */ template explicit operator T() const { - return castValue(dynamic_, (T*)nullptr); + if (std::holds_alternative(value_)) { + auto& dynamic = std::get(value_); + return castValue(dynamic, (T*)nullptr); + } else { + const auto& [runtime, value] = std::get(value_); + return castValue(runtime, value, (T*)nullptr); + } } - inline explicit operator folly::dynamic() const noexcept { - return dynamic_; + inline explicit operator folly::dynamic() const { + if (std::holds_alternative(value_)) { + return std::get(value_); + } else { + const auto& [runtime, value] = std::get(value_); + return jsi::dynamicFromValue(*runtime, value); + } } /* * Checks if the stored value has specified type. */ template - bool hasType() const noexcept { - return checkValueType(dynamic_, (T*)nullptr); + bool hasType() const { + if (std::holds_alternative(value_)) { + auto& dynamic = std::get(value_); + return checkValueType(dynamic, (T*)nullptr); + } else { + const auto& [runtime, value] = std::get(value_); + return checkValueType(runtime, value, (T*)nullptr); + } } /* * Checks if the stored value is *not* `null`. */ - bool hasValue() const noexcept { - return !dynamic_.isNull(); + bool hasValue() const { + if (std::holds_alternative(value_)) { + auto& dynamic = std::get(value_); + return !dynamic.isNull(); + } else { + const auto& [runtime, value] = std::get(value_); + return !value.isNull() && !value.isUndefined(); + } } private: - folly::dynamic dynamic_; + using JsiValuePair = std::pair; + std::variant value_; static bool checkValueType( const folly::dynamic& /*dynamic*/, @@ -127,42 +166,104 @@ class RawValue { return true; } + static bool checkValueType( + jsi::Runtime* /*runtime*/, + const jsi::Value& /*value*/, + RawValue* /*type*/) noexcept { + return true; + } + static bool checkValueType( const folly::dynamic& dynamic, bool* /*type*/) noexcept { return dynamic.isBool(); } + static bool checkValueType( + jsi::Runtime* /*runtime*/, + const jsi::Value& value, + bool* /*type*/) noexcept { + return value.isBool(); + } + static bool checkValueType( const folly::dynamic& dynamic, int* /*type*/) noexcept { return dynamic.isNumber(); } + static bool checkValueType( + jsi::Runtime* /*runtime*/, + const jsi::Value& value, + int* /*type*/) noexcept { + return value.isNumber(); + } + static bool checkValueType( const folly::dynamic& dynamic, int64_t* /*type*/) noexcept { return dynamic.isNumber(); } + static bool checkValueType( + jsi::Runtime* /*runtime*/, + const jsi::Value& value, + int64_t* /*type*/) noexcept { + return value.isNumber(); + } + static bool checkValueType( const folly::dynamic& dynamic, float* /*type*/) noexcept { return dynamic.isNumber(); } + static bool checkValueType( + jsi::Runtime* /*runtime*/, + const jsi::Value& value, + float* /*type*/) noexcept { + return value.isNumber(); + } + static bool checkValueType( const folly::dynamic& dynamic, double* /*type*/) noexcept { return dynamic.isNumber(); } + static bool checkValueType( + jsi::Runtime* /*runtime*/, + const jsi::Value& value, + double* /*type*/) noexcept { + return value.isNumber(); + } + static bool checkValueType( const folly::dynamic& dynamic, std::string* /*type*/) noexcept { return dynamic.isString(); } + static bool checkValueType( + jsi::Runtime* /*runtime*/, + const jsi::Value& value, + std::string* /*type*/) noexcept { + return value.isString(); + } + + static bool checkValueType( + const folly::dynamic& /*dynamic*/, + JsiValuePair* /*type*/) noexcept { + return false; + } + + static bool checkValueType( + jsi::Runtime* /*runtime*/, + const jsi::Value& /*value*/, + JsiValuePair* /*type*/) noexcept { + return true; + } + template static bool checkValueType( const folly::dynamic& dynamic, @@ -183,6 +284,36 @@ class RawValue { return true; } + template + static bool checkValueType( + jsi::Runtime* runtime, + const jsi::Value& value, + std::vector* /*type*/) noexcept { + if (!value.isObject()) { + return false; + } + + jsi::Object asObject = value.getObject(*runtime); + + if (!asObject.isArray(*runtime)) { + return false; + } + + jsi::Array array = asObject.getArray(*runtime); + size_t size = array.size(*runtime); + for (size_t i = 0; i < size; i++) { + jsi::Value itemValue = array.getValueAtIndex(*runtime, i); + if (!checkValueType(runtime, itemValue, (T*)nullptr)) { + return false; + } + + // Note: We test only one element. + break; + } + + return true; + } + template static bool checkValueType( const folly::dynamic& dynamic, @@ -204,6 +335,34 @@ class RawValue { return true; } + template + static bool checkValueType( + jsi::Runtime* runtime, + const jsi::Value& value, + std::unordered_map* /*type*/) { + if (!value.isObject()) { + return false; + } + + jsi::Object asObject = value.getObject(*runtime); + + auto propertyNames = asObject.getPropertyNames(*runtime); + size_t size = propertyNames.size(*runtime); + for (size_t i = 0; i < size; i++) { + jsi::String propertyName = + propertyNames.getValueAtIndex(*runtime, i).getString(*runtime); + jsi::Value propertyValue = asObject.getProperty(*runtime, propertyName); + if (!checkValueType(runtime, propertyValue, (T*)nullptr)) { + return false; + } + + // Note: We test only one element. + break; + } + + return true; + } + // Casts static RawValue castValue( const folly::dynamic& dynamic, @@ -211,32 +370,98 @@ class RawValue { return RawValue(dynamic); } + static RawValue castValue( + jsi::Runtime* runtime, + const jsi::Value& value, + RawValue* /*type*/) noexcept { + return RawValue(*runtime, value); + } + static bool castValue(const folly::dynamic& dynamic, bool* /*type*/) { return dynamic.getBool(); } + static bool castValue( + jsi::Runtime* /*runtime*/, + const jsi::Value& value, + bool* /*type*/) { + return value.asBool(); + } + static int castValue(const folly::dynamic& dynamic, int* /*type*/) { return static_cast(dynamic.asInt()); } + static int + castValue(jsi::Runtime* /*runtime*/, const jsi::Value& value, int* /*type*/) { + double number = value.asNumber(); + return static_cast(number); + } + static int64_t castValue(const folly::dynamic& dynamic, int64_t* /*type*/) { return dynamic.asInt(); } + static int64_t castValue( + jsi::Runtime* /*runtime*/, + const jsi::Value& value, + int64_t* /*type*/) { + double number = value.asNumber(); + return static_cast(number); + } + static float castValue(const folly::dynamic& dynamic, float* /*type*/) { return static_cast(dynamic.asDouble()); } + static float castValue( + jsi::Runtime* /*runtime*/, + const jsi::Value& value, + float* /*type*/) { + double number = value.asNumber(); + return static_cast(number); + } + static double castValue(const folly::dynamic& dynamic, double* /*type*/) { return dynamic.asDouble(); } + static double castValue( + jsi::Runtime* /*runtime*/, + const jsi::Value& value, + double* /*type*/) { + return value.asNumber(); + } + static std::string castValue( const folly::dynamic& dynamic, std::string* /*type*/) { return dynamic.getString(); } + static std::string castValue( + jsi::Runtime* runtime, + const jsi::Value& value, + std::string* /*type*/) { + jsi::String stringValue = value.asString(*runtime); + return stringValue.utf8(*runtime); + } + + static JsiValuePair castValue( + const folly::dynamic& /*dynamic*/, + JsiValuePair* /*type*/) { + react_native_assert(false); + throw std::runtime_error( + "Cannot cast dynamic to a jsi::Value type. Please use the 'useRawPropsJsiValue' feature flag to enable jsi::Value support for RawValues."); + } + + static JsiValuePair castValue( + jsi::Runtime* runtime, + const jsi::Value& value, + JsiValuePair* /*type*/) { + return {runtime, jsi::Value(*runtime, value)}; + } + template static std::vector castValue( const folly::dynamic& dynamic, @@ -250,6 +475,26 @@ class RawValue { return result; } + template + static std::vector castValue( + jsi::Runtime* runtime, + const jsi::Value& value, + std::vector* /*type*/) { + react_native_assert(value.isObject()); + jsi::Object object = value.getObject(*runtime); + react_native_assert(object.isArray(*runtime)); + jsi::Array array = object.getArray(*runtime); + size_t size = array.size(*runtime); + std::vector result; + result.reserve(size); + for (size_t i = 0; i < size; i++) { + jsi::Value itemValue = array.getValueAtIndex(*runtime, i); + T item = castValue(runtime, itemValue, (T*)nullptr); + result.push_back(std::move(item)); + } + return result; + } + template static std::vector> castValue( const folly::dynamic& dynamic, @@ -263,6 +508,27 @@ class RawValue { return result; } + template + static std::vector> castValue( + jsi::Runtime* runtime, + const jsi::Value& value, + std::vector>* /*type*/) { + react_native_assert(value.isObject()); + jsi::Object object = value.getObject(*runtime); + react_native_assert(object.isArray(*runtime)); + jsi::Array array = std::move(object).getArray(*runtime); + size_t size = array.size(*runtime); + std::vector> result; + result.reserve(size); + for (size_t i = 0; i < size; i++) { + jsi::Value itemValue = array.getValueAtIndex(*runtime, i); + std::vector item = + castValue(runtime, itemValue, (std::vector*)nullptr); + result.push_back(std::move(item)); + } + return result; + } + template static std::unordered_map castValue( const folly::dynamic& dynamic, @@ -275,6 +541,33 @@ class RawValue { } return result; } + + template + static std::unordered_map castValue( + jsi::Runtime* runtime, + const jsi::Value& value, + std::unordered_map* /*type*/) { + react_native_assert(value.isObject()); + jsi::Object object = value.getObject(*runtime); + jsi::Array propertyNames = object.getPropertyNames(*runtime); + size_t size = propertyNames.size(*runtime); + std::unordered_map result; + for (size_t i = 0; i < size; i++) { + jsi::Value propertyNameValue = propertyNames.getValueAtIndex(*runtime, i); + jsi::String propertyName = propertyNameValue.getString(*runtime); + jsi::Value propertyValue = object.getProperty(*runtime, propertyName); + if (propertyValue.isUndefined()) { + // Skip undefined values to mimic JSIDynamic::dynamicFromValue behavior. + // Null values are allowed in the map. + continue; + } + + std::string propertyNameString = propertyName.utf8(*runtime); + T property = castValue(runtime, propertyValue, (T*)nullptr); + result.emplace(propertyNameString, std::move(property)); + } + return result; + } }; } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/React-graphics.podspec b/packages/react-native/ReactCommon/react/renderer/graphics/React-graphics.podspec index 9548d69c19e..a651b742767 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/React-graphics.podspec +++ b/packages/react-native/ReactCommon/react/renderer/graphics/React-graphics.podspec @@ -70,4 +70,10 @@ Pod::Spec.new do |s| s.dependency "DoubleConversion" s.dependency "fast_float", "6.1.4" s.dependency "fmt", "11.0.2" + + if ENV["USE_HERMES"] == nil || ENV["USE_HERMES"] == "1" + s.dependency "hermes-engine" + else + s.dependency "React-jsc" + end end diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index d3ee1601cd7..3060b8d72de 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -411,6 +411,15 @@ const definitions: FeatureFlagDefinitions = { purpose: 'experimentation', }, }, + useRawPropsJsiValue: { + defaultValue: false, + metadata: { + dateAdded: '2024-12-02', + description: + 'Instead of using folly::dynamic as internal representation in RawProps and RawValue, use jsi::Value', + purpose: 'experimentation', + }, + }, useRuntimeShadowNodeReferenceUpdate: { defaultValue: true, metadata: { diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index a1d8d5351ca..62b82fc6f45 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<<67e1f8c80caedcbf7b28a089a2744b9a>> + * @generated SignedSource<<52cce0be8ae96e530267bf0dbbcfbd2d>> * @flow strict */ @@ -94,6 +94,7 @@ export type ReactNativeFeatureFlags = { useNativeViewConfigsInBridgelessMode: Getter, useOptimisedViewPreallocationOnAndroid: Getter, useOptimizedEventBatchingOnAndroid: Getter, + useRawPropsJsiValue: Getter, useRuntimeShadowNodeReferenceUpdate: Getter, useTurboModuleInterop: Getter, useTurboModules: Getter, @@ -360,6 +361,10 @@ export const useOptimisedViewPreallocationOnAndroid: Getter = createNat * Uses an optimized mechanism for event batching on Android that does not need to wait for a Choreographer frame callback. */ export const useOptimizedEventBatchingOnAndroid: Getter = createNativeFlagGetter('useOptimizedEventBatchingOnAndroid', false); +/** + * Instead of using folly::dynamic as internal representation in RawProps and RawValue, use jsi::Value + */ +export const useRawPropsJsiValue: Getter = createNativeFlagGetter('useRawPropsJsiValue', false); /** * When enabled, cloning shadow nodes within react native will update the reference held by the current JS fiber tree. */ diff --git a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js index 903b1d01e7e..a34893dcf26 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<<01d174fa990b1b9cccd8bea4694fc1b4>> * @flow strict */ @@ -67,6 +67,7 @@ export interface Spec extends TurboModule { +useNativeViewConfigsInBridgelessMode?: () => boolean; +useOptimisedViewPreallocationOnAndroid?: () => boolean; +useOptimizedEventBatchingOnAndroid?: () => boolean; + +useRawPropsJsiValue?: () => boolean; +useRuntimeShadowNodeReferenceUpdate?: () => boolean; +useTurboModuleInterop?: () => boolean; +useTurboModules?: () => boolean; diff --git a/packages/rn-tester/Podfile.lock b/packages/rn-tester/Podfile.lock index f5e78684172..f06802e190b 100644 --- a/packages/rn-tester/Podfile.lock +++ b/packages/rn-tester/Podfile.lock @@ -1237,6 +1237,7 @@ PODS: - fast_float (= 6.1.4) - fmt (= 11.0.2) - glog + - hermes-engine - RCT-Folly/Fabric (= 2024.11.18.00) - React-jsi - React-jsiexecutor