react-native-windows 0.80.1 → 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 (83) 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/UriImageManager.cpp +5 -3
  9. package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.cpp +6 -1
  10. package/Microsoft.ReactNative/Fabric/WindowsImageManager.cpp +14 -1
  11. package/Microsoft.ReactNative/Fabric/platform/react/threading/TaskDispatchThread.cpp +75 -24
  12. package/Microsoft.ReactNative/Fabric/platform/react/threading/TaskDispatchThread.h +4 -25
  13. package/Microsoft.ReactNative/JsiApi.cpp +1 -1
  14. package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +1 -0
  15. package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj.filters +3 -0
  16. package/Microsoft.ReactNative/ReactHost/DebuggerNotifications.h +54 -0
  17. package/Microsoft.ReactNative/ReactHost/React.h +11 -4
  18. package/Microsoft.ReactNative/ReactHost/ReactHost.cpp +195 -29
  19. package/Microsoft.ReactNative/ReactHost/ReactHost.h +22 -4
  20. package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +24 -5
  21. package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.h +1 -1
  22. package/Microsoft.ReactNative/ReactRootView.cpp +108 -0
  23. package/Microsoft.ReactNative/ReactRootView.h +6 -0
  24. package/Microsoft.ReactNative/Views/DevMenu.cpp +1 -1
  25. package/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems +1 -1
  26. package/PropertySheets/Generated/PackageVersion.g.props +3 -3
  27. package/PropertySheets/JSEngine.props +1 -1
  28. package/PropertySheets/React.Cpp.props +2 -2
  29. package/ReactCommon/ReactCommon.vcxproj +18 -1
  30. package/ReactCommon/TEMP_UntilReactCommonUpdate/cxxreact/NativeToJsBridge.cpp +1 -1
  31. package/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/test/testlib.cpp +4 -4
  32. package/ReactCommon/TEMP_UntilReactCommonUpdate/jsinspector-modern/NetworkIOAgent.cpp +23 -9
  33. package/ReactCommon/TEMP_UntilReactCommonUpdate/jsinspector-modern/NetworkIOAgent.h +16 -0
  34. package/ReactCommon/cgmanifest.json +1 -1
  35. package/Scripts/Tfs/Layout-MSRN-Headers.ps1 +2 -0
  36. package/Shared/DevServerHelper.h +13 -3
  37. package/Shared/DevSettings.h +7 -0
  38. package/Shared/DevSupportManager.cpp +79 -20
  39. package/Shared/DevSupportManager.h +7 -19
  40. package/Shared/Hermes/HermesRuntimeAgentDelegate.cpp +99 -0
  41. package/Shared/Hermes/HermesRuntimeAgentDelegate.h +81 -0
  42. package/Shared/Hermes/HermesRuntimeTargetDelegate.cpp +263 -0
  43. package/Shared/Hermes/HermesRuntimeTargetDelegate.h +77 -0
  44. package/Shared/HermesRuntimeHolder.cpp +29 -111
  45. package/Shared/HermesRuntimeHolder.h +214 -32
  46. package/Shared/IDevSupportManager.h +5 -2
  47. package/Shared/Inspector/ReactInspectorPackagerConnectionDelegate.cpp +108 -0
  48. package/Shared/Inspector/ReactInspectorPackagerConnectionDelegate.h +19 -0
  49. package/Shared/Inspector/ReactInspectorThread.h +18 -0
  50. package/Shared/JSI/RuntimeHolder.h +5 -2
  51. package/Shared/OInstance.cpp +44 -27
  52. package/Shared/Shared.vcxitems +27 -17
  53. package/Shared/Shared.vcxitems.filters +33 -15
  54. package/package.json +4 -4
  55. package/Microsoft.ReactNative.Cxx/ApiLoaders/JSRuntimeApi.cpp +0 -79
  56. package/Microsoft.ReactNative.Cxx/ApiLoaders/JSRuntimeApi.h +0 -51
  57. package/Microsoft.ReactNative.Cxx/ApiLoaders/JSRuntimeApi.inc +0 -50
  58. package/Microsoft.ReactNative.Cxx/ApiLoaders/NodeApi.cpp +0 -41
  59. package/Microsoft.ReactNative.Cxx/ApiLoaders/NodeApi.h +0 -127
  60. package/Microsoft.ReactNative.Cxx/ApiLoaders/NodeApi.inc +0 -125
  61. package/Microsoft.ReactNative.Cxx/ApiLoaders/NodeApi_posix.cpp +0 -16
  62. package/Microsoft.ReactNative.Cxx/ApiLoaders/NodeApi_win.cpp +0 -23
  63. package/Microsoft.ReactNative.Cxx/JSI/decorator.h +0 -1054
  64. package/Microsoft.ReactNative.Cxx/JSI/instrumentation.h +0 -145
  65. package/Microsoft.ReactNative.Cxx/JSI/jsi-inl.h +0 -372
  66. package/Microsoft.ReactNative.Cxx/JSI/jsi.cpp +0 -797
  67. package/Microsoft.ReactNative.Cxx/JSI/jsi.h +0 -1799
  68. package/Microsoft.ReactNative.Cxx/JSI/threadsafe.h +0 -79
  69. package/Microsoft.ReactNative.Cxx/NodeApiJsiRuntime.cpp +0 -3531
  70. package/Microsoft.ReactNative.Cxx/NodeApiJsiRuntime.h +0 -38
  71. package/Microsoft.ReactNative.Cxx/node-api/js_native_api.h +0 -614
  72. package/Microsoft.ReactNative.Cxx/node-api/js_native_api_types.h +0 -212
  73. package/Microsoft.ReactNative.Cxx/node-api/js_runtime_api.h +0 -199
  74. package/ReactCommon/TEMP_UntilReactCommonUpdate/cxxreact/JSExecutor.cpp +0 -78
  75. package/ReactCommon/TEMP_UntilReactCommonUpdate/cxxreact/JSExecutor.h +0 -196
  76. package/ReactCommon/TEMP_UntilReactCommonUpdate/jserrorhandler/JsErrorHandler.cpp +0 -429
  77. package/ReactCommon/TEMP_UntilReactCommonUpdate/jsitooling/react/runtime/JSRuntimeFactory.cpp +0 -45
  78. package/ReactCommon/TEMP_UntilReactCommonUpdate/jsitooling/react/runtime/JSRuntimeFactory.h +0 -91
  79. package/ReactCommon/TEMP_UntilReactCommonUpdate/react/runtime/ReactInstance.cpp +0 -670
  80. package/Shared/InspectorPackagerConnection.cpp +0 -232
  81. package/Shared/InspectorPackagerConnection.h +0 -61
  82. /package/Shared/{HermesSamplingProfiler.cpp → Hermes/HermesSamplingProfiler.cpp} +0 -0
  83. /package/Shared/{HermesSamplingProfiler.h → Hermes/HermesSamplingProfiler.h} +0 -0
