react-native-windows 0.83.0-preview.4 → 0.83.2
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/Common/unicode.cpp +36 -0
- package/Common/unicode.h +8 -0
- package/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.cpp +6 -4
- package/Microsoft.ReactNative/Fabric/Composition/TextDrawing.cpp +1 -1
- package/Microsoft.ReactNative/Fabric/Composition/TooltipService.cpp +80 -0
- package/Microsoft.ReactNative/Fabric/Composition/TooltipService.h +17 -0
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/textlayoutmanager/WindowsTextLayoutManager.cpp +1 -1
- package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +3 -2
- package/Microsoft.ReactNative/ReactNativeAppBuilder.idl +3 -0
- package/Microsoft.ReactNative/Utils/LocalBundleReader.cpp +33 -25
- package/Microsoft.ReactNative/Utils/LocalBundleReader.h +5 -3
- package/Microsoft.ReactNative/Utils/UwpScriptStore.cpp +2 -2
- package/Microsoft.ReactNative/Utils/UwpScriptStore.h +3 -2
- package/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems +16 -0
- package/Microsoft.ReactNative.Managed/Microsoft.ReactNative.Managed.csproj +3 -3
- package/Microsoft.ReactNative.Managed.CodeGen/Microsoft.ReactNative.Managed.CodeGen.csproj +10 -10
- package/Microsoft.ReactNative.Managed.CodeGen/Properties/PublishProfiles/DeployAsTool-Debug.pubxml +1 -1
- package/Microsoft.ReactNative.Managed.CodeGen/Properties/PublishProfiles/DeployAsTool-Release.pubxml +1 -1
- package/PropertySheets/Generated/PackageVersion.g.props +3 -3
- package/PropertySheets/React.Cpp.props +4 -3
- package/PropertySheets/WinUI.props +2 -2
- package/Scripts/JustMyXaml.ps1 +8 -8
- package/Scripts/UnitTest.ps1 +3 -1
- package/Scripts/creaternwapp.cmd +12 -2
- package/Scripts/creaternwlib.cmd +12 -2
- package/Scripts/rnw-dependencies.ps1 +15 -16
- package/Shared/DevSupportManager.cpp +55 -48
- package/Shared/DevSupportManager.h +0 -1
- package/Shared/Modules/IWebSocketModuleContentHandler.h +15 -0
- package/Shared/Modules/WebSocketModule.cpp +8 -3
- package/Shared/Networking/DefaultBlobResource.cpp +37 -0
- package/Shared/Networking/DefaultBlobResource.h +12 -0
- package/Shared/Networking/WinRTWebSocketResource.h +5 -1
- package/just-task.js +13 -2
- package/package.json +6 -6
- package/templates/cpp-app/windows/MyApp/MyApp.vcxproj +1 -1
- package/templates/cpp-lib/windows/MyLib/MyLib.vcxproj +1 -1
package/Scripts/JustMyXaml.ps1
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# This script enables or disables VS
|
|
1
|
+
# This script enables or disables VS 2026's JustMyXaml feature
|
|
2
2
|
[CmdletBinding()]
|
|
3
3
|
param([bool]$Enable)
|
|
4
4
|
|
|
@@ -7,14 +7,14 @@ if (!([bool](([System.Security.Principal.WindowsIdentity]::GetCurrent()).groups
|
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
$instanceId = & "$(${env:ProgramFiles(x86)})\Microsoft Visual Studio\Installer\vswhere.exe" -property instanceId
|
|
10
|
-
$hiveFile = "$($env:LocalAppData)\Microsoft\VisualStudio\
|
|
11
|
-
& reg.exe load HKLM\
|
|
12
|
-
New-PSDrive -Name
|
|
13
|
-
$currentValue = (Get-ItemProperty
|
|
10
|
+
$hiveFile = "$($env:LocalAppData)\Microsoft\VisualStudio\18.0_$instanceId\privateregistry.bin"
|
|
11
|
+
& reg.exe load HKLM\VS2026_HIVE $hiveFile | Out-Null
|
|
12
|
+
New-PSDrive -Name VS2026 -PSProvider Registry -Root HKLM\VS2026_HIVE -ErrorAction Stop | Out-Null
|
|
13
|
+
$currentValue = (Get-ItemProperty VS2026:\Software\Microsoft\VisualStudio\18.0_$instanceId\Debugger -Name EnableXamlVisualDiagnosticsJustMyXaml).EnableXamlVisualDiagnosticsJustMyXaml
|
|
14
14
|
if ($currentValue -eq 0) { $currentValue = $false; } else { $currentValue = $true; }
|
|
15
15
|
Write-Host "Current value: $currentValue"
|
|
16
16
|
if ($Enable) { $newValue = 1; } else { $newValue = 0; }
|
|
17
|
-
Set-ItemProperty
|
|
17
|
+
Set-ItemProperty VS2026:\Software\Microsoft\VisualStudio\18.0_$instanceId\Debugger -Name EnableXamlVisualDiagnosticsJustMyXaml -Value $newValue -Type DWord
|
|
18
18
|
Write-Host "New value: $Enable"
|
|
19
|
-
Remove-PSDrive -Name
|
|
20
|
-
& reg.exe unload HKLM\
|
|
19
|
+
Remove-PSDrive -Name VS2026
|
|
20
|
+
& reg.exe unload HKLM\VS2026_HIVE | Out-Null
|
package/Scripts/UnitTest.ps1
CHANGED
|
@@ -23,7 +23,9 @@ param (
|
|
|
23
23
|
"ReactCommon.UnitTests\ReactCommon.UnitTests.exe")
|
|
24
24
|
),
|
|
25
25
|
|
|
26
|
-
[System.IO.FileInfo] $VsTest =
|
|
26
|
+
[System.IO.FileInfo] $VsTest =
|
|
27
|
+
"$(& "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" -latest -property installationPath)\" +
|
|
28
|
+
"Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe"
|
|
27
29
|
)
|
|
28
30
|
|
|
29
31
|
if ($Include.Count) {
|
package/Scripts/creaternwapp.cmd
CHANGED
|
@@ -103,7 +103,7 @@ if "%R_VERSION%"=="" (
|
|
|
103
103
|
for /f "delims=" %%a in ('npm show react-native-windows@%RNW_VERSION% devDependencies.react') do @set R_VERSION=%%a
|
|
104
104
|
)
|
|
105
105
|
|
|
106
|
-
@echo creaternwapp.cmd Determining concrete versions for react@%R_VERSION%, react-native@%RN_VERSION%, @react-native-community/cli@%RNCLI_VERSION%, and react-native-windows@%RNW_VERSION%
|
|
106
|
+
@echo creaternwapp.cmd Determining concrete versions for react@%R_VERSION%, react-native@%RN_VERSION%, @react-native-community/cli@%RNCLI_VERSION%, and react-native-windows@%RNW_VERSION%
|
|
107
107
|
for /f "delims=" %%a in ('npm show react-native-windows@%RNW_VERSION% version') do @set RNW_VERSION=%%a
|
|
108
108
|
for /f "delims=" %%a in ('npm show react-native@%RN_VERSION% version') do @set RN_VERSION=%%a
|
|
109
109
|
for /f "delims=" %%a in ('npm show @react-native-community/cli@%RNCLI_VERSION% version') do @set RNCLI_VERSION=%%a
|
|
@@ -178,10 +178,20 @@ call git commit -m "add rnw dependency"
|
|
|
178
178
|
@echo creaternwapp.cmd Running init-windows with: npx --yes @react-native-community/cli@%RNCLI_VERSION% init-windows --template %RNW_TEMPLATE_TYPE% --overwrite --logging
|
|
179
179
|
call npx --yes @react-native-community/cli@%RNCLI_VERSION% init-windows --template %RNW_TEMPLATE_TYPE% --overwrite --logging
|
|
180
180
|
|
|
181
|
+
if %ERRORLEVEL% neq 0 (
|
|
182
|
+
@echo creaternwapp.cmd init-windows command not available from react-native CLI, falling back to react-native-windows-init
|
|
183
|
+
call npx --yes react-native-windows-init@%RNW_VERSION% --template %RNW_TEMPLATE_TYPE% --overwrite --logging
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
if %ERRORLEVEL% neq 0 (
|
|
187
|
+
@echo creaternwapp.cmd: Unable to initialize Windows project
|
|
188
|
+
exit /b %ERRORLEVEL%
|
|
189
|
+
)
|
|
190
|
+
|
|
181
191
|
@echo creaternwapp.cmd Done, see new %RNW_TEMPLATE_TYPE% project in %CD% with react@%R_VERSION%, react-native@%RN_VERSION%, and react-native-windows@%RNW_VERSION%
|
|
182
192
|
|
|
183
193
|
popd
|
|
184
194
|
|
|
185
195
|
endlocal
|
|
186
196
|
|
|
187
|
-
exit /b %ERRORLEVEL%
|
|
197
|
+
exit /b %ERRORLEVEL%
|
package/Scripts/creaternwlib.cmd
CHANGED
|
@@ -108,7 +108,7 @@ if "%R_VERSION%"=="" (
|
|
|
108
108
|
for /f "delims=" %%a in ('npm show react-native-windows@%RNW_VERSION% devDependencies.react') do @set R_VERSION=%%a
|
|
109
109
|
)
|
|
110
110
|
|
|
111
|
-
@echo creaternwlib.cmd Determining concrete versions for react@%R_VERSION%, react-native@%RN_VERSION%, and react-native-windows@%RNW_VERSION%
|
|
111
|
+
@echo creaternwlib.cmd Determining concrete versions for react@%R_VERSION%, react-native@%RN_VERSION%, and react-native-windows@%RNW_VERSION%
|
|
112
112
|
for /f "delims=" %%a in ('npm show react-native-windows@%RNW_VERSION% version') do @set RNW_VERSION=%%a
|
|
113
113
|
for /f "delims=" %%a in ('npm show react-native@%RN_VERSION% version') do @set RN_VERSION=%%a
|
|
114
114
|
for /f "delims=" %%a in ('npm show @react-native-community/cli@%RNCLI_VERSION% version') do @set RNCLI_VERSION=%%a
|
|
@@ -167,10 +167,20 @@ call git commit -m "chore: add rnw dependency"
|
|
|
167
167
|
@echo creaternwlib.cmd Running init-windows with: yarn react-native init-windows --template %RNW_TEMPLATE_TYPE% --overwrite --logging
|
|
168
168
|
call yarn react-native init-windows --template %RNW_TEMPLATE_TYPE% --overwrite --logging
|
|
169
169
|
|
|
170
|
+
if %ERRORLEVEL% neq 0 (
|
|
171
|
+
@echo creaternwlib.cmd init-windows command not available from react-native CLI, falling back to react-native-windows-init
|
|
172
|
+
call npx --yes react-native-windows-init@%RNW_VERSION% --template %RNW_TEMPLATE_TYPE% --overwrite --logging
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
if %ERRORLEVEL% neq 0 (
|
|
176
|
+
@echo creaternwlib.cmd: Unable to initialize Windows project
|
|
177
|
+
exit /b %ERRORLEVEL%
|
|
178
|
+
)
|
|
179
|
+
|
|
170
180
|
@echo creaternwlib.cmd Done, see new %RNW_TEMPLATE_TYPE% project in %CD% with react@%R_VERSION%, react-native@%RN_VERSION%, and react-native-windows@%RNW_VERSION%
|
|
171
181
|
|
|
172
182
|
popd
|
|
173
183
|
|
|
174
184
|
endlocal
|
|
175
185
|
|
|
176
|
-
exit /b %ERRORLEVEL%
|
|
186
|
+
exit /b %ERRORLEVEL%
|
|
@@ -8,7 +8,7 @@ param(
|
|
|
8
8
|
[string]$Check = [CheckId]::All,
|
|
9
9
|
|
|
10
10
|
[Parameter(ValueFromRemainingArguments)]
|
|
11
|
-
[ValidateSet('appDev', 'rnwDev', 'buildLab', '
|
|
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 = "
|
|
115
|
+
$vsver = "18.6.1";
|
|
117
116
|
|
|
118
117
|
# The exact .NET SDK version to check for
|
|
119
|
-
$dotnetver = "
|
|
118
|
+
$dotnetver = "10.0";
|
|
120
119
|
# Version name of the winget package
|
|
121
|
-
$wingetDotNetVer = "
|
|
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.
|
|
244
|
+
WinGetInstall Microsoft.VisualStudio.Enterprise
|
|
246
245
|
} else {
|
|
247
|
-
WinGetInstall Microsoft.VisualStudio.
|
|
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
|
|
462
|
-
Tags = @('appDev', '
|
|
460
|
+
Name = "Visual Studio 2026 (>= $vsver) & req. components";
|
|
461
|
+
Tags = @('appDev', 'vs2026');
|
|
463
462
|
Valid = { CheckVS; }
|
|
464
463
|
Install = { InstallVS };
|
|
465
464
|
HasVerboseOutput = $true;
|
|
@@ -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,7 +599,7 @@ function WinGetInstall {
|
|
|
600
599
|
Write-Verbose "Executing `winget install `"$wingetPackage`"";
|
|
601
600
|
& winget install "$wingetPackage" --accept-source-agreements --accept-package-agreements
|
|
602
601
|
}
|
|
603
|
-
|
|
602
|
+
|
|
604
603
|
# Refresh PATH environment variable to pick up newly installed tools
|
|
605
604
|
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
|
|
606
605
|
}
|
|
@@ -693,12 +692,12 @@ foreach ($req in $filteredRequirements)
|
|
|
693
692
|
try {
|
|
694
693
|
$validAfterInstall = Invoke-Command $req.Valid;
|
|
695
694
|
} catch { }
|
|
696
|
-
|
|
695
|
+
|
|
697
696
|
if ($validAfterInstall) {
|
|
698
697
|
$Installed++;
|
|
699
698
|
continue; # go to the next item
|
|
700
699
|
}
|
|
701
|
-
|
|
700
|
+
|
|
702
701
|
if ($LASTEXITCODE -ne 0) {
|
|
703
702
|
throw "Last exit code was non-zero: $LASTEXITCODE - $outputFromInstall";
|
|
704
703
|
}
|
|
@@ -737,4 +736,4 @@ if ($NeedsRerun -ne 0) {
|
|
|
737
736
|
$Tags | Out-File $MarkerFile;
|
|
738
737
|
if (!$ShellInvocation) { Read-Host 'Press Enter to exit' }
|
|
739
738
|
exit 0;
|
|
740
|
-
}
|
|
739
|
+
}
|
|
@@ -33,7 +33,6 @@
|
|
|
33
33
|
#include <cxxreact/MessageQueueThread.h>
|
|
34
34
|
#pragma warning(pop)
|
|
35
35
|
|
|
36
|
-
#include <future>
|
|
37
36
|
#include <mutex>
|
|
38
37
|
|
|
39
38
|
#include <AppModel.h>
|
|
@@ -47,61 +46,59 @@ using namespace facebook::react;
|
|
|
47
46
|
|
|
48
47
|
namespace Microsoft::ReactNative {
|
|
49
48
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
49
|
+
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Storage::Streams::IBuffer> GetJavaScriptFromServerAsync(
|
|
50
|
+
const std::string &url) {
|
|
51
|
+
try {
|
|
52
|
+
winrt::Windows::Web::Http::Filters::HttpBaseProtocolFilter filter;
|
|
53
|
+
filter.CacheControl().ReadBehavior(winrt::Windows::Web::Http::Filters::HttpCacheReadBehavior::NoCache);
|
|
54
|
+
winrt::Windows::Web::Http::HttpClient httpClient(filter);
|
|
55
|
+
winrt::Windows::Foundation::Uri uri(Microsoft::Common::Unicode::Utf8ToUtf16(url));
|
|
55
56
|
|
|
56
|
-
|
|
57
|
+
co_await winrt::resume_background();
|
|
57
58
|
|
|
58
|
-
|
|
59
|
-
|
|
59
|
+
winrt::Windows::Web::Http::HttpRequestMessage request(winrt::Windows::Web::Http::HttpMethod::Get(), uri);
|
|
60
|
+
auto asyncRequest = httpClient.SendRequestAsync(request);
|
|
60
61
|
#ifdef DEFAULT_CPPWINRT_EXCEPTIONS
|
|
61
|
-
try {
|
|
62
62
|
winrt::Windows::Web::Http::HttpResponseMessage response = co_await asyncRequest;
|
|
63
|
-
} catch (winrt::hresult_error const &e) {
|
|
64
|
-
co_return std::make_pair(
|
|
65
|
-
Microsoft::Common::Unicode::Utf16ToUtf8(e.message().c_str(), e.message().size()).c_str(), false);
|
|
66
|
-
}
|
|
67
63
|
#else
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
64
|
+
co_await lessthrow_await_adapter<winrt::Windows::Foundation::IAsyncOperationWithProgress<
|
|
65
|
+
winrt::Windows::Web::Http::HttpResponseMessage,
|
|
66
|
+
winrt::Windows::Web::Http::HttpProgress>>{asyncRequest};
|
|
67
|
+
|
|
68
|
+
HRESULT hr = asyncRequest.ErrorCode();
|
|
69
|
+
if (FAILED(hr)) {
|
|
70
|
+
std::string error;
|
|
71
|
+
if (hr == WININET_E_CANNOT_CONNECT) {
|
|
72
|
+
error =
|
|
73
|
+
fmt::format("A connection with the server {} could not be established.\n\nIs the packager running?", url);
|
|
74
|
+
} else {
|
|
75
|
+
error = fmt::format("Error 0x{:x} downloading {}.", static_cast<int>(asyncRequest.ErrorCode()), url);
|
|
76
|
+
}
|
|
77
|
+
throw winrt::hresult_error(E_FAIL, winrt::to_hstring(error));
|
|
79
78
|
}
|
|
80
|
-
co_return std::make_pair(error, false);
|
|
81
|
-
}
|
|
82
79
|
|
|
83
|
-
|
|
80
|
+
winrt::Windows::Web::Http::HttpResponseMessage response = asyncRequest.GetResults();
|
|
84
81
|
#endif
|
|
85
82
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
} else {
|
|
101
|
-
result = fmt::format("HTTP Error {} downloading {}.", static_cast<int>(response.StatusCode()), url);
|
|
102
|
-
}
|
|
83
|
+
winrt::Windows::Storage::Streams::IBuffer buffer = co_await response.Content().ReadAsBufferAsync();
|
|
84
|
+
|
|
85
|
+
if (!response.IsSuccessStatusCode()) {
|
|
86
|
+
std::string error;
|
|
87
|
+
if (buffer.Length() > 0) {
|
|
88
|
+
auto reader = winrt::Windows::Storage::Streams::DataReader::FromBuffer(buffer);
|
|
89
|
+
error.resize(buffer.Length());
|
|
90
|
+
auto buf = reinterpret_cast<uint8_t *>(error.data());
|
|
91
|
+
reader.ReadBytes(winrt::array_view(buf, buf + buffer.Length()));
|
|
92
|
+
} else {
|
|
93
|
+
error = fmt::format("HTTP Error {} downloading {}.", static_cast<int>(response.StatusCode()), url);
|
|
94
|
+
}
|
|
95
|
+
throw winrt::hresult_error(E_FAIL, winrt::to_hstring(error));
|
|
96
|
+
}
|
|
103
97
|
|
|
104
|
-
|
|
98
|
+
co_return buffer;
|
|
99
|
+
} catch (winrt::hresult_error const &) {
|
|
100
|
+
throw;
|
|
101
|
+
}
|
|
105
102
|
}
|
|
106
103
|
|
|
107
104
|
void LaunchDevTools(const facebook::react::DevSettings &settings) {
|
|
@@ -185,7 +182,8 @@ std::string GetPackageName(const std::string &bundleAppId) {
|
|
|
185
182
|
return packageName;
|
|
186
183
|
}
|
|
187
184
|
|
|
188
|
-
|
|
185
|
+
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Web::Http::HttpStatusCode> PollForLiveReload(
|
|
186
|
+
const std::string &url) {
|
|
189
187
|
winrt::Windows::Web::Http::HttpClient httpClient;
|
|
190
188
|
winrt::Windows::Foundation::Uri uri(Microsoft::Common::Unicode::Utf8ToUtf16(url));
|
|
191
189
|
httpClient.DefaultRequestHeaders().Connection().TryParseAdd(L"keep-alive");
|
|
@@ -299,7 +297,16 @@ std::pair<std::string, bool> GetJavaScriptFromServer(
|
|
|
299
297
|
inlineSourceMap,
|
|
300
298
|
hermesBytecodeVersion);
|
|
301
299
|
try {
|
|
302
|
-
|
|
300
|
+
auto buffer = GetJavaScriptFromServerAsync(bundleUrl).get();
|
|
301
|
+
std::string result(buffer.Length(), '\0');
|
|
302
|
+
if (!result.empty()) {
|
|
303
|
+
auto reader = winrt::Windows::Storage::Streams::DataReader::FromBuffer(buffer);
|
|
304
|
+
reader.ReadBytes(winrt::array_view<uint8_t>{
|
|
305
|
+
reinterpret_cast<uint8_t *>(&result[0]), reinterpret_cast<uint8_t *>(&result[result.length()])});
|
|
306
|
+
}
|
|
307
|
+
return std::make_pair(std::move(result), true);
|
|
308
|
+
} catch (std::exception const &e) {
|
|
309
|
+
return std::make_pair(std::string{"Error: "} + e.what(), false);
|
|
303
310
|
} catch (winrt::hresult_error const &e) {
|
|
304
311
|
return std::make_pair(
|
|
305
312
|
"Error: " + Microsoft::Common::Unicode::Utf16ToUtf8(e.message().c_str(), e.message().size()), false);
|
|
@@ -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 ¶ms) noexcept = 0;
|
|
22
25
|
|
|
23
26
|
virtual void ProcessMessage(
|
|
24
27
|
std::vector<uint8_t> &&message,
|
|
25
28
|
winrt::Microsoft::ReactNative::JSValueObject ¶ms) 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 ¶ms) noexcept = 0;
|
|
36
|
+
|
|
37
|
+
virtual bool TryProcessMessage(
|
|
38
|
+
int64_t socketId,
|
|
39
|
+
std::vector<uint8_t> &&message,
|
|
40
|
+
winrt::Microsoft::ReactNative::JSValueObject ¶ms) 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->
|
|
95
|
+
handled = contentHandler->TryProcessMessage(id, std::move(data), args);
|
|
95
96
|
} else {
|
|
96
|
-
contentHandler->
|
|
97
|
+
handled = contentHandler->TryProcessMessage(id, string{message}, args);
|
|
97
98
|
}
|
|
98
|
-
}
|
|
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 ¶ms) 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 ¶ms) 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 ¶ms) 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 ¶ms) noexcept override;
|
|
55
57
|
|
|
56
58
|
void ProcessMessage(std::vector<uint8_t> &&message, winrt::Microsoft::ReactNative::JSValueObject ¶ms) noexcept
|
|
57
59
|
override;
|
|
58
60
|
|
|
61
|
+
bool TryProcessMessage(
|
|
62
|
+
int64_t socketId,
|
|
63
|
+
std::string &&message,
|
|
64
|
+
winrt::Microsoft::ReactNative::JSValueObject ¶ms) noexcept override;
|
|
65
|
+
|
|
66
|
+
bool TryProcessMessage(
|
|
67
|
+
int64_t socketId,
|
|
68
|
+
std::vector<uint8_t> &&message,
|
|
69
|
+
winrt::Microsoft::ReactNative::JSValueObject ¶ms) 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
|
|
package/just-task.js
CHANGED
|
@@ -25,6 +25,7 @@ const fs = require('fs');
|
|
|
25
25
|
const {
|
|
26
26
|
registerNuGetRestoreTask,
|
|
27
27
|
} = require('@rnw-scripts/just-task/nuget-restore-task');
|
|
28
|
+
const {findPowerShell} = require('@react-native-windows/find-dotnet-tools');
|
|
28
29
|
|
|
29
30
|
option('production');
|
|
30
31
|
option('clean');
|
|
@@ -46,9 +47,9 @@ function codegen(test) {
|
|
|
46
47
|
|
|
47
48
|
function layoutMSRNCxx() {
|
|
48
49
|
if (require('os').platform() === 'win32') {
|
|
49
|
-
const powershell =
|
|
50
|
+
const powershell = findPowerShell();
|
|
50
51
|
execSync(
|
|
51
|
-
|
|
52
|
+
`"${powershell}" -NoProfile .\\Scripts\\Tfs\\Layout-MSRN-Headers.ps1 -GenerateLocalCxx`,
|
|
52
53
|
{
|
|
53
54
|
env: process.env,
|
|
54
55
|
},
|
|
@@ -84,12 +85,22 @@ registerNuGetRestoreTask({
|
|
|
84
85
|
scriptArguments: ['-SkipLockDeletion'],
|
|
85
86
|
});
|
|
86
87
|
|
|
88
|
+
function installDotnetToolsTask() {
|
|
89
|
+
execSync(
|
|
90
|
+
`dotnet tool restore --tool-manifest ${path.resolve(__dirname, 'dotnet-tools.json')}`,
|
|
91
|
+
{env: process.env},
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
task('installDotnetTools', installDotnetToolsTask);
|
|
96
|
+
|
|
87
97
|
task(
|
|
88
98
|
'build',
|
|
89
99
|
series(
|
|
90
100
|
condition('clean', () => argv().clean),
|
|
91
101
|
'copyRNLibraries',
|
|
92
102
|
'copyReadmeAndLicenseFromRoot',
|
|
103
|
+
condition('installDotnetTools', () => !process.env.TF_BUILD),
|
|
93
104
|
'layoutMSRNCxx',
|
|
94
105
|
'compileTsPlatformOverrides',
|
|
95
106
|
'restoreNuGetPackages',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-windows",
|
|
3
|
-
"version": "0.83.
|
|
3
|
+
"version": "0.83.2",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"@react-native-community/cli": "20.0.0",
|
|
27
27
|
"@react-native-community/cli-platform-android": "20.0.0",
|
|
28
28
|
"@react-native-community/cli-platform-ios": "20.0.0",
|
|
29
|
-
"@react-native-windows/cli": "0.83.
|
|
29
|
+
"@react-native-windows/cli": "0.83.2",
|
|
30
30
|
"@react-native/assets": "1.0.0",
|
|
31
31
|
"@react-native/assets-registry": "0.83.4",
|
|
32
32
|
"@react-native/codegen": "0.83.4",
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
"yargs": "^17.6.2"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
|
-
"@react-native-windows/codegen": "0.83.
|
|
72
|
+
"@react-native-windows/codegen": "0.83.1",
|
|
73
73
|
"@react-native/metro-config": "0.83.4",
|
|
74
74
|
"@rnw-scripts/babel-react-native-config": "0.0.0",
|
|
75
75
|
"@rnw-scripts/eslint-config": "1.2.38",
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
"prettier": "2.8.8",
|
|
87
87
|
"react": "19.2.0",
|
|
88
88
|
"react-native": "0.83.4",
|
|
89
|
-
"react-native-platform-override": "0.83.
|
|
89
|
+
"react-native-platform-override": "0.83.1",
|
|
90
90
|
"react-refresh": "^0.14.0",
|
|
91
91
|
"typescript": "5.0.4"
|
|
92
92
|
},
|
|
@@ -96,11 +96,11 @@
|
|
|
96
96
|
"react-native": "^0.83.0"
|
|
97
97
|
},
|
|
98
98
|
"beachball": {
|
|
99
|
-
"defaultNpmTag": "
|
|
99
|
+
"defaultNpmTag": "v0.83-stable",
|
|
100
100
|
"disallowedChangeTypes": [
|
|
101
101
|
"major",
|
|
102
102
|
"minor",
|
|
103
|
-
"
|
|
103
|
+
"prerelease",
|
|
104
104
|
"premajor",
|
|
105
105
|
"preminor",
|
|
106
106
|
"prepatch"
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
<PropertyGroup Label="Configuration">
|
|
51
51
|
<ConfigurationType>Application</ConfigurationType>
|
|
52
52
|
<CharacterSet>Unicode</CharacterSet>
|
|
53
|
-
<PlatformToolset>
|
|
53
|
+
<PlatformToolset>v145</PlatformToolset>
|
|
54
54
|
</PropertyGroup>
|
|
55
55
|
<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
|
|
56
56
|
<UseDebugLibraries>true</UseDebugLibraries>
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
<PropertyGroup Label="Configuration">
|
|
50
50
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
|
51
51
|
<CharacterSet>Unicode</CharacterSet>
|
|
52
|
-
<PlatformToolset>
|
|
52
|
+
<PlatformToolset>v145</PlatformToolset>
|
|
53
53
|
<GenerateManifest>false</GenerateManifest>
|
|
54
54
|
</PropertyGroup>
|
|
55
55
|
<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
|