react-native-windows 0.74.35 → 0.74.37

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 (27) hide show
  1. package/Microsoft.ReactNative/Fabric/AbiViewProps.cpp +8 -10
  2. package/Microsoft.ReactNative/Fabric/ComponentView.cpp +4 -1
  3. package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +1 -1
  4. package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.cpp +2 -2
  5. package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.cpp +5 -2
  6. package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.h +2 -1
  7. package/Microsoft.ReactNative/Fabric/Composition/TooltipService.cpp +41 -37
  8. package/Microsoft.ReactNative/Fabric/platform/react/renderer/graphics/HostPlatformColor.h +3 -8
  9. package/Microsoft.ReactNative/Fabric/platform/react/renderer/graphics/PlatformColorParser.h +0 -1
  10. package/Microsoft.ReactNative.Cxx/NativeModules.h +9 -0
  11. package/PropertySheets/Generated/PackageVersion.g.props +3 -3
  12. package/Shared/Networking/WinRTWebSocketResource.cpp +371 -6
  13. package/Shared/Networking/WinRTWebSocketResource.h +118 -0
  14. package/codegen/react/components/rnwcore/ActivityIndicatorView.g.h +6 -6
  15. package/codegen/react/components/rnwcore/AndroidDrawerLayout.g.h +6 -6
  16. package/codegen/react/components/rnwcore/AndroidHorizontalScrollContentView.g.h +6 -6
  17. package/codegen/react/components/rnwcore/AndroidProgressBar.g.h +6 -6
  18. package/codegen/react/components/rnwcore/AndroidSwipeRefreshLayout.g.h +6 -6
  19. package/codegen/react/components/rnwcore/AndroidSwitch.g.h +6 -6
  20. package/codegen/react/components/rnwcore/DebuggingOverlay.g.h +6 -6
  21. package/codegen/react/components/rnwcore/InputAccessory.g.h +6 -6
  22. package/codegen/react/components/rnwcore/ModalHostView.g.h +6 -6
  23. package/codegen/react/components/rnwcore/PullToRefreshView.g.h +6 -6
  24. package/codegen/react/components/rnwcore/SafeAreaView.g.h +6 -6
  25. package/codegen/react/components/rnwcore/Switch.g.h +6 -6
  26. package/codegen/react/components/rnwcore/UnimplementedNativeView.g.h +6 -6
  27. package/package.json +3 -3
@@ -21,16 +21,18 @@
21
21
 
22
22
  using Microsoft::Common::Utilities::CheckedReinterpretCast;
23
23
 
24
+ using Mso::DispatchQueue;
25
+
24
26
  using std::function;
25
27
  using std::lock_guard;
26
28
  using std::mutex;
27
- using std::size_t;
28
29
  using std::string;
29
30
  using std::vector;
30
31
 
31
32
  using winrt::fire_and_forget;
32
33
  using winrt::hresult;
33
34
  using winrt::hresult_error;
35
+ using winrt::hstring;
34
36
  using winrt::resume_background;
35
37
  using winrt::resume_on_signal;
36
38
  using winrt::Windows::Foundation::IAsyncAction;
@@ -38,6 +40,7 @@ using winrt::Windows::Foundation::Uri;
38
40
  using winrt::Windows::Networking::Sockets::IMessageWebSocket;
39
41
  using winrt::Windows::Networking::Sockets::IMessageWebSocketMessageReceivedEventArgs;
40
42
  using winrt::Windows::Networking::Sockets::IWebSocket;
43
+ using winrt::Windows::Networking::Sockets::IWebSocketClosedEventArgs;
41
44
  using winrt::Windows::Networking::Sockets::MessageWebSocket;
42
45
  using winrt::Windows::Networking::Sockets::SocketMessageType;
43
46
  using winrt::Windows::Networking::Sockets::WebSocketClosedEventArgs;