@@ -8,16 +8,219 @@
8
8
  #include <ReactPropertyBag.h>
9
9
  #include <cxxreact/MessageQueueThread.h>
10
10
  #include <hermes/hermes_api.h>
11
- #include <jsitooling/react/runtime/JSRuntimeFactory.h>
11
+ #include <react/runtime/JSRuntimeFactory.h>
12
12
 
13
13
  namespace Microsoft::ReactNative {
14
14
 
15
- class HermesRuntimeHolder : public Microsoft::JSI::RuntimeHolderLazyInit {
15
+ template <typename TLambda, typename TFunctor>
16
+ class FunctorAdapter {
17
+ static_assert(sizeof(TLambda) == -1, "Unsupported signature");
18
+ };
19
+
20
+ template <typename TLambda, typename TResult, typename... TArgs>
21
+ class FunctorAdapter<TLambda, TResult(NAPI_CDECL)(void *, TArgs...)> {
22
+ public:
23
+ static TResult NAPI_CDECL Invoke(void *data, TArgs... args) {
24
+ return reinterpret_cast<TLambda *>(data)->operator()(args...);
25
+ }
26
+ };
27
+
28
+ template <typename TFunctor, typename TLambda>
29
+ inline TFunctor AsFunctor(TLambda &&lambda) {
30
+ using TLambdaType = std::remove_reference_t<TLambda>;
31
+ using TAdapter =
32
+ FunctorAdapter<TLambdaType, std::remove_pointer_t<decltype(std::remove_reference_t<TFunctor>::invoke)>>;
33
+ return TFunctor{
34
+ static_cast<void *>(new TLambdaType(std::forward<TLambdaType>(lambda))), &TAdapter::Invoke, [](void *data) {
35
+ delete static_cast<TLambdaType *>(data);
36
+ }};
37
+ }
38
+
39
+ template <typename TFunctor, typename TInvoke>
40
+ class FunctorWrapperBase {
41
+ static_assert(sizeof(TInvoke) == -1, "Unsupported signature");
42
+ };
43
+
44
+ template <typename TFunctor, typename TResult, typename... TArgs>
45
+ class FunctorWrapperBase<TFunctor, TResult(NAPI_CDECL *)(void *, TArgs...)> {
46
+ public:
47
+ FunctorWrapperBase(TFunctor functor) : functor_(functor) {}
48
+
49
+ ~FunctorWrapperBase() {
50
+ if (functor_.release != nullptr) {
51
+ functor_.release(functor_.data);
52
+ }
53
+ }
54
+
55
+ TResult operator()(TArgs... args) {
56
+ return functor_.invoke(functor_.data, args...);
57
+ }
58
+
59
+ private:
60
+ TFunctor functor_;
61
+ };
62
+
63
+ template <typename TFunctor>
64
+ class FunctorWrapper : public FunctorWrapperBase<TFunctor, decltype(std::declval<TFunctor>().invoke)> {
65
+ public:
66
+ using FunctorWrapperBase<TFunctor, decltype(std::declval<TFunctor>().invoke)>::FunctorWrapperBase;
67
+ };
68
+
69
+ class HermesCdpDebugApiDeleter {
70
+ public:
71
+ void operator()(hermes_cdp_debug_api cdp_debug_api);
72
+ };
73
+
74
+ class HermesCdpAgentDeleter {
75
+ public:
76
+ void operator()(hermes_cdp_agent cdp_agent);
77
+ };
78
+
79
+ class HermesCdpStateDeleter {
80
+ public:
81
+ void operator()(hermes_cdp_state cdp_state);
82
+ };
83
+
84
+ class HermesStackTraceDeleter {
85
+ public:
86
+ void operator()(hermes_stack_trace stack_trace);
87
+ };
88
+
89
+ class HermesSamplingProfileDeleter {
90
+ public:
91
+ void operator()(hermes_sampling_profile sampling_profile);
92
+ };
93
+
94
+ using HermesUniqueCdpDebugApi = std::unique_ptr<hermes_cdp_debug_api_s, HermesCdpDebugApiDeleter>;
95
+ using HermesUniqueCdpAgent = std::unique_ptr<hermes_cdp_agent_s, HermesCdpAgentDeleter>;
96
+ using HermesUniqueCdpState = std::unique_ptr<hermes_cdp_state_s, HermesCdpStateDeleter>;
97
+ using HermesUniqueStackTrace = std::unique_ptr<hermes_stack_trace_s, HermesStackTraceDeleter>;
98
+ using HermesUniqueSamplingProfile = std::unique_ptr<hermes_sampling_profile_s, HermesSamplingProfileDeleter>;
99
+
100
+ class HermesInspectorApi {
101
+ public:
102
+ HermesInspectorApi() = delete;
103
+
104
+ static void checkStatus(hermes_status status) {
105
+ if (status != hermes_status_ok) {
106
+ throw std::runtime_error("Hermes API call failed");
107
+ }
108
+ }
109
+
110
+ static HermesUniqueCdpDebugApi createCdpDebugApi(hermes_runtime runtime) {
111
+ hermes_cdp_debug_api cdp_debug_api{};
112
+ checkStatus(vtable->create_cdp_debug_api(runtime, &cdp_debug_api));
113
+ return HermesUniqueCdpDebugApi{cdp_debug_api};
114
+ }
115
+
116
+ static void addConsoleMessage(
117
+ hermes_cdp_debug_api cdpDebugApi,
118
+ double timestamp,
119
+ hermes_console_api_type type,
120
+ const char *argsPropertyName,
121
+ hermes_stack_trace stackTrace) {
122
+ checkStatus(vtable->add_console_message(cdpDebugApi, timestamp, type, argsPropertyName, stackTrace));
123
+ }
124
+
125
+ static HermesUniqueCdpAgent createCdpAgent(
126
+ hermes_cdp_debug_api cdpDebugApi,
127
+ int32_t execitionContextId,
128
+ hermes_enqueue_runtime_task_functor enqueueRuntimeTaskCallback,
129
+ hermes_enqueue_frontend_message_functor enqueueFrontendMessageCallback,
130
+ hermes_cdp_state cdp_state) {
131
+ hermes_cdp_agent cdp_agent{};
132
+ checkStatus(vtable->create_cdp_agent(
133
+ cdpDebugApi,
134
+ execitionContextId,
135
+ enqueueRuntimeTaskCallback,
136
+ enqueueFrontendMessageCallback,
137
+ cdp_state,
138
+ &cdp_agent));
139
+ return HermesUniqueCdpAgent{cdp_agent};
140
+ }
141
+
142
+ static HermesUniqueCdpState getCdpState(hermes_cdp_agent cdp_agent) {
143
+ hermes_cdp_state cdp_state{};
144
+ checkStatus(vtable->cdp_agent_get_state(cdp_agent, &cdp_state));
145
+ return HermesUniqueCdpState{cdp_state};
146
+ }
147
+
148
+ static void handleCommand(hermes_cdp_agent cdpAgent, const char *jsonUtf8, size_t jsonSize) {
149
+ checkStatus(vtable->cdp_agent_handle_command(cdpAgent, jsonUtf8, jsonSize));
150
+ }
151
+
152
+ static void enableRuntimeDomain(hermes_cdp_agent cdpAgent) {
153
+ checkStatus(vtable->cdp_agent_enable_runtime_domain(cdpAgent));
154
+ }
155
+
156
+ static void enableDebuggerDomain(hermes_cdp_agent cdpAgent) {
157
+ checkStatus(vtable->cdp_agent_enable_debugger_domain(cdpAgent));
158
+ }
159
+
160
+ static HermesUniqueStackTrace captureStackTrace(hermes_runtime runtime) {
161
+ hermes_stack_trace stack_trace{};
162
+ checkStatus(vtable->capture_stack_trace(runtime, &stack_trace));
163
+ return HermesUniqueStackTrace{stack_trace};
164
+ }
165
+
166
+ static void enableSamplingProfiler(hermes_runtime runtime) {
167
+ checkStatus(vtable->enable_sampling_profiler(runtime));
168
+ }
169
+
170
+ static void disableSamplingProfiler(hermes_runtime runtime) {
171
+ checkStatus(vtable->disable_sampling_profiler(runtime));
172
+ }
173
+
174
+ static HermesUniqueSamplingProfile collectSamplingProfile(
175
+ hermes_runtime runtime,
176
+ void *cb_data,
177
+ hermes_on_sampling_profile_info_callback on_info_callback,
178
+ hermes_on_sampling_profile_sample_callback on_sample_callback,
179
+ hermes_on_sampling_profile_frame_callback on_frame_callback) {
180
+ hermes_sampling_profile profile{};
181
+ checkStatus(vtable->collect_sampling_profile(
182
+ runtime, cb_data, on_info_callback, on_sample_callback, on_frame_callback, &profile));
183
+ return HermesUniqueSamplingProfile{profile};
184
+ }
185
+
186
+ private:
187
+ friend HermesCdpDebugApiDeleter;
188
+ friend HermesCdpAgentDeleter;
189
+ friend HermesCdpStateDeleter;
190
+ friend HermesStackTraceDeleter;
191
+ friend HermesSamplingProfileDeleter;
192
+
193
+ friend void setHermesInspectorVTable(const hermes_inspector_vtable *vtable);
194
+
195
+ static const hermes_inspector_vtable *vtable;
196
+ };
197
+
198
+ inline void HermesCdpDebugApiDeleter::operator()(hermes_cdp_debug_api cdp_debug_api) {
199
+ HermesInspectorApi::vtable->release_cdp_debug_api(cdp_debug_api);
200
+ }
201
+
202
+ inline void HermesCdpAgentDeleter::operator()(hermes_cdp_agent cdp_agent) {
203
+ HermesInspectorApi::vtable->release_cdp_agent(cdp_agent);
204
+ }
205
+
206
+ inline void HermesCdpStateDeleter::operator()(hermes_cdp_state cdp_state) {
207
+ HermesInspectorApi::vtable->release_cdp_state(cdp_state);
208
+ }
209
+
210
+ inline void HermesStackTraceDeleter::operator()(hermes_stack_trace stack_trace) {
211
+ HermesInspectorApi::vtable->release_stack_trace(stack_trace);
212
+ }
213
+
214
+ inline void HermesSamplingProfileDeleter::operator()(hermes_sampling_profile sampling_profile) {
215
+ HermesInspectorApi::vtable->release_sampling_profile(sampling_profile);
216
+ }
217
+
218
+ class HermesRuntimeHolder : public Microsoft::JSI::RuntimeHolderLazyInit,
219
+ public std::enable_shared_from_this<HermesRuntimeHolder> {
16
220
  public: // RuntimeHolderLazyInit implementation.
17
221
  std::shared_ptr<facebook::jsi::Runtime> getRuntime() noexcept override;
18
222
  facebook::react::JSIEngineOverride getRuntimeType() noexcept override;
19
223
  void crashHandler(int fileDescriptor) noexcept override;
20
- void teardown() noexcept override;
21
224
 
22
225
  public:
23
226
  HermesRuntimeHolder(
@@ -26,6 +229,8 @@ class HermesRuntimeHolder : public Microsoft::JSI::RuntimeHolderLazyInit {
26
229
  std::shared_ptr<facebook::jsi::PreparedScriptStore> preparedScriptStore) noexcept;
27
230
  ~HermesRuntimeHolder();
28
231
 
232
+ std::shared_ptr<facebook::react::jsinspector_modern::RuntimeTargetDelegate> createRuntimeTargetDelegate() override;
233
+
29
234
  static std::shared_ptr<HermesRuntimeHolder> loadFrom(
30
235
  winrt::Microsoft::ReactNative::ReactPropertyBag const &propertyBag) noexcept;
31
236
 
@@ -40,6 +245,8 @@ class HermesRuntimeHolder : public Microsoft::JSI::RuntimeHolderLazyInit {
40
245
  static void disableSamplingProfiler() noexcept;
41
246
  static void dumpSampledTraceToFile(const std::string &fileName) noexcept;
42
247
 
248
+ hermes_runtime getHermesRuntime() noexcept;
249
+
43
250
  private:
44
251
  void initRuntime() noexcept;
45
252
 
@@ -53,42 +260,17 @@ class HermesRuntimeHolder : public Microsoft::JSI::RuntimeHolderLazyInit {
53
260
  std::shared_ptr<facebook::jsi::PreparedScriptStore> m_preparedScriptStore;
54
261
  };
55
262
 
56
- class HermesJSRuntime : public facebook::react::JSRuntime {
263
+ class HermesJSRuntime final : public facebook::react::JSRuntime {
57
264
  public:
58
265
  HermesJSRuntime(std::shared_ptr<Microsoft::JSI::RuntimeHolderLazyInit> hermesRuntimeHolder);
59
266
 
60
267
  facebook::jsi::Runtime &getRuntime() noexcept override;
61
- void addConsoleMessage(facebook::jsi::Runtime &runtime, facebook::react::jsinspector_modern::ConsoleMessage message)
62
- override;
63
- bool supportsConsole() const override;
64
- std::unique_ptr<facebook::react::jsinspector_modern::StackTrace> captureStackTrace(
65
- facebook::jsi::Runtime &runtime,
66
- size_t framesToSkip = 0) override;
67
-
68
- /**
69
- * Start sampling profiler.
70
- */
71
- void enableSamplingProfiler() override;
72
-
73
- /**
74
- * Stop sampling profiler.
75
- */
76
- void disableSamplingProfiler() override;
77
-
78
- /**
79
- * Return recorded sampling profile for the previous sampling session.
80
- */
81
- facebook::react::jsinspector_modern::tracing::RuntimeSamplingProfile collectSamplingProfile() override;
82
-
83
- std::unique_ptr<facebook::react::jsinspector_modern::RuntimeAgentDelegate> createAgentDelegate(
84
- facebook::react::jsinspector_modern::FrontendChannel frontendChannel,
85
- facebook::react::jsinspector_modern::SessionState &sessionState,
86
- std::unique_ptr<facebook::react::jsinspector_modern::RuntimeAgentDelegate::ExportedState> previouslyExportedState,
87
- const facebook::react::jsinspector_modern::ExecutionContextDescription &executionContextDescription,
88
- facebook::react::RuntimeExecutor runtimeExecutor) override;
268
+
269
+ facebook::react::jsinspector_modern::RuntimeTargetDelegate &getRuntimeTargetDelegate() override;
89
270
 
90
271
  private:
91
272
  std::shared_ptr<Microsoft::JSI::RuntimeHolderLazyInit> m_holder;
273
+ std::shared_ptr<facebook::react::jsinspector_modern::RuntimeTargetDelegate> m_runtimeTargetDelegate;
92
274
  };
93
275
 
94
276
  } // namespace Microsoft::ReactNative
@@ -23,9 +23,12 @@ struct IDevSupportManager {
23
23
  const uint16_t sourceBundlePort,
24
24
  std::function<void()> onChangeCallback) = 0;
25
25
  virtual void StopPollingLiveReload() = 0;
26
+ virtual void OpenDevTools(const std::string &bundleAppId) = 0;
26
27
 
27
- virtual void EnsureHermesInspector(const std::string &packagerHost, const uint16_t packagerPort) noexcept = 0;
28
- virtual void UpdateBundleStatus(bool isLastDownloadSuccess, int64_t updateTimestamp) noexcept = 0;
28
+ virtual void EnsureInspectorPackagerConnection(
29
+ const std::string &packagerHost,
30
+ const uint16_t packagerPort,
31
+ const std::string &bundleAppId) noexcept = 0;
29
32
  };
30
33
 
31
34
  std::shared_ptr<IDevSupportManager> CreateDevSupportManager();
@@ -0,0 +1,108 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ #include "ReactInspectorPackagerConnectionDelegate.h"
5
+
6
+ #include <Networking/WinRTWebSocketResource.h>
7
+ #include <dispatchQueue/dispatchQueue.h>
8
+ #include <winrt/Microsoft.ReactNative.h>
9
+ #include "ReactInspectorThread.h"
10
+
11
+ namespace Microsoft::ReactNative {
12
+
13
+ namespace {
14
+
15
+ class ReactInspectorWebSocket : public facebook::react::jsinspector_modern::IWebSocket {
16
+ public:
17
+ ReactInspectorWebSocket(
18
+ std::string const &url,
19
+ std::weak_ptr<facebook::react::jsinspector_modern::IWebSocketDelegate> delegate);
20
+ void send(std::string_view message) override;
21
+ ~ReactInspectorWebSocket() override;
22
+
23
+ private:
24
+ std::shared_ptr<Microsoft::React::Networking::WinRTWebSocketResource> m_packagerWebSocketConnection;
25
+ std::weak_ptr<facebook::react::jsinspector_modern::IWebSocketDelegate> m_weakDelegate;
26
+ std::atomic<bool> m_didConnect{false};
27
+ };
28
+
29
+ ReactInspectorWebSocket::ReactInspectorWebSocket(
30
+ std::string const &url,
31
+ std::weak_ptr<facebook::react::jsinspector_modern::IWebSocketDelegate> delegate)
32
+ : m_weakDelegate{delegate} {
33
+ std::vector<winrt::Windows::Security::Cryptography::Certificates::ChainValidationResult> certExceptions;
34
+
35
+ m_packagerWebSocketConnection =
36
+ std::make_shared<Microsoft::React::Networking::WinRTWebSocketResource>(std::move(certExceptions));
37
+
38
+ m_packagerWebSocketConnection->SetOnConnect([this, delegate]() {
39
+ ReactInspectorThread::Instance().InvokeElsePost([this, delegate]() {
40
+ m_didConnect = true;
41
+ if (const auto strongDelegate = delegate.lock()) {
42
+ strongDelegate->didOpen();
43
+ }
44
+ });
45
+ });
46
+ m_packagerWebSocketConnection->SetOnMessage([delegate](auto &&, const std::string &message, bool isBinary) {
47
+ ReactInspectorThread::Instance().InvokeElsePost([delegate, message]() {
48
+ if (const auto strongDelegate = delegate.lock()) {
49
+ strongDelegate->didReceiveMessage(message);
50
+ }
51
+ });
52
+ });
53
+ m_packagerWebSocketConnection->SetOnError(
54
+ [delegate](const Microsoft::React::Networking::IWebSocketResource::Error &error) {
55
+ ReactInspectorThread::Instance().InvokeElsePost([delegate, error]() {
56
+ if (const auto strongDelegate = delegate.lock()) {
57
+ strongDelegate->didFailWithError(std::nullopt, error.Message);
58
+ }
59
+ });
60
+ });
61
+ m_packagerWebSocketConnection->SetOnClose([this, delegate](auto &&...) {
62
+ ReactInspectorThread::Instance().InvokeElsePost([this, delegate]() {
63
+ // Only call didClose() if we successfully connected first
64
+ // This prevents didClose() from being called during failed connection attempts
65
+ if (m_didConnect) {
66
+ if (const auto strongDelegate = delegate.lock()) {
67
+ strongDelegate->didClose();
68
+ }
69
+ }
70
+ });
71
+ });
72
+
73
+ Microsoft::React::Networking::IWebSocketResource::Protocols protocols;
74
+ Microsoft::React::Networking::IWebSocketResource::Options options;
75
+ m_packagerWebSocketConnection->Connect(std::string{url}, protocols, options);
76
+ }
77
+
78
+ void ReactInspectorWebSocket::send(std::string_view message) {
79
+ m_packagerWebSocketConnection->Send(std::string{message});
80
+ }
81
+
82
+ ReactInspectorWebSocket::~ReactInspectorWebSocket() {
83
+ // Don't close WebSocket during shutdown - the OS will clean it up
84
+ // Attempting to close async during DLL unload causes thread pool failures
85
+ // The connection will be terminated when the process exits anyway
86
+ }
87
+
88
+ } // namespace
89
+
90
+ std::unique_ptr<facebook::react::jsinspector_modern::IWebSocket>
91
+ ReactInspectorPackagerConnectionDelegate::connectWebSocket(
92
+ const std::string &url,
93
+ std::weak_ptr<facebook::react::jsinspector_modern::IWebSocketDelegate> delegate) {
94
+ return std::make_unique<ReactInspectorWebSocket>(url, delegate);
95
+ }
96
+
97
+ winrt::fire_and_forget RunWithDelayAsync(std::function<void(void)> callback, std::chrono::milliseconds delayMs) {
98
+ co_await winrt::resume_after(delayMs);
99
+ ReactInspectorThread::Instance().InvokeElsePost([callback]() { callback(); });
100
+ }
101
+
102
+ void ReactInspectorPackagerConnectionDelegate::scheduleCallback(
103
+ std::function<void(void)> callback,
104
+ std::chrono::milliseconds delayMs) {
105
+ RunWithDelayAsync(callback, delayMs);
106
+ }
107
+
108
+ } // namespace Microsoft::ReactNative
@@ -0,0 +1,19 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ #pragma once
5
+ #include <jsinspector-modern/InspectorPackagerConnection.h>
6
+
7
+ namespace Microsoft::ReactNative {
8
+
9
+ class ReactInspectorPackagerConnectionDelegate final
10
+ : public facebook::react::jsinspector_modern::InspectorPackagerConnectionDelegate {
11
+ public: // InspectorPackagerConnectionDelegate implementation
12
+ std::unique_ptr<facebook::react::jsinspector_modern::IWebSocket> connectWebSocket(
13
+ const std::string &url,
14
+ std::weak_ptr<facebook::react::jsinspector_modern::IWebSocketDelegate> delegate) override;
15
+
16
+ void scheduleCallback(std::function<void(void)> callback, std::chrono::milliseconds delayMs) override;
17
+ };
18
+
19
+ } // namespace Microsoft::ReactNative
@@ -0,0 +1,18 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ #pragma once
5
+
6
+ #include <dispatchQueue/dispatchQueue.h>
7
+
8
+ namespace Microsoft::ReactNative {
9
+
10
+ class ReactInspectorThread {
11
+ public:
12
+ static Mso::DispatchQueue &Instance() {
13
+ static Mso::DispatchQueue queue = Mso::DispatchQueue::MakeSerialQueue();
14
+ return queue;
15
+ }
16
+ };
17
+
18
+ } // namespace Microsoft::ReactNative
@@ -4,6 +4,7 @@
4
4
  #include <memory>
5
5
 
6
6
  #include <DevSettings.h>
7
+ #include <jsinspector-modern/RuntimeTarget.h>
7
8
 
8
9
  namespace Microsoft::JSI {
9
10
 
@@ -18,11 +19,13 @@ struct RuntimeHolderLazyInit {
18
19
  virtual std::shared_ptr<facebook::jsi::Runtime> getRuntime() noexcept = 0;
19
20
  virtual facebook::react::JSIEngineOverride getRuntimeType() noexcept = 0;
20
21
 
21
- virtual void teardown() noexcept {};
22
-
23
22
  // You can call this when a crash happens to attempt recording additional data
24
23
  // The fileDescriptor supplied is a raw file stream an implementation might write JSON to.
25
24
  virtual void crashHandler(int fileDescriptor) noexcept {};
25
+
26
+ virtual std::shared_ptr<facebook::react::jsinspector_modern::RuntimeTargetDelegate> createRuntimeTargetDelegate() {
27
+ return nullptr;
28
+ }
26
29
  };
27
30
 
28
31
  } // namespace Microsoft::JSI
@@ -45,7 +45,9 @@
45
45
  #include <Shlwapi.h>
46
46
  #include <WebSocketJSExecutorFactory.h>
47
47
  #include <safeint.h>
48
+ #include "Inspector/ReactInspectorThread.h"
48
49
  #include "PackagerConnection.h"
50
+ #include "Threading/MessageDispatchQueue.h"
49
51
 
50
52
  #if defined(USE_HERMES) && defined(ENABLE_DEVSERVER_HBCBUNDLES)
51
53
  #include <hermes/BytecodeVersion.h>
@@ -117,7 +119,6 @@ void LoadRemoteUrlScript(
117
119
  hermesBytecodeVersion);
118
120
 
119
121
  if (!success) {
120
- devManager->UpdateBundleStatus(false, -1);
121
122
  devSettings->errorCallback(jsBundleString);
122
123
  return;
123
124
  }
@@ -125,7 +126,6 @@ void LoadRemoteUrlScript(
125
126
  int64_t currentTimeInMilliSeconds =
126
127
  std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch())
127
128
  .count();
128
- devManager->UpdateBundleStatus(true, currentTimeInMilliSeconds);
129
129
 
130
130
  auto bundleUrl = facebook::react::DevServerHelper::get_BundleUrl(
131
131
  devSettings->sourceBundleHost,
@@ -210,11 +210,33 @@ std::unique_ptr<const facebook::react::JSBigString> JsBigStringFromPath(
210
210
 
211
211
  } // namespace Microsoft::ReactNative
212
212
 
213
- namespace facebook {
214
- namespace react {
213
+ namespace facebook::react {
215
214
 
216
215
  namespace {
217
216
 
217
+ // OJSIExecutor is needed to override getRuntimeTargetDelegate to support the modern JSI inspector.
218
+ class OJSIExecutor : public JSIExecutor {
219
+ public:
220
+ OJSIExecutor(
221
+ std::shared_ptr<jsi::Runtime> runtime,
222
+ std::shared_ptr<ExecutorDelegate> delegate,
223
+ const JSIScopedTimeoutInvoker &timeoutInvoker,
224
+ RuntimeInstaller runtimeInstaller,
225
+ std::shared_ptr<facebook::react::jsinspector_modern::RuntimeTargetDelegate> &&targetDelegate) noexcept
226
+ : JSIExecutor(std::move(runtime), std::move(delegate), timeoutInvoker, std::move(runtimeInstaller)),
227
+ targetDelegate_(std::move(targetDelegate)) {}
228
+ jsinspector_modern::RuntimeTargetDelegate &getRuntimeTargetDelegate() override {
229
+ if (!targetDelegate_) {
230
+ // Use the fallback implementation from JSIExecutor.
231
+ return JSIExecutor::getRuntimeTargetDelegate();
232
+ }
233
+ return *targetDelegate_;
234
+ }
235
+
236
+ private:
237
+ std::shared_ptr<facebook::react::jsinspector_modern::RuntimeTargetDelegate> targetDelegate_;
238
+ };
239
+
218
240
  class OJSIExecutorFactory : public JSExecutorFactory {
219
241
  public:
220
242
  std::unique_ptr<JSExecutor> createJSExecutor(
@@ -231,7 +253,7 @@ class OJSIExecutorFactory : public JSExecutorFactory {
231
253
  }
232
254
  bindNativeLogger(*runtimeHolder_->getRuntime(), logger);
233
255
 
234
- return std::make_unique<JSIExecutor>(
256
+ return std::make_unique<OJSIExecutor>(
235
257
  runtimeHolder_->getRuntime(),
236
258
  std::move(delegate),
237
259
  JSIExecutor::defaultTimeoutInvoker,
@@ -239,7 +261,8 @@ class OJSIExecutorFactory : public JSExecutorFactory {
239
261
  #ifdef ENABLE_JS_SYSTRACE_TO_ETW
240
262
  facebook::react::tracing::initializeJSHooks(runtime, isProfiling);
241
263
  #endif
242
- });
264
+ },
265
+ runtimeHolder_->createRuntimeTargetDelegate());
243
266
  }
244
267
 
245
268
  OJSIExecutorFactory(
@@ -328,20 +351,6 @@ void InstanceImpl::SetInError() noexcept {
328
351
  m_isInError = true;
329
352
  }
330
353
 
331
- namespace {
332
- bool shouldStartHermesInspector(DevSettings &devSettings) {
333
- bool isHermes =
334
- ((devSettings.jsiEngineOverride == JSIEngineOverride::Hermes) ||
335
- (devSettings.jsiEngineOverride == JSIEngineOverride::Default && devSettings.jsiRuntimeHolder &&
336
- devSettings.jsiRuntimeHolder->getRuntimeType() == facebook::react::JSIEngineOverride::Hermes));
337
-
338
- if (isHermes && devSettings.useDirectDebugger && !devSettings.useWebDebugger)
339
- return true;
340
- else
341
- return false;
342
- }
343
- } // namespace
344
-
345
354
  InstanceImpl::InstanceImpl(
346
355
  std::shared_ptr<Instance> &&instance,
347
356
  std::string &&jsBundleBasePath,
@@ -372,8 +381,9 @@ InstanceImpl::InstanceImpl(
372
381
  facebook::react::tracing::initializeETW();
373
382
  #endif
374
383
 
375
- if (shouldStartHermesInspector(*m_devSettings)) {
376
- m_devManager->EnsureHermesInspector(m_devSettings->sourceBundleHost, m_devSettings->sourceBundlePort);
384
+ if (m_devSettings->useDirectDebugger) {
385
+ m_devManager->EnsureInspectorPackagerConnection(
386
+ m_devSettings->sourceBundleHost, m_devSettings->sourceBundlePort, m_devSettings->bundleAppId);
377
387
  }
378
388
 
379
389
  // Default (common) NativeModules
@@ -483,7 +493,8 @@ InstanceImpl::InstanceImpl(
483
493
  }
484
494
  }
485
495
 
486
- m_innerInstance->initializeBridge(std::move(callback), jsef, m_jsThread, m_moduleRegistry);
496
+ m_innerInstance->initializeBridge(
497
+ std::move(callback), jsef, m_jsThread, m_moduleRegistry, m_devSettings->inspectorHostTarget);
487
498
 
488
499
  // For RuntimeScheduler to work properly, we need to install TurboModuleManager with RuntimeSchedulerCallbackInvoker.
489
500
  // To be able to do that, we need to be able to call m_innerInstance->getRuntimeExecutor(), which we can only do after
@@ -586,9 +597,16 @@ void InstanceImpl::loadBundleInternal(std::string &&jsBundleRelativePath, bool s
586
597
  }
587
598
 
588
599
  InstanceImpl::~InstanceImpl() {
589
- if (shouldStartHermesInspector(*m_devSettings) && m_devSettings->jsiRuntimeHolder) {
590
- m_devSettings->jsiRuntimeHolder->teardown();
600
+ if (m_devSettings->inspectorHostTarget) {
601
+ Mso::React::MessageDispatchQueue messageDispatchQueue{
602
+ ::Microsoft::ReactNative::ReactInspectorThread::Instance(), nullptr};
603
+ messageDispatchQueue.runOnQueueSync([weakInnerInstance = std::weak_ptr(m_innerInstance)]() {
604
+ if (std::shared_ptr<facebook::react::Instance> innerInstance = weakInnerInstance.lock()) {
605
+ innerInstance->unregisterFromInspector();
606
+ }
607
+ });
591
608
  }
609
+
592
610
  m_nativeQueue->quitSynchronous();
593
611
  }
594
612
 
@@ -722,5 +740,4 @@ void InstanceImpl::invokeCallback(const int64_t callbackId, folly::dynamic &&par
722
740
  m_innerInstance->callJSCallback(callbackId, std::move(params));
723
741
  }
724
742
 
725
- } // namespace react
726
- } // namespace facebook
743
+ } // namespace facebook::react