react-native 0.83.0-nightly-20250908-02e3a999e → 0.83.0-nightly-20250909-e7ce4ff0b

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/Libraries/AppDelegate/RCTAppDelegate.h +0 -2
  2. package/Libraries/AppDelegate/RCTAppDelegate.mm +1 -0
  3. package/Libraries/BatchedBridge/BatchedBridge.js +1 -0
  4. package/Libraries/BatchedBridge/MessageQueue.js +1 -0
  5. package/Libraries/Core/ReactNativeVersion.js +1 -1
  6. package/Libraries/Core/Timers/JSTimers.js +1 -0
  7. package/Libraries/Core/Timers/NativeTiming.js +1 -0
  8. package/Libraries/Core/Timers/immediateShim.js +1 -0
  9. package/Libraries/Network/RCTInspectorNetworkReporter.mm +2 -2
  10. package/Libraries/Renderer/shims/ReactNativeTypes.js +2 -1
  11. package/README.md +5 -2
  12. package/React/Base/RCTVersion.m +1 -1
  13. package/React/React-RCTFabric.podspec +1 -1
  14. package/ReactAndroid/gradle.properties +1 -1
  15. package/ReactAndroid/hermes-engine/build.gradle.kts +1 -1
  16. package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.kt +1 -1
  17. package/ReactAndroid/src/main/jni/CMakeLists.txt +3 -0
  18. package/ReactAndroid/src/main/jni/react/devsupport/CMakeLists.txt +1 -1
  19. package/ReactAndroid/src/main/jni/react/devsupport/JInspectorNetworkReporter.cpp +1 -1
  20. package/ReactAndroid/src/main/jni/react/hermes/reactexecutor/CMakeLists.txt +1 -1
  21. package/ReactAndroid/src/main/jni/react/runtime/hermes/jni/CMakeLists.txt +1 -1
  22. package/ReactAndroid/src/main/jni/react/runtime/jni/CMakeLists.txt +1 -1
  23. package/ReactCommon/cxxreact/ReactNativeVersion.h +1 -1
  24. package/ReactCommon/hermes/executor/CMakeLists.txt +1 -1
  25. package/ReactCommon/hermes/inspector-modern/CMakeLists.txt +1 -1
  26. package/ReactCommon/jsinspector-modern/NetworkIOAgent.cpp +8 -8
  27. package/ReactCommon/jsinspector-modern/network/CMakeLists.txt +1 -3
  28. package/ReactCommon/jsinspector-modern/network/CdpNetwork.cpp +7 -16
  29. package/ReactCommon/jsinspector-modern/network/CdpNetwork.h +5 -9
  30. package/ReactCommon/jsinspector-modern/network/HttpUtils.cpp +2 -1
  31. package/ReactCommon/jsinspector-modern/network/HttpUtils.h +3 -3
  32. package/ReactCommon/jsinspector-modern/network/NetworkHandler.cpp +209 -0
  33. package/ReactCommon/jsinspector-modern/network/NetworkHandler.h +147 -0
  34. package/ReactCommon/jsinspector-modern/network/React-jsinspectornetwork.podspec +0 -3
  35. package/ReactCommon/react/networking/CMakeLists.txt +21 -0
  36. package/ReactCommon/react/networking/NetworkReporter.cpp +192 -0
  37. package/ReactCommon/{jsinspector-modern/network → react/networking}/NetworkReporter.h +3 -62
  38. package/ReactCommon/{jsinspector-modern/network → react/networking}/NetworkTypes.h +2 -2
  39. package/ReactCommon/react/networking/React-networking.podspec +51 -0
  40. package/ReactCommon/react/runtime/CMakeLists.txt +1 -1
  41. package/ReactCommon/react/runtime/hermes/CMakeLists.txt +1 -1
  42. package/package.json +8 -8
  43. package/scripts/react_native_pods.rb +1 -0
  44. package/sdks/hermesc/osx-bin/hermes +0 -0
  45. package/sdks/hermesc/osx-bin/hermesc +0 -0
  46. package/sdks/hermesc/win64-bin/hermesc.exe +0 -0
  47. package/src/private/specs_DEPRECATED/modules/NativeTiming.js +1 -0
  48. package/types_generated/Libraries/Renderer/shims/ReactNativeTypes.d.ts +2 -1
  49. package/ReactCommon/jsinspector-modern/network/NetworkReporter.cpp +0 -316