@@ -54,9 +57,9 @@ namespace {
54
57
  ///
55
58
  /// Implements an awaiter for Mso::DispatchQueue
56
59
  ///
57
- auto resume_in_queue(const Mso::DispatchQueue &queue) noexcept {
60
+ auto resume_in_queue(const DispatchQueue &queue) noexcept {
58
61
  struct awaitable {
59
- awaitable(const Mso::DispatchQueue &queue) noexcept : m_queue{queue} {}
62
+ awaitable(const DispatchQueue &queue) noexcept : m_queue{queue} {}
60
63
 
61
64
  bool await_ready() const noexcept {
62
65
  return false;
@@ -79,10 +82,367 @@ auto resume_in_queue(const Mso::DispatchQueue &queue) noexcept {
79
82
  return awaitable{queue};
80
83
  } // resume_in_queue
81
84
 
85
+ DispatchQueue GetCurrentOrSerialQueue() noexcept {
86
+ auto queue = DispatchQueue::CurrentQueue();
87
+ if (!queue)
88
+ queue = DispatchQueue::MakeSerialQueue();
89
+
90
+ return queue;
91
+ }
92
+
82
93
  } // namespace
83
94
 
84
95
  namespace Microsoft::React::Networking {
85
96
 
97
+ #pragma region WinRTWebSocketResource2
98
+
99
+ WinRTWebSocketResource2::WinRTWebSocketResource2(
100
+ IMessageWebSocket &&socket,
101
+ IDataWriter &&writer,
102
+ vector<ChainValidationResult> &&certExceptions,
103
+ DispatchQueue callingQueue)
104
+ : m_socket{std::move(socket)},
105
+ m_writer(std::move(writer)),
106
+ m_readyState{ReadyState::Connecting},
107
+ m_connectPerformed{CreateEvent(/*attributes*/ nullptr, /*manual reset*/ true, /*state*/ false, /*name*/ nullptr)},
108
+ m_callingQueue{callingQueue} {
109
+ for (const auto &certException : certExceptions) {
110
+ m_socket.Control().IgnorableServerCertificateErrors().Append(certException);
111
+ }
112
+ }
113
+
114
+ // private
115
+ WinRTWebSocketResource2::WinRTWebSocketResource2(
116
+ IMessageWebSocket &&socket,
117
+ vector<ChainValidationResult> &&certExceptions)
118
+ : WinRTWebSocketResource2(
119
+ std::move(socket),
120
+ DataWriter{socket.OutputStream()},
121
+ std::move(certExceptions),
122
+ GetCurrentOrSerialQueue()) {}
123
+
124
+ WinRTWebSocketResource2::WinRTWebSocketResource2(vector<ChainValidationResult> &&certExceptions)
125
+ : WinRTWebSocketResource2(MessageWebSocket{}, std::move(certExceptions)) {}
126
+
127
+ WinRTWebSocketResource2::~WinRTWebSocketResource2() noexcept /*override*/
128
+ {}
129
+
130
+ void WinRTWebSocketResource2::Fail(string &&message, ErrorType type) noexcept {
131
+ auto self = shared_from_this();
132
+
133
+ self->m_backgroundQueue.Post([self, message = std::move(message), type]() {
134
+ self->m_readyState = ReadyState::Closed;
135
+ self->m_callingQueue.Post([self, message = std::move(message), type]() {
136
+ if (self->m_errorHandler) {
137
+ self->m_errorHandler({std::move(message), type});
138
+ }
139
+ });
140
+ });
141
+ }
142
+
143
+ void WinRTWebSocketResource2::Fail(hresult &&error, ErrorType type) noexcept {
144
+ Fail(Utilities::HResultToString(std::move(error)), type);
145
+ }
146
+
147
+ void WinRTWebSocketResource2::Fail(hresult_error const &error, ErrorType type) noexcept {
148
+ Fail(Utilities::HResultToString(error), type);
149
+ }
150
+
151
+ void WinRTWebSocketResource2::OnMessageReceived(
152
+ IMessageWebSocket const &,
153
+ IMessageWebSocketMessageReceivedEventArgs const &args) {
154
+ auto self = shared_from_this();
155
+ string response;
156
+
157
+ IDataReader reader{nullptr};
158
+ // Use WinRT ABI to avoid throwing exceptions on expected code paths
159
+ HRESULT hr =
160
+ reinterpret_cast<ABI::Windows::Networking::Sockets::IMessageWebSocketMessageReceivedEventArgs *>(
161
+ winrt::get_abi(args))
162
+ ->GetDataReader(reinterpret_cast<ABI::Windows::Storage::Streams::IDataReader **>(winrt::put_abi(reader)));
163
+
164
+ if (FAILED(hr)) {
165
+ string errorMessage;
166
+ ErrorType errorType;
167
+ // See
168
+ // https://docs.microsoft.com/uwp/api/windows.networking.sockets.messagewebsocketmessagereceivedeventargs.getdatareader?view=winrt-22621#remarks
169
+ if (hr == WININET_E_CONNECTION_ABORTED) {
170
+ errorMessage = "[0x80072EFE] Underlying TCP connection suddenly terminated";
171
+ errorType = ErrorType::Connection;
172
+ // Note: It is not clear whether all read-related errors should close the socket.
173
+ Close(CloseCode::BadPayload, std::move(errorMessage));
174
+ } else {
175
+ errorMessage = Utilities::HResultToString(hr);
176
+ errorType = ErrorType::Receive;
177
+ }
178
+
179
+ self->Fail(std::move(errorMessage), errorType);
180
+
181
+ return;
182
+ }
183
+
184
+ try {
185
+ auto len = reader.UnconsumedBufferLength();
186
+ if (args.MessageType() == SocketMessageType::Utf8) {
187
+ reader.UnicodeEncoding(UnicodeEncoding::Utf8);
188
+ vector<uint8_t> data(len);
189
+ reader.ReadBytes(data);
190
+
191
+ response = string(CheckedReinterpretCast<char *>(data.data()), data.size());
192
+ } else {
193
+ auto buffer = reader.ReadBuffer(len);
194
+ auto data = CryptographicBuffer::EncodeToBase64String(buffer);
195
+
196
+ response = winrt::to_string(std::wstring_view(data));
197
+ }
198
+ } catch (hresult_error const &e) {
199
+ return self->Fail(e, ErrorType::Receive);
200
+ }
201
+
202
+ // Posting inside try-catch block causes errors.
203
+ self->m_callingQueue.Post([self, response = std::move(response), messageType = args.MessageType()]() {
204
+ if (self->m_readHandler) {
205
+ self->m_readHandler(response.length(), response, messageType == SocketMessageType::Binary);
206
+ }
207
+ });
208
+ }
209
+
210
+ void WinRTWebSocketResource2::OnClosed(IWebSocket const &sender, IWebSocketClosedEventArgs const &args) {
211
+ auto self = shared_from_this();
212
+
213
+ self->m_backgroundQueue.Post([self]() { self->m_readyState = ReadyState::Closed; });
214
+
215
+ self->m_callingQueue.Post([self]() {
216
+ if (self->m_closeHandler) {
217
+ self->m_closeHandler(self->m_closeCode, self->m_closeReason);
218
+ }
219
+ });
220
+ }
221
+
222
+ fire_and_forget WinRTWebSocketResource2::PerformConnect(Uri &&uri) noexcept {
223
+ auto self = shared_from_this();
224
+ auto coUri = std::move(uri);
225
+
226
+ co_await resume_in_queue(self->m_backgroundQueue);
227
+
228
+ auto async = self->m_socket.ConnectAsync(coUri);
229
+ co_await lessthrow_await_adapter<IAsyncAction>{async};
230
+
231
+ co_await resume_in_queue(self->m_callingQueue);
232
+
233
+ auto result = async.ErrorCode();
234
+
235
+ try {
236
+ if (result >= 0) { // Non-failing HRESULT
237
+ co_await resume_in_queue(self->m_backgroundQueue);
238
+ self->m_readyState = ReadyState::Open;
239
+
240
+ co_await resume_in_queue(self->m_callingQueue);
241
+ if (self->m_connectHandler) {
242
+ self->m_connectHandler();
243
+ }
244
+ } else {
245
+ self->Fail(std::move(result), ErrorType::Connection);
246
+ }
247
+ } catch (hresult_error const &e) {
248
+ self->Fail(e, ErrorType::Connection);
249
+ } catch (std::exception const &e) {
250
+ self->Fail(e.what(), ErrorType::Connection);
251
+ }
252
+
253
+ SetEvent(self->m_connectPerformed.get());
254
+ }
255
+
256
+ fire_and_forget WinRTWebSocketResource2::PerformClose() noexcept {
257
+ auto self = shared_from_this();
258
+
259
+ co_await resume_on_signal(self->m_connectPerformed.get());
260
+
261
+ co_await resume_in_queue(self->m_backgroundQueue);
262
+
263
+ // See https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/close
264
+ co_await self->SendPendingMessages();
265
+
266
+ try {
267
+ self->m_socket.Close(static_cast<uint16_t>(m_closeCode), winrt::to_hstring(m_closeReason));
268
+ self->m_readyState = ReadyState::Closing;
269
+ } catch (winrt::hresult_invalid_argument const &e) {
270
+ Fail(e, ErrorType::Close);
271
+ } catch (hresult_error const &e) {
272
+ Fail(e, ErrorType::Close);
273
+ } catch (const std::exception &e) {
274
+ Fail(e.what(), ErrorType::Close);
275
+ }
276
+ }
277
+
278
+ fire_and_forget WinRTWebSocketResource2::PerformWrite(string &&message, bool isBinary) noexcept {
279
+ auto self = shared_from_this();
280
+ string coMessage = std::move(message);
281
+
282
+ co_await resume_in_queue(self->m_backgroundQueue); // Ensure writes happen sequentially
283
+ self->m_outgoingMessages.emplace(std::move(coMessage), isBinary);
284
+
285
+ co_await resume_on_signal(self->m_connectPerformed.get());
286
+
287
+ co_await resume_in_queue(self->m_backgroundQueue);
288
+
289
+ co_await self->SendPendingMessages();
290
+ }
291
+
292
+ IAsyncAction WinRTWebSocketResource2::SendPendingMessages() noexcept {
293
+ auto self = shared_from_this();
294
+
295
+ while (!self->m_outgoingMessages.empty()) {
296
+ if (self->m_readyState != ReadyState::Open) {
297
+ co_return;
298
+ }
299
+
300
+ size_t length = 0;
301
+ string messageLocal;
302
+ bool isBinaryLocal;
303
+ try {
304
+ std::tie(messageLocal, isBinaryLocal) = self->m_outgoingMessages.front();
305
+ self->m_outgoingMessages.pop();
306
+ if (isBinaryLocal) {
307
+ self->m_socket.Control().MessageType(SocketMessageType::Binary);
308
+
309
+ auto buffer = CryptographicBuffer::DecodeFromBase64String(winrt::to_hstring(messageLocal));
310
+ if (buffer) {
311
+ length = buffer.Length();
312
+ self->m_writer.WriteBuffer(buffer);
313
+ }
314
+ } else {
315
+ self->m_socket.Control().MessageType(SocketMessageType::Utf8);
316
+
317
+ length = messageLocal.size();
318
+ winrt::array_view<const uint8_t> view(
319
+ CheckedReinterpretCast<const uint8_t *>(messageLocal.c_str()),
320
+ CheckedReinterpretCast<const uint8_t *>(messageLocal.c_str()) + messageLocal.length());
321
+ self->m_writer.WriteBytes(view);
322
+ }
323
+ } catch (hresult_error const &e) { // TODO: Remove after fixing unit tests exceptions.
324
+ self->Fail(e, ErrorType::Send);
325
+ co_return;
326
+ } catch (const std::exception &e) {
327
+ self->Fail(e.what(), ErrorType::Send);
328
+ co_return;
329
+ }
330
+
331
+ auto async = self->m_writer.StoreAsync();
332
+ co_await lessthrow_await_adapter<DataWriterStoreOperation>{async};
333
+
334
+ auto result = async.ErrorCode();
335
+ if (result < 0) {
336
+ Fail(std::move(result), ErrorType::Send);
337
+ }
338
+ }
339
+ }
340
+
341
+ #pragma region IWebSocketResource
342
+
343
+ void WinRTWebSocketResource2::Connect(string &&url, const Protocols &protocols, const Options &options) noexcept {
344
+ // Register MessageReceived BEFORE calling Connect
345
+ // https://learn.microsoft.com/en-us/uwp/api/windows.networking.sockets.messagewebsocket.messagereceived?view=winrt-22621
346
+ m_socket.MessageReceived([self = shared_from_this()](
347
+ IMessageWebSocket const &sender, IMessageWebSocketMessageReceivedEventArgs const &args) {
348
+ self->OnMessageReceived(sender, args);
349
+ });
350
+
351
+ m_socket.Closed([self = shared_from_this()](IWebSocket const &sender, IWebSocketClosedEventArgs const &args) {
352
+ self->OnClosed(sender, args);
353
+ });
354
+
355
+ auto supportedProtocols = m_socket.Control().SupportedProtocols();
356
+ for (const auto &protocol : protocols) {
357
+ supportedProtocols.Append(winrt::to_hstring(protocol));
358
+ }
359
+
360
+ Uri uri{nullptr};
361
+ bool hasOriginHeader{false};
362
+ try {
363
+ uri = Uri{winrt::to_hstring(url)};
364
+
365
+ for (const auto &header : options) {
366
+ m_socket.SetRequestHeader(header.first, winrt::to_hstring(header.second));
367
+ if (boost::iequals(header.first, L"Origin")) {
368
+ hasOriginHeader = true;
369
+ }
370
+ }
371
+
372
+ // #12626 - If Origin header is not provided, set to connect endpoint.
373
+ if (!hasOriginHeader) {
374
+ auto scheme = uri.SchemeName();
375
+ auto host = uri.Host();
376
+ auto port = uri.Port();
377
+
378
+ if (scheme == L"ws") {
379
+ scheme = L"http";
380
+ } else if (scheme == L"wss") {
381
+ scheme = L"https";
382
+ }
383
+
384
+ // Only add a port if a port is defined.
385
+ hstring originPort = port != 0 ? L":" + winrt::to_hstring(port) : L"";
386
+ auto origin = hstring{scheme + L"://" + host + originPort};
387
+
388
+ m_socket.SetRequestHeader(L"Origin", std::move(origin));
389
+ }
390
+ } catch (hresult_error const &e) {
391
+ Fail(e, ErrorType::Connection);
392
+
393
+ SetEvent(m_connectPerformed.get());
394
+
395
+ return;
396
+ }
397
+
398
+ PerformConnect(std::move(uri));
399
+ }
400
+
401
+ void WinRTWebSocketResource2::Ping() noexcept {}
402
+
403
+ void WinRTWebSocketResource2::Send(string &&message) noexcept {
404
+ PerformWrite(std::move(message), false);
405
+ }
406
+
407
+ void WinRTWebSocketResource2::SendBinary(string &&base64String) noexcept {
408
+ PerformWrite(std::move(base64String), true);
409
+ }
410
+
411
+ void WinRTWebSocketResource2::Close(CloseCode code, const string &reason) noexcept {
412
+ m_closeCode = code;
413
+ m_closeReason = reason;
414
+ PerformClose();
415
+ }
416
+
417
+ IWebSocketResource::ReadyState WinRTWebSocketResource2::GetReadyState() const noexcept {
418
+ return m_readyState;
419
+ }
420
+
421
+ void WinRTWebSocketResource2::SetOnConnect(function<void()> &&handler) noexcept {
422
+ m_connectHandler = std::move(handler);
423
+ }
424
+
425
+ void WinRTWebSocketResource2::SetOnPing(function<void()> && /*handler*/) noexcept {}
426
+
427
+ void WinRTWebSocketResource2::SetOnSend(function<void(size_t)> && /*handler*/) noexcept {}
428
+
429
+ void WinRTWebSocketResource2::SetOnMessage(function<void(size_t, const string &, bool isBinary)> &&handler) noexcept {
430
+ m_readHandler = std::move(handler);
431
+ }
432
+
433
+ void WinRTWebSocketResource2::SetOnClose(function<void(CloseCode, const string &)> &&handler) noexcept {
434
+ m_closeHandler = std::move(handler);
435
+ }
436
+
437
+ void WinRTWebSocketResource2::SetOnError(function<void(Error &&)> &&handler) noexcept {
438
+ m_errorHandler = std::move(handler);
439
+ }
440
+
441
+ #pragma endregion IWebSocketResource
442
+
443
+ #pragma endregion WinRTWebSocketResource2
444
+
445
+ #pragma region Legacy resource
86
446
  // private
87
447
  WinRTWebSocketResource::WinRTWebSocketResource(
88
448
  IMessageWebSocket &&socket,
@@ -331,7 +691,7 @@ void WinRTWebSocketResource::Connect(string &&url, const Protocols &protocols, c
331
691
  response = string(CheckedReinterpretCast<char *>(data.data()), data.size());
332
692
  } else {
333
693
  auto buffer = reader.ReadBuffer(len);
334
- winrt::hstring data = CryptographicBuffer::EncodeToBase64String(buffer);
694
+ hstring data = CryptographicBuffer::EncodeToBase64String(buffer);
335
695
 
336
696
  response = winrt::to_string(std::wstring_view(data));
337
697
  }
@@ -360,7 +720,7 @@ void WinRTWebSocketResource::Connect(string &&url, const Protocols &protocols, c
360
720
  }
361
721
  }
362
722
 
363
- winrt::Windows::Foundation::Collections::IVector<winrt::hstring> supportedProtocols =
723
+ winrt::Windows::Foundation::Collections::IVector<hstring> supportedProtocols =
364
724
  m_socket.Control().SupportedProtocols();
365
725
  for (const auto &protocol : protocols) {
366
726
  supportedProtocols.Append(winrt::to_hstring(protocol));
@@ -382,7 +742,10 @@ void WinRTWebSocketResource::Connect(string &&url, const Protocols &protocols, c
382
742
  scheme = L"https";
383
743
  }
384
744
 
385
- auto origin = winrt::hstring{scheme + L"://" + host + L":" + winrt::to_hstring(port)};
745
+ // Only add a port if a port is defined
746
+ hstring originPort = port != 0 ? L":" + winrt::to_hstring(port) : L"";
747
+ auto origin = hstring{scheme + L"://" + host + originPort};
748
+
386
749
  m_socket.SetRequestHeader(L"Origin", std::move(origin));
387
750
  }
388
751
 
@@ -458,4 +821,6 @@ void WinRTWebSocketResource::SetOnError(function<void(Error &&)> &&handler) noex
458
821
 
459
822
  #pragma endregion IWebSocketResource
460
823
 
824
+ #pragma endregion Legacy resource
825
+
461
826
  } // namespace Microsoft::React::Networking
@@ -16,6 +16,124 @@
16
16
 
17
17
  namespace Microsoft::React::Networking {
18
18
 
19
+ class WinRTWebSocketResource2 : public IWebSocketResource,
20
+ public std::enable_shared_from_this<WinRTWebSocketResource2> {
21
+ winrt::Windows::Networking::Sockets::IMessageWebSocket m_socket;
22
+
23
+ ///
24
+ // Connection attempt performed, either succeeding or failing
25
+ ///
26
+ winrt::handle m_connectPerformed;
27
+
28
+ ReadyState m_readyState;
29
+ Mso::DispatchQueue m_callingQueue;
30
+ Mso::DispatchQueue m_backgroundQueue;
31
+ std::queue<std::pair<std::string, bool>> m_outgoingMessages;
32
+ CloseCode m_closeCode{CloseCode::Normal};
33
+ std::string m_closeReason;
34
+
35
+ std::function<void()> m_connectHandler;
36
+ std::function<void(std::size_t, const std::string &, bool)> m_readHandler;
37
+ std::function<void(CloseCode, const std::string &)> m_closeHandler;
38
+ std::function<void(Error &&)> m_errorHandler;
39
+
40
+ winrt::Windows::Storage::Streams::IDataWriter m_writer;
41
+
42
+ void Fail(std::string &&message, ErrorType type) noexcept;
43
+ void Fail(winrt::hresult &&e, ErrorType type) noexcept;
44
+ void Fail(winrt::hresult_error const &e, ErrorType type) noexcept;
45
+
46
+ void OnMessageReceived(
47
+ winrt::Windows::Networking::Sockets::IMessageWebSocket const &,
48
+ winrt::Windows::Networking::Sockets::IMessageWebSocketMessageReceivedEventArgs const &args);
49
+
50
+ void OnClosed(
51
+ winrt::Windows::Networking::Sockets::IWebSocket const &,
52
+ winrt::Windows::Networking::Sockets::IWebSocketClosedEventArgs const &args);
53
+
54
+ winrt::fire_and_forget PerformConnect(winrt::Windows::Foundation::Uri &&uri) noexcept;
55
+ winrt::fire_and_forget PerformWrite(std::string &&message, bool isBinary) noexcept;
56
+ winrt::fire_and_forget PerformClose() noexcept;
57
+ winrt::Windows::Foundation::IAsyncAction SendPendingMessages() noexcept;
58
+
59
+ WinRTWebSocketResource2(
60
+ winrt::Windows::Networking::Sockets::IMessageWebSocket &&socket,
61
+ std::vector<winrt::Windows::Security::Cryptography::Certificates::ChainValidationResult> &&certExceptions);
62
+
63
+ public:
64
+ WinRTWebSocketResource2(
65
+ winrt::Windows::Networking::Sockets::IMessageWebSocket &&socket,
66
+ winrt::Windows::Storage::Streams::IDataWriter &&writer,
67
+ std::vector<winrt::Windows::Security::Cryptography::Certificates::ChainValidationResult> &&certExceptions,
68
+ Mso::DispatchQueue callingQueue);
69
+
70
+ WinRTWebSocketResource2(
71
+ std::vector<winrt::Windows::Security::Cryptography::Certificates::ChainValidationResult> &&certExceptions);
72
+
73
+ ~WinRTWebSocketResource2() noexcept override;
74
+
75
+ #pragma region IWebSocketResource
76
+
77
+ /// <summary>
78
+ /// <see cref="IWebSocketResource::Connect" />
79
+ /// </summary>
80
+ void Connect(std::string &&url, const Protocols &protocols, const Options &options) noexcept override;
81
+
82
+ /// <summary>
83
+ /// <see cref="IWebSocketResource::Ping" />
84
+ /// </summary>
85
+ void Ping() noexcept override;
86
+
87
+ /// <summary>
88
+ /// <see cref="IWebSocketResource::Send" />
89
+ /// </summary>
90
+ void Send(std::string &&message) noexcept override;
91
+
92
+ /// <summary>
93
+ /// <see cref="IWebSocketResource::SendBinary" />
94
+ /// </summary>
95
+ void SendBinary(std::string &&base64String) noexcept override;
96
+
97
+ /// <summary>
98
+ /// <see cref="IWebSocketResource::Close" />
99
+ /// </summary>
100
+ void Close(CloseCode code, const std::string &reason) noexcept override;
101
+
102
+ ReadyState GetReadyState() const noexcept override;
103
+
104
+ /// <summary>
105
+ /// <see cref="IWebSocketResource::SetOnConnect" />
106
+ /// </summary>
107
+ void SetOnConnect(std::function<void()> &&handler) noexcept override;
108
+
109
+ /// <summary>
110
+ /// <see cref="IWebSocketResource::SetOnPing" />
111
+ /// </summary>
112
+ void SetOnPing(std::function<void()> &&handler) noexcept override;
113
+
114
+ /// <summary>
115
+ /// <see cref="IWebSocketResource::SetOnSend" />
116
+ /// </summary>
117
+ void SetOnSend(std::function<void(std::size_t)> &&handler) noexcept override;
118
+
119
+ /// <summary>
120
+ /// <see cref="IWebSocketResource::SetOnMessage" />
121
+ /// </summary>
122
+ void SetOnMessage(std::function<void(std::size_t, const std::string &, bool isBinary)> &&handler) noexcept override;
123
+
124
+ /// <summary>
125
+ /// <see cref="IWebSocketResource::SetOnClose" />
126
+ /// </summary>
127
+ void SetOnClose(std::function<void(CloseCode, const std::string &)> &&handler) noexcept override;
128
+
129
+ /// <summary>
130
+ /// <see cref="IWebSocketResource::SetOnError" />
131
+ /// </summary>
132
+ void SetOnError(std::function<void(Error &&)> &&handler) noexcept override;
133
+
134
+ #pragma endregion IWebSocketResource
135
+ };
136
+
19
137
  class WinRTWebSocketResource : public IWebSocketResource, public std::enable_shared_from_this<WinRTWebSocketResource> {
20
138
  winrt::Windows::Networking::Sockets::IMessageWebSocket m_socket;
21
139
  // TODO: Use or remove.
@@ -147,7 +147,7 @@ void RegisterActivityIndicatorViewNativeComponent(
147
147
  userData->UpdateEventEmitter(std::make_shared<ActivityIndicatorViewEventEmitter>(eventEmitter));
148
148
  });
149
149
 
150
- if constexpr (&TUserData::FinalizeUpdate != &BaseActivityIndicatorView<TUserData>::FinalizeUpdate) {
150
+ if CONSTEXPR_SUPPORTED_ON_VIRTUAL_FN_ADDRESS (&TUserData::FinalizeUpdate != &BaseActivityIndicatorView<TUserData>::FinalizeUpdate) {
151
151
  builder.SetFinalizeUpdateHandler([](const winrt::Microsoft::ReactNative::ComponentView &view,
152
152
  winrt::Microsoft::ReactNative::ComponentViewUpdateMask mask) noexcept {
153
153
  auto userData = view.UserData().as<TUserData>();
@@ -155,7 +155,7 @@ void RegisterActivityIndicatorViewNativeComponent(
155
155
  });
156
156
  }
157
157
 
158
- if constexpr (&TUserData::UpdateState != &BaseActivityIndicatorView<TUserData>::UpdateState) {
158
+ if CONSTEXPR_SUPPORTED_ON_VIRTUAL_FN_ADDRESS (&TUserData::UpdateState != &BaseActivityIndicatorView<TUserData>::UpdateState) {
159
159
  builder.SetUpdateStateHandler([](const winrt::Microsoft::ReactNative::ComponentView &view,
160
160
  const winrt::Microsoft::ReactNative::IComponentState &newState) noexcept {
161
161
  auto userData = view.UserData().as<TUserData>();
@@ -163,7 +163,7 @@ void RegisterActivityIndicatorViewNativeComponent(
163
163
  });
164
164
  }
165
165
 
166
- if constexpr (&TUserData::MountChildComponentView != &BaseActivityIndicatorView<TUserData>::MountChildComponentView) {
166
+ if CONSTEXPR_SUPPORTED_ON_VIRTUAL_FN_ADDRESS (&TUserData::MountChildComponentView != &BaseActivityIndicatorView<TUserData>::MountChildComponentView) {
167
167
  builder.SetMountChildComponentViewHandler([](const winrt::Microsoft::ReactNative::ComponentView &view,
168
168
  const winrt::Microsoft::ReactNative::MountChildComponentViewArgs &args) noexcept {
169
169
  auto userData = view.UserData().as<TUserData>();
@@ -171,7 +171,7 @@ void RegisterActivityIndicatorViewNativeComponent(
171
171
  });
172
172
  }
173
173
 
174
- if constexpr (&TUserData::UnmountChildComponentView != &BaseActivityIndicatorView<TUserData>::UnmountChildComponentView) {
174
+ if CONSTEXPR_SUPPORTED_ON_VIRTUAL_FN_ADDRESS (&TUserData::UnmountChildComponentView != &BaseActivityIndicatorView<TUserData>::UnmountChildComponentView) {
175
175
  builder.SetUnmountChildComponentViewHandler([](const winrt::Microsoft::ReactNative::ComponentView &view,
176
176
  const winrt::Microsoft::ReactNative::UnmountChildComponentViewArgs &args) noexcept {
177
177
  auto userData = view.UserData().as<TUserData>();
@@ -181,13 +181,13 @@ void RegisterActivityIndicatorViewNativeComponent(
181
181
 
182
182
  compBuilder.SetViewComponentViewInitializer([](const winrt::Microsoft::ReactNative::ComponentView &view) noexcept {
183
183
  auto userData = winrt::make_self<TUserData>();
184
- if constexpr (&TUserData::Initialize != &BaseActivityIndicatorView<TUserData>::Initialize) {
184
+ if CONSTEXPR_SUPPORTED_ON_VIRTUAL_FN_ADDRESS (&TUserData::Initialize != &BaseActivityIndicatorView<TUserData>::Initialize) {
185
185
  userData->Initialize(view);
186
186
  }
187
187
  view.UserData(*userData);
188
188
  });
189
189
 
190
- if constexpr (&TUserData::CreateVisual != &BaseActivityIndicatorView<TUserData>::CreateVisual) {
190
+ if CONSTEXPR_SUPPORTED_ON_VIRTUAL_FN_ADDRESS (&TUserData::CreateVisual != &BaseActivityIndicatorView<TUserData>::CreateVisual) {
191
191
  compBuilder.SetCreateVisualHandler([](const winrt::Microsoft::ReactNative::ComponentView &view) noexcept {
192
192
  auto userData = view.UserData().as<TUserData>();
193
193
  return userData->CreateVisual(view);
@@ -224,7 +224,7 @@ void RegisterAndroidDrawerLayoutNativeComponent(
224
224
  userData->UpdateEventEmitter(std::make_shared<AndroidDrawerLayoutEventEmitter>(eventEmitter));
225
225
  });
226
226
 
227
- if constexpr (&TUserData::FinalizeUpdate != &BaseAndroidDrawerLayout<TUserData>::FinalizeUpdate) {
227
+ if CONSTEXPR_SUPPORTED_ON_VIRTUAL_FN_ADDRESS (&TUserData::FinalizeUpdate != &BaseAndroidDrawerLayout<TUserData>::FinalizeUpdate) {
228
228
  builder.SetFinalizeUpdateHandler([](const winrt::Microsoft::ReactNative::ComponentView &view,
229
229
  winrt::Microsoft::ReactNative::ComponentViewUpdateMask mask) noexcept {
230
230
  auto userData = view.UserData().as<TUserData>();
@@ -232,7 +232,7 @@ void RegisterAndroidDrawerLayoutNativeComponent(
232
232
  });
233
233
  }
234
234
 
235
- if constexpr (&TUserData::UpdateState != &BaseAndroidDrawerLayout<TUserData>::UpdateState) {
235
+ if CONSTEXPR_SUPPORTED_ON_VIRTUAL_FN_ADDRESS (&TUserData::UpdateState != &BaseAndroidDrawerLayout<TUserData>::UpdateState) {
236
236
  builder.SetUpdateStateHandler([](const winrt::Microsoft::ReactNative::ComponentView &view,
237
237
  const winrt::Microsoft::ReactNative::IComponentState &newState) noexcept {
238
238
  auto userData = view.UserData().as<TUserData>();
@@ -246,7 +246,7 @@ void RegisterAndroidDrawerLayoutNativeComponent(
246
246
  userData->HandleCommand(view, args);
247
247
  });
248
248
 
249
- if constexpr (&TUserData::MountChildComponentView != &BaseAndroidDrawerLayout<TUserData>::MountChildComponentView) {
249
+ if CONSTEXPR_SUPPORTED_ON_VIRTUAL_FN_ADDRESS (&TUserData::MountChildComponentView != &BaseAndroidDrawerLayout<TUserData>::MountChildComponentView) {
250
250
  builder.SetMountChildComponentViewHandler([](const winrt::Microsoft::ReactNative::ComponentView &view,
251
251
  const winrt::Microsoft::ReactNative::MountChildComponentViewArgs &args) noexcept {
252
252
  auto userData = view.UserData().as<TUserData>();
@@ -254,7 +254,7 @@ void RegisterAndroidDrawerLayoutNativeComponent(
254
254
  });
255
255
  }
256
256
 
257
- if constexpr (&TUserData::UnmountChildComponentView != &BaseAndroidDrawerLayout<TUserData>::UnmountChildComponentView) {
257
+ if CONSTEXPR_SUPPORTED_ON_VIRTUAL_FN_ADDRESS (&TUserData::UnmountChildComponentView != &BaseAndroidDrawerLayout<TUserData>::UnmountChildComponentView) {
258
258
  builder.SetUnmountChildComponentViewHandler([](const winrt::Microsoft::ReactNative::ComponentView &view,
259
259
  const winrt::Microsoft::ReactNative::UnmountChildComponentViewArgs &args) noexcept {
260
260
  auto userData = view.UserData().as<TUserData>();
@@ -264,13 +264,13 @@ void RegisterAndroidDrawerLayoutNativeComponent(
264
264
 
265
265
  compBuilder.SetViewComponentViewInitializer([](const winrt::Microsoft::ReactNative::ComponentView &view) noexcept {
266
266
  auto userData = winrt::make_self<TUserData>();
267
- if constexpr (&TUserData::Initialize != &BaseAndroidDrawerLayout<TUserData>::Initialize) {
267
+ if CONSTEXPR_SUPPORTED_ON_VIRTUAL_FN_ADDRESS (&TUserData::Initialize != &BaseAndroidDrawerLayout<TUserData>::Initialize) {
268
268
  userData->Initialize(view);
269
269
  }
270
270
  view.UserData(*userData);
271
271
  });
272
272
 
273
- if constexpr (&TUserData::CreateVisual != &BaseAndroidDrawerLayout<TUserData>::CreateVisual) {
273
+ if CONSTEXPR_SUPPORTED_ON_VIRTUAL_FN_ADDRESS (&TUserData::CreateVisual != &BaseAndroidDrawerLayout<TUserData>::CreateVisual) {
274
274
  compBuilder.SetCreateVisualHandler([](const winrt::Microsoft::ReactNative::ComponentView &view) noexcept {
275
275
  auto userData = view.UserData().as<TUserData>();
276
276
  return userData->CreateVisual(view);