react-native-windows 0.80.1 → 0.80.6
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.
- package/Directory.Build.props +1 -1
- package/Microsoft.ReactNative/Fabric/Composition/DebuggerUIIsland.cpp +169 -0
- package/Microsoft.ReactNative/Fabric/Composition/DebuggerUIIsland.h +42 -0
- package/Microsoft.ReactNative/Fabric/Composition/DebuggingOverlayComponentView.cpp +1 -1
- package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp +60 -33
- package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.cpp +68 -1
- package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.h +9 -0
- package/Microsoft.ReactNative/Fabric/Composition/UriImageManager.cpp +5 -3
- package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.cpp +6 -1
- package/Microsoft.ReactNative/Fabric/WindowsImageManager.cpp +14 -1
- package/Microsoft.ReactNative/Fabric/platform/react/threading/TaskDispatchThread.cpp +75 -24
- package/Microsoft.ReactNative/Fabric/platform/react/threading/TaskDispatchThread.h +4 -25
- package/Microsoft.ReactNative/JsiApi.cpp +1 -1
- package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +1 -0
- package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj.filters +3 -0
- package/Microsoft.ReactNative/ReactHost/DebuggerNotifications.h +54 -0
- package/Microsoft.ReactNative/ReactHost/React.h +11 -4
- package/Microsoft.ReactNative/ReactHost/ReactHost.cpp +195 -29
- package/Microsoft.ReactNative/ReactHost/ReactHost.h +22 -4
- package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +24 -5
- package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.h +1 -1
- package/Microsoft.ReactNative/ReactRootView.cpp +108 -0
- package/Microsoft.ReactNative/ReactRootView.h +6 -0
- package/Microsoft.ReactNative/Views/DevMenu.cpp +1 -1
- package/Microsoft.ReactNative.Cxx/JSI/decorator.h +41 -0
- package/Microsoft.ReactNative.Cxx/JSI/jsi-inl.h +16 -0
- package/Microsoft.ReactNative.Cxx/JSI/jsi.cpp +125 -0
- package/Microsoft.ReactNative.Cxx/JSI/jsi.h +167 -1
- package/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems +1 -1
- package/Microsoft.ReactNative.Cxx/NodeApiJsiRuntime.cpp +110 -38
- package/Microsoft.ReactNative.Cxx/node-api/js_native_api.h +44 -31
- package/Microsoft.ReactNative.Cxx/node-api/js_native_api_types.h +13 -14
- package/Microsoft.ReactNative.Cxx/node-api/js_runtime_api.h +19 -4
- package/Microsoft.ReactNative.Cxx/node-api/node_api.h +270 -0
- package/Microsoft.ReactNative.Cxx/node-api/node_api_types.h +52 -0
- package/PropertySheets/Generated/PackageVersion.g.props +3 -3
- package/PropertySheets/JSEngine.props +1 -1
- package/PropertySheets/React.Cpp.props +2 -2
- package/ReactCommon/ReactCommon.vcxproj +18 -1
- package/ReactCommon/TEMP_UntilReactCommonUpdate/cxxreact/NativeToJsBridge.cpp +1 -1
- package/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/test/testlib.cpp +4 -4
- package/ReactCommon/TEMP_UntilReactCommonUpdate/jsinspector-modern/NetworkIOAgent.cpp +23 -9
- package/ReactCommon/TEMP_UntilReactCommonUpdate/jsinspector-modern/NetworkIOAgent.h +16 -0
- package/ReactCommon/cgmanifest.json +1 -1
- package/Scripts/Tfs/Layout-MSRN-Headers.ps1 +2 -0
- package/Shared/DevServerHelper.h +13 -3
- package/Shared/DevSettings.h +7 -0
- package/Shared/DevSupportManager.cpp +79 -20
- package/Shared/DevSupportManager.h +7 -19
- package/Shared/Hermes/HermesRuntimeAgentDelegate.cpp +99 -0
- package/Shared/Hermes/HermesRuntimeAgentDelegate.h +81 -0
- package/Shared/Hermes/HermesRuntimeTargetDelegate.cpp +263 -0
- package/Shared/Hermes/HermesRuntimeTargetDelegate.h +77 -0
- package/Shared/HermesRuntimeHolder.cpp +29 -111
- package/Shared/HermesRuntimeHolder.h +214 -32
- package/Shared/IDevSupportManager.h +5 -2
- package/Shared/Inspector/ReactInspectorPackagerConnectionDelegate.cpp +108 -0
- package/Shared/Inspector/ReactInspectorPackagerConnectionDelegate.h +19 -0
- package/Shared/Inspector/ReactInspectorThread.h +18 -0
- package/Shared/JSI/RuntimeHolder.h +5 -2
- package/Shared/OInstance.cpp +44 -27
- package/Shared/Shared.vcxitems +27 -17
- package/Shared/Shared.vcxitems.filters +33 -15
- package/package.json +5 -5
- package/ReactCommon/TEMP_UntilReactCommonUpdate/cxxreact/JSExecutor.cpp +0 -78
- package/ReactCommon/TEMP_UntilReactCommonUpdate/cxxreact/JSExecutor.h +0 -196
- package/ReactCommon/TEMP_UntilReactCommonUpdate/jserrorhandler/JsErrorHandler.cpp +0 -429
- package/ReactCommon/TEMP_UntilReactCommonUpdate/jsitooling/react/runtime/JSRuntimeFactory.cpp +0 -45
- package/ReactCommon/TEMP_UntilReactCommonUpdate/jsitooling/react/runtime/JSRuntimeFactory.h +0 -91
- package/ReactCommon/TEMP_UntilReactCommonUpdate/react/runtime/ReactInstance.cpp +0 -670
- package/Shared/InspectorPackagerConnection.cpp +0 -232
- package/Shared/InspectorPackagerConnection.h +0 -61
- /package/Shared/{HermesSamplingProfiler.cpp → Hermes/HermesSamplingProfiler.cpp} +0 -0
- /package/Shared/{HermesSamplingProfiler.h → Hermes/HermesSamplingProfiler.h} +0 -0
package/Shared/DevServerHelper.h
CHANGED
|
@@ -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;
|
package/Shared/DevSettings.h
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
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
|
|
53
|
-
|
|
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::
|
|
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
|