mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
beeec9929b |
@@ -583,7 +583,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
node-version: ["24", "22", "20"]
|
||||
node-version: ["24", "22"]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
],
|
||||
"bugs": "https://github.com/facebook/react-native/issues",
|
||||
"engines": {
|
||||
"node": ">= 20.19.4"
|
||||
"node": ">= 22.14.0"
|
||||
},
|
||||
"files": [
|
||||
"path-support.js",
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
],
|
||||
"bugs": "https://github.com/facebook/react-native/issues",
|
||||
"engines": {
|
||||
"node": ">= 20.19.4"
|
||||
"node": ">= 22.14.0"
|
||||
},
|
||||
"files": [
|
||||
"index.js"
|
||||
|
||||
@@ -43,6 +43,6 @@
|
||||
}
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 20.19.4"
|
||||
"node": ">= 22.14.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
],
|
||||
"bugs": "https://github.com/facebook/react-native/issues",
|
||||
"engines": {
|
||||
"node": ">= 20.19.4"
|
||||
"node": ">= 22.14.0"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
|
||||
@@ -20,6 +20,6 @@
|
||||
"BUILD_INFO"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 20.19.4"
|
||||
"node": ">= 22.14.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
},
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 20.19.4",
|
||||
"node": ">= 22.14.0",
|
||||
"electron": ">=36.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
"ws": "^6.2.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 20.19.4"
|
||||
"node": ">= 22.14.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"selfsigned": "^2.4.1",
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
],
|
||||
"bugs": "https://github.com/facebook/react-native/issues",
|
||||
"engines": {
|
||||
"node": ">= 20.19.4"
|
||||
"node": ">= 22.14.0"
|
||||
},
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
|
||||
@@ -22,6 +22,6 @@
|
||||
"hermes-eslint": "0.29.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 20.19.4"
|
||||
"node": ">= 22.14.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +36,6 @@
|
||||
"hermes-eslint": "0.29.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 20.19.4"
|
||||
"node": ">= 22.14.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
],
|
||||
"bugs": "https://github.com/facebook/react-native/issues",
|
||||
"engines": {
|
||||
"node": ">= 20.19.4"
|
||||
"node": ">= 22.14.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "./gradlew build",
|
||||
|
||||
-2
@@ -18,7 +18,6 @@ import com.facebook.react.tasks.GenerateEntryPointTask
|
||||
import com.facebook.react.tasks.GeneratePackageListTask
|
||||
import com.facebook.react.utils.AgpConfiguratorUtils.configureBuildConfigFieldsForApp
|
||||
import com.facebook.react.utils.AgpConfiguratorUtils.configureBuildConfigFieldsForLibraries
|
||||
import com.facebook.react.utils.AgpConfiguratorUtils.configureBuildTypesForApp
|
||||
import com.facebook.react.utils.AgpConfiguratorUtils.configureDevServerLocation
|
||||
import com.facebook.react.utils.AgpConfiguratorUtils.configureNamespaceForLibraries
|
||||
import com.facebook.react.utils.BackwardCompatUtils.configureBackwardCompatibilityReactMap
|
||||
@@ -85,7 +84,6 @@ class ReactPlugin : Plugin<Project> {
|
||||
configureAutolinking(project, extension)
|
||||
configureCodegen(project, extension, rootExtension, isLibrary = false)
|
||||
configureResources(project, extension)
|
||||
configureBuildTypesForApp(project)
|
||||
}
|
||||
|
||||
// Library Only Configuration
|
||||
|
||||
-21
@@ -19,7 +19,6 @@ import java.net.Inet4Address
|
||||
import java.net.NetworkInterface
|
||||
import javax.xml.parsers.DocumentBuilder
|
||||
import javax.xml.parsers.DocumentBuilderFactory
|
||||
import kotlin.plus
|
||||
import org.gradle.api.Action
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.plugins.AppliedPlugin
|
||||
@@ -28,26 +27,6 @@ import org.w3c.dom.Element
|
||||
@Suppress("UnstableApiUsage")
|
||||
internal object AgpConfiguratorUtils {
|
||||
|
||||
fun configureBuildTypesForApp(project: Project) {
|
||||
val action =
|
||||
Action<AppliedPlugin> {
|
||||
project.extensions
|
||||
.getByType(ApplicationAndroidComponentsExtension::class.java)
|
||||
.finalizeDsl { ext ->
|
||||
ext.buildTypes {
|
||||
val debug =
|
||||
getByName("debug").apply {
|
||||
manifestPlaceholders["usesCleartextTraffic"] = "true"
|
||||
}
|
||||
getByName("release").apply {
|
||||
manifestPlaceholders["usesCleartextTraffic"] = "false"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
project.pluginManager.withPlugin("com.android.application", action)
|
||||
}
|
||||
|
||||
fun configureBuildConfigFieldsForApp(project: Project, extension: ReactExtension) {
|
||||
val action =
|
||||
Action<AppliedPlugin> {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
],
|
||||
"bugs": "https://github.com/facebook/react-native/issues",
|
||||
"engines": {
|
||||
"node": ">= 20.19.4"
|
||||
"node": ">= 22.14.0"
|
||||
},
|
||||
"exports": {
|
||||
".": "./src/index.js",
|
||||
|
||||
@@ -30,6 +30,6 @@
|
||||
}
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 20.19.4"
|
||||
"node": ">= 22.14.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
],
|
||||
"bugs": "https://github.com/facebook/react-native/issues",
|
||||
"engines": {
|
||||
"node": ">= 20.19.4"
|
||||
"node": ">= 22.14.0"
|
||||
},
|
||||
"files": [
|
||||
"console.js",
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
],
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 20.19.4"
|
||||
"node": ">= 22.14.0"
|
||||
},
|
||||
"main": "src/index.js",
|
||||
"files": [
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
],
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 20.19.4"
|
||||
"node": ">= 22.14.0"
|
||||
},
|
||||
"main": "src/index.js",
|
||||
"files": [
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
],
|
||||
"bugs": "https://github.com/facebook/react-native/issues",
|
||||
"engines": {
|
||||
"node": ">= 20.19.4"
|
||||
"node": ">= 22.14.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "yarn clean && node scripts/build.js --verbose",
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
],
|
||||
"bugs": "https://github.com/facebook/react-native/issues",
|
||||
"engines": {
|
||||
"node": ">= 20.19.4"
|
||||
"node": ">= 22.14.0"
|
||||
},
|
||||
"exports": {
|
||||
".": "./src/index.js",
|
||||
|
||||
@@ -8,13 +8,12 @@
|
||||
* @format
|
||||
*/
|
||||
|
||||
import Performance from '../../src/private/webapis/performance/Performance';
|
||||
import NativePerformance from '../../src/private/webapis/performance/specs/NativePerformance';
|
||||
|
||||
// In case if the native implementation of the Performance API is available, use it,
|
||||
// otherwise fall back to the legacy/default one, which only defines 'Performance.now()'
|
||||
if (NativePerformance) {
|
||||
const Performance =
|
||||
require('../../src/private/webapis/performance/Performance').default;
|
||||
// $FlowExpectedError[cannot-write]
|
||||
global.performance = new Performance();
|
||||
} else {
|
||||
|
||||
@@ -50,8 +50,9 @@ class LazyVector {
|
||||
|
||||
const_reference at(size_type pos) const {
|
||||
#ifndef _LIBCPP_NO_EXCEPTIONS
|
||||
if (!(pos < _size))
|
||||
if (!(pos < _size)) {
|
||||
throw std::out_of_range("out of range");
|
||||
}
|
||||
#else
|
||||
assert(pos < _size || !"out of range");
|
||||
#endif
|
||||
|
||||
@@ -25,11 +25,13 @@ static NSUInteger RCTDeviceFreeMemory(void)
|
||||
kern_return_t kern;
|
||||
|
||||
kern = host_page_size(host_port, &page_size);
|
||||
if (kern != KERN_SUCCESS)
|
||||
if (kern != KERN_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
kern = host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size);
|
||||
if (kern != KERN_SUCCESS)
|
||||
if (kern != KERN_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
return (vm_stat.free_count - vm_stat.speculative_count) * page_size;
|
||||
}
|
||||
|
||||
@@ -278,8 +280,9 @@ static NSUInteger RCTDeviceFreeMemory(void)
|
||||
- (void)calculateMaxBufferCount
|
||||
{
|
||||
NSUInteger bytes = CGImageGetBytesPerRow(self.currentFrame.CGImage) * CGImageGetHeight(self.currentFrame.CGImage);
|
||||
if (bytes == 0)
|
||||
if (bytes == 0) {
|
||||
bytes = 1024;
|
||||
}
|
||||
|
||||
NSUInteger max = 0;
|
||||
if (self.maxBufferSize > 0) {
|
||||
|
||||
@@ -71,8 +71,9 @@ RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : (NSCoder *)aDecoder)
|
||||
|
||||
- (void)beginRefreshingProgrammatically
|
||||
{
|
||||
if (!_hasMovedToWindow)
|
||||
if (!_hasMovedToWindow) {
|
||||
return;
|
||||
}
|
||||
|
||||
UInt64 beginRefreshingTimestamp = _currentRefreshingStateTimestamp;
|
||||
_refreshingProgrammatically = YES;
|
||||
@@ -108,8 +109,9 @@ RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : (NSCoder *)aDecoder)
|
||||
|
||||
- (void)endRefreshingProgrammatically
|
||||
{
|
||||
if (!_hasMovedToWindow)
|
||||
if (!_hasMovedToWindow) {
|
||||
return;
|
||||
}
|
||||
// The contentOffset of the scrollview MUST be greater than the contentInset before calling
|
||||
// endRefreshing otherwise the next pull to refresh will not work properly.
|
||||
UIScrollView *scrollView = self.scrollView;
|
||||
|
||||
@@ -135,10 +135,6 @@ public class ReactRootView extends FrameLayout implements RootView, ReactRoot {
|
||||
private void init() {
|
||||
setRootViewTag(ReactRootViewTagGenerator.getNextRootViewTag());
|
||||
setClipChildren(false);
|
||||
|
||||
if (ReactNativeFeatureFlags.enableFontScaleChangesUpdatingLayout()) {
|
||||
DisplayMetricsHolder.initDisplayMetrics(getContext().getApplicationContext());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -16,8 +16,9 @@ using namespace facebook::react;
|
||||
namespace {
|
||||
int tempFileFromString(std::string contents) {
|
||||
const char* tmpDir = getenv("TMPDIR");
|
||||
if (tmpDir == nullptr)
|
||||
if (tmpDir == nullptr) {
|
||||
tmpDir = "/tmp";
|
||||
}
|
||||
std::string tmp{tmpDir};
|
||||
tmp += "/temp.XXXXXX";
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
],
|
||||
"bugs": "https://github.com/facebook/react-native/issues",
|
||||
"engines": {
|
||||
"node": ">= 20.19.4"
|
||||
"node": ">= 22.14.0"
|
||||
},
|
||||
"bin": {
|
||||
"react-native": "cli.js"
|
||||
|
||||
@@ -15,11 +15,9 @@ import type {
|
||||
PerformanceEntryJSON,
|
||||
} from './PerformanceEntry';
|
||||
|
||||
import {warnNoNativePerformance} from './internals/Utilities';
|
||||
import {PerformanceEntry} from './PerformanceEntry';
|
||||
import MaybeNativePerformance from './specs/NativePerformance';
|
||||
import nullthrows from 'nullthrows';
|
||||
|
||||
const NativePerformance = nullthrows(MaybeNativePerformance);
|
||||
import NativePerformance from './specs/NativePerformance';
|
||||
|
||||
export type PerformanceEventTimingJSON = {
|
||||
...PerformanceEntryJSON,
|
||||
@@ -88,8 +86,14 @@ function getCachedEventCounts(): Map<string, number> {
|
||||
return cachedEventCounts;
|
||||
}
|
||||
|
||||
if (!NativePerformance || !NativePerformance?.getEventCounts) {
|
||||
warnNoNativePerformance();
|
||||
cachedEventCounts = new Map();
|
||||
return cachedEventCounts;
|
||||
}
|
||||
|
||||
const eventCounts = new Map<string, number>(
|
||||
NativePerformance.getEventCounts() ?? [],
|
||||
NativePerformance.getEventCounts?.() ?? [],
|
||||
);
|
||||
cachedEventCounts = eventCounts;
|
||||
|
||||
|
||||
@@ -35,9 +35,8 @@ import {
|
||||
} from './internals/Utilities';
|
||||
import MemoryInfo from './MemoryInfo';
|
||||
import ReactNativeStartupTiming from './ReactNativeStartupTiming';
|
||||
import MaybeNativePerformance from './specs/NativePerformance';
|
||||
import NativePerformance from './specs/NativePerformance';
|
||||
import {PerformanceMark, PerformanceMeasure} from './UserTiming';
|
||||
import nullthrows from 'nullthrows';
|
||||
|
||||
export type PerformanceMeasureOptions =
|
||||
| $ReadOnly<{
|
||||
@@ -59,13 +58,11 @@ export type PerformanceMeasureOptions =
|
||||
const ENTRY_TYPES_AVAILABLE_FROM_TIMELINE: $ReadOnlyArray<PerformanceEntryType> =
|
||||
['mark', 'measure'];
|
||||
|
||||
const NativePerformance = nullthrows(MaybeNativePerformance);
|
||||
|
||||
const cachedReportMark = NativePerformance.reportMark;
|
||||
const cachedReportMeasure = NativePerformance.reportMeasure;
|
||||
const cachedGetMarkTime = NativePerformance.getMarkTime;
|
||||
const cachedNativeClearMarks = NativePerformance.clearMarks;
|
||||
const cachedNativeClearMeasures = NativePerformance.clearMeasures;
|
||||
const cachedReportMark = NativePerformance?.reportMark;
|
||||
const cachedReportMeasure = NativePerformance?.reportMeasure;
|
||||
const cachedGetMarkTime = NativePerformance?.getMarkTime;
|
||||
const cachedNativeClearMarks = NativePerformance?.clearMarks;
|
||||
const cachedNativeClearMeasures = NativePerformance?.clearMeasures;
|
||||
|
||||
const MARK_OPTIONS_REUSABLE_OBJECT: {...PerformanceMarkOptions} = {
|
||||
startTime: 0,
|
||||
@@ -101,46 +98,53 @@ export default class Performance {
|
||||
|
||||
// Get the current JS memory information.
|
||||
get memory(): MemoryInfo {
|
||||
// JSI API implementations may have different variants of names for the JS
|
||||
// heap information we need here. We will parse the result based on our
|
||||
// guess of the implementation for now.
|
||||
const memoryInfo = NativePerformance.getSimpleMemoryInfo();
|
||||
if (memoryInfo.hasOwnProperty('hermes_heapSize')) {
|
||||
// We got memory information from Hermes
|
||||
const {
|
||||
hermes_heapSize: totalJSHeapSize,
|
||||
hermes_allocatedBytes: usedJSHeapSize,
|
||||
} = memoryInfo;
|
||||
if (NativePerformance?.getSimpleMemoryInfo) {
|
||||
// JSI API implementations may have different variants of names for the JS
|
||||
// heap information we need here. We will parse the result based on our
|
||||
// guess of the implementation for now.
|
||||
const memoryInfo = NativePerformance.getSimpleMemoryInfo();
|
||||
if (memoryInfo.hasOwnProperty('hermes_heapSize')) {
|
||||
// We got memory information from Hermes
|
||||
const {
|
||||
hermes_heapSize: totalJSHeapSize,
|
||||
hermes_allocatedBytes: usedJSHeapSize,
|
||||
} = memoryInfo;
|
||||
|
||||
return new MemoryInfo({
|
||||
jsHeapSizeLimit: null, // We don't know the heap size limit from Hermes.
|
||||
totalJSHeapSize,
|
||||
usedJSHeapSize,
|
||||
});
|
||||
} else {
|
||||
// JSC and V8 has no native implementations for memory information in JSI::Instrumentation
|
||||
return new MemoryInfo();
|
||||
return new MemoryInfo({
|
||||
jsHeapSizeLimit: null, // We don't know the heap size limit from Hermes.
|
||||
totalJSHeapSize,
|
||||
usedJSHeapSize,
|
||||
});
|
||||
} else {
|
||||
// JSC and V8 has no native implementations for memory information in JSI::Instrumentation
|
||||
return new MemoryInfo();
|
||||
}
|
||||
}
|
||||
|
||||
return new MemoryInfo();
|
||||
}
|
||||
|
||||
// Startup metrics is not used in web, but only in React Native.
|
||||
get rnStartupTiming(): ReactNativeStartupTiming {
|
||||
const {
|
||||
startTime,
|
||||
endTime,
|
||||
initializeRuntimeStart,
|
||||
initializeRuntimeEnd,
|
||||
executeJavaScriptBundleEntryPointStart,
|
||||
executeJavaScriptBundleEntryPointEnd,
|
||||
} = NativePerformance.getReactNativeStartupTiming();
|
||||
return new ReactNativeStartupTiming({
|
||||
startTime,
|
||||
endTime,
|
||||
initializeRuntimeStart,
|
||||
initializeRuntimeEnd,
|
||||
executeJavaScriptBundleEntryPointStart,
|
||||
executeJavaScriptBundleEntryPointEnd,
|
||||
});
|
||||
if (NativePerformance?.getReactNativeStartupTiming) {
|
||||
const {
|
||||
startTime,
|
||||
endTime,
|
||||
initializeRuntimeStart,
|
||||
initializeRuntimeEnd,
|
||||
executeJavaScriptBundleEntryPointStart,
|
||||
executeJavaScriptBundleEntryPointEnd,
|
||||
} = NativePerformance.getReactNativeStartupTiming();
|
||||
return new ReactNativeStartupTiming({
|
||||
startTime,
|
||||
endTime,
|
||||
initializeRuntimeStart,
|
||||
initializeRuntimeEnd,
|
||||
executeJavaScriptBundleEntryPointStart,
|
||||
executeJavaScriptBundleEntryPointEnd,
|
||||
});
|
||||
}
|
||||
return new ReactNativeStartupTiming();
|
||||
}
|
||||
|
||||
mark(
|
||||
@@ -213,6 +217,11 @@ export default class Performance {
|
||||
}
|
||||
|
||||
clearMarks(markName?: string): void {
|
||||
if (!cachedNativeClearMarks) {
|
||||
warnNoNativePerformance();
|
||||
return;
|
||||
}
|
||||
|
||||
cachedNativeClearMarks(markName);
|
||||
}
|
||||
|
||||
@@ -405,6 +414,11 @@ export default class Performance {
|
||||
}
|
||||
|
||||
clearMeasures(measureName?: string): void {
|
||||
if (!cachedNativeClearMeasures) {
|
||||
warnNoNativePerformance();
|
||||
return;
|
||||
}
|
||||
|
||||
cachedNativeClearMeasures(measureName);
|
||||
}
|
||||
|
||||
@@ -420,6 +434,10 @@ export default class Performance {
|
||||
* https://www.w3.org/TR/performance-timeline/#extensions-to-the-performance-interface
|
||||
*/
|
||||
getEntries(): PerformanceEntryList {
|
||||
if (!NativePerformance?.getEntries) {
|
||||
warnNoNativePerformance();
|
||||
return [];
|
||||
}
|
||||
return NativePerformance.getEntries().map(rawToPerformanceEntry);
|
||||
}
|
||||
|
||||
@@ -432,6 +450,11 @@ export default class Performance {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (!NativePerformance?.getEntriesByType) {
|
||||
warnNoNativePerformance();
|
||||
return [];
|
||||
}
|
||||
|
||||
return NativePerformance.getEntriesByType(
|
||||
performanceEntryTypeToRaw(entryType),
|
||||
).map(rawToPerformanceEntry);
|
||||
@@ -449,6 +472,11 @@ export default class Performance {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (!NativePerformance?.getEntriesByName) {
|
||||
warnNoNativePerformance();
|
||||
return [];
|
||||
}
|
||||
|
||||
return NativePerformance.getEntriesByName(
|
||||
entryName,
|
||||
entryType != null ? performanceEntryTypeToRaw(entryType) : undefined,
|
||||
|
||||
+29
-8
@@ -21,13 +21,12 @@ import {
|
||||
rawToPerformanceEntry,
|
||||
rawToPerformanceEntryType,
|
||||
} from './internals/RawPerformanceEntry';
|
||||
import MaybeNativePerformance from './specs/NativePerformance';
|
||||
import {warnNoNativePerformance} from './internals/Utilities';
|
||||
import NativePerformance from './specs/NativePerformance';
|
||||
import nullthrows from 'nullthrows';
|
||||
|
||||
export {PerformanceEntry} from './PerformanceEntry';
|
||||
|
||||
const NativePerformance = nullthrows(MaybeNativePerformance);
|
||||
|
||||
export class PerformanceObserverEntryList {
|
||||
#entries: PerformanceEntryList;
|
||||
|
||||
@@ -76,6 +75,13 @@ export interface PerformanceObserverInit {
|
||||
}
|
||||
|
||||
function getSupportedPerformanceEntryTypes(): $ReadOnlyArray<PerformanceEntryType> {
|
||||
if (!NativePerformance) {
|
||||
return Object.freeze([]);
|
||||
}
|
||||
if (!NativePerformance.getSupportedPerformanceEntryTypes) {
|
||||
// fallback if getSupportedPerformanceEntryTypes is not defined on native side
|
||||
return Object.freeze(['mark', 'measure', 'event']);
|
||||
}
|
||||
return Object.freeze(
|
||||
NativePerformance.getSupportedPerformanceEntryTypes().map(
|
||||
rawToPerformanceEntryType,
|
||||
@@ -114,6 +120,11 @@ export class PerformanceObserver {
|
||||
}
|
||||
|
||||
observe(options: PerformanceObserverInit): void {
|
||||
if (!NativePerformance || NativePerformance.observe == null) {
|
||||
warnNoNativePerformance();
|
||||
return;
|
||||
}
|
||||
|
||||
this.#validateObserveOptions(options);
|
||||
|
||||
if (this.#nativeObserverHandle == null) {
|
||||
@@ -124,12 +135,12 @@ export class PerformanceObserver {
|
||||
|
||||
if (options.entryTypes) {
|
||||
this.#type = 'multiple';
|
||||
NativePerformance.observe(observerHandle, {
|
||||
NativePerformance.observe?.(observerHandle, {
|
||||
entryTypes: options.entryTypes.map(performanceEntryTypeToRaw),
|
||||
});
|
||||
} else if (options.type) {
|
||||
this.#type = 'single';
|
||||
NativePerformance.observe(observerHandle, {
|
||||
NativePerformance.observe?.(observerHandle, {
|
||||
type: performanceEntryTypeToRaw(options.type),
|
||||
buffered: options.buffered,
|
||||
durationThreshold: options.durationThreshold,
|
||||
@@ -138,7 +149,12 @@ export class PerformanceObserver {
|
||||
}
|
||||
|
||||
disconnect(): void {
|
||||
if (this.#nativeObserverHandle == null) {
|
||||
if (!NativePerformance) {
|
||||
warnNoNativePerformance();
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.#nativeObserverHandle == null || !NativePerformance.disconnect) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -146,11 +162,16 @@ export class PerformanceObserver {
|
||||
}
|
||||
|
||||
#createNativeObserver(): OpaqueNativeObserverHandle | null {
|
||||
if (!NativePerformance || !NativePerformance.createObserver) {
|
||||
warnNoNativePerformance();
|
||||
return null;
|
||||
}
|
||||
|
||||
this.#calledAtLeastOnce = false;
|
||||
|
||||
const observerHandle: OpaqueNativeObserverHandle =
|
||||
NativePerformance.createObserver(() => {
|
||||
const rawEntries = NativePerformance.takeRecords(
|
||||
const rawEntries = NativePerformance.takeRecords?.(
|
||||
observerHandle,
|
||||
true, // sort records
|
||||
);
|
||||
@@ -164,7 +185,7 @@ export class PerformanceObserver {
|
||||
let droppedEntriesCount = 0;
|
||||
if (!this.#calledAtLeastOnce) {
|
||||
droppedEntriesCount =
|
||||
NativePerformance.getDroppedEntriesCount(observerHandle);
|
||||
NativePerformance.getDroppedEntriesCount?.(observerHandle) ?? 0;
|
||||
this.#calledAtLeastOnce = true;
|
||||
}
|
||||
|
||||
|
||||
+2
-4
@@ -13,7 +13,7 @@ import '@react-native/fantom/src/setUpDefaultReactNativeEnvironment';
|
||||
import type Performance from 'react-native/src/private/webapis/performance/Performance';
|
||||
import type {PerformanceObserverEntryList} from 'react-native/src/private/webapis/performance/PerformanceObserver';
|
||||
|
||||
import MaybeNativePerformance from '../specs/NativePerformance';
|
||||
import NativePerformance from '../specs/NativePerformance';
|
||||
import * as Fantom from '@react-native/fantom';
|
||||
import nullthrows from 'nullthrows';
|
||||
import {useState} from 'react';
|
||||
@@ -22,8 +22,6 @@ import setUpPerformanceObserver from 'react-native/src/private/setup/setUpPerfor
|
||||
import {PerformanceEventTiming} from 'react-native/src/private/webapis/performance/EventTiming';
|
||||
import {PerformanceObserver} from 'react-native/src/private/webapis/performance/PerformanceObserver';
|
||||
|
||||
const NativePerformance = nullthrows(MaybeNativePerformance);
|
||||
|
||||
setUpPerformanceObserver();
|
||||
|
||||
declare var performance: Performance;
|
||||
@@ -195,7 +193,7 @@ describe('Event Timing API', () => {
|
||||
});
|
||||
|
||||
it('reports number of dispatched events via performance.eventCounts', () => {
|
||||
NativePerformance.clearEventCountsForTesting?.();
|
||||
NativePerformance?.clearEventCountsForTesting?.();
|
||||
|
||||
const root = Fantom.createRoot();
|
||||
Fantom.runTask(() => {
|
||||
|
||||
+10
-13
@@ -18,11 +18,8 @@ import type {
|
||||
|
||||
import ensureInstance from '../../../__tests__/utilities/ensureInstance';
|
||||
import DOMException from '../../errors/DOMException';
|
||||
import MaybeNativePerformance from '../specs/NativePerformance';
|
||||
import NativePerformance from '../specs/NativePerformance';
|
||||
import {PerformanceMark, PerformanceMeasure} from '../UserTiming';
|
||||
import nullthrows from 'nullthrows';
|
||||
|
||||
const NativePerformance = nullthrows(MaybeNativePerformance);
|
||||
|
||||
declare var performance: Performance;
|
||||
|
||||
@@ -47,7 +44,7 @@ describe('User Timing', () => {
|
||||
|
||||
describe('mark', () => {
|
||||
it('works with default timestamp', () => {
|
||||
NativePerformance.setCurrentTimeStampForTesting?.(25);
|
||||
NativePerformance?.setCurrentTimeStampForTesting?.(25);
|
||||
|
||||
const mark = performance.mark('mark-now');
|
||||
|
||||
@@ -147,7 +144,7 @@ describe('User Timing', () => {
|
||||
describe('measure', () => {
|
||||
describe('with measureOptions', () => {
|
||||
it('uses 0 as default start and now as default end', () => {
|
||||
NativePerformance.setCurrentTimeStampForTesting?.(25);
|
||||
NativePerformance?.setCurrentTimeStampForTesting?.(25);
|
||||
|
||||
const measure = performance.measure('measure-with-defaults', {});
|
||||
|
||||
@@ -160,7 +157,7 @@ describe('User Timing', () => {
|
||||
});
|
||||
|
||||
it('works with a start timestamp', () => {
|
||||
NativePerformance.setCurrentTimeStampForTesting?.(25);
|
||||
NativePerformance?.setCurrentTimeStampForTesting?.(25);
|
||||
|
||||
const measure = performance.measure('measure-with-start-timestamp', {
|
||||
start: 10,
|
||||
@@ -175,7 +172,7 @@ describe('User Timing', () => {
|
||||
});
|
||||
|
||||
it('works with start mark', () => {
|
||||
NativePerformance.setCurrentTimeStampForTesting?.(25);
|
||||
NativePerformance?.setCurrentTimeStampForTesting?.(25);
|
||||
|
||||
performance.mark('start-mark', {
|
||||
startTime: 10,
|
||||
@@ -194,7 +191,7 @@ describe('User Timing', () => {
|
||||
});
|
||||
|
||||
it('works with end mark', () => {
|
||||
NativePerformance.setCurrentTimeStampForTesting?.(25);
|
||||
NativePerformance?.setCurrentTimeStampForTesting?.(25);
|
||||
|
||||
performance.mark('end-mark', {
|
||||
startTime: 50,
|
||||
@@ -213,7 +210,7 @@ describe('User Timing', () => {
|
||||
});
|
||||
|
||||
it('works with start mark and end mark', () => {
|
||||
NativePerformance.setCurrentTimeStampForTesting?.(25);
|
||||
NativePerformance?.setCurrentTimeStampForTesting?.(25);
|
||||
|
||||
performance.mark('start-mark', {
|
||||
startTime: 10,
|
||||
@@ -378,7 +375,7 @@ describe('User Timing', () => {
|
||||
|
||||
describe('with startMark / endMark', () => {
|
||||
it('uses 0 as default start and now as default end', () => {
|
||||
NativePerformance.setCurrentTimeStampForTesting?.(25);
|
||||
NativePerformance?.setCurrentTimeStampForTesting?.(25);
|
||||
|
||||
const measure = performance.measure('measure-with-defaults');
|
||||
|
||||
@@ -391,7 +388,7 @@ describe('User Timing', () => {
|
||||
});
|
||||
|
||||
it('works with startMark', () => {
|
||||
NativePerformance.setCurrentTimeStampForTesting?.(25);
|
||||
NativePerformance?.setCurrentTimeStampForTesting?.(25);
|
||||
|
||||
performance.mark('start-mark', {
|
||||
startTime: 10,
|
||||
@@ -411,7 +408,7 @@ describe('User Timing', () => {
|
||||
});
|
||||
|
||||
it('works with startMark and endMark', () => {
|
||||
NativePerformance.setCurrentTimeStampForTesting?.(25);
|
||||
NativePerformance?.setCurrentTimeStampForTesting?.(25);
|
||||
|
||||
performance.mark('start-mark', {
|
||||
startTime: 10,
|
||||
|
||||
+13
-13
@@ -53,7 +53,7 @@ export type PerformanceObserverInit = {
|
||||
};
|
||||
|
||||
export interface Spec extends TurboModule {
|
||||
+now: () => number;
|
||||
+now?: () => number;
|
||||
+reportMark?: (name: string, startTime: number, entry: mixed) => void;
|
||||
+reportMeasure?: (
|
||||
name: string,
|
||||
@@ -62,36 +62,36 @@ export interface Spec extends TurboModule {
|
||||
entry: mixed,
|
||||
) => void;
|
||||
+getMarkTime?: (name: string) => ?number;
|
||||
+clearMarks: (entryName?: string) => void;
|
||||
+clearMeasures: (entryName?: string) => void;
|
||||
+getEntries: () => $ReadOnlyArray<RawPerformanceEntry>;
|
||||
+getEntriesByName: (
|
||||
+clearMarks?: (entryName?: string) => void;
|
||||
+clearMeasures?: (entryName?: string) => void;
|
||||
+getEntries?: () => $ReadOnlyArray<RawPerformanceEntry>;
|
||||
+getEntriesByName?: (
|
||||
entryName: string,
|
||||
entryType?: ?RawPerformanceEntryType,
|
||||
) => $ReadOnlyArray<RawPerformanceEntry>;
|
||||
+getEntriesByType: (
|
||||
+getEntriesByType?: (
|
||||
entryType: RawPerformanceEntryType,
|
||||
) => $ReadOnlyArray<RawPerformanceEntry>;
|
||||
+getEventCounts: () => $ReadOnlyArray<[string, number]>;
|
||||
+getEventCounts?: () => $ReadOnlyArray<[string, number]>;
|
||||
+getSimpleMemoryInfo: () => NativeMemoryInfo;
|
||||
+getReactNativeStartupTiming: () => ReactNativeStartupTiming;
|
||||
|
||||
+createObserver: (
|
||||
+createObserver?: (
|
||||
callback: NativeBatchedObserverCallback,
|
||||
) => OpaqueNativeObserverHandle;
|
||||
+getDroppedEntriesCount: (observer: OpaqueNativeObserverHandle) => number;
|
||||
+getDroppedEntriesCount?: (observer: OpaqueNativeObserverHandle) => number;
|
||||
|
||||
+observe: (
|
||||
+observe?: (
|
||||
observer: OpaqueNativeObserverHandle,
|
||||
options: PerformanceObserverInit,
|
||||
) => void;
|
||||
+disconnect: (observer: OpaqueNativeObserverHandle) => void;
|
||||
+takeRecords: (
|
||||
+disconnect?: (observer: OpaqueNativeObserverHandle) => void;
|
||||
+takeRecords?: (
|
||||
observer: OpaqueNativeObserverHandle,
|
||||
sort: boolean,
|
||||
) => $ReadOnlyArray<RawPerformanceEntry>;
|
||||
|
||||
+getSupportedPerformanceEntryTypes: () => $ReadOnlyArray<RawPerformanceEntryType>;
|
||||
+getSupportedPerformanceEntryTypes?: () => $ReadOnlyArray<RawPerformanceEntryType>;
|
||||
|
||||
+setCurrentTimeStampForTesting?: (timeStamp: number) => void;
|
||||
+clearEventCountsForTesting?: () => void;
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
|
||||
|
||||
<application android:usesCleartextTraffic="true" tools:targetApi="28" tools:ignore="GoogleAppIndexingWarning" />
|
||||
</manifest>
|
||||
@@ -50,7 +50,6 @@
|
||||
</queries>
|
||||
|
||||
<application
|
||||
android:usesCleartextTraffic="${usesCleartextTraffic}"
|
||||
android:name=".RNTesterApplication"
|
||||
android:allowBackup="true"
|
||||
android:banner="@drawable/tv_banner"
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
"directory": "packages/rn-tester"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 20.19.4"
|
||||
"node": ">= 22.14.0"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-native start",
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
],
|
||||
"bugs": "https://github.com/facebook/react-native/issues",
|
||||
"engines": {
|
||||
"node": ">= 20.19.4"
|
||||
"node": ">= 22.14.0"
|
||||
},
|
||||
"exports": {
|
||||
".": {
|
||||
|
||||
@@ -33,6 +33,6 @@
|
||||
"rxjs": "^7.8.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 20.19.4"
|
||||
"node": ">= 22.14.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"private": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 20.19.4"
|
||||
"node": ">= 22.14.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rnx-kit/rn-changelog-generator": "^0.4.0",
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"description": "TypeScript related unit test for @react-native/codegen",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 20.19.4"
|
||||
"node": ">= 22.14.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "yarn clean && node scripts/build.js --verbose && tsc",
|
||||
|
||||
@@ -82,13 +82,6 @@ const FANTOM_BENCHMARK_DEFAULT_MODE: FantomTestConfigMode =
|
||||
|
||||
const MAX_FANTOM_CONFIGURATION_VARIATIONS = 12;
|
||||
|
||||
const VALID_FANTOM_PRAGMAS = [
|
||||
'fantom_mode',
|
||||
'fantom_flags',
|
||||
'fantom_hermes_variant',
|
||||
'fantom_react_fb_flags',
|
||||
];
|
||||
|
||||
/**
|
||||
* Extracts the Fantom configurations from the test file, specified as part of
|
||||
* the docblock comment. E.g.:
|
||||
@@ -125,8 +118,6 @@ export default function getFantomTestConfigs(
|
||||
const docblock = extract(testContents);
|
||||
const pragmas = parse(docblock) as DocblockPragmas;
|
||||
|
||||
verifyFantomPragmas(pragmas);
|
||||
|
||||
const config: FantomTestConfig = {
|
||||
mode: DEFAULT_MODE,
|
||||
hermesVariant: DEFAULT_HERMES_VARIANT,
|
||||
@@ -410,19 +401,3 @@ function parseFeatureFlagValue<T: boolean | number | string>(
|
||||
throw new Error(`Unsupported feature flag type: ${typeof defaultValue}`);
|
||||
}
|
||||
}
|
||||
|
||||
function verifyFantomPragmas(pragmas: DocblockPragmas): void {
|
||||
for (const pragma of Object.keys(pragmas)) {
|
||||
if (
|
||||
pragma.startsWith('fantom_') &&
|
||||
!VALID_FANTOM_PRAGMAS.includes(pragma)
|
||||
) {
|
||||
const validFantomPragmas = VALID_FANTOM_PRAGMAS.map(p => `@${p}`).join(
|
||||
', ',
|
||||
);
|
||||
throw new Error(
|
||||
`Unrecognized Fantom pragma @${pragma}. Valid pragmas are ${validFantomPragmas}.`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user