@@ -5,8 +5,6 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- #import <React/RCTBridgeDelegate.h>
9
- #import <React/RCTConvert.h>
10
8
  #import <UIKit/UIKit.h>
11
9
  #import "RCTDefaultReactNativeFactoryDelegate.h"
12
10
  #import "RCTReactNativeFactory.h"
@@ -6,6 +6,7 @@
6
6
  */
7
7
 
8
8
  #import "RCTAppDelegate.h"
9
+ #import <React/RCTBridgeDelegate.h>
9
10
  #import <React/RCTLog.h>
10
11
  #import <React/RCTRootView.h>
11
12
  #import <React/RCTSurfacePresenterBridgeAdapter.h>
@@ -6,6 +6,7 @@
6
6
  *
7
7
  * @flow strict
8
8
  * @format
9
+ * @deprecated
9
10
  */
10
11
 
11
12
  'use strict';
@@ -6,6 +6,7 @@
6
6
  *
7
7
  * @flow strict
8
8
  * @format
9
+ * @deprecated
9
10
  */
10
11
 
11
12
  'use strict';
@@ -29,7 +29,7 @@ export default class ReactNativeVersion {
29
29
  static major: number = 0;
30
30
  static minor: number = 83;
31
31
  static patch: number = 0;
32
- static prerelease: string | null = 'nightly-20250908-02e3a999e';
32
+ static prerelease: string | null = 'nightly-20250909-e7ce4ff0b';
33
33
 
34
34
  static getVersionString(): string {
35
35
  return `${this.major}.${this.minor}.${this.patch}${this.prerelease != null ? `-${this.prerelease}` : ''}`;
@@ -6,6 +6,7 @@
6
6
  *
7
7
  * @flow
8
8
  * @format
9
+ * @deprecated
9
10
  */
10
11
 
11
12
  import NativeTiming from './NativeTiming';
@@ -6,6 +6,7 @@
6
6
  *
7
7
  * @flow strict
8
8
  * @format
9
+ * @deprecated
9
10
  */
10
11
 
11
12
  export * from '../../../src/private/specs_DEPRECATED/modules/NativeTiming';
@@ -6,6 +6,7 @@
6
6
  *
7
7
  * @flow
8
8
  * @format
9
+ * @deprecated
9
10
  */
10
11
 
11
12
  'use strict';
@@ -10,9 +10,9 @@
10
10
  #import "RCTNetworkConversions.h"
11
11
 
12
12
  #import <React/RCTLog.h>
13
- #import <jsinspector-modern/network/NetworkReporter.h>
13
+ #import <react/networking/NetworkReporter.h>
14
14
 
15
- using namespace facebook::react::jsinspector_modern;
15
+ using namespace facebook::react;
16
16
 
17
17
  #ifdef REACT_NATIVE_DEBUGGER_ENABLED
18
18
  namespace {
@@ -7,7 +7,7 @@
7
7
  * @noformat
8
8
  * @nolint
9
9
  * @flow strict
10
- * @generated SignedSource<<deb7924d11c790f99448a1c2f0edddb9>>
10
+ * @generated SignedSource<<c0e57723772ea5f1aa8c3c897ac3c216>>
11
11
  */
12
12
 
13
13
  import type {
@@ -135,6 +135,7 @@ export type RenderRootOptions = {
135
135
  error: mixed,
136
136
  errorInfo: {+componentStack?: ?string},
137
137
  ) => void,
138
+ onDefaultTransitionIndicator?: () => void | (() => void),
138
139
  };
139
140
 
140
141
  /**
package/README.md CHANGED
@@ -17,10 +17,13 @@
17
17
  <img src="https://img.shields.io/npm/v/react-native?color=brightgreen&label=npm%20package" alt="Current npm package version." />
18
18
  </a>
19
19
  <a href="https://reactnative.dev/docs/contributing">
20
- <img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg" alt="PRs welcome!" />
20
+ <img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg" alt="PRs are welcome!" />
21
21
  </a>
22
22
  <a href="https://twitter.com/intent/follow?screen_name=reactnative">
23
- <img src="https://img.shields.io/twitter/follow/reactnative.svg?label=Follow%20@reactnative" alt="Follow @reactnative" />
23
+ <img src="https://img.shields.io/twitter/follow/reactnative.svg?label=Follow%20@reactnative" alt="Follow @reactnative on X" />
24
+ </a>
25
+ <a href="https://bsky.app/profile/reactnative.dev">
26
+ <img src="https://img.shields.io/badge/Bluesky-0285FF?logo=bluesky&logoColor=fff" alt="Follow @reactnative.dev on Bluesky" />
24
27
  </a>
25
28
  </p>
26
29
 
@@ -24,7 +24,7 @@ NSDictionary* RCTGetReactNativeVersion(void)
24
24
  RCTVersionMajor: @(0),
25
25
  RCTVersionMinor: @(83),
26
26
  RCTVersionPatch: @(0),
27
- RCTVersionPrerelease: @"nightly-20250908-02e3a999e",
27
+ RCTVersionPrerelease: @"nightly-20250909-e7ce4ff0b",
28
28
  };
29
29
  });
30
30
  return __rnVersion;
@@ -91,9 +91,9 @@ Pod::Spec.new do |s|
91
91
  add_dependency(s, "React-RCTAnimation", :framework_name => 'RCTAnimation')
92
92
  add_dependency(s, "React-jsinspector", :framework_name => 'jsinspector_modern')
93
93
  add_dependency(s, "React-jsinspectorcdp", :framework_name => 'jsinspector_moderncdp')
94
- add_dependency(s, "React-jsinspectornetwork", :framework_name => 'jsinspector_modernnetwork')
95
94
  add_dependency(s, "React-jsinspectortracing", :framework_name => 'jsinspector_moderntracing')
96
95
  add_dependency(s, "React-performancecdpmetrics", :framework_name => 'React_performancecdpmetrics')
96
+ add_dependency(s, "React-networking", :framework_name => 'React_networking')
97
97
  add_dependency(s, "React-renderercss")
98
98
  add_dependency(s, "React-RCTFBReactNativeSpec")
99
99
 
@@ -1,4 +1,4 @@
1
- VERSION_NAME=0.83.0-nightly-20250908-02e3a999e
1
+ VERSION_NAME=0.83.0-nightly-20250909-e7ce4ff0b
2
2
  HERMES_VERSION_NAME=1000.0.0
3
3
  react.internal.publishingGroup=com.facebook.react
4
4
  react.internal.hermesPublishingGroup=com.facebook.hermes
@@ -88,7 +88,7 @@ val hermesVersionProvider: Provider<String> =
88
88
  val hermesVersionFile =
89
89
  File(
90
90
  reactNativeRootDir,
91
- if (hermesV1Enabled) "sdks/.hermesv1version" else "\"sdks/.hermesversion\"",
91
+ if (hermesV1Enabled) "sdks/.hermesv1version" else "sdks/.hermesversion",
92
92
  )
93
93
 
94
94
  if (hermesVersionFile.exists()) {
@@ -15,6 +15,6 @@ public object ReactNativeVersion {
15
15
  "major" to 0,
16
16
  "minor" to 83,
17
17
  "patch" to 0,
18
- "prerelease" to "nightly-20250908-02e3a999e"
18
+ "prerelease" to "nightly-20250909-e7ce4ff0b"
19
19
  )
20
20
  }
@@ -124,6 +124,7 @@ add_react_common_subdir(react/nativemodule/dom)
124
124
  add_react_common_subdir(react/nativemodule/featureflags)
125
125
  add_react_common_subdir(react/nativemodule/microtasks)
126
126
  add_react_common_subdir(react/nativemodule/idlecallbacks)
127
+ add_react_common_subdir(react/networking)
127
128
  add_react_common_subdir(jserrorhandler)
128
129
  add_react_common_subdir(react/runtime)
129
130
  add_react_common_subdir(react/runtime/hermes)
@@ -190,6 +191,7 @@ add_library(reactnative
190
191
  $<TARGET_OBJECTS:react_nativemodule_featureflags>
191
192
  $<TARGET_OBJECTS:react_nativemodule_idlecallbacks>
192
193
  $<TARGET_OBJECTS:react_nativemodule_microtasks>
194
+ $<TARGET_OBJECTS:react_networking>
193
195
  $<TARGET_OBJECTS:react_newarchdefaults>
194
196
  $<TARGET_OBJECTS:react_performance_cdpmetrics>
195
197
  $<TARGET_OBJECTS:react_performance_timeline>
@@ -279,6 +281,7 @@ target_include_directories(reactnative
279
281
  $<TARGET_PROPERTY:react_nativemodule_featureflags,INTERFACE_INCLUDE_DIRECTORIES>
280
282
  $<TARGET_PROPERTY:react_nativemodule_idlecallbacks,INTERFACE_INCLUDE_DIRECTORIES>
281
283
  $<TARGET_PROPERTY:react_nativemodule_microtasks,INTERFACE_INCLUDE_DIRECTORIES>
284
+ $<TARGET_PROPERTY:react_networking,INTERFACE_INCLUDE_DIRECTORIES>
282
285
  $<TARGET_PROPERTY:react_newarchdefaults,INTERFACE_INCLUDE_DIRECTORIES>
283
286
  $<TARGET_PROPERTY:react_performance_cdpmetrics,INTERFACE_INCLUDE_DIRECTORIES>
284
287
  $<TARGET_PROPERTY:react_performance_timeline,INTERFACE_INCLUDE_DIRECTORIES>
@@ -20,6 +20,6 @@ target_include_directories(react_devsupportjni PUBLIC .)
20
20
  target_link_libraries(react_devsupportjni
21
21
  fbjni
22
22
  jsinspector
23
- jsinspector_network)
23
+ react_networking)
24
24
 
25
25
  target_compile_reactnative_options(react_devsupportjni PRIVATE)
@@ -7,7 +7,7 @@
7
7
 
8
8
  #include "JInspectorNetworkReporter.h"
9
9
 
10
- #include <jsinspector-modern/network/NetworkReporter.h>
10
+ #include <react/networking/NetworkReporter.h>
11
11
 
12
12
  #include <cstddef>
13
13
  #include <string>
@@ -28,7 +28,7 @@ target_compile_reactnative_options(hermes_executor PRIVATE)
28
28
  if(${CMAKE_BUILD_TYPE} MATCHES Debug OR REACT_NATIVE_DEBUG_OPTIMIZED)
29
29
  target_compile_options(hermes_executor PRIVATE -DHERMES_ENABLE_DEBUGGER=1)
30
30
 
31
- if (DEFINED HERMES_V1_ENABLED)
31
+ if (HERMES_V1_ENABLED)
32
32
  target_compile_options(hermes_executor PRIVATE -DHERMES_V1_ENABLED=1)
33
33
  endif()
34
34
  endif()
@@ -30,7 +30,7 @@ target_compile_reactnative_options(hermesinstancejni PRIVATE)
30
30
  if(${CMAKE_BUILD_TYPE} MATCHES Debug OR REACT_NATIVE_DEBUG_OPTIMIZED)
31
31
  target_compile_options(hermesinstancejni PRIVATE -DHERMES_ENABLE_DEBUGGER=1)
32
32
 
33
- if (DEFINED HERMES_V1_ENABLED)
33
+ if (HERMES_V1_ENABLED)
34
34
  target_compile_options(hermesinstancejni PRIVATE -DHERMES_V1_ENABLED=1)
35
35
  endif()
36
36
  endif ()
@@ -20,7 +20,7 @@ target_compile_reactnative_options(rninstance PRIVATE)
20
20
  if(${CMAKE_BUILD_TYPE} MATCHES Debug OR REACT_NATIVE_DEBUG_OPTIMIZED)
21
21
  target_compile_options(rninstance PRIVATE -DHERMES_ENABLE_DEBUGGER=1)
22
22
 
23
- if (DEFINED HERMES_V1_ENABLED)
23
+ if (HERMES_V1_ENABLED)
24
24
  target_compile_options(rninstance PRIVATE -DHERMES_V1_ENABLED=1)
25
25
  endif()
26
26
  endif ()
@@ -22,7 +22,7 @@ constexpr struct {
22
22
  int32_t Major = 0;
23
23
  int32_t Minor = 83;
24
24
  int32_t Patch = 0;
25
- std::string_view Prerelease = "nightly-20250908-02e3a999e";
25
+ std::string_view Prerelease = "nightly-20250909-e7ce4ff0b";
26
26
  } ReactNativeVersion;
27
27
 
28
28
  } // namespace facebook::react
@@ -33,7 +33,7 @@ if(${CMAKE_BUILD_TYPE} MATCHES Debug OR REACT_NATIVE_DEBUG_OPTIMIZED)
33
33
  -DHERMES_ENABLE_DEBUGGER=1
34
34
  )
35
35
 
36
- if (DEFINED HERMES_V1_ENABLED)
36
+ if (HERMES_V1_ENABLED)
37
37
  target_compile_options(hermes_executor_common PRIVATE -DHERMES_V1_ENABLED=1)
38
38
  endif()
39
39
  else()
@@ -24,7 +24,7 @@ if(${CMAKE_BUILD_TYPE} MATCHES Debug OR REACT_NATIVE_DEBUG_OPTIMIZED)
24
24
  -DHERMES_ENABLE_DEBUGGER=1
25
25
  )
26
26
 
27
- if (DEFINED HERMES_V1_ENABLED)
27
+ if (HERMES_V1_ENABLED)
28
28
  target_compile_options(hermes_inspector_modern PRIVATE -DHERMES_V1_ENABLED=1)
29
29
  endif()
30
30
  endif()
@@ -11,7 +11,7 @@
11
11
  #include "Base64.h"
12
12
  #include "Utf8.h"
13
13
 
14
- #include <jsinspector-modern/network/NetworkReporter.h>
14
+ #include <jsinspector-modern/network/NetworkHandler.h>
15
15
 
16
16
  #include <sstream>
17
17
  #include <tuple>
@@ -272,19 +272,19 @@ bool NetworkIOAgent::handleRequest(
272
272
  }
273
273
 
274
274
  if (InspectorFlags::getInstance().getNetworkInspectionEnabled()) {
275
- auto& networkReporter = NetworkReporter::getInstance();
275
+ auto& networkHandler = NetworkHandler::getInstance();
276
276
 
277
277
  // @cdp Network.enable support is experimental.
278
278
  if (req.method == "Network.enable") {
279
- networkReporter.setFrontendChannel(frontendChannel_);
280
- networkReporter.enableDebugging();
279
+ networkHandler.setFrontendChannel(frontendChannel_);
280
+ networkHandler.enable();
281
281
  frontendChannel_(cdp::jsonResult(req.id));
282
282
  return true;
283
283
  }
284
284
 
285
285
  // @cdp Network.disable support is experimental.
286
286
  if (req.method == "Network.disable") {
287
- networkReporter.disableDebugging();
287
+ networkHandler.disable();
288
288
  frontendChannel_(cdp::jsonResult(req.id));
289
289
  return true;
290
290
  }
@@ -497,9 +497,9 @@ void NetworkIOAgent::handleGetResponseBody(const cdp::PreparsedRequest& req) {
497
497
  return;
498
498
  }
499
499
 
500
- auto& networkReporter = NetworkReporter::getInstance();
500
+ auto& networkHandler = NetworkHandler::getInstance();
501
501
 
502
- if (!networkReporter.isDebuggingEnabled()) {
502
+ if (!networkHandler.isEnabled()) {
503
503
  frontendChannel_(cdp::jsonError(
504
504
  requestId,
505
505
  cdp::ErrorCode::InvalidRequest,
@@ -508,7 +508,7 @@ void NetworkIOAgent::handleGetResponseBody(const cdp::PreparsedRequest& req) {
508
508
  }
509
509
 
510
510
  auto storedResponse =
511
- networkReporter.getResponseBody(req.params.at("requestId").asString());
511
+ networkHandler.getResponseBody(req.params.at("requestId").asString());
512
512
 
513
513
  if (!storedResponse) {
514
514
  frontendChannel_(cdp::jsonError(
@@ -24,6 +24,4 @@ target_include_directories(jsinspector_network PUBLIC ${REACT_COMMON_DIR})
24
24
  target_link_libraries(jsinspector_network
25
25
  folly_runtime
26
26
  glog
27
- jsinspector_cdp
28
- react_performance_timeline
29
- react_timing)
27
+ jsinspector_cdp)
@@ -27,15 +27,6 @@ folly::dynamic headersToDynamic(const std::optional<Headers>& headers) {
27
27
 
28
28
  } // namespace
29
29
 
30
- /* static */ Request Request::fromInputParams(const RequestInfo& requestInfo) {
31
- return {
32
- .url = requestInfo.url,
33
- .method = requestInfo.httpMethod,
34
- .headers = requestInfo.headers,
35
- .postData = requestInfo.httpBody,
36
- };
37
- }
38
-
39
30
  folly::dynamic Request::toDynamic() const {
40
31
  folly::dynamic result = folly::dynamic::object;
41
32
 
@@ -48,16 +39,16 @@ folly::dynamic Request::toDynamic() const {
48
39
  }
49
40
 
50
41
  /* static */ Response Response::fromInputParams(
51
- const ResponseInfo& responseInfo,
42
+ const std::string& url,
43
+ uint16_t status,
44
+ const std::optional<Headers>& headers,
52
45
  int encodedDataLength) {
53
- auto headers = responseInfo.headers.value_or(Headers());
54
-
55
46
  return {
56
- .url = responseInfo.url,
57
- .status = responseInfo.statusCode,
58
- .statusText = httpReasonPhrase(responseInfo.statusCode),
47
+ .url = url,
48
+ .status = status,
49
+ .statusText = httpReasonPhrase(status),
59
50
  .headers = headers,
60
- .mimeType = mimeTypeFromHeaders(headers),
51
+ .mimeType = mimeTypeFromHeaders(headers.value_or(Headers())),
61
52
  .encodedDataLength = encodedDataLength,
62
53
  };
63
54
  }
@@ -7,8 +7,6 @@
7
7
 
8
8
  #pragma once
9
9
 
10
- #include "NetworkTypes.h"
11
-
12
10
  #include <folly/dynamic.h>
13
11
 
14
12
  #include <string>
@@ -18,6 +16,8 @@
18
16
 
19
17
  namespace facebook::react::jsinspector_modern::cdp::network {
20
18
 
19
+ using Headers = std::map<std::string, std::string>;
20
+
21
21
  /**
22
22
  * https://chromedevtools.github.io/devtools-protocol/tot/Network/#type-Request
23
23
  */
@@ -27,12 +27,6 @@ struct Request {
27
27
  std::optional<Headers> headers;
28
28
  std::optional<std::string> postData;
29
29
 
30
- /**
31
- * Convenience function to construct a `Request` from the generic
32
- * `RequestInfo` input object.
33
- */
34
- static Request fromInputParams(const RequestInfo& requestInfo);
35
-
36
30
  folly::dynamic toDynamic() const;
37
31
  };
38
32
 
@@ -52,7 +46,9 @@ struct Response {
52
46
  * `ResponseInfo` input object.
53
47
  */
54
48
  static Response fromInputParams(
55
- const ResponseInfo& responseInfo,
49
+ const std::string& url,
50
+ uint16_t status,
51
+ const std::optional<Headers>& headers,
56
52
  int encodedDataLength);
57
53
 
58
54
  folly::dynamic toDynamic() const;
@@ -146,7 +146,8 @@ std::string httpReasonPhrase(uint16_t status) {
146
146
  return "<Unknown>";
147
147
  }
148
148
 
149
- std::string mimeTypeFromHeaders(const Headers& headers) {
149
+ std::string mimeTypeFromHeaders(
150
+ const std::map<std::string, std::string>& headers) {
150
151
  std::string mimeType = "application/octet-stream";
151
152
 
152
153
  for (const auto& [name, value] : headers) {
@@ -7,8 +7,7 @@
7
7
 
8
8
  #pragma once
9
9
 
10
- #include "NetworkTypes.h"
11
-
10
+ #include <map>
12
11
  #include <string>
13
12
 
14
13
  namespace facebook::react::jsinspector_modern {
@@ -22,6 +21,7 @@ std::string httpReasonPhrase(uint16_t status);
22
21
  * Get the MIME type for a response based on the 'Content-Type' header. If
23
22
  * the header is not present, returns 'application/octet-stream'.
24
23
  */
25
- std::string mimeTypeFromHeaders(const Headers& headers);
24
+ std::string mimeTypeFromHeaders(
25
+ const std::map<std::string, std::string>& headers);
26
26
 
27
27
  } // namespace facebook::react::jsinspector_modern
@@ -0,0 +1,209 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ #include "NetworkHandler.h"
9
+
10
+ #include <jsinspector-modern/cdp/CdpJson.h>
11
+
12
+ #include <glog/logging.h>
13
+ #include <chrono>
14
+
15
+ namespace facebook::react::jsinspector_modern {
16
+
17
+ namespace {
18
+
19
+ /**
20
+ * Get the current Unix timestamp in seconds (µs precision, CDP format).
21
+ */
22
+ double getCurrentUnixTimestampSeconds() {
23
+ auto now = std::chrono::system_clock::now().time_since_epoch();
24
+ auto seconds = std::chrono::duration_cast<std::chrono::seconds>(now).count();
25
+ auto micros =
26
+ std::chrono::duration_cast<std::chrono::microseconds>(now).count() %
27
+ 1000000;
28
+
29
+ return static_cast<double>(seconds) +
30
+ (static_cast<double>(micros) / 1000000.0);
31
+ }
32
+
33
+ } // namespace
34
+
35
+ NetworkHandler& NetworkHandler::getInstance() {
36
+ static NetworkHandler instance;
37
+ return instance;
38
+ }
39
+
40
+ void NetworkHandler::setFrontendChannel(FrontendChannel frontendChannel) {
41
+ frontendChannel_ = std::move(frontendChannel);
42
+ }
43
+
44
+ bool NetworkHandler::enable() {
45
+ if (enabled_.load(std::memory_order_acquire)) {
46
+ return false;
47
+ }
48
+
49
+ enabled_.store(true, std::memory_order_release);
50
+ return true;
51
+ }
52
+
53
+ bool NetworkHandler::disable() {
54
+ if (!enabled_.load(std::memory_order_acquire)) {
55
+ return false;
56
+ }
57
+
58
+ enabled_.store(false, std::memory_order_release);
59
+ requestBodyBuffer_.clear();
60
+ return true;
61
+ }
62
+
63
+ void NetworkHandler::onRequestWillBeSent(
64
+ const std::string& requestId,
65
+ const cdp::network::Request& request,
66
+ const std::optional<cdp::network::Response>& redirectResponse) {
67
+ if (!isEnabledNoSync()) {
68
+ return;
69
+ }
70
+
71
+ double timestamp = getCurrentUnixTimestampSeconds();
72
+ auto params = cdp::network::RequestWillBeSentParams{
73
+ .requestId = requestId,
74
+ .loaderId = "",
75
+ .documentURL = "mobile",
76
+ .request = request,
77
+ // NOTE: Both timestamp and wallTime use the same unit, however wallTime
78
+ // is relative to an "arbitrary epoch". In our implementation, use the
79
+ // Unix epoch for both.
80
+ .timestamp = timestamp,
81
+ .wallTime = timestamp,
82
+ .initiator = folly::dynamic::object("type", "script"),
83
+ .redirectHasExtraInfo = redirectResponse.has_value(),
84
+ .redirectResponse = redirectResponse,
85
+ };
86
+
87
+ frontendChannel_(
88
+ cdp::jsonNotification("Network.requestWillBeSent", params.toDynamic()));
89
+ }
90
+
91
+ void NetworkHandler::onRequestWillBeSentExtraInfo(
92
+ const std::string& requestId,
93
+ const Headers& headers) {
94
+ if (!isEnabledNoSync()) {
95
+ return;
96
+ }
97
+
98
+ auto params = cdp::network::RequestWillBeSentExtraInfoParams{
99
+ .requestId = requestId,
100
+ .headers = headers,
101
+ .connectTiming = {.requestTime = getCurrentUnixTimestampSeconds()},
102
+ };
103
+
104
+ frontendChannel_(cdp::jsonNotification(
105
+ "Network.requestWillBeSentExtraInfo", params.toDynamic()));
106
+ }
107
+
108
+ void NetworkHandler::onResponseReceived(
109
+ const std::string& requestId,
110
+ const cdp::network::Response& response) {
111
+ if (!isEnabledNoSync()) {
112
+ return;
113
+ }
114
+
115
+ auto resourceType = cdp::network::resourceTypeFromMimeType(response.mimeType);
116
+ resourceTypeMap_.emplace(requestId, resourceType);
117
+
118
+ auto params = cdp::network::ResponseReceivedParams{
119
+ .requestId = requestId,
120
+ .loaderId = "",
121
+ .timestamp = getCurrentUnixTimestampSeconds(),
122
+ .type = resourceType,
123
+ .response = response,
124
+ .hasExtraInfo = false,
125
+ };
126
+
127
+ frontendChannel_(
128
+ cdp::jsonNotification("Network.responseReceived", params.toDynamic()));
129
+ }
130
+
131
+ void NetworkHandler::onDataReceived(
132
+ const std::string& requestId,
133
+ int dataLength,
134
+ int encodedDataLength) {
135
+ if (!isEnabledNoSync()) {
136
+ return;
137
+ }
138
+
139
+ auto params = cdp::network::DataReceivedParams{
140
+ .requestId = requestId,
141
+ .timestamp = getCurrentUnixTimestampSeconds(),
142
+ .dataLength = dataLength,
143
+ .encodedDataLength = encodedDataLength,
144
+ };
145
+
146
+ frontendChannel_(
147
+ cdp::jsonNotification("Network.dataReceived", params.toDynamic()));
148
+ }
149
+
150
+ void NetworkHandler::onLoadingFinished(
151
+ const std::string& requestId,
152
+ int encodedDataLength) {
153
+ if (!isEnabledNoSync()) {
154
+ return;
155
+ }
156
+
157
+ auto params = cdp::network::LoadingFinishedParams{
158
+ .requestId = requestId,
159
+ .timestamp = getCurrentUnixTimestampSeconds(),
160
+ .encodedDataLength = encodedDataLength,
161
+ };
162
+
163
+ frontendChannel_(
164
+ cdp::jsonNotification("Network.loadingFinished", params.toDynamic()));
165
+ }
166
+
167
+ void NetworkHandler::onLoadingFailed(
168
+ const std::string& requestId,
169
+ bool cancelled) const {
170
+ if (!isEnabledNoSync()) {
171
+ return;
172
+ }
173
+
174
+ auto params = cdp::network::LoadingFailedParams{
175
+ .requestId = requestId,
176
+ .timestamp = getCurrentUnixTimestampSeconds(),
177
+ .type = resourceTypeMap_.find(requestId) != resourceTypeMap_.end()
178
+ ? resourceTypeMap_.at(requestId)
179
+ : "Other",
180
+ .errorText = cancelled ? "net::ERR_ABORTED" : "net::ERR_FAILED",
181
+ .canceled = cancelled,
182
+ };
183
+
184
+ frontendChannel_(
185
+ cdp::jsonNotification("Network.loadingFailed", params.toDynamic()));
186
+ }
187
+
188
+ void NetworkHandler::storeResponseBody(
189
+ const std::string& requestId,
190
+ std::string_view body,
191
+ bool base64Encoded) {
192
+ std::lock_guard<std::mutex> lock(requestBodyMutex_);
193
+ requestBodyBuffer_.put(requestId, body, base64Encoded);
194
+ }
195
+
196
+ std::optional<std::tuple<std::string, bool>> NetworkHandler::getResponseBody(
197
+ const std::string& requestId) {
198
+ std::lock_guard<std::mutex> lock(requestBodyMutex_);
199
+ auto responseBody = requestBodyBuffer_.get(requestId);
200
+
201
+ if (responseBody == nullptr) {
202
+ return std::nullopt;
203
+ }
204
+
205
+ return std::make_optional<std::tuple<std::string, bool>>(
206
+ responseBody->data, responseBody->base64Encoded);
207
+ }
208
+
209
+ } // namespace facebook::react::jsinspector_modern