diff --git a/packages/react-native/Libraries/Network/React-RCTNetwork.podspec b/packages/react-native/Libraries/Network/React-RCTNetwork.podspec index 5560831aa5eaf5..feda0b84f1bc56 100644 --- a/packages/react-native/Libraries/Network/React-RCTNetwork.podspec +++ b/packages/react-native/Libraries/Network/React-RCTNetwork.podspec @@ -46,6 +46,7 @@ Pod::Spec.new do |s| add_dependency(s, "React-RCTFBReactNativeSpec") add_dependency(s, "ReactCommon", :subspec => "turbomodule/core", :additional_framework_paths => ["react/nativemodule/core"]) + add_dependency(s, "React-featureflags") add_dependency(s, "React-jsinspectorcdp", :framework_name => 'jsinspector_moderncdp') add_dependency(s, "React-jsinspectornetwork", :framework_name => 'jsinspector_modernnetwork') add_dependency(s, "React-NativeModulesApple", :additional_framework_paths => ["build/generated/ios"]) diff --git a/packages/react-native/ReactCommon/jsinspector-modern/network/CMakeLists.txt b/packages/react-native/ReactCommon/jsinspector-modern/network/CMakeLists.txt index 1749a26b3e0d10..162debbcf27f50 100644 --- a/packages/react-native/ReactCommon/jsinspector-modern/network/CMakeLists.txt +++ b/packages/react-native/ReactCommon/jsinspector-modern/network/CMakeLists.txt @@ -24,4 +24,5 @@ target_include_directories(jsinspector_network PUBLIC ${REACT_COMMON_DIR}) target_link_libraries(jsinspector_network folly_runtime jsinspector_cdp -) + react_performance_timeline + react_timing) diff --git a/packages/react-native/ReactCommon/jsinspector-modern/network/NetworkReporter.cpp b/packages/react-native/ReactCommon/jsinspector-modern/network/NetworkReporter.cpp index 44e49417eceedc..1eb6e19f20f6d6 100644 --- a/packages/react-native/ReactCommon/jsinspector-modern/network/NetworkReporter.cpp +++ b/packages/react-native/ReactCommon/jsinspector-modern/network/NetworkReporter.cpp @@ -15,6 +15,8 @@ #include #include #endif +#include +#include #ifdef REACT_NATIVE_DEBUGGER_ENABLED #include @@ -27,7 +29,7 @@ namespace facebook::react::jsinspector_modern { namespace { /** - * Get the current Unix timestamp in seconds (µs precision). + * Get the current Unix timestamp in seconds (µs precision, CDP format). */ double getCurrentUnixTimestampSeconds() { auto now = std::chrono::system_clock::now().time_since_epoch(); @@ -74,7 +76,23 @@ void NetworkReporter::reportRequestStart( const std::string& requestId, const RequestInfo& requestInfo, int encodedDataLength, - const std::optional& redirectResponse) const { + const std::optional& redirectResponse) { + if (ReactNativeFeatureFlags::enableResourceTimingAPI()) { + double now = PerformanceEntryReporter::getInstance()->getCurrentTimeStamp(); + + // All builds: Annotate PerformanceResourceTiming metadata + { + std::lock_guard lock(perfTimingsMutex_); + perfTimingsBuffer_.emplace( + requestId, + ResourceTimingData{ + .url = requestInfo.url, + .fetchStart = now, + .requestStart = now, + }); + } + } + #ifdef REACT_NATIVE_DEBUGGER_ENABLED // Debug build: CDP event handling if (!isDebuggingEnabledNoSync()) { @@ -107,8 +125,20 @@ void NetworkReporter::reportRequestStart( #endif } -void NetworkReporter::reportConnectionTiming( - const std::string& /*requestId*/) const { +void NetworkReporter::reportConnectionTiming(const std::string& requestId) { + if (ReactNativeFeatureFlags::enableResourceTimingAPI()) { + double now = PerformanceEntryReporter::getInstance()->getCurrentTimeStamp(); + + // All builds: Annotate PerformanceResourceTiming metadata + { + std::lock_guard lock(perfTimingsMutex_); + auto it = perfTimingsBuffer_.find(requestId); + if (it != perfTimingsBuffer_.end()) { + it->second.connectStart = now; + } + } + } + #ifdef REACT_NATIVE_DEBUGGER_ENABLED // Debug build: CDP event handling if (!isDebuggingEnabledNoSync()) { @@ -136,7 +166,21 @@ void NetworkReporter::reportRequestFailed( void NetworkReporter::reportResponseStart( const std::string& requestId, const ResponseInfo& responseInfo, - int encodedDataLength) const { + int encodedDataLength) { + if (ReactNativeFeatureFlags::enableResourceTimingAPI()) { + double now = PerformanceEntryReporter::getInstance()->getCurrentTimeStamp(); + + // All builds: Annotate PerformanceResourceTiming metadata + { + std::lock_guard lock(perfTimingsMutex_); + auto it = perfTimingsBuffer_.find(requestId); + if (it != perfTimingsBuffer_.end()) { + it->second.responseStart = now; + it->second.responseStatus = responseInfo.statusCode; + } + } + } + #ifdef REACT_NATIVE_DEBUGGER_ENABLED // Debug build: CDP event handling if (!isDebuggingEnabledNoSync()) { @@ -159,8 +203,21 @@ void NetworkReporter::reportResponseStart( #endif } -void NetworkReporter::reportDataReceived( - const std::string& /*requestId*/) const { +void NetworkReporter::reportDataReceived(const std::string& requestId) { + if (ReactNativeFeatureFlags::enableResourceTimingAPI()) { + double now = PerformanceEntryReporter::getInstance()->getCurrentTimeStamp(); + + // All builds: Annotate PerformanceResourceTiming metadata + { + std::lock_guard lock(perfTimingsMutex_); + auto it = perfTimingsBuffer_.find(requestId); + if (it != perfTimingsBuffer_.end()) { + it->second.connectEnd = now; + it->second.responseStart = now; + } + } + } + #ifdef REACT_NATIVE_DEBUGGER_ENABLED // Debug build: CDP event handling if (!isDebuggingEnabledNoSync()) { @@ -174,7 +231,30 @@ void NetworkReporter::reportDataReceived( void NetworkReporter::reportResponseEnd( const std::string& requestId, - int encodedDataLength) const { + int encodedDataLength) { + if (ReactNativeFeatureFlags::enableResourceTimingAPI()) { + double now = PerformanceEntryReporter::getInstance()->getCurrentTimeStamp(); + + // All builds: Report PerformanceResourceTiming event + { + std::lock_guard lock(perfTimingsMutex_); + auto it = perfTimingsBuffer_.find(requestId); + if (it != perfTimingsBuffer_.end()) { + auto& eventData = it->second; + PerformanceEntryReporter::getInstance()->reportResourceTiming( + eventData.url, + eventData.fetchStart, + eventData.requestStart, + eventData.connectStart.value_or(now), + eventData.connectEnd.value_or(now), + eventData.responseStart.value_or(now), + now, + eventData.responseStatus); + perfTimingsBuffer_.erase(requestId); + } + } + } + #ifdef REACT_NATIVE_DEBUGGER_ENABLED // Debug build: CDP event handling if (!isDebuggingEnabledNoSync()) { diff --git a/packages/react-native/ReactCommon/jsinspector-modern/network/NetworkReporter.h b/packages/react-native/ReactCommon/jsinspector-modern/network/NetworkReporter.h index c6d281e15c7584..4227deca3df0b8 100644 --- a/packages/react-native/ReactCommon/jsinspector-modern/network/NetworkReporter.h +++ b/packages/react-native/ReactCommon/jsinspector-modern/network/NetworkReporter.h @@ -9,8 +9,11 @@ #include "NetworkTypes.h" +#include + #include #include +#include #include namespace facebook::react::jsinspector_modern { @@ -22,6 +25,24 @@ namespace facebook::react::jsinspector_modern { */ using FrontendChannel = std::function; +/** + * Container for static network event metadata aligning with the + * `PerformanceResourceTiming` interface. + * + * This is a lightweight type stored in `perfTimingsBuffer_` and used for + * reporting complete events to the Web Performance subsystem. Not used for CDP + * reporting. + */ +struct ResourceTimingData { + std::string url; + DOMHighResTimeStamp fetchStart; + DOMHighResTimeStamp requestStart; + std::optional connectStart; + std::optional connectEnd; + std::optional responseStart; + std::optional responseStatus; +}; + /** * [Experimental] An interface for reporting network events to the modern * debugger server and Web Performance APIs. @@ -67,7 +88,7 @@ class NetworkReporter { const std::string& requestId, const RequestInfo& requestInfo, int encodedDataLength, - const std::optional& redirectResponse) const; + const std::optional& redirectResponse); /** * Report detailed timing info, such as DNS lookup, when a request has @@ -79,7 +100,7 @@ class NetworkReporter { * * https://w3c.github.io/resource-timing/#dom-performanceresourcetiming-connectstart */ - void reportConnectionTiming(const std::string& requestId) const; + void reportConnectionTiming(const std::string& requestId); /** * Report when a network request has failed. @@ -100,14 +121,14 @@ class NetworkReporter { void reportResponseStart( const std::string& requestId, const ResponseInfo& responseInfo, - int encodedDataLength) const; + int encodedDataLength); /** * Report when additional chunks of the response body have been received. * * Corresponds to `Network.dataReceived` in CDP. */ - void reportDataReceived(const std::string& requestId) const; + void reportDataReceived(const std::string& requestId); /** * Report when a network request is complete and we are no longer receiving @@ -118,8 +139,7 @@ class NetworkReporter { * * https://w3c.github.io/resource-timing/#dom-performanceresourcetiming-responseend */ - void reportResponseEnd(const std::string& requestId, int encodedDataLength) - const; + void reportResponseEnd(const std::string& requestId, int encodedDataLength); private: FrontendChannel frontendChannel_; @@ -134,6 +154,9 @@ class NetworkReporter { inline bool isDebuggingEnabledNoSync() const { return debuggingEnabled_.load(std::memory_order_relaxed); } + + std::unordered_map perfTimingsBuffer_{}; + std::mutex perfTimingsMutex_; }; } // namespace facebook::react::jsinspector_modern diff --git a/packages/react-native/ReactCommon/jsinspector-modern/network/React-jsinspectornetwork.podspec b/packages/react-native/ReactCommon/jsinspector-modern/network/React-jsinspectornetwork.podspec index eb2b513439a796..b4c4a2b545f2b8 100644 --- a/packages/react-native/ReactCommon/jsinspector-modern/network/React-jsinspectornetwork.podspec +++ b/packages/react-native/ReactCommon/jsinspector-modern/network/React-jsinspectornetwork.podspec @@ -47,6 +47,9 @@ Pod::Spec.new do |s| end add_dependency(s, "React-jsinspectorcdp", :framework_name => 'jsinspector_moderncdp') + add_dependency(s, "React-featureflags") + s.dependency "React-performancetimeline" + s.dependency "React-timing" add_rn_third_party_dependencies(s) end diff --git a/packages/react-native/ReactCommon/react/performance/timeline/CMakeLists.txt b/packages/react-native/ReactCommon/react/performance/timeline/CMakeLists.txt index c507e4fd449ec6..4de6a14a509859 100644 --- a/packages/react-native/ReactCommon/react/performance/timeline/CMakeLists.txt +++ b/packages/react-native/ReactCommon/react/performance/timeline/CMakeLists.txt @@ -18,4 +18,5 @@ target_include_directories(react_performance_timeline PUBLIC ${REACT_COMMON_DIR} target_link_libraries(react_performance_timeline jsinspector_tracing reactperflogger + react_featureflags react_timing) diff --git a/packages/react-native/ReactCommon/react/performance/timeline/PerformanceEntry.h b/packages/react-native/ReactCommon/react/performance/timeline/PerformanceEntry.h index 45a7044934c725..e794902f85dc86 100644 --- a/packages/react-native/ReactCommon/react/performance/timeline/PerformanceEntry.h +++ b/packages/react-native/ReactCommon/react/performance/timeline/PerformanceEntry.h @@ -57,8 +57,8 @@ struct PerformanceResourceTiming : AbstractPerformanceEntry { static constexpr PerformanceEntryType entryType = PerformanceEntryType::RESOURCE; /** Aligns with `startTime`. */ - std::optional fetchStart; - std::optional requestStart; + DOMHighResTimeStamp fetchStart; + DOMHighResTimeStamp requestStart; std::optional connectStart; std::optional connectEnd; std::optional responseStart; diff --git a/packages/react-native/ReactCommon/react/performance/timeline/PerformanceEntryReporter.cpp b/packages/react-native/ReactCommon/react/performance/timeline/PerformanceEntryReporter.cpp index 8273a89d429a68..2d0ba22aec3fbf 100644 --- a/packages/react-native/ReactCommon/react/performance/timeline/PerformanceEntryReporter.cpp +++ b/packages/react-native/ReactCommon/react/performance/timeline/PerformanceEntryReporter.cpp @@ -30,6 +30,10 @@ std::vector getSupportedEntryTypesInternal() { PerformanceEntryType::LONGTASK, }; + if (ReactNativeFeatureFlags::enableResourceTimingAPI()) { + supportedEntryTypes.emplace_back(PerformanceEntryType::RESOURCE); + } + return supportedEntryTypes; } @@ -289,6 +293,37 @@ void PerformanceEntryReporter::reportLongTask( observerRegistry_->queuePerformanceEntry(entry); } +PerformanceResourceTiming PerformanceEntryReporter::reportResourceTiming( + const std::string& url, + DOMHighResTimeStamp fetchStart, + DOMHighResTimeStamp requestStart, + std::optional connectStart, + std::optional connectEnd, + DOMHighResTimeStamp responseStart, + DOMHighResTimeStamp responseEnd, + const std::optional& responseStatus) { + const auto entry = PerformanceResourceTiming{ + {.name = url, .startTime = fetchStart}, + fetchStart, + requestStart, + connectStart, + connectEnd, + responseStart, + responseEnd, + responseStatus, + }; + + // Add to buffers & notify observers + { + std::unique_lock lock(buffersMutex_); + resourceTimingBuffer_.add(entry); + } + + observerRegistry_->queuePerformanceEntry(entry); + + return entry; +} + void PerformanceEntryReporter::traceMark(const PerformanceMark& entry) const { auto& performanceTracer = jsinspector_modern::PerformanceTracer::getInstance(); diff --git a/packages/react-native/ReactCommon/react/performance/timeline/PerformanceEntryReporter.h b/packages/react-native/ReactCommon/react/performance/timeline/PerformanceEntryReporter.h index a8a75fbfcd6b7d..fba99695551f42 100644 --- a/packages/react-native/ReactCommon/react/performance/timeline/PerformanceEntryReporter.h +++ b/packages/react-native/ReactCommon/react/performance/timeline/PerformanceEntryReporter.h @@ -21,8 +21,11 @@ namespace facebook::react { +// Aligned with maxBufferSize implemented by browsers +// https://w3c.github.io/timing-entrytypes-registry/#registry constexpr size_t EVENT_BUFFER_SIZE = 150; constexpr size_t LONG_TASK_BUFFER_SIZE = 200; +constexpr size_t RESOURCE_TIMING_BUFFER_SIZE = 250; constexpr DOMHighResTimeStamp LONG_TASK_DURATION_THRESHOLD_MS = 50.0; @@ -101,15 +104,26 @@ class PerformanceEntryReporter { void reportLongTask(double startTime, double duration); + PerformanceResourceTiming reportResourceTiming( + const std::string& url, + DOMHighResTimeStamp fetchStart, + DOMHighResTimeStamp requestStart, + std::optional connectStart, + std::optional connectEnd, + DOMHighResTimeStamp responseStart, + DOMHighResTimeStamp responseEnd, + const std::optional& responseStatus); + private: std::unique_ptr observerRegistry_; mutable std::shared_mutex buffersMutex_; PerformanceEntryCircularBuffer eventBuffer_{EVENT_BUFFER_SIZE}; PerformanceEntryCircularBuffer longTaskBuffer_{LONG_TASK_BUFFER_SIZE}; + PerformanceEntryCircularBuffer resourceTimingBuffer_{ + RESOURCE_TIMING_BUFFER_SIZE}; PerformanceEntryKeyedBuffer markBuffer_; PerformanceEntryKeyedBuffer measureBuffer_; - PerformanceEntryKeyedBuffer resourceBuffer_; std::unordered_map eventCounts_; @@ -129,7 +143,7 @@ class PerformanceEntryReporter { case PerformanceEntryType::LONGTASK: return longTaskBuffer_; case PerformanceEntryType::RESOURCE: - return resourceBuffer_; + return resourceTimingBuffer_; case PerformanceEntryType::_NEXT: throw std::logic_error("Cannot get buffer for _NEXT entry type"); } @@ -147,7 +161,7 @@ class PerformanceEntryReporter { case PerformanceEntryType::LONGTASK: return longTaskBuffer_; case PerformanceEntryType::RESOURCE: - return resourceBuffer_; + return resourceTimingBuffer_; case PerformanceEntryType::_NEXT: throw std::logic_error("Cannot get buffer for _NEXT entry type"); } diff --git a/packages/react-native/src/private/webapis/performance/internals/RawPerformanceEntry.js b/packages/react-native/src/private/webapis/performance/internals/RawPerformanceEntry.js index 99a0cbb4bfb99a..6a635c0a37a90c 100644 --- a/packages/react-native/src/private/webapis/performance/internals/RawPerformanceEntry.js +++ b/packages/react-native/src/private/webapis/performance/internals/RawPerformanceEntry.js @@ -77,6 +77,8 @@ export function rawToPerformanceEntryType( return 'event'; case RawPerformanceEntryTypeValues.LONGTASK: return 'longtask'; + case RawPerformanceEntryTypeValues.RESOURCE: + return 'resource'; default: throw new TypeError( `rawToPerformanceEntryType: unexpected performance entry type received: ${type}`, diff --git a/packages/rn-tester/Podfile.lock b/packages/rn-tester/Podfile.lock index 04dc96e2e44d02..03c0606ae22082 100644 --- a/packages/rn-tester/Podfile.lock +++ b/packages/rn-tester/Podfile.lock @@ -1706,7 +1706,10 @@ PODS: - glog - RCT-Folly - RCT-Folly/Fabric + - React-featureflags - React-jsinspectorcdp + - React-performancetimeline + - React-timing - SocketRocket - React-jsinspectortracing (1000.0.0): - boost @@ -1807,7 +1810,6 @@ PODS: - glog - RCT-Folly - RCT-Folly/Fabric - - React-cxxreact - React-featureflags - React-jsinspectortracing - React-perflogger @@ -1968,6 +1970,7 @@ PODS: - RCT-Folly/Fabric - RCTTypeSafety - React-Core/RCTNetworkHeaders + - React-featureflags - React-jsi - React-jsinspectorcdp - React-jsinspectornetwork @@ -2562,88 +2565,88 @@ EXTERNAL SOURCES: :path: "../react-native/ReactCommon/yoga" SPEC CHECKSUMS: - boost: 1dca942403ed9342f98334bf4c3621f011aa7946 - DoubleConversion: f16ae600a246532c4020132d54af21d0ddb2a385 + boost: 7e761d76ca2ce687f7cc98e698152abd03a18f90 + DoubleConversion: cb417026b2400c8f53ae97020b2be961b59470cb fast_float: b32c788ed9c6a8c584d114d0047beda9664e7cc6 - FBLazyVector: 05133a4d3886934758fc5a9b149e1881dc333ab7 - fmt: 01b82d4ca6470831d1cc0852a1af644be019e8f6 - glog: 08b301085f15bcbb6ff8632a8ebaf239aae04e6a - hermes-engine: 1d4ebea15d13af28be0dd602bf09c8a27bdf5163 + FBLazyVector: d3c2dd739a63c1a124e775df075dc7c517a719cb + fmt: a40bb5bd0294ea969aaaba240a927bd33d878cdd + glog: 5683914934d5b6e4240e497e0f4a3b42d1854183 + hermes-engine: 5a9adf9081befbac6b81bc0c81522430a7eb7da1 MyNativeView: 649cc955b283053e5832e8d45c2a20597daa94cd NativeCxxModuleExample: d9bac8e847a427f0a40b0c9fb066ab102b3aefd0 OCMock: 589f2c84dacb1f5aaf6e4cec1f292551fe748e74 OSSLibraryExample: 9264008f6ba6a068cb2db3765ffdf519c9c0f6a4 RCT-Folly: 846fda9475e61ec7bcbf8a3fe81edfcaeb090669 RCTDeprecation: 3808e36294137f9ee5668f4df2e73dc079cd1dcf - RCTRequired: c482db71773e4c26f5590519ee0146ff97969018 - RCTTypeSafety: 9dbb69d76b01b3eb6cfff10751b120eb4719ce90 - React: 879e9950c4e457a0b9be526798a2203056afed3f - React-callinvoker: e88f762ae931d38f3cfc01264c40c1b8f96bfec5 - React-Core: b2c9b5ddac40521fcb16f20207e0d90e699f0c4a - React-CoreModules: 959fe435b21b13b20dd7ef6704c842e5df0dfa5b - React-cxxreact: 70dba7dd6868ac16f35972ca1530adaae213847a - React-debug: 19bd15a4a86f82d088b818dcbde0f0d0cb390295 - React-defaultsnativemodule: a10c0e1ce88b78d8592f16c36baa0b3606688577 - React-domnativemodule: b3dadb6d8e294af4ac3753ef149aae65460477ac - React-Fabric: 3d970b3cb38e9caff5f23e5bd9084524682df818 - React-FabricComponents: 573612e5e9860abc659022d5cc7e1ea8f3353097 - React-FabricImage: 2d08fc8b5cd765296d1c94b8ecb309195cd92359 - React-featureflags: f1aa11419d898f0e37fcb69aafbb998ad29f401e - React-featureflagsnativemodule: ade1ba31d23165a496b79d796ae90b6e09456c7b - React-graphics: ef012d8da4de9f8918245695d94632a3574e8ea5 - React-hermes: 1c67e1a0fc49390e87cdbf94c593ea067d32ce7b - React-idlecallbacksnativemodule: 819e49f01e4ec1c734b79963c6e199456445fed0 - React-ImageManager: 491286f8492d005ddd9c9d26fc6148f718754eb0 - React-jserrorhandler: e127c151810a44eef37e217ce3ea8dc53420aa98 - React-jsi: 59b237396968e53b088eb7bca9c95234ea1450f5 - React-jsiexecutor: a4c1de07d91be19a293ec81d291f9d4ba345cf23 - React-jsinspector: a3a3c0734d8653dfaafd7935350f5f43ff59e60e - React-jsinspectorcdp: f9f23167d4badcd29964aa33d1f60e649bde6f21 - React-jsinspectornetwork: 87f3a2fe7b04888d0941c1c5153607ed4d76c729 - React-jsinspectortracing: a1746d20ea583ddd63235d152016fa2fabbedd74 - React-jsitooling: 13a6ebc6c03a50ca547f62a91035e2ecce9faa4d - React-jsitracing: 2cb26de27216895357b7210c5a3b667d40a2a528 - React-logger: 69cbfaada2b1c8afe1bc9f07321887f8b77e1cb0 - React-Mapbuffer: 0dc40f635b0bbe2bb5233157a5ca55c55f975bee - React-microtasksnativemodule: 1c80957ecd552c51a72ae1fdd7e2c5d48d6e2198 - React-NativeModulesApple: d1dc1e75a9a14f03dc2f92670c9a47b3700b909f - React-oscompat: 3901fd714c34a966ec7bae2a9174c0cbe1ac1cfb - React-perflogger: b0932efaaba483aa13641b9353617c26ea2c124d - React-performancetimeline: 63e45db09d75e583b1936650cceb5b046ee58523 - React-RCTActionSheet: de1d8b7aeb3ae93a251a63f8e8038cc93b9d6ca7 - React-RCTAnimation: 3e795e73197b73e03f5d0f304bba1064778cc2ed - React-RCTAppDelegate: 08268b740164533a5aae8f7c7c92b4699e7c4863 - React-RCTBlob: 010dc14969ca00e517f4787f8cd753a0fd4ae500 - React-RCTFabric: 714bceb61d1f756ed51e1487ba420e149bb92c00 - React-RCTFBReactNativeSpec: 63ae58457f1fac05840b1b5cc647e347d12059cd - React-RCTImage: e111fae23fcd63032a44359e2706557dc36d5179 - React-RCTLinking: 4cb3934aa86071ba4944f05d068b62e407aa30d6 - React-RCTNetwork: 675ad1254b2acf6c8ec8c458ca8b272852bbeac1 - React-RCTPushNotification: 69e20f2132e9c6ef4b1f3d259931846d6f557694 - React-RCTRuntime: 7100e6ea948233548900ca58a3165c38e7624f7b - React-RCTSettings: bde52ef71ca7bdd23b4811e3abc8d4b0ecec8856 - React-RCTTest: 9671edc72a8cc2d5ed6bcbdd7203ab5d5b992d06 - React-RCTText: 564f5a51a1dd2916d4e2711acb10d238ff4c605d - React-RCTVibration: daf99169033e893ee17aa8690593cac6626fab81 - React-rendererconsistency: afa3b7b2f1e5c890e782de21c7f99f190953a2c5 - React-renderercss: ebafade0a3898cd029adbb08fea725c56bf6231c - React-rendererdebug: 6953132835c928321f2cefb866dd0b66b5cdd1b1 - React-rncore: 06ab92ea476589c10e8f0f57a54617312a2e6c5e - React-RuntimeApple: ea3a775f149d886455320498fd25bb207b827cde - React-RuntimeCore: 562bffbcfc958d9fa5c91f50ed642713165c51fa - React-runtimeexecutor: 09cce6fc74b13861ec60fdfd91066a393812fde5 - React-RuntimeHermes: 8609744a966766484b0615955b783d3419157c6b - React-runtimescheduler: 2251e2735d02b45f01b1116e8e5bfe0c9bc755df - React-timing: 3603ea1f09bcf7dd97cf62604218f7b471b90942 - React-utils: e2117130776cd778c123a31fcc0c7270b4f87f66 - ReactAppDependencyProvider: 7fa8930678f4d59ea5c58e22ba8bf73039b257fb + RCTRequired: a00614e2da5344c2cda3d287050b6cee00e21dc6 + RCTTypeSafety: 459a16418c6b413060d35434ba3e83f5b0bd2651 + React: 170a01a19ba2525ab7f11243e2df6b19bf268093 + React-callinvoker: f08f425e4043cd1998a158b6e39a6aed1fd1d718 + React-Core: 798334ba9a8a5a97e84ab56b5565d6ed5ac09712 + React-CoreModules: 25e5ff9b077e8a3780672a9eae5197e54ce367e1 + React-cxxreact: 8a5de0fe0933c56fdf4c3548902d9525ea73322b + React-debug: 195df38487d3f48a7af04deddeb4a5c6d4440416 + React-defaultsnativemodule: 47959b704240e39c6b401d3e3fe1da114b271ac6 + React-domnativemodule: b6dd0c3be3e4514052f68d0b5a94a8d06e0f14fd + React-Fabric: 06175f348d6df210e7545ee513e38fe1709a6d82 + React-FabricComponents: ace73c8cc991f299d9b3aa9556cd5b6e86a8b8e6 + React-FabricImage: ff9dc6afafc92e0da3f3d33d96ec40317bb8ec10 + React-featureflags: 595651ea13c63a9f77f06d9a1973b665b4a28b7e + React-featureflagsnativemodule: f5f69151bc4c2945003fc502ebaecee7fda02c42 + React-graphics: 38cc9ba3336bd50960e6052648374f3591abc7a6 + React-hermes: 34666bbd8d6b585e290f000d4d31c2182ece8940 + React-idlecallbacksnativemodule: b66d99ffb2ff765e1bd952b6bc6bf4ba3d5204d3 + React-ImageManager: a6833445e17879933378b7c0ba45ee42115c14bc + React-jserrorhandler: bec134a192c50338193544404d45df24fb8a19ca + React-jsi: 4ad77650fb0ca4229569eb2532db7a87e3d12662 + React-jsiexecutor: 569425f7cd2c3e005a17e5211843e541c11d6916 + React-jsinspector: 885e8180e898f07e4d7df29e2681a89e69d736d3 + React-jsinspectorcdp: 5fb266e5f23d3a2819ba848e9d4d0b6b00f95934 + React-jsinspectornetwork: 1655a81f3fe14789df41e063bd56dd130cc3562a + React-jsinspectortracing: 80e9418ac67630c76f15ef06534087037a822330 + React-jsitooling: 0c28fbc10441f8b63f4c6bf443cb36416500ce2b + React-jsitracing: ce443686f52538d1033ce7db1e7d643e866262f0 + React-logger: 116c3ae5a9906671d157aa00882a5ee75a5a7ebc + React-Mapbuffer: fc937cfa41140d7724c559c3d16c50dd725361c8 + React-microtasksnativemodule: dd4dfd6306d8b42f5dab9ecb3bf04124e979a3da + React-NativeModulesApple: d3aec3f4d3cb80507777e1feeba3bdc70f9504a0 + React-oscompat: 7133e0e945cda067ae36b22502df663d73002864 + React-perflogger: ada3cdf3dfc8b7cd1fabe3c91b672e23981611ab + React-performancetimeline: e7d5849d89ee39557dcd56dfb6e7b0d49003d925 + React-RCTActionSheet: 1bf8cc8086ad1c15da3407dfb7bc9dd94dc7595d + React-RCTAnimation: 263593e66c89bf810604b1ace15dfa382a1ca2df + React-RCTAppDelegate: 3d35d7226338009b22d1cf9621eaa827acb8fd1d + React-RCTBlob: 7b76230c53fe87d305eeeb250b0aae031bb6cbae + React-RCTFabric: a43fc393b6e505fd60a7fea43edbdcf609f33bf0 + React-RCTFBReactNativeSpec: 503491a0584dc29f03ef9f8ed366794604cd59ef + React-RCTImage: de404b6b0ebe53976a97e3a0dee819c83e12977b + React-RCTLinking: 06742cfad41c506091403a414370743a4ed75af3 + React-RCTNetwork: b4577eec0092c16d8996e415e4cac7a372d6d362 + React-RCTPushNotification: ea11178d499696516e0ff9ae335edbe99b06f94b + React-RCTRuntime: 07b41aed797e8d950ada851c6363ecf931335663 + React-RCTSettings: d3c2dd305ec81f7faf42762ec598d57f07fd43be + React-RCTTest: 2db46eda60bc2228cb67622a580e8e86b00088d9 + React-RCTText: e416825b80c530647040ef91d23ffd35ccc87981 + React-RCTVibration: 1837a27fc16eeffc9509779c3334fde54c012bcc + React-rendererconsistency: 777c894edc43dde01499189917ac54ee76ae6a6a + React-renderercss: a9cb6ba7f49a80dc4b4f7008bae1590d12f27049 + React-rendererdebug: fea8bde927403a198742b2d940a5f1cd8230c0b4 + React-rncore: 4a81ce7b8e47448973a6b29c765b07e01715921e + React-RuntimeApple: 97755a0b9f6adff1e1911ef4894cb0c5a9e40c77 + React-RuntimeCore: 6854e513a18b7b8980732f561679de6cab1b5b4d + React-runtimeexecutor: fb2d342a477bb13f7128cceb711ee8311edce0c0 + React-RuntimeHermes: 90f09fae56f0b1f458927beb171177a157334fe6 + React-runtimescheduler: 0b50423a4c40db7d1d0c3cc6893b407bf7fb946c + React-timing: 9d49179631e5e3c759e6e82d4c613c73da80a144 + React-utils: 3ea3fa757fec88afb26db14889fb4e7e8b5ca134 + ReactAppDependencyProvider: 68f2d2cefd6c9b9f2865246be2bfe86ebd49238d ReactCodegen: 0c8d830ce35b1b48f8b674b0d00e532abc448470 - ReactCommon: 621bc6d58e5f902e35e9f3452092aaab7fcd025f - ReactCommon-Samples: 25ccde761335cc3fca1aa2adf670625823c98f6e + ReactCommon: a53973ab35d399560ace331ec9e2b26db0592cec + ReactCommon-Samples: 3dd174c775b04ab7d59a1b3c1a832e04377c9538 ScreenshotManager: 8687f6358b007230590842b03505606e905c3ce9 SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748 - Yoga: a99949337fd8434aedb236685499ef43362c7c18 + Yoga: 59290f2ce3fc5c34797a21244288cad99b357b63 PODFILE CHECKSUM: 8591f96a513620a2a83a0b9a125ad3fa32ea1369 -COCOAPODS: 1.15.2 +COCOAPODS: 1.16.2