react-native-windows 0.83.0-preview.2 → 0.83.0-preview.3

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.
@@ -94,7 +94,7 @@
94
94
  </ItemGroup>
95
95
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
96
96
  <ItemGroup>
97
- <PackageReference Include="boost" Version="1.83.0.0" />
97
+ <PackageReference Include="boost" Version="1.84.0.0" />
98
98
  <PackageReference Include="Microsoft.Windows.CppWinRT" Version="$(CppWinRTVersion)" PrivateAssets="all" />
99
99
  </ItemGroup>
100
100
  <ImportGroup Label="ExtensionTargets">
@@ -362,7 +362,7 @@
362
362
  <TemporaryFollyPatchFiles Include="$(MSBuildThisFileDirectory)\TEMP_UntilFollyUpdate\**\*.*" />
363
363
  </ItemGroup>
364
364
  <ItemGroup>
365
- <PackageReference Include="boost" Version="1.83.0.0" />
365
+ <PackageReference Include="boost" Version="1.84.0.0" />
366
366
  </ItemGroup>
367
367
  <Target Name="Deploy" />
368
368
  <!-- Reenable this task if we need to temporarily replace any folly files for fixes, while we wait for PRs to land in folly -->
@@ -28,8 +28,8 @@
28
28
  export default class ReactNativeVersion {
29
29
  static major: number = 0;
30
30
  static minor: number = 83;
31
- static patch: number = 0;
32
- static prerelease: string | null = 'rc.5';
31
+ static patch: number = 4;
32
+ static prerelease: string | null = null;
33
33
 
34
34
  static getVersionString(): string {
35
35
  return `${this.major}.${this.minor}.${this.patch}${this.prerelease != null ? `-${this.prerelease}` : ''}`;
@@ -146,17 +146,34 @@ if (__DEV__) {
146
146
  ? guessHostFromDevServerUrl(devServer.url)
147
147
  : 'localhost';
148
148
 
149
- // Read the optional global variable for backward compatibility.
150
- // It was added in https://github.com/facebook/react-native/commit/bf2b435322e89d0aeee8792b1c6e04656c2719a0.
151
- const port =
149
+ // Derive scheme and port from the dev server URL when possible,
150
+ // falling back to ws://host:8097 for local development.
151
+ let wsScheme = 'ws';
152
+ let port = 8097;
153
+
154
+ if (
152
155
  // $FlowFixMe[prop-missing]
153
156
  // $FlowFixMe[incompatible-use]
154
157
  window.__REACT_DEVTOOLS_PORT__ != null
155
- ? window.__REACT_DEVTOOLS_PORT__
156
- : 8097;
158
+ ) {
159
+ // $FlowFixMe[prop-missing]
160
+ port = window.__REACT_DEVTOOLS_PORT__;
161
+ } else if (devServer.bundleLoadedFromServer) {
162
+ try {
163
+ const devUrl = new URL(devServer.url);
164
+ if (devUrl.protocol === 'https:') {
165
+ wsScheme = 'wss';
166
+ }
167
+ if (devUrl.port) {
168
+ port = parseInt(devUrl.port, 10);
169
+ } else if (devUrl.protocol === 'https:') {
170
+ port = 443;
171
+ }
172
+ } catch (e) {}
173
+ }
157
174
 
158
175
  const WebSocket = require('../WebSocket/WebSocket').default;
159
- ws = new WebSocket('ws://' + host + ':' + port);
176
+ ws = new WebSocket(wsScheme + '://' + host + ':' + port);
160
177
  ws.addEventListener('close', event => {
161
178
  isWebSocketOpen = false;
162
179
  });
@@ -1023,16 +1023,16 @@ void ScrollViewComponentView::OnKeyDown(
1023
1023
  args.Handled(pageUp(true));
1024
1024
  break;
1025
1025
  case winrt::Windows::System::VirtualKey::Up:
1026
- args.Handled(lineUp(true));
1026
+ args.Handled(lineUp(false));
1027
1027
  break;
1028
1028
  case winrt::Windows::System::VirtualKey::Down:
1029
- args.Handled(lineDown(true));
1029
+ args.Handled(lineDown(false));
1030
1030
  break;
1031
1031
  case winrt::Windows::System::VirtualKey::Left:
1032
- args.Handled(lineLeft(true));
1032
+ args.Handled(lineLeft(false));
1033
1033
  break;
1034
1034
  case winrt::Windows::System::VirtualKey::Right:
1035
- args.Handled(lineRight(true));
1035
+ args.Handled(lineRight(false));
1036
1036
  break;
1037
1037
  }
1038
1038
 
@@ -1780,7 +1780,10 @@ void WindowsTextInputComponentView::DrawText() noexcept {
1780
1780
  }
1781
1781
 
1782
1782
  // TODO keep track of proper invalid rect
1783
+ // Prevent reentrancy: TxDrawD2D may call TxViewChange -> DrawText
1784
+ m_cDrawBlock++;
1783
1785
  auto hrDraw = m_textServices->TxDrawD2D(d2dDeviceContext, &rc, nullptr, TXTVIEW_ACTIVE);
1786
+ m_cDrawBlock--;
1784
1787
  winrt::check_hresult(hrDraw);
1785
1788
 
1786
1789
  // draw placeholder text if needed
@@ -426,9 +426,9 @@
426
426
  </ProjectReference>
427
427
  </ItemGroup>
428
428
  <ItemGroup>
429
- <PackageReference Include="boost" Version="1.83.0.0" />
429
+ <PackageReference Include="boost" Version="1.84.0.0" />
430
430
  <PackageReference Include="Microsoft.Windows.CppWinRT" Version="$(CppWinRTVersion)" PrivateAssets="all" />
431
- <PackageReference Include="Microsoft.JavaScript.Hermes" Version="$(HermesVersion)" />
431
+ <PackageReference Include="$(HermesPackageName)" Version="$(HermesVersion)" />
432
432
  <PackageReference Include="$(WinUIPackageName)" Version="$(WinUIPackageVersion)" Condition="'$(OverrideWinUIPackage)'!='true'" />
433
433
  <PackageReference Include="$(V8PackageName)" Version="$(V8Version)" Condition="'$(UseV8)' == 'true'" />
434
434
  </ItemGroup>
@@ -21,8 +21,8 @@
21
21
  <Import Project="$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Uwp.CppApp.targets" />
22
22
 
23
23
  <ItemGroup>
24
- <PackageReference Include="boost" Version="1.83.0.0" />
24
+ <PackageReference Include="boost" Version="1.84.0.0" />
25
25
  <PackageReference Include="Microsoft.VCRTForwarders.140" Version="1.0.2-rc" />
26
26
  </ItemGroup>
27
27
 
28
- </Project>
28
+ </Project>
@@ -23,8 +23,8 @@
23
23
  <Import Project="$(ReactNativeWindowsDir)\PropertySheets\Codegen.targets" />
24
24
 
25
25
  <ItemGroup>
26
- <PackageReference Include="boost" Version="1.83.0.0" />
26
+ <PackageReference Include="boost" Version="1.84.0.0" />
27
27
  <PackageReference Include="Microsoft.VCRTForwarders.140" Version="1.0.2-rc" />
28
28
  </ItemGroup>
29
29
 
30
- </Project>
30
+ </Project>
@@ -25,7 +25,7 @@
25
25
  <!-- WinUI package name and version are set by WinUI.props -->
26
26
  <PackageReference Include="$(WinUIPackageName)" Version="$(WinUIPackageVersion)" Condition="'$(OverrideWinUIPackage)'!='true'" />
27
27
  <!-- Hermes version is set by JSEngine.props -->
28
- <PackageReference Include="Microsoft.JavaScript.Hermes" Version="$(HermesVersion)" />
28
+ <PackageReference Include="$(HermesPackageName)" Version="$(HermesVersion)" />
29
29
  </ItemGroup>
30
30
 
31
31
  <Import Project="$(ReactNativeWindowsDir)PropertySheets\ManagedCodeGen\Microsoft.ReactNative.Managed.CodeGen.targets"
@@ -25,7 +25,7 @@
25
25
  <!-- WinUI package name and version are set by WinUI.props -->
26
26
  <PackageReference Include="$(WinUIPackageName)" Version="$(WinUIPackageVersion)" Condition="'$(OverrideWinUIPackage)'!='true'" />
27
27
  <!-- Hermes version is set by JSEngine.props -->
28
- <PackageReference Include="Microsoft.JavaScript.Hermes" Version="$(HermesVersion)" />
28
+ <PackageReference Include="$(HermesPackageName)" Version="$(HermesVersion)" />
29
29
  </ItemGroup>
30
30
 
31
31
  <!-- The props file for bundling is not set up to be just defaults, it assumes to be run at the end of the project. -->
@@ -10,11 +10,11 @@
10
10
  -->
11
11
  <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
12
12
  <PropertyGroup>
13
- <ReactNativeWindowsVersion>0.83.0-preview.2</ReactNativeWindowsVersion>
13
+ <ReactNativeWindowsVersion>0.83.0-preview.3</ReactNativeWindowsVersion>
14
14
  <ReactNativeWindowsMajor>0</ReactNativeWindowsMajor>
15
15
  <ReactNativeWindowsMinor>83</ReactNativeWindowsMinor>
16
16
  <ReactNativeWindowsPatch>0</ReactNativeWindowsPatch>
17
17
  <ReactNativeWindowsCanary>false</ReactNativeWindowsCanary>
18
- <ReactNativeWindowsCommitId>d89154d68c6b2f5f1a2355042d166f9dac8f1ba3</ReactNativeWindowsCommitId>
18
+ <ReactNativeWindowsCommitId>d23bf1e20c21916c5c28bf4d5c781aa58e3999f5</ReactNativeWindowsCommitId>
19
19
  </PropertyGroup>
20
20
  </Project>
@@ -7,8 +7,9 @@
7
7
  <UseHermes Condition="'$(UseHermes)' == ''">true</UseHermes>
8
8
  <!-- This will be true if (1) the client want to use hermes by setting UseHermes to true OR (2) We are building for UWP where dynamic switching is enabled -->
9
9
  <HermesVersion Condition="'$(HermesVersion)' == ''">0.0.0-2512.22001-bc3d0ed7</HermesVersion>
10
+ <HermesPackageName Condition="'$(HermesPackageName)' == ''">Microsoft.JavaScript.Hermes</HermesPackageName>
10
11
  <HermesPackage Condition="'$(HermesPackage)' == '' And Exists('$(PkgMicrosoft_JavaScript_Hermes)')">$(PkgMicrosoft_JavaScript_Hermes)</HermesPackage>
11
- <HermesPackage Condition="'$(HermesPackage)' == ''">$(NuGetPackageRoot)\Microsoft.JavaScript.Hermes\$(HermesVersion)</HermesPackage>
12
+ <HermesPackage Condition="'$(HermesPackage)' == ''">$(NuGetPackageRoot)\$(HermesPackageName)\$(HermesVersion)</HermesPackage>
12
13
  <EnableHermesInspectorInReleaseFlavor Condition="'$(EnableHermesInspectorInReleaseFlavor)' == ''">false</EnableHermesInspectorInReleaseFlavor>
13
14
  <!-- Disable linking Hermes into the output in cases where we need to fully rely on HermesShim -->
14
15
  <HermesNoLink Condition="'$(HermesNoLink)' == '' and '$(Configuration)' == 'Release' and '$(EnableHermesInspectorInReleaseFlavor)' != 'true'">true</HermesNoLink>
@@ -239,7 +239,7 @@
239
239
  </ProjectReference>
240
240
  </ItemGroup>
241
241
  <ItemGroup>
242
- <PackageReference Include="boost" Version="1.83.0.0" />
242
+ <PackageReference Include="boost" Version="1.84.0.0" />
243
243
  <PackageReference Include="Microsoft.Windows.CppWinRT" Version="$(CppWinRTVersion)" PrivateAssets="all" />
244
244
  </ItemGroup>
245
245
  <PropertyGroup>
@@ -0,0 +1,40 @@
1
+ # Copyright (c) Microsoft Corporation.
2
+ # Licensed under the MIT License.
3
+
4
+ <#
5
+ .SYNOPSIS
6
+ Downloads a file from a URI with retry logic.
7
+
8
+ .PARAMETER Uri
9
+ The URI to download from.
10
+
11
+ .PARAMETER OutFile
12
+ The output file path.
13
+
14
+ .PARAMETER MaxRetries
15
+ Maximum number of download attempts. Default is 3.
16
+ #>
17
+ param(
18
+ [Parameter(Mandatory)]
19
+ [string]$Uri,
20
+
21
+ [Parameter(Mandatory)]
22
+ [string]$OutFile,
23
+
24
+ [int]$MaxRetries = 3
25
+ )
26
+
27
+ Set-StrictMode -Version Latest
28
+ $ErrorActionPreference = 'Stop'
29
+
30
+ for ($i = 1; $i -le $MaxRetries; $i++) {
31
+ try {
32
+ Write-Host "Downloading $OutFile (attempt $i of $MaxRetries)"
33
+ Invoke-WebRequest -Uri $Uri -OutFile $OutFile
34
+ return
35
+ } catch {
36
+ Write-Host "Attempt $i failed: $_"
37
+ if ($i -eq $MaxRetries) { throw }
38
+ Start-Sleep -Seconds (5 * $i)
39
+ }
40
+ }
@@ -10,7 +10,7 @@
10
10
  * node vnext/Scripts/perf/compare-results.js [options]
11
11
  *
12
12
  * Options:
13
- * --results <path> Path to CI results JSON (default: .perf-results/results.json)
13
+ * --results <path> Path to CI results JSON (repeatable, default: .perf-results/results.json)
14
14
  * --baselines <dir> Path to base branch perf snapshots directory
15
15
  * --output <path> Path to write markdown report (default: .perf-results/report.md)
16
16
  * --fail-on-regression Exit 1 if regressions found (default: true in CI)
@@ -25,17 +25,29 @@ const path = require('path');
25
25
 
26
26
  function parseArgs() {
27
27
  const args = process.argv.slice(2);
28
+
29
+ // Auto-discover results files: JS perf + native perf
30
+ const defaultResults = [
31
+ '.perf-results/results.json',
32
+ '.native-perf-results/results.json',
33
+ ].filter(p => fs.existsSync(p));
34
+
28
35
  const opts = {
29
- results: '.perf-results/results.json',
36
+ results: defaultResults,
30
37
  baselines: null, // auto-detect from test file paths
31
38
  output: '.perf-results/report.md',
32
39
  failOnRegression: !!process.env.CI,
33
40
  };
34
41
 
42
+ let explicitResults = false;
35
43
  for (let i = 0; i < args.length; i++) {
36
44
  switch (args[i]) {
37
45
  case '--results':
38
- opts.results = args[++i];
46
+ if (!explicitResults) {
47
+ opts.results = [];
48
+ explicitResults = true;
49
+ }
50
+ opts.results.push(args[++i]);
39
51
  break;
40
52
  case '--baselines':
41
53
  opts.baselines = args[++i];
@@ -98,6 +110,7 @@ function compareEntry(head, base, threshold) {
98
110
  : 0;
99
111
 
100
112
  const errors = [];
113
+ const isTrackMode = threshold.mode === 'track';
101
114
 
102
115
  const absoluteDelta = head.medianDuration - base.medianDuration;
103
116
  const minAbsoluteDelta =
@@ -126,8 +139,9 @@ function compareEntry(head, base, threshold) {
126
139
  head,
127
140
  base,
128
141
  percentChange,
129
- passed: errors.length === 0,
142
+ passed: isTrackMode || errors.length === 0,
130
143
  errors,
144
+ isTrackMode,
131
145
  };
132
146
  }
133
147
 
@@ -207,6 +221,24 @@ function generateMarkdown(suiteComparisons, ciResults) {
207
221
  }
208
222
  }
209
223
 
224
+ // Track-mode warnings (not blocking)
225
+ const trackedWarnings = suiteComparisons.flatMap(s =>
226
+ s.results.filter(r => r.isTrackMode && r.errors.length > 0),
227
+ );
228
+ if (trackedWarnings.length > 0) {
229
+ md += '### ⚠️ Tracked (not blocking)\n\n';
230
+ md += '| Scenario | Baseline | Current | Change |\n';
231
+ md += '|----------|----------|---------|--------|\n';
232
+ for (const r of trackedWarnings) {
233
+ const baseline = r.base ? `${r.base.meanDuration.toFixed(2)}ms` : 'N/A';
234
+ const current = r.head ? `${r.head.meanDuration.toFixed(2)}ms` : 'N/A';
235
+ const change =
236
+ r.percentChange != null ? `+${r.percentChange.toFixed(1)}%` : 'N/A';
237
+ md += `| ${r.name} | ${baseline} | ${current} | ${change} |\n`;
238
+ }
239
+ md += '\n';
240
+ }
241
+
210
242
  // Passed suites
211
243
  const passedSuites = suiteComparisons.filter(s => !s.hasRegressions);
212
244
  if (passedSuites.length > 0) {
@@ -257,17 +289,41 @@ function generateMarkdown(suiteComparisons, ciResults) {
257
289
  function main() {
258
290
  const opts = parseArgs();
259
291
 
260
- // 1. Load CI results JSON
261
- if (!fs.existsSync(opts.results)) {
262
- console.error(`❌ Results file not found: ${opts.results}`);
292
+ // 1. Load CI results JSON (supports multiple --results paths)
293
+ const ciResults = {
294
+ suites: [],
295
+ branch: '',
296
+ commitSha: '',
297
+ timestamp: '',
298
+ summary: {
299
+ totalSuites: 0,
300
+ totalTests: 0,
301
+ passed: 0,
302
+ failed: 0,
303
+ durationMs: 0,
304
+ },
305
+ };
306
+ const resultsPaths = opts.results.filter(p => fs.existsSync(p));
307
+ if (resultsPaths.length === 0) {
308
+ console.error(`❌ No results files found: ${opts.results.join(', ')}`);
263
309
  console.error('Run perf tests with CI=true first: CI=true yarn perf:ci');
264
310
  process.exit(1);
265
311
  }
266
-
267
- const ciResults = JSON.parse(fs.readFileSync(opts.results, 'utf-8'));
268
- console.log(
269
- `📊 Loaded ${ciResults.suites.length} suite(s) from ${opts.results}`,
270
- );
312
+ for (const resultsPath of resultsPaths) {
313
+ const partial = JSON.parse(fs.readFileSync(resultsPath, 'utf-8'));
314
+ ciResults.suites.push(...(partial.suites || []));
315
+ ciResults.branch = ciResults.branch || partial.branch;
316
+ ciResults.commitSha = ciResults.commitSha || partial.commitSha;
317
+ ciResults.timestamp = ciResults.timestamp || partial.timestamp;
318
+ ciResults.summary.totalSuites += partial.summary?.totalSuites || 0;
319
+ ciResults.summary.totalTests += partial.summary?.totalTests || 0;
320
+ ciResults.summary.passed += partial.summary?.passed || 0;
321
+ ciResults.summary.failed += partial.summary?.failed || 0;
322
+ ciResults.summary.durationMs += partial.summary?.durationMs || 0;
323
+ console.log(
324
+ `📊 Loaded ${partial.suites.length} suite(s) from ${resultsPath}`,
325
+ );
326
+ }
271
327
 
272
328
  // 2. Compare each suite against its committed baseline
273
329
  const suiteComparisons = [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-windows",
3
- "version": "0.83.0-preview.2",
3
+ "version": "0.83.0-preview.3",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -26,16 +26,16 @@
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.0-preview.1",
29
+ "@react-native-windows/cli": "0.83.0-preview.2",
30
30
  "@react-native/assets": "1.0.0",
31
- "@react-native/assets-registry": "0.83.0-rc.5",
32
- "@react-native/codegen": "0.83.0-rc.5",
33
- "@react-native/community-cli-plugin": "0.83.0-rc.5",
34
- "@react-native/gradle-plugin": "0.83.0-rc.5",
35
- "@react-native/js-polyfills": "0.83.0-rc.5",
36
- "@react-native/new-app-screen": "0.83.0-rc.5",
37
- "@react-native/normalize-colors": "0.83.0-rc.5",
38
- "@react-native/virtualized-lists": "0.83.0-rc.5",
31
+ "@react-native/assets-registry": "0.83.4",
32
+ "@react-native/codegen": "0.83.4",
33
+ "@react-native/community-cli-plugin": "0.83.4",
34
+ "@react-native/gradle-plugin": "0.83.4",
35
+ "@react-native/js-polyfills": "0.83.4",
36
+ "@react-native/new-app-screen": "0.83.4",
37
+ "@react-native/normalize-colors": "0.83.4",
38
+ "@react-native/virtualized-lists": "0.83.4",
39
39
  "abort-controller": "^3.0.0",
40
40
  "anser": "^1.4.9",
41
41
  "ansi-regex": "^5.0.0",
@@ -47,7 +47,7 @@
47
47
  "event-target-shim": "^5.0.1",
48
48
  "flow-enums-runtime": "^0.0.6",
49
49
  "glob": "^7.1.1",
50
- "hermes-compiler": "0.14.0",
50
+ "hermes-compiler": "0.14.1",
51
51
  "invariant": "^2.2.4",
52
52
  "jest-environment-node": "^29.7.0",
53
53
  "memoize-one": "^5.0.0",
@@ -69,8 +69,8 @@
69
69
  "yargs": "^17.6.2"
70
70
  },
71
71
  "devDependencies": {
72
- "@react-native-windows/codegen": "0.83.0-preview.1",
73
- "@react-native/metro-config": "0.83.0-rc.5",
72
+ "@react-native-windows/codegen": "0.83.0-preview.2",
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",
76
76
  "@rnw-scripts/jest-out-of-tree-snapshot-resolver": "^1.1.42",
@@ -85,7 +85,7 @@
85
85
  "just-scripts": "^1.3.3",
86
86
  "prettier": "2.8.8",
87
87
  "react": "19.2.0",
88
- "react-native": "0.83.0-rc.5",
88
+ "react-native": "0.83.4",
89
89
  "react-native-platform-override": "0.83.0-preview.1",
90
90
  "react-refresh": "^0.14.0",
91
91
  "typescript": "5.0.4"
@@ -93,7 +93,7 @@
93
93
  "peerDependencies": {
94
94
  "@types/react": "^19.1.1",
95
95
  "react": "^19.2.0",
96
- "react-native": "0.83.0-rc.5"
96
+ "react-native": "^0.83.0"
97
97
  },
98
98
  "beachball": {
99
99
  "defaultNpmTag": "preview",