react-native-windows 0.80.0 → 0.80.5

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 (86) hide show
  1. package/Directory.Build.props +1 -1
  2. package/Microsoft.ReactNative/Fabric/Composition/DebuggerUIIsland.cpp +169 -0
  3. package/Microsoft.ReactNative/Fabric/Composition/DebuggerUIIsland.h +42 -0
  4. package/Microsoft.ReactNative/Fabric/Composition/DebuggingOverlayComponentView.cpp +1 -1
  5. package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp +60 -33
  6. package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.cpp +68 -1
  7. package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.h +9 -0
  8. package/Microsoft.ReactNative/Fabric/Composition/TextDrawing.cpp +5 -37
  9. package/Microsoft.ReactNative/Fabric/Composition/UriImageManager.cpp +5 -3
  10. package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.cpp +6 -1
  11. package/Microsoft.ReactNative/Fabric/WindowsImageManager.cpp +14 -1
  12. package/Microsoft.ReactNative/Fabric/platform/react/renderer/graphics/PlatformColorUtils.cpp +0 -17
  13. package/Microsoft.ReactNative/Fabric/platform/react/renderer/graphics/PlatformColorUtils.h +0 -3
  14. package/Microsoft.ReactNative/Fabric/platform/react/threading/TaskDispatchThread.cpp +75 -24
  15. package/Microsoft.ReactNative/Fabric/platform/react/threading/TaskDispatchThread.h +4 -25
  16. package/Microsoft.ReactNative/JsiApi.cpp +1 -1
  17. package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +1 -0
  18. package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj.filters +3 -0
  19. package/Microsoft.ReactNative/ReactHost/DebuggerNotifications.h +54 -0
  20. package/Microsoft.ReactNative/ReactHost/React.h +11 -4
  21. package/Microsoft.ReactNative/ReactHost/ReactHost.cpp +195 -29
  22. package/Microsoft.ReactNative/ReactHost/ReactHost.h +22 -4
  23. package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +24 -5
  24. package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.h +1 -1
  25. package/Microsoft.ReactNative/ReactRootView.cpp +108 -0
  26. package/Microsoft.ReactNative/ReactRootView.h +6 -0
  27. package/Microsoft.ReactNative/Views/DevMenu.cpp +1 -1
  28. package/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems +1 -1
  29. package/PropertySheets/Generated/PackageVersion.g.props +3 -3
  30. package/PropertySheets/JSEngine.props +1 -1
  31. package/PropertySheets/React.Cpp.props +2 -2
  32. package/ReactCommon/ReactCommon.vcxproj +18 -1
  33. package/ReactCommon/TEMP_UntilReactCommonUpdate/cxxreact/NativeToJsBridge.cpp +1 -1
  34. package/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/test/testlib.cpp +4 -4
  35. package/ReactCommon/TEMP_UntilReactCommonUpdate/jsinspector-modern/NetworkIOAgent.cpp +23 -9
  36. package/ReactCommon/TEMP_UntilReactCommonUpdate/jsinspector-modern/NetworkIOAgent.h +16 -0
  37. package/ReactCommon/cgmanifest.json +1 -1
  38. package/Scripts/Tfs/Layout-MSRN-Headers.ps1 +2 -0
  39. package/Shared/DevServerHelper.h +13 -3
  40. package/Shared/DevSettings.h +7 -0
  41. package/Shared/DevSupportManager.cpp +79 -20
  42. package/Shared/DevSupportManager.h +7 -19
  43. package/Shared/Hermes/HermesRuntimeAgentDelegate.cpp +99 -0
  44. package/Shared/Hermes/HermesRuntimeAgentDelegate.h +81 -0
  45. package/Shared/Hermes/HermesRuntimeTargetDelegate.cpp +263 -0
  46. package/Shared/Hermes/HermesRuntimeTargetDelegate.h +77 -0
  47. package/Shared/HermesRuntimeHolder.cpp +29 -111
  48. package/Shared/HermesRuntimeHolder.h +214 -32
  49. package/Shared/IDevSupportManager.h +5 -2
  50. package/Shared/Inspector/ReactInspectorPackagerConnectionDelegate.cpp +108 -0
  51. package/Shared/Inspector/ReactInspectorPackagerConnectionDelegate.h +19 -0
  52. package/Shared/Inspector/ReactInspectorThread.h +18 -0
  53. package/Shared/JSI/RuntimeHolder.h +5 -2
  54. package/Shared/OInstance.cpp +44 -27
  55. package/Shared/Shared.vcxitems +27 -17
  56. package/Shared/Shared.vcxitems.filters +33 -15
  57. package/package.json +4 -4
  58. package/Microsoft.ReactNative.Cxx/ApiLoaders/JSRuntimeApi.cpp +0 -79
  59. package/Microsoft.ReactNative.Cxx/ApiLoaders/JSRuntimeApi.h +0 -51
  60. package/Microsoft.ReactNative.Cxx/ApiLoaders/JSRuntimeApi.inc +0 -50
  61. package/Microsoft.ReactNative.Cxx/ApiLoaders/NodeApi.cpp +0 -41
  62. package/Microsoft.ReactNative.Cxx/ApiLoaders/NodeApi.h +0 -127
  63. package/Microsoft.ReactNative.Cxx/ApiLoaders/NodeApi.inc +0 -125
  64. package/Microsoft.ReactNative.Cxx/ApiLoaders/NodeApi_posix.cpp +0 -16
  65. package/Microsoft.ReactNative.Cxx/ApiLoaders/NodeApi_win.cpp +0 -23
  66. package/Microsoft.ReactNative.Cxx/JSI/decorator.h +0 -1054
  67. package/Microsoft.ReactNative.Cxx/JSI/instrumentation.h +0 -145
  68. package/Microsoft.ReactNative.Cxx/JSI/jsi-inl.h +0 -372
  69. package/Microsoft.ReactNative.Cxx/JSI/jsi.cpp +0 -797
  70. package/Microsoft.ReactNative.Cxx/JSI/jsi.h +0 -1799
  71. package/Microsoft.ReactNative.Cxx/JSI/threadsafe.h +0 -79
  72. package/Microsoft.ReactNative.Cxx/NodeApiJsiRuntime.cpp +0 -3531
  73. package/Microsoft.ReactNative.Cxx/NodeApiJsiRuntime.h +0 -38
  74. package/Microsoft.ReactNative.Cxx/node-api/js_native_api.h +0 -614
  75. package/Microsoft.ReactNative.Cxx/node-api/js_native_api_types.h +0 -212
  76. package/Microsoft.ReactNative.Cxx/node-api/js_runtime_api.h +0 -199
  77. package/ReactCommon/TEMP_UntilReactCommonUpdate/cxxreact/JSExecutor.cpp +0 -78
  78. package/ReactCommon/TEMP_UntilReactCommonUpdate/cxxreact/JSExecutor.h +0 -196
  79. package/ReactCommon/TEMP_UntilReactCommonUpdate/jserrorhandler/JsErrorHandler.cpp +0 -429
  80. package/ReactCommon/TEMP_UntilReactCommonUpdate/jsitooling/react/runtime/JSRuntimeFactory.cpp +0 -45
  81. package/ReactCommon/TEMP_UntilReactCommonUpdate/jsitooling/react/runtime/JSRuntimeFactory.h +0 -91
  82. package/ReactCommon/TEMP_UntilReactCommonUpdate/react/runtime/ReactInstance.cpp +0 -670
  83. package/Shared/InspectorPackagerConnection.cpp +0 -232
  84. package/Shared/InspectorPackagerConnection.h +0 -61
  85. /package/Shared/{HermesSamplingProfiler.cpp → Hermes/HermesSamplingProfiler.cpp} +0 -0
  86. /package/Shared/{HermesSamplingProfiler.h → Hermes/HermesSamplingProfiler.h} +0 -0
