react-native-windows 0.81.26 → 0.81.28

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 (38) hide show
  1. package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +3 -2
  2. package/Microsoft.ReactNative/Modules/NativeUIManager.cpp +2 -1
  3. package/Microsoft.ReactNative/ReactNativeAppBuilder.idl +3 -0
  4. package/Microsoft.ReactNative/Utils/LocalBundleReader.cpp +33 -25
  5. package/Microsoft.ReactNative/Utils/LocalBundleReader.h +5 -3
  6. package/Microsoft.ReactNative/Utils/PropertyUtils.h +1 -1
  7. package/Microsoft.ReactNative/Utils/UwpScriptStore.cpp +2 -2
  8. package/Microsoft.ReactNative/Utils/UwpScriptStore.h +3 -2
  9. package/Microsoft.ReactNative/Views/FrameworkElementViewManager.cpp +1 -1
  10. package/Microsoft.ReactNative/Views/ScrollViewManager.cpp +5 -5
  11. package/Microsoft.ReactNative/Views/TextViewManager.cpp +1 -1
  12. package/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems +16 -0
  13. package/Microsoft.ReactNative.Cxx/NativeModules.h +2 -1
  14. package/Microsoft.ReactNative.Managed/Microsoft.ReactNative.Managed.csproj +3 -3
  15. package/Microsoft.ReactNative.Managed.CodeGen/Microsoft.ReactNative.Managed.CodeGen.csproj +8 -18
  16. package/Microsoft.ReactNative.Managed.CodeGen/Properties/PublishProfiles/DeployAsTool-Debug.pubxml +1 -1
  17. package/Microsoft.ReactNative.Managed.CodeGen/Properties/PublishProfiles/DeployAsTool-Release.pubxml +1 -1
  18. package/PropertySheets/Generated/PackageVersion.g.props +3 -3
  19. package/PropertySheets/JSEngine.props +1 -1
  20. package/PropertySheets/React.Cpp.props +4 -3
  21. package/PropertySheets/WinUI.props +2 -2
  22. package/Scripts/JustMyXaml.ps1 +8 -8
  23. package/Scripts/NuGetRestoreForceEvaluateAllSolutions.ps1 +12 -18
  24. package/Scripts/UnitTest.ps1 +3 -1
  25. package/Scripts/rnw-dependencies.ps1 +27 -14
  26. package/Shared/DevSupportManager.cpp +55 -48
  27. package/Shared/DevSupportManager.h +0 -1
  28. package/Shared/Hermes/HermesSamplingProfiler.cpp +2 -4
  29. package/Shared/Modules/IWebSocketModuleContentHandler.h +15 -0
  30. package/Shared/Modules/WebSocketModule.cpp +8 -3
  31. package/Shared/Networking/DefaultBlobResource.cpp +37 -0
  32. package/Shared/Networking/DefaultBlobResource.h +12 -0
  33. package/Shared/Networking/WinRTWebSocketResource.h +5 -1
  34. package/codegen/rnwcoreJSI-generated.cpp +419 -419
  35. package/just-task.js +13 -2
  36. package/package.json +3 -3
  37. package/templates/cpp-app/windows/MyApp/MyApp.vcxproj +1 -1
  38. package/templates/cpp-lib/windows/MyLib/MyLib.vcxproj +1 -1
@@ -8,7 +8,7 @@ param(
8
8
  [string]$Check = [CheckId]::All,
9
9
 
10
10
  [Parameter(ValueFromRemainingArguments)]
11
- [ValidateSet('appDev', 'rnwDev', 'buildLab', 'vs2022', 'clone')]
11
+ [ValidateSet('appDev', 'rnwDev', 'buildLab', 'vs2026', 'clone')]
12
12
  [String[]]$Tags = @('appDev'),
13
13
  [switch]$Enterprise = $false
14
14
  )
@@ -94,7 +94,6 @@ $vsComponents = @('Microsoft.Component.MSBuild',
94
94
  $vcToolsComponent,
95
95
  'Microsoft.VisualStudio.ComponentGroup.UWP.Support',
96
96
  'Microsoft.VisualStudio.ComponentGroup.NativeDesktop.Core',
97
- 'Microsoft.VisualStudio.Component.Windows10SDK.19041',
98
97
  'Microsoft.VisualStudio.Component.Windows11SDK.22621');
99
98
 
100
99
  # UWP.VC is not needed to build the projects with msbuild, but the VS IDE requires it.
@@ -113,12 +112,12 @@ $wingetver = "1.7.11261";
113
112
 
114
113
  # The minimum VS version to check for
115
114
  # Note: For install to work, whatever min version you specify here must be met by the current package available on winget.
116
- $vsver = "17.11.0";
115
+ $vsver = "18.6.1";
117
116
 
118
117
  # The exact .NET SDK version to check for
119
- $dotnetver = "8.0";
118
+ $dotnetver = "10.0";
120
119
  # Version name of the winget package
121
- $wingetDotNetVer = "8";
120
+ $wingetDotNetVer = "10";
122
121
 
123
122
  $v = [System.Environment]::OSVersion.Version;
124
123
  if ($env:Agent_BuildDirectory) {
@@ -242,9 +241,9 @@ function InstallVS {
242
241
 
243
242
  if ($Enterprise) {
244
243
  # The CI machines need the enterprise version of VS as that is what is hardcoded in all the scripts
245
- WinGetInstall Microsoft.VisualStudio.2022.Enterprise
244
+ WinGetInstall Microsoft.VisualStudio.Enterprise
246
245
  } else {
247
- WinGetInstall Microsoft.VisualStudio.2022.Community
246
+ WinGetInstall Microsoft.VisualStudio.Community
248
247
  }
249
248
 
250
249
  $vsWhere = Get-VSWhere;
@@ -458,8 +457,8 @@ $requirements = @(
458
457
  },
459
458
  @{
460
459
  Id=[CheckId]::VSUWP;
461
- Name = "Visual Studio 2022 (>= $vsver) & req. components";
462
- Tags = @('appDev', 'vs2022');
460
+ Name = "Visual Studio 2026 (>= $vsver) & req. components";
461
+ Tags = @('appDev', 'vs2026');
463
462
  Valid = { CheckVS; }
464
463
  Install = { InstallVS };
465
464
  HasVerboseOutput = $true;
@@ -469,7 +468,7 @@ $requirements = @(
469
468
  Name = 'Node.js (LTS, >= 22.0)';
470
469
  Tags = @('appDev');
471
470
  Valid = { CheckNode; }
472
- Install = { WinGetInstall OpenJS.NodeJS.LTS "22.14.0" };
471
+ Install = { WinGetInstall OpenJS.NodeJS.22 "22.22.0"};
473
472
  HasVerboseOutput = $true;
474
473
  },
475
474
  @{
@@ -491,7 +490,7 @@ $requirements = @(
491
490
  $downloadPath = "$env:TEMP\WindowsApplicationDriver.msi"
492
491
  Write-Verbose "Downloading WinAppDriver from $url";
493
492
  Invoke-WebRequest -UseBasicParsing $url -OutFile $downloadPath
494
-
493
+
495
494
  # SDL Compliance: Verify signature (Work Item 58386093)
496
495
  $signature = Get-AuthenticodeSignature $downloadPath
497
496
  if ($signature.Status -ne "Valid") {
@@ -499,10 +498,10 @@ $requirements = @(
499
498
  throw "WinAppDriver signature verification failed"
500
499
  }
501
500
  if ($signature.SignerCertificate.Subject -notlike "*Microsoft*") {
502
- Remove-Item $downloadPath -ErrorAction SilentlyContinue
501
+ Remove-Item $downloadPath -ErrorAction SilentlyContinue
503
502
  throw "WinAppDriver not signed by Microsoft"
504
503
  }
505
-
504
+
506
505
  & $downloadPath /q
507
506
  Remove-Item $downloadPath -ErrorAction SilentlyContinue
508
507
  };
@@ -600,6 +599,9 @@ function WinGetInstall {
600
599
  Write-Verbose "Executing `winget install `"$wingetPackage`"";
601
600
  & winget install "$wingetPackage" --accept-source-agreements --accept-package-agreements
602
601
  }
602
+
603
+ # Refresh PATH environment variable to pick up newly installed tools
604
+ $env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
603
605
  }
604
606
 
605
607
  function IsElevated {
@@ -685,6 +687,17 @@ foreach ($req in $filteredRequirements)
685
687
  $LASTEXITCODE = 0;
686
688
  $outputFromInstall = Invoke-Command $req.Install -ErrorAction Stop;
687
689
 
690
+ # Re-validate after install attempt - winget may return non-zero for "already installed"
691
+ $validAfterInstall = $false;
692
+ try {
693
+ $validAfterInstall = Invoke-Command $req.Valid;
694
+ } catch { }
695
+
696
+ if ($validAfterInstall) {
697
+ $Installed++;
698
+ continue; # go to the next item
699
+ }
700
+
688
701
  if ($LASTEXITCODE -ne 0) {
689
702
  throw "Last exit code was non-zero: $LASTEXITCODE - $outputFromInstall";
690
703
  }
@@ -723,4 +736,4 @@ if ($NeedsRerun -ne 0) {
723
736
  $Tags | Out-File $MarkerFile;
724
737
  if (!$ShellInvocation) { Read-Host 'Press Enter to exit' }
725
738
  exit 0;
726
- }
739
+ }
@@ -35,7 +35,6 @@
35
35
  #include <cxxreact/MessageQueueThread.h>
36
36
  #pragma warning(pop)
37
37
 
38
- #include <future>
39
38
  #include <mutex>
40
39
 
41
40
  #include <AppModel.h>
@@ -49,61 +48,59 @@ using namespace facebook::react;
49
48
 
50
49
  namespace Microsoft::ReactNative {
51
50
 
52
- std::future<std::pair<std::string, bool>> GetJavaScriptFromServerAsync(const std::string &url) {
53
- winrt::Windows::Web::Http::Filters::HttpBaseProtocolFilter filter;
54
- filter.CacheControl().ReadBehavior(winrt::Windows::Web::Http::Filters::HttpCacheReadBehavior::NoCache);
55
- winrt::Windows::Web::Http::HttpClient httpClient(filter);
56
- winrt::Windows::Foundation::Uri uri(Microsoft::Common::Unicode::Utf8ToUtf16(url));
51
+ winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Storage::Streams::IBuffer> GetJavaScriptFromServerAsync(
52
+ const std::string &url) {
53
+ try {
54
+ winrt::Windows::Web::Http::Filters::HttpBaseProtocolFilter filter;
55
+ filter.CacheControl().ReadBehavior(winrt::Windows::Web::Http::Filters::HttpCacheReadBehavior::NoCache);
56
+ winrt::Windows::Web::Http::HttpClient httpClient(filter);
57
+ winrt::Windows::Foundation::Uri uri(Microsoft::Common::Unicode::Utf8ToUtf16(url));
57
58
 
58
- co_await winrt::resume_background();
59
+ co_await winrt::resume_background();
59
60
 
60
- winrt::Windows::Web::Http::HttpRequestMessage request(winrt::Windows::Web::Http::HttpMethod::Get(), uri);
61
- auto asyncRequest = httpClient.SendRequestAsync(request);
61
+ winrt::Windows::Web::Http::HttpRequestMessage request(winrt::Windows::Web::Http::HttpMethod::Get(), uri);
62
+ auto asyncRequest = httpClient.SendRequestAsync(request);
62
63
  #ifdef DEFAULT_CPPWINRT_EXCEPTIONS
63
- try {
64
64
  winrt::Windows::Web::Http::HttpResponseMessage response = co_await asyncRequest;
65
- } catch (winrt::hresult_error const &e) {
66
- co_return std::make_pair(
67
- Microsoft::Common::Unicode::Utf16ToUtf8(e.message().c_str(), e.message().size()).c_str(), false);
68
- }
69
65
  #else
70
- co_await lessthrow_await_adapter<winrt::Windows::Foundation::IAsyncOperationWithProgress<
71
- winrt::Windows::Web::Http::HttpResponseMessage,
72
- winrt::Windows::Web::Http::HttpProgress>>{asyncRequest};
73
-
74
- HRESULT hr = asyncRequest.ErrorCode();
75
- if (FAILED(hr)) {
76
- std::string error;
77
- if (hr == WININET_E_CANNOT_CONNECT) {
78
- error = fmt::format("A connection with the server {} could not be established.\n\nIs the packager running?", url);
79
- } else {
80
- error = fmt::format("Error 0x{:x} downloading {}.", static_cast<int>(asyncRequest.ErrorCode()), url);
66
+ co_await lessthrow_await_adapter<winrt::Windows::Foundation::IAsyncOperationWithProgress<
67
+ winrt::Windows::Web::Http::HttpResponseMessage,
68
+ winrt::Windows::Web::Http::HttpProgress>>{asyncRequest};
69
+
70
+ HRESULT hr = asyncRequest.ErrorCode();
71
+ if (FAILED(hr)) {
72
+ std::string error;
73
+ if (hr == WININET_E_CANNOT_CONNECT) {
74
+ error =
75
+ fmt::format("A connection with the server {} could not be established.\n\nIs the packager running?", url);
76
+ } else {
77
+ error = fmt::format("Error 0x{:x} downloading {}.", static_cast<int>(asyncRequest.ErrorCode()), url);
78
+ }
79
+ throw winrt::hresult_error(E_FAIL, winrt::to_hstring(error));
81
80
  }
82
- co_return std::make_pair(error, false);
83
- }
84
81
 
85
- winrt::Windows::Web::Http::HttpResponseMessage response = asyncRequest.GetResults();
82
+ winrt::Windows::Web::Http::HttpResponseMessage response = asyncRequest.GetResults();
86
83
  #endif
87
84
 
88
- winrt::Windows::Storage::Streams::IBuffer buffer = co_await response.Content().ReadAsBufferAsync();
89
- auto reader = winrt::Windows::Storage::Streams::DataReader::FromBuffer(buffer);
90
-
91
- reader.UnicodeEncoding(winrt::Windows::Storage::Streams::UnicodeEncoding::Utf8);
92
- uint32_t len = reader.UnconsumedBufferLength();
93
- std::string result;
94
- if (len > 0 || response.IsSuccessStatusCode()) {
95
- std::string data;
96
- data.resize(len);
97
- auto buf = reinterpret_cast<uint8_t *>(data.data());
98
- static_assert(
99
- sizeof(buf[0]) == sizeof(data[0]), "perf optimization relies on uint8_t and char being the same size");
100
- reader.ReadBytes(winrt::array_view(buf, buf + len));
101
- result = std::move(data);
102
- } else {
103
- result = fmt::format("HTTP Error {} downloading {}.", static_cast<int>(response.StatusCode()), url);
104
- }
85
+ winrt::Windows::Storage::Streams::IBuffer buffer = co_await response.Content().ReadAsBufferAsync();
86
+
87
+ if (!response.IsSuccessStatusCode()) {
88
+ std::string error;
89
+ if (buffer.Length() > 0) {
90
+ auto reader = winrt::Windows::Storage::Streams::DataReader::FromBuffer(buffer);
91
+ error.resize(buffer.Length());
92
+ auto buf = reinterpret_cast<uint8_t *>(error.data());
93
+ reader.ReadBytes(winrt::array_view(buf, buf + buffer.Length()));
94
+ } else {
95
+ error = fmt::format("HTTP Error {} downloading {}.", static_cast<int>(response.StatusCode()), url);
96
+ }
97
+ throw winrt::hresult_error(E_FAIL, winrt::to_hstring(error));
98
+ }
105
99
 
106
- co_return std::make_pair(std::move(result), response.IsSuccessStatusCode());
100
+ co_return buffer;
101
+ } catch (winrt::hresult_error const &) {
102
+ throw;
103
+ }
107
104
  }
108
105
 
109
106
  void LaunchDevTools(const facebook::react::DevSettings &settings) {
@@ -219,7 +216,8 @@ std::string GetPackageName(const std::string &bundleAppId) {
219
216
  return packageName;
220
217
  }
221
218
 
222
- std::future<winrt::Windows::Web::Http::HttpStatusCode> PollForLiveReload(const std::string &url) {
219
+ winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Web::Http::HttpStatusCode> PollForLiveReload(
220
+ const std::string &url) {
223
221
  winrt::Windows::Web::Http::HttpClient httpClient;
224
222
  winrt::Windows::Foundation::Uri uri(Microsoft::Common::Unicode::Utf8ToUtf16(url));
225
223
  httpClient.DefaultRequestHeaders().Connection().TryParseAdd(L"keep-alive");
@@ -349,7 +347,16 @@ std::pair<std::string, bool> GetJavaScriptFromServer(
349
347
  inlineSourceMap,
350
348
  hermesBytecodeVersion);
351
349
  try {
352
- return GetJavaScriptFromServerAsync(bundleUrl).get();
350
+ auto buffer = GetJavaScriptFromServerAsync(bundleUrl).get();
351
+ std::string result(buffer.Length(), '\0');
352
+ if (!result.empty()) {
353
+ auto reader = winrt::Windows::Storage::Streams::DataReader::FromBuffer(buffer);
354
+ reader.ReadBytes(winrt::array_view<uint8_t>{
355
+ reinterpret_cast<uint8_t *>(&result[0]), reinterpret_cast<uint8_t *>(&result[result.length()])});
356
+ }
357
+ return std::make_pair(std::move(result), true);
358
+ } catch (std::exception const &e) {
359
+ return std::make_pair(std::string{"Error: "} + e.what(), false);
353
360
  } catch (winrt::hresult_error const &e) {
354
361
  return std::make_pair(
355
362
  "Error: " + Microsoft::Common::Unicode::Utf16ToUtf8(e.message().c_str(), e.message().size()), false);
@@ -10,7 +10,6 @@
10
10
  #include <winrt/Windows.Networking.Sockets.h>
11
11
  #include <atomic>
12
12
  #include <functional>
13
- #include <future>
14
13
  #include <memory>
15
14
  #include <string>
16
15
 
@@ -32,10 +32,8 @@ auto resume_in_dispatcher(const IReactDispatcher &dispatcher) noexcept {
32
32
 
33
33
  void await_resume() const noexcept {}
34
34
 
35
- void await_suspend(std::experimental::coroutine_handle<> resume) noexcept {
36
- callback_ = [context = resume.address()]() noexcept {
37
- std::experimental::coroutine_handle<>::from_address(context)();
38
- };
35
+ void await_suspend(std::coroutine_handle<> resume) noexcept {
36
+ callback_ = [context = resume.address()]() noexcept { std::coroutine_handle<>::from_address(context)(); };
39
37
  dispatcher_.Post(std::move(callback_));
40
38
  }
41
39
 
@@ -18,11 +18,26 @@ namespace Microsoft::React {
18
18
  struct IWebSocketModuleContentHandler {
19
19
  virtual ~IWebSocketModuleContentHandler() noexcept {}
20
20
 
21
+ /// Returns true if this handler should process messages for the given socket.
22
+ virtual bool CanHandleSocket(int64_t socketId) noexcept = 0;
23
+
21
24
  virtual void ProcessMessage(std::string &&message, winrt::Microsoft::ReactNative::JSValueObject &params) noexcept = 0;
22
25
 
23
26
  virtual void ProcessMessage(
24
27
  std::vector<uint8_t> &&message,
25
28
  winrt::Microsoft::ReactNative::JSValueObject &params) noexcept = 0;
29
+
30
+ /// Check CanHandleSocket() then ProcessMessage() in one call.
31
+ /// Returns true if the message was handled.
32
+ virtual bool TryProcessMessage(
33
+ int64_t socketId,
34
+ std::string &&message,
35
+ winrt::Microsoft::ReactNative::JSValueObject &params) noexcept = 0;
36
+
37
+ virtual bool TryProcessMessage(
38
+ int64_t socketId,
39
+ std::vector<uint8_t> &&message,
40
+ winrt::Microsoft::ReactNative::JSValueObject &params) noexcept = 0;
26
41
  };
27
42
 
28
43
  } // namespace Microsoft::React
@@ -84,6 +84,7 @@ shared_ptr<IWebSocketResource> WebSocketTurboModule::CreateResource(int64_t id,
84
84
  if (auto prop = propBag.Get(BlobModuleContentHandlerPropertyId()))
85
85
  contentHandler = prop.Value().lock();
86
86
 
87
+ bool handled = false;
87
88
  if (contentHandler) {
88
89
  if (isBinary) {
89
90
  auto buffer = CryptographicBuffer::DecodeFromBase64String(winrt::to_hstring(message));
@@ -91,11 +92,15 @@ shared_ptr<IWebSocketResource> WebSocketTurboModule::CreateResource(int64_t id,
91
92
  CryptographicBuffer::CopyToByteArray(buffer, arr);
92
93
  auto data = vector<uint8_t>(arr.begin(), arr.end());
93
94
 
94
- contentHandler->ProcessMessage(std::move(data), args);
95
+ handled = contentHandler->TryProcessMessage(id, std::move(data), args);
95
96
  } else {
96
- contentHandler->ProcessMessage(string{message}, args);
97
+ handled = contentHandler->TryProcessMessage(id, string{message}, args);
97
98
  }
98
- } else {
99
+ }
100
+ // When the content handler processes the message, it takes ownership of the
101
+ // payload and populates args itself (e.g. as a blob reference), so we only
102
+ // fall back to setting args["data"] when no handler claimed the message.
103
+ if (!handled) {
99
104
  args["data"] = message;
100
105
  }
101
106
 
@@ -221,6 +221,11 @@ BlobWebSocketModuleContentHandler::BlobWebSocketModuleContentHandler(shared_ptr<
221
221
 
222
222
  #pragma region IWebSocketModuleContentHandler
223
223
 
224
+ bool BlobWebSocketModuleContentHandler::CanHandleSocket(int64_t socketId) noexcept /*override*/ {
225
+ scoped_lock lock{m_mutex};
226
+ return m_socketIds.find(socketId) != m_socketIds.end();
227
+ }
228
+
224
229
  void BlobWebSocketModuleContentHandler::ProcessMessage(
225
230
  string &&message,
226
231
  msrn::JSValueObject &params) noexcept /*override*/
@@ -241,6 +246,38 @@ void BlobWebSocketModuleContentHandler::ProcessMessage(
241
246
  params[blobKeys.Type] = blobKeys.Blob;
242
247
  }
243
248
 
249
+ bool BlobWebSocketModuleContentHandler::TryProcessMessage(
250
+ int64_t socketId,
251
+ string &&message,
252
+ msrn::JSValueObject &params) noexcept /*override*/
253
+ {
254
+ scoped_lock lock{m_mutex};
255
+ if (m_socketIds.find(socketId) == m_socketIds.end())
256
+ return false;
257
+
258
+ params[blobKeys.Data] = std::move(message);
259
+ return true;
260
+ }
261
+
262
+ bool BlobWebSocketModuleContentHandler::TryProcessMessage(
263
+ int64_t socketId,
264
+ vector<uint8_t> &&message,
265
+ msrn::JSValueObject &params) noexcept /*override*/
266
+ {
267
+ scoped_lock lock{m_mutex};
268
+ if (m_socketIds.find(socketId) == m_socketIds.end())
269
+ return false;
270
+
271
+ auto blob = msrn::JSValueObject{
272
+ {blobKeys.Offset, 0},
273
+ {blobKeys.Size, message.size()},
274
+ {blobKeys.BlobId, m_blobPersistor->StoreMessage(std::move(message))}};
275
+
276
+ params[blobKeys.Data] = std::move(blob);
277
+ params[blobKeys.Type] = blobKeys.Blob;
278
+ return true;
279
+ }
280
+
244
281
  #pragma endregion IWebSocketModuleContentHandler
245
282
 
246
283
  void BlobWebSocketModuleContentHandler::Register(int64_t socketID) noexcept {
@@ -51,11 +51,23 @@ class BlobWebSocketModuleContentHandler final : public IWebSocketModuleContentHa
51
51
 
52
52
  #pragma region IWebSocketModuleContentHandler
53
53
 
54
+ bool CanHandleSocket(int64_t socketId) noexcept override;
55
+
54
56
  void ProcessMessage(std::string &&message, winrt::Microsoft::ReactNative::JSValueObject &params) noexcept override;
55
57
 
56
58
  void ProcessMessage(std::vector<uint8_t> &&message, winrt::Microsoft::ReactNative::JSValueObject &params) noexcept
57
59
  override;
58
60
 
61
+ bool TryProcessMessage(
62
+ int64_t socketId,
63
+ std::string &&message,
64
+ winrt::Microsoft::ReactNative::JSValueObject &params) noexcept override;
65
+
66
+ bool TryProcessMessage(
67
+ int64_t socketId,
68
+ std::vector<uint8_t> &&message,
69
+ winrt::Microsoft::ReactNative::JSValueObject &params) noexcept override;
70
+
59
71
  #pragma endregion IWebSocketModuleContentHandler
60
72
 
61
73
  void Register(int64_t socketID) noexcept;
@@ -27,8 +27,12 @@ class WinRTWebSocketResource2 : public IWebSocketResource,
27
27
  void operator=(const TaskSequencer &) = delete;
28
28
 
29
29
  private:
30
+ // `experimental` is deprecated starting Visual Studio 2026
31
+ #if _MSC_VER >= 1951
32
+ using CoroHandle = std::coroutine_handle<>;
33
+ #else
30
34
  using CoroHandle = std::experimental::coroutine_handle<>;
31
-
35
+ #endif
32
36
  struct Suspender {
33
37
  CoroHandle m_handle;
34
38