@@ -76,12 +76,20 @@ class DevServerHelper {
76
76
  const std::string &packagerHost,
77
77
  const uint16_t packagerPort,
78
78
  const std::string &deviceName,
79
- const std::string &packageName) {
79
+ const std::string &packageName,
80
+ const std::string &deviceId) {
80
81
  return string_format(
81
82
  InspectorDeviceUrlFormat,
82
83
  GetDeviceLocalHost(packagerHost, packagerPort).c_str(),
83
84
  deviceName.c_str(),
84
- packageName.c_str());
85
+ packageName.c_str(),
86
+ deviceId.c_str());
87
+ }
88
+
89
+ static std::string
90
+ get_OpenDebuggerUrl(const std::string &packagerHost, const uint16_t packagerPort, const std::string &deviceId) {
91
+ return string_format(
92
+ OpenDebuggerUrlFormat, GetDeviceLocalHost(packagerHost, packagerPort).c_str(), deviceId.c_str());
85
93
  }
86
94
 
87
95
  static constexpr const char DefaultPackagerHost[] = "localhost";
@@ -105,11 +113,13 @@ class DevServerHelper {
105
113
  static constexpr const char PackagerConnectionUrlFormat[] = "ws://%s/message";
106
114
  static constexpr const char PackagerStatusUrlFormat[] = "http://%s/status";
107
115
  static constexpr const char PackagerOpenStackFrameUrlFormat[] = "https://%s/open-stack-frame";
108
- static constexpr const char InspectorDeviceUrlFormat[] = "ws://%s/inspector/device?name=%s&app=%s";
116
+ static constexpr const char InspectorDeviceUrlFormat[] = "ws://%s/inspector/device?name=%s&app=%s&device=%s";
117
+ static constexpr const char OpenDebuggerUrlFormat[] = "http://%s/open-debugger?device=%s";
109
118
 
110
119
  static constexpr const char PackagerOkStatus[] = "packager-status:running";
111
120
  const int LongPollFailureDelayMs = 5000;
112
121
 
122
+ // TODO: [vmoroz] avoid using vaiadic args for the format and move it to a utility class.
113
123
  template <typename... Args>
114
124
  static std::string string_format(const char *format, Args... args) {
115
125
  size_t size = snprintf(nullptr, 0, format, args...) + 1;
@@ -23,6 +23,10 @@ struct RuntimeHolderLazyInit;
23
23
  namespace facebook {
24
24
  namespace react {
25
25
 
26
+ namespace jsinspector_modern {
27
+ class HostTarget;
28
+ } // namespace jsinspector_modern
29
+
26
30
  enum class JSIEngineOverride : int32_t {
27
31
  Default = 0, // No JSI, will use the legacy ExecutorFactory
28
32
  Chakra = 1, // Use the JSIExecutorFactory with ChakraRuntime
@@ -117,6 +121,9 @@ struct DevSettings {
117
121
 
118
122
  // If true, then use only Turbo Modules instead of CxxModules.
119
123
  bool useTurboModulesOnly{false};
124
+
125
+ // The HostTarget instance for Fusebox
126
+ facebook::react::jsinspector_modern::HostTarget *inspectorHostTarget;
120
127
  };
121
128
 
122
129
  } // namespace react
@@ -9,14 +9,19 @@
9
9
  #include <Shared/DevSettings.h>
10
10
 
11
11
  #include <Executors/WebSocketJSExecutor.h>
12
+ #include "Inspector/ReactInspectorPackagerConnectionDelegate.h"
12
13
  #include "PackagerConnection.h"
13
14
 
14
15
  #include "Unicode.h"
15
16
  #include "Utilities.h"
16
17
 
17
18
  #include <Utils/CppWinrtLessExceptions.h>
19
+ #include <jsinspector-modern/InspectorFlags.h>
18
20
  #include <winrt/Windows.Foundation.h>
21
+ #include <winrt/Windows.Security.Cryptography.Core.h>
22
+ #include <winrt/Windows.Security.Cryptography.h>
19
23
  #include <winrt/Windows.Storage.Streams.h>
24
+ #include <winrt/Windows.System.Profile.h>
20
25
  #include <winrt/Windows.Web.Http.Filters.h>
21
26
  #include <winrt/Windows.Web.Http.Headers.h>
22
27
  #include <winrt/Windows.Web.Http.h>
@@ -171,6 +176,49 @@ bool IsIgnorablePollHResult(HRESULT hr) {
171
176
  return hr == WININET_E_INVALID_SERVER_RESPONSE;
172
177
  }
173
178
 
179
+ std::string GetDeviceId(const std::string &packageName) {
180
+ const auto hash = winrt::Windows::Security::Cryptography::Core::HashAlgorithmProvider::OpenAlgorithm(
181
+ winrt::Windows::Security::Cryptography::Core::HashAlgorithmNames::Sha256())
182
+ .CreateHash();
183
+ hash.Append(winrt::Windows::System::Profile::SystemIdentification::GetSystemIdForPublisher().Id());
184
+ winrt::Windows::Storage::Streams::InMemoryRandomAccessStream stream;
185
+ winrt::Windows::Storage::Streams::DataWriter writer;
186
+ // If an app ID is provided, we will allow reconnection to DevTools.
187
+ // Apps must supply a unique app ID to each ReactNativeHost instance settings for this to behave correctly.
188
+ if (!packageName.empty()) {
189
+ const auto packageNameBuffer = winrt::Windows::Security::Cryptography::CryptographicBuffer::ConvertStringToBinary(
190
+ winrt::to_hstring(packageName), winrt::Windows::Security::Cryptography::BinaryStringEncoding::Utf16BE);
191
+ hash.Append(packageNameBuffer);
192
+ } else {
193
+ const auto processId = GetCurrentProcessId();
194
+ std::vector<uint8_t> processIdBytes(
195
+ reinterpret_cast<const uint8_t *>(&processId), reinterpret_cast<const uint8_t *>(&processId + 1));
196
+ winrt::array_view<uint8_t> processIdByteArray(processIdBytes);
197
+ const auto processIdBuffer =
198
+ winrt::Windows::Security::Cryptography::CryptographicBuffer::CreateFromByteArray(processIdByteArray);
199
+ hash.Append(processIdBuffer);
200
+ }
201
+ const auto hashBuffer = hash.GetValueAndReset();
202
+ const auto hashString = winrt::Windows::Security::Cryptography::CryptographicBuffer::EncodeToHexString(hashBuffer);
203
+ return winrt::to_string(hashString);
204
+ }
205
+
206
+ std::string GetPackageName(const std::string &bundleAppId) {
207
+ if (!bundleAppId.empty()) {
208
+ return bundleAppId;
209
+ }
210
+
211
+ std::string packageName{"RNW"};
212
+ wchar_t fullName[PACKAGE_FULL_NAME_MAX_LENGTH]{};
213
+ uint32_t size = ARRAYSIZE(fullName);
214
+ if (SUCCEEDED(GetCurrentPackageFullName(&size, fullName))) {
215
+ // we are in an unpackaged app
216
+ packageName = winrt::to_string(fullName);
217
+ }
218
+
219
+ return packageName;
220
+ }
221
+
174
222
  std::future<winrt::Windows::Web::Http::HttpStatusCode> PollForLiveReload(const std::string &url) {
175
223
  winrt::Windows::Web::Http::HttpClient httpClient;
176
224
  winrt::Windows::Foundation::Uri uri(Microsoft::Common::Unicode::Utf8ToUtf16(url));
@@ -238,37 +286,48 @@ void DevSupportManager::StopPollingLiveReload() {
238
286
  m_cancellation_token = true;
239
287
  }
240
288
 
241
- void DevSupportManager::EnsureHermesInspector(
289
+ // TODO: (vmoroz) Use or delete this function
290
+ void DevSupportManager::OpenDevTools(const std::string &bundleAppId) {
291
+ winrt::Windows::Web::Http::Filters::HttpBaseProtocolFilter filter;
292
+ filter.CacheControl().ReadBehavior(winrt::Windows::Web::Http::Filters::HttpCacheReadBehavior::NoCache);
293
+ winrt::Windows::Web::Http::HttpClient httpClient(filter);
294
+ // TODO: Use currently configured dev server host
295
+ winrt::Windows::Foundation::Uri uri(
296
+ Microsoft::Common::Unicode::Utf8ToUtf16(facebook::react::DevServerHelper::get_OpenDebuggerUrl(
297
+ std::string{DevServerHelper::DefaultPackagerHost},
298
+ DevServerHelper::DefaultPackagerPort,
299
+ GetDeviceId(GetPackageName(bundleAppId)))));
300
+
301
+ winrt::Windows::Web::Http::HttpRequestMessage request(winrt::Windows::Web::Http::HttpMethod::Post(), uri);
302
+ httpClient.SendRequestAsync(request);
303
+ }
304
+
305
+ void DevSupportManager::EnsureInspectorPackagerConnection(
242
306
  [[maybe_unused]] const std::string &packagerHost,
243
- [[maybe_unused]] const uint16_t packagerPort) noexcept {
307
+ [[maybe_unused]] const uint16_t packagerPort,
308
+ [[maybe_unused]] const std::string &bundleAppId) noexcept {
244
309
  static std::once_flag once;
245
- std::call_once(once, [this, &packagerHost, packagerPort]() {
246
- // TODO: should we use the bundleAppId as the app param if available?
247
- std::string packageName("RNW");
248
- wchar_t fullName[PACKAGE_FULL_NAME_MAX_LENGTH]{};
249
- UINT32 size = ARRAYSIZE(fullName);
250
- if (SUCCEEDED(GetCurrentPackageFullName(&size, fullName))) {
251
- // we are in an unpackaged app
252
- packageName = winrt::to_string(fullName);
253
- }
254
-
310
+ std::call_once(once, [this, &packagerHost, packagerPort, &bundleAppId]() {
311
+ std::string packageName = GetPackageName(bundleAppId);
255
312
  std::string deviceName("RNWHost");
256
313
  auto hostNames = winrt::Windows::Networking::Connectivity::NetworkInformation::GetHostNames();
257
314
  if (hostNames && hostNames.First() && hostNames.First().Current()) {
258
315
  deviceName = winrt::to_string(hostNames.First().Current().DisplayName());
259
316
  }
260
317
 
261
- m_inspectorPackagerConnection = std::make_shared<InspectorPackagerConnection>(
262
- facebook::react::DevServerHelper::get_InspectorDeviceUrl(packagerHost, packagerPort, deviceName, packageName),
263
- m_BundleStatusProvider);
264
- m_inspectorPackagerConnection->connectAsync();
318
+ std::string deviceId = GetDeviceId(packageName);
319
+ std::string inspectorUrl = facebook::react::DevServerHelper::get_InspectorDeviceUrl(
320
+ packagerHost, packagerPort, deviceName, packageName, deviceId);
321
+ jsinspector_modern::InspectorFlags &inspectorFlags = jsinspector_modern::InspectorFlags::getInstance();
322
+ m_inspectorPackagerConnection = std::make_unique<jsinspector_modern::InspectorPackagerConnection>(
323
+ inspectorUrl,
324
+ deviceName,
325
+ packageName,
326
+ std::make_unique<Microsoft::ReactNative::ReactInspectorPackagerConnectionDelegate>());
327
+ m_inspectorPackagerConnection->connect();
265
328
  });
266
329
  }
267
330
 
268
- void DevSupportManager::UpdateBundleStatus(bool isLastDownloadSuccess, int64_t updateTimestamp) noexcept {
269
- m_BundleStatusProvider->updateBundleStatus(isLastDownloadSuccess, updateTimestamp);
270
- }
271
-
272
331
  std::pair<std::string, bool> GetJavaScriptFromServer(
273
332
  const std::string &sourceBundleHost,
274
333
  const uint16_t sourceBundlePort,
@@ -14,7 +14,7 @@
14
14
  #include <memory>
15
15
  #include <string>
16
16
 
17
- #include <InspectorPackagerConnection.h>
17
+ #include <jsinspector-modern/InspectorPackagerConnection.h>
18
18
 
19
19
  namespace facebook {
20
20
  namespace react {
@@ -48,29 +48,17 @@ class DevSupportManager final : public facebook::react::IDevSupportManager {
48
48
  const uint16_t sourceBundlePort,
49
49
  std::function<void()> onChangeCallback) override;
50
50
  virtual void StopPollingLiveReload() override;
51
+ virtual void OpenDevTools(const std::string &bundleAppId) override;
51
52
 
52
- virtual void EnsureHermesInspector(const std::string &packagerHost, const uint16_t packagerPort) noexcept override;
53
- virtual void UpdateBundleStatus(bool isLastDownloadSuccess, int64_t updateTimestamp) noexcept override;
53
+ virtual void EnsureInspectorPackagerConnection(
54
+ const std::string &packagerHost,
55
+ const uint16_t packagerPort,
56
+ const std::string &bundleAppId) noexcept override;
54
57
 
55
58
  private:
56
59
  std::atomic_bool m_cancellation_token;
57
60
 
58
- std::shared_ptr<InspectorPackagerConnection> m_inspectorPackagerConnection;
59
-
60
- struct BundleStatusProvider : public InspectorPackagerConnection::IBundleStatusProvider {
61
- virtual InspectorPackagerConnection::BundleStatus getBundleStatus() {
62
- return m_bundleStatus;
63
- }
64
-
65
- void updateBundleStatus(bool isLastDownloadSuccess, int64_t updateTimestamp) {
66
- m_bundleStatus.m_isLastDownloadSuccess = isLastDownloadSuccess;
67
- m_bundleStatus.m_updateTimestamp = updateTimestamp;
68
- }
69
-
70
- private:
71
- InspectorPackagerConnection::BundleStatus m_bundleStatus;
72
- };
73
- std::shared_ptr<BundleStatusProvider> m_BundleStatusProvider = std::make_shared<BundleStatusProvider>();
61
+ std::unique_ptr<facebook::react::jsinspector_modern::InspectorPackagerConnection> m_inspectorPackagerConnection;
74
62
  };
75
63
 
76
64
  } // namespace Microsoft::ReactNative
@@ -0,0 +1,99 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ /*
5
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
6
+ *
7
+ * This source code is licensed under the MIT license found in the
8
+ * LICENSE file in the root directory of this source tree.
9
+ */
10
+
11
+ // This file must match the code in React Native folder:
12
+ // ReactCommon/hermes/inspector-modern/chrome/HermesRuntimeAgentDelegate.cpp
13
+ // Unlike the code in React Native sources, this class delegates calls to Hermes C-based API.
14
+
15
+ #include "HermesRuntimeAgentDelegate.h"
16
+
17
+ #include <jsinspector-modern/ReactCdp.h>
18
+
19
+ using namespace facebook::react::jsinspector_modern;
20
+
21
+ namespace Microsoft::ReactNative {
22
+
23
+ namespace {
24
+
25
+ struct HermesStateWrapper : public RuntimeAgentDelegate::ExportedState {
26
+ explicit HermesStateWrapper(HermesUniqueCdpState &&hermesCdpState) : hermesCdpState_(std::move(hermesCdpState)) {}
27
+
28
+ static HermesUniqueCdpState unwrapDestructively(ExportedState *wrapper) {
29
+ if (!wrapper) {
30
+ return {};
31
+ }
32
+ if (auto *typedWrapper = dynamic_cast<HermesStateWrapper *>(wrapper)) {
33
+ return std::move(typedWrapper->hermesCdpState_);
34
+ }
35
+ return {};
36
+ }
37
+
38
+ private:
39
+ HermesUniqueCdpState hermesCdpState_;
40
+ };
41
+
42
+ } // namespace
43
+
44
+ HermesRuntimeAgentDelegate::HermesRuntimeAgentDelegate(
45
+ FrontendChannel frontendChannel,
46
+ SessionState &sessionState,
47
+ std::unique_ptr<RuntimeAgentDelegate::ExportedState> previouslyExportedState,
48
+ const ExecutionContextDescription &executionContextDescription,
49
+ hermes_runtime runtime,
50
+ HermesRuntimeTargetDelegate &runtimeTargetDelegate,
51
+ facebook::react::RuntimeExecutor runtimeExecutor)
52
+ : hermesCdpAgent_(HermesInspectorApi::createCdpAgent(
53
+ runtimeTargetDelegate.getCdpDebugApi(),
54
+ executionContextDescription.id,
55
+ // Adapt std::function<void(std::function<void(jsi::Runtime& runtime)>&& callback)>
56
+ // to hermes_enqueue_runtime_task_functor
57
+ AsFunctor<hermes_enqueue_runtime_task_functor>(
58
+ [runtimeExecutor = std::move(runtimeExecutor), runtime](hermes_run_runtime_task_functor runtimeTask) {
59
+ // Adapt std::function<void(jsi::Runtime& runtime)> to hermes_runtime_task_functor
60
+ runtimeExecutor(
61
+ [runtime, fn = std::make_shared<FunctorWrapper<hermes_run_runtime_task_functor>>(runtimeTask)](
62
+ facebook::jsi::Runtime &rt) { (*fn)(runtime); });
63
+ }),
64
+ // Adapt void(const char *json_utf8, size_t json_size) to std::function<void(std::string_view)>
65
+ AsFunctor<hermes_enqueue_frontend_message_functor>(
66
+ [frontendChannel = std::move(frontendChannel)](const char *json_utf8, size_t json_size) {
67
+ frontendChannel(std::string_view(json_utf8, json_size));
68
+ }),
69
+ HermesStateWrapper::unwrapDestructively(previouslyExportedState.get()).release())) {
70
+ // Enable domains conditionally based on session state
71
+ // This matches the iOS/Android implementation pattern:
72
+ // Domains are enabled in response to Chrome DevTools sending Runtime.enable/Debugger.enable
73
+ if (sessionState.isRuntimeDomainEnabled) {
74
+ HermesInspectorApi::enableRuntimeDomain(hermesCdpAgent_.get());
75
+ }
76
+ if (sessionState.isDebuggerDomainEnabled) {
77
+ HermesInspectorApi::enableDebuggerDomain(hermesCdpAgent_.get());
78
+ }
79
+ }
80
+
81
+ HermesRuntimeAgentDelegate::~HermesRuntimeAgentDelegate() = default;
82
+
83
+ bool HermesRuntimeAgentDelegate::handleRequest(const cdp::PreparsedRequest &req) {
84
+ if (req.method.starts_with("Log.")) {
85
+ // Since we know Hermes doesn't do anything useful with Log messages,
86
+ // but our containing HostAgent will, bail out early.
87
+ return false;
88
+ }
89
+
90
+ std::string json = req.toJson();
91
+ HermesInspectorApi::handleCommand(hermesCdpAgent_.get(), json.c_str(), json.size());
92
+ return true;
93
+ }
94
+
95
+ std::unique_ptr<RuntimeAgentDelegate::ExportedState> HermesRuntimeAgentDelegate::getExportedState() {
96
+ return std::make_unique<HermesStateWrapper>(HermesInspectorApi::getCdpState(hermesCdpAgent_.get()));
97
+ }
98
+
99
+ } // namespace Microsoft::ReactNative
@@ -0,0 +1,81 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ /*
5
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
6
+ *
7
+ * This source code is licensed under the MIT license found in the
8
+ * LICENSE file in the root directory of this source tree.
9
+ */
10
+
11
+ // This file must match the code in React Native folder:
12
+ // ReactCommon/hermes/inspector-modern/chrome/HermesRuntimeAgentDelegate.h
13
+ // Unlike the code in React Native sources, this class delegates calls to Hermes C-based API.
14
+ // We use different namespace for this class comparing with the RN code.
15
+
16
+ #pragma once
17
+
18
+ #include "HermesRuntimeTargetDelegate.h"
19
+
20
+ #include <ReactCommon/RuntimeExecutor.h>
21
+ #include <jsinspector-modern/ReactCdp.h>
22
+ #include "HermesRuntimeHolder.h"
23
+
24
+ namespace Microsoft::ReactNative {
25
+
26
+ // A RuntimeAgentDelegate that handles requests from the Chrome DevTools
27
+ // Protocol for an instance of Hermes, using the modern CDPAgent API.
28
+ class HermesRuntimeAgentDelegate : public facebook::react::jsinspector_modern::RuntimeAgentDelegate {
29
+ public:
30
+ /**
31
+ * \param frontendChannel A channel used to send responses and events to the
32
+ * frontend.
33
+ * \param sessionState The state of the current CDP session. This will only
34
+ * be accessed on the main thread (during the constructor, in handleRequest,
35
+ * etc).
36
+ * \param previouslyExportedState The exported state from a previous instance
37
+ * of RuntimeAgentDelegate (NOT necessarily HermesRuntimeAgentDelegate).
38
+ * This may be nullptr, and if not nullptr it may be of any concrete type that
39
+ * implements RuntimeAgentDelegate::ExportedState.
40
+ * \param executionContextDescription A description of the execution context
41
+ * represented by this runtime. This is used for disambiguating the
42
+ * source/destination of CDP messages when there are multiple runtimes
43
+ * (concurrently or over the life of a Host).
44
+ * \param hermes_runtime The Hermes runtime that this agent is attached to. The caller
45
+ * is responsible for keeping this object alive for the duration of the
46
+ * \c HermesRuntimeAgentDelegate lifetime.
47
+ * \param runtimeTargetDelegate The \c HermesRuntimeTargetDelegate object
48
+ * object for the passed runtime.
49
+ * \param runtimeExecutor A callback for scheduling work on the JS thread.
50
+ * \c runtimeExecutor may drop scheduled work if the runtime is destroyed
51
+ * first.
52
+ */
53
+ HermesRuntimeAgentDelegate(
54
+ facebook::react::jsinspector_modern::FrontendChannel frontendChannel,
55
+ facebook::react::jsinspector_modern::SessionState &sessionState,
56
+ std::unique_ptr<facebook::react::jsinspector_modern::RuntimeAgentDelegate::ExportedState> previouslyExportedState,
57
+ const facebook::react::jsinspector_modern::ExecutionContextDescription &executionContextDescription,
58
+ hermes_runtime runtime,
59
+ HermesRuntimeTargetDelegate &runtimeTargetDelegate,
60
+ facebook::react::RuntimeExecutor runtimeExecutor);
61
+
62
+ ~HermesRuntimeAgentDelegate() override;
63
+
64
+ public: // RuntimeAgentDelegate implementation
65
+ /**
66
+ * Handle a CDP request. The response will be sent over the provided
67
+ * \c FrontendChannel synchronously or asynchronously.
68
+ * \param req The parsed request.
69
+ * \returns true if this agent has responded, or will respond asynchronously,
70
+ * to the request (with either a success or error message). False if the
71
+ * agent expects another agent to respond to the request instead.
72
+ */
73
+ bool handleRequest(const facebook::react::jsinspector_modern::cdp::PreparsedRequest &req) override;
74
+
75
+ std::unique_ptr<RuntimeAgentDelegate::ExportedState> getExportedState() override;
76
+
77
+ private:
78
+ HermesUniqueCdpAgent hermesCdpAgent_;
79
+ };
80
+
81
+ } // namespace Microsoft::ReactNative