@office-iss/react-native-win32 0.0.0-canary.265 → 0.0.0-canary.267
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/.flowconfig +1 -1
- package/CHANGELOG.json +15011 -14981
- package/CHANGELOG.md +20 -4
- package/Libraries/Animated/animations/Animation.js +4 -1
- package/Libraries/Components/DrawerAndroid/DrawerLayoutAndroid.js +3 -1
- package/Libraries/Components/Keyboard/KeyboardAvoidingView.js +17 -0
- package/Libraries/Components/ProgressBarAndroid/ProgressBarAndroid.android.js +1 -0
- package/Libraries/Components/Touchable/BoundingDimensions.js +11 -3
- package/Libraries/Components/Touchable/Position.js +7 -2
- package/Libraries/Components/Touchable/Touchable.js +4 -0
- package/Libraries/Components/Touchable/Touchable.win32.js +4 -0
- package/Libraries/Components/View/ReactNativeStyleAttributes.js +1 -1
- package/Libraries/Core/ReactNativeVersion.js +1 -1
- package/Libraries/Core/setUpReactDevTools.js +33 -7
- package/Libraries/Inspector/NetworkOverlay.js +4 -0
- package/Libraries/Inspector/ReactDevToolsOverlay.js +8 -13
- package/Libraries/Interaction/TouchHistoryMath.js +22 -19
- package/Libraries/LogBox/Data/LogBoxData.js +2 -2
- package/Libraries/NativeComponent/BaseViewConfig.android.js +1 -1
- package/Libraries/NativeComponent/BaseViewConfig.ios.js +1 -1
- package/Libraries/NativeComponent/BaseViewConfig.win32.js +1 -1
- package/Libraries/Network/XHRInterceptor.js +63 -14
- package/Libraries/Renderer/shims/ReactNativeTypes.js +2 -1
- package/Libraries/StyleSheet/StyleSheetTypes.js +1 -1
- package/Libraries/WebSocket/WebSocketEvent.js +4 -1
- package/Libraries/WebSocket/WebSocketInterceptor.js +31 -13
- package/index.js +4 -0
- package/index.win32.js +4 -0
- package/overrides.json +12 -12
- package/package.json +14 -14
- package/src/private/devmenu/DevMenu.d.ts +20 -0
- package/src/private/devmenu/DevMenu.js +31 -0
- package/src/private/featureflags/ReactNativeFeatureFlags.js +22 -11
- package/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +4 -3
- package/src/private/reactdevtools/ReactDevToolsSettingsManager.android.js +20 -0
- package/src/private/reactdevtools/ReactDevToolsSettingsManager.ios.js +30 -0
- package/src/private/reactdevtools/ReactDevToolsSettingsManager.win32.js +20 -0
- package/src/private/specs/components/AndroidHorizontalScrollContentViewNativeComponent.js +1 -0
- package/src/private/specs/modules/{NativeDevToolsSettingsManager.js → NativeReactDevToolsSettingsManager.js} +3 -5
- package/src/private/webapis/performance/EventTiming.js +1 -1
- package/src/private/webapis/performance/Performance.js +3 -21
- package/src/private/webapis/performance/PerformanceObserver.js +68 -155
- package/src/private/webapis/performance/Utilities.js +25 -0
- package/src/private/webapis/performance/specs/NativePerformanceObserver.js +24 -16
- package/src/private/webapis/performance/specs/__mocks__/NativePerformance.js +11 -9
- package/src/private/webapis/performance/specs/__mocks__/NativePerformanceObserver.js +85 -58
- package/types/experimental.d.ts +1 -1
- package/types/index.d.ts +1 -1
- package/types/public/ReactNativeTypes.d.ts +0 -4
- package/Libraries/DevToolsSettings/DevToolsSettingsManager.android.js +0 -35
- package/Libraries/DevToolsSettings/DevToolsSettingsManager.d.ts +0 -20
- package/Libraries/DevToolsSettings/DevToolsSettingsManager.ios.js +0 -49
- package/Libraries/DevToolsSettings/DevToolsSettingsManager.win32.js +0 -35
- package/Libraries/DevToolsSettings/NativeDevToolsSettingsManager.js +0 -13
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
|
-
* @generated SignedSource<<
|
|
7
|
+
* @generated SignedSource<<e161b67cb919ad7e2e67ddcb3c501adb>>
|
|
8
8
|
* @flow strict
|
|
9
9
|
*/
|
|
10
10
|
|
|
@@ -36,6 +36,7 @@ export type ReactNativeFeatureFlagsJsOnly = {
|
|
|
36
36
|
enableAnimatedPropsMemo: Getter<boolean>,
|
|
37
37
|
enableOptimisedVirtualizedCells: Getter<boolean>,
|
|
38
38
|
isLayoutAnimationEnabled: Getter<boolean>,
|
|
39
|
+
shouldSkipStateUpdatesForLoopingAnimations: Getter<boolean>,
|
|
39
40
|
shouldUseAnimatedObjectForTransform: Getter<boolean>,
|
|
40
41
|
shouldUseRemoveClippedSubviewsAsDefaultOnIOS: Getter<boolean>,
|
|
41
42
|
shouldUseSetNativePropsInFabric: Getter<boolean>,
|
|
@@ -55,13 +56,14 @@ export type ReactNativeFeatureFlags = {
|
|
|
55
56
|
destroyFabricSurfacesInReactInstanceManager: Getter<boolean>,
|
|
56
57
|
enableAlignItemsBaselineOnFabricIOS: Getter<boolean>,
|
|
57
58
|
enableAndroidLineHeightCentering: Getter<boolean>,
|
|
58
|
-
enableAndroidMixBlendModeProp: Getter<boolean>,
|
|
59
59
|
enableBackgroundStyleApplicator: Getter<boolean>,
|
|
60
|
+
enableBridgelessArchitecture: Getter<boolean>,
|
|
60
61
|
enableCleanTextInputYogaNode: Getter<boolean>,
|
|
61
62
|
enableDeletionOfUnmountedViews: Getter<boolean>,
|
|
62
63
|
enableEagerRootViewAttachment: Getter<boolean>,
|
|
63
64
|
enableEventEmitterRetentionDuringGesturesOnAndroid: Getter<boolean>,
|
|
64
65
|
enableFabricLogs: Getter<boolean>,
|
|
66
|
+
enableFabricRenderer: Getter<boolean>,
|
|
65
67
|
enableFabricRendererExclusively: Getter<boolean>,
|
|
66
68
|
enableGranularShadowTreeStateReconciliation: Getter<boolean>,
|
|
67
69
|
enableIOSViewClipToPaddingBox: Getter<boolean>,
|
|
@@ -97,8 +99,8 @@ export type ReactNativeFeatureFlags = {
|
|
|
97
99
|
useOptimizedEventBatchingOnAndroid: Getter<boolean>,
|
|
98
100
|
useRuntimeShadowNodeReferenceUpdate: Getter<boolean>,
|
|
99
101
|
useRuntimeShadowNodeReferenceUpdateOnLayout: Getter<boolean>,
|
|
100
|
-
useStateAlignmentMechanism: Getter<boolean>,
|
|
101
102
|
useTurboModuleInterop: Getter<boolean>,
|
|
103
|
+
useTurboModules: Getter<boolean>,
|
|
102
104
|
}
|
|
103
105
|
|
|
104
106
|
/**
|
|
@@ -146,6 +148,11 @@ export const enableOptimisedVirtualizedCells: Getter<boolean> = createJavaScript
|
|
|
146
148
|
*/
|
|
147
149
|
export const isLayoutAnimationEnabled: Getter<boolean> = createJavaScriptFlagGetter('isLayoutAnimationEnabled', true);
|
|
148
150
|
|
|
151
|
+
/**
|
|
152
|
+
* If the animation is within Animated.loop, we do not send state updates to React.
|
|
153
|
+
*/
|
|
154
|
+
export const shouldSkipStateUpdatesForLoopingAnimations: Getter<boolean> = createJavaScriptFlagGetter('shouldSkipStateUpdatesForLoopingAnimations', false);
|
|
155
|
+
|
|
149
156
|
/**
|
|
150
157
|
* Enables use of AnimatedObject for animating transform values.
|
|
151
158
|
*/
|
|
@@ -204,14 +211,14 @@ export const enableAlignItemsBaselineOnFabricIOS: Getter<boolean> = createNative
|
|
|
204
211
|
* When enabled, custom line height calculation will be centered from top to bottom.
|
|
205
212
|
*/
|
|
206
213
|
export const enableAndroidLineHeightCentering: Getter<boolean> = createNativeFlagGetter('enableAndroidLineHeightCentering', false);
|
|
207
|
-
/**
|
|
208
|
-
* Enables mix-blend-mode prop on Android.
|
|
209
|
-
*/
|
|
210
|
-
export const enableAndroidMixBlendModeProp: Getter<boolean> = createNativeFlagGetter('enableAndroidMixBlendModeProp', false);
|
|
211
214
|
/**
|
|
212
215
|
* Use BackgroundStyleApplicator in place of other background/border drawing code
|
|
213
216
|
*/
|
|
214
217
|
export const enableBackgroundStyleApplicator: Getter<boolean> = createNativeFlagGetter('enableBackgroundStyleApplicator', true);
|
|
218
|
+
/**
|
|
219
|
+
* Feature flag to enable the new bridgeless architecture. Note: Enabling this will force enable the following flags: `useTurboModules` & `enableFabricRenderer.
|
|
220
|
+
*/
|
|
221
|
+
export const enableBridgelessArchitecture: Getter<boolean> = createNativeFlagGetter('enableBridgelessArchitecture', false);
|
|
215
222
|
/**
|
|
216
223
|
* Clean yoga node when <TextInput /> does not change.
|
|
217
224
|
*/
|
|
@@ -232,6 +239,10 @@ export const enableEventEmitterRetentionDuringGesturesOnAndroid: Getter<boolean>
|
|
|
232
239
|
* This feature flag enables logs for Fabric.
|
|
233
240
|
*/
|
|
234
241
|
export const enableFabricLogs: Getter<boolean> = createNativeFlagGetter('enableFabricLogs', false);
|
|
242
|
+
/**
|
|
243
|
+
* Enables the use of the Fabric renderer in the whole app.
|
|
244
|
+
*/
|
|
245
|
+
export const enableFabricRenderer: Getter<boolean> = createNativeFlagGetter('enableFabricRenderer', false);
|
|
235
246
|
/**
|
|
236
247
|
* When the app is completely migrated to Fabric, set this flag to true to disable parts of Paper infrastructure that are not needed anymore but consume memory and CPU. Specifically, UIViewOperationQueue and EventDispatcherImpl will no longer work as they will not subscribe to ReactChoreographer for updates.
|
|
237
248
|
*/
|
|
@@ -372,14 +383,14 @@ export const useRuntimeShadowNodeReferenceUpdate: Getter<boolean> = createNative
|
|
|
372
383
|
* When enabled, cloning shadow nodes during layout will update the reference held by the current JS fiber tree.
|
|
373
384
|
*/
|
|
374
385
|
export const useRuntimeShadowNodeReferenceUpdateOnLayout: Getter<boolean> = createNativeFlagGetter('useRuntimeShadowNodeReferenceUpdateOnLayout', false);
|
|
375
|
-
/**
|
|
376
|
-
* When enabled, it uses optimised state reconciliation algorithm.
|
|
377
|
-
*/
|
|
378
|
-
export const useStateAlignmentMechanism: Getter<boolean> = createNativeFlagGetter('useStateAlignmentMechanism', false);
|
|
379
386
|
/**
|
|
380
387
|
* In Bridgeless mode, should legacy NativeModules use the TurboModule system?
|
|
381
388
|
*/
|
|
382
389
|
export const useTurboModuleInterop: Getter<boolean> = createNativeFlagGetter('useTurboModuleInterop', false);
|
|
390
|
+
/**
|
|
391
|
+
* When enabled, NativeModules will be executed by using the TurboModule system
|
|
392
|
+
*/
|
|
393
|
+
export const useTurboModules: Getter<boolean> = createNativeFlagGetter('useTurboModules', false);
|
|
383
394
|
|
|
384
395
|
/**
|
|
385
396
|
* Overrides the feature flags with the provided methods.
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
|
-
* @generated SignedSource<<
|
|
7
|
+
* @generated SignedSource<<cd4a2a047e3a6fdb4205efb518906462>>
|
|
8
8
|
* @flow strict
|
|
9
9
|
*/
|
|
10
10
|
|
|
@@ -30,13 +30,14 @@ export interface Spec extends TurboModule {
|
|
|
30
30
|
+destroyFabricSurfacesInReactInstanceManager?: () => boolean;
|
|
31
31
|
+enableAlignItemsBaselineOnFabricIOS?: () => boolean;
|
|
32
32
|
+enableAndroidLineHeightCentering?: () => boolean;
|
|
33
|
-
+enableAndroidMixBlendModeProp?: () => boolean;
|
|
34
33
|
+enableBackgroundStyleApplicator?: () => boolean;
|
|
34
|
+
+enableBridgelessArchitecture?: () => boolean;
|
|
35
35
|
+enableCleanTextInputYogaNode?: () => boolean;
|
|
36
36
|
+enableDeletionOfUnmountedViews?: () => boolean;
|
|
37
37
|
+enableEagerRootViewAttachment?: () => boolean;
|
|
38
38
|
+enableEventEmitterRetentionDuringGesturesOnAndroid?: () => boolean;
|
|
39
39
|
+enableFabricLogs?: () => boolean;
|
|
40
|
+
+enableFabricRenderer?: () => boolean;
|
|
40
41
|
+enableFabricRendererExclusively?: () => boolean;
|
|
41
42
|
+enableGranularShadowTreeStateReconciliation?: () => boolean;
|
|
42
43
|
+enableIOSViewClipToPaddingBox?: () => boolean;
|
|
@@ -72,8 +73,8 @@ export interface Spec extends TurboModule {
|
|
|
72
73
|
+useOptimizedEventBatchingOnAndroid?: () => boolean;
|
|
73
74
|
+useRuntimeShadowNodeReferenceUpdate?: () => boolean;
|
|
74
75
|
+useRuntimeShadowNodeReferenceUpdateOnLayout?: () => boolean;
|
|
75
|
-
+useStateAlignmentMechanism?: () => boolean;
|
|
76
76
|
+useTurboModuleInterop?: () => boolean;
|
|
77
|
+
+useTurboModules?: () => boolean;
|
|
77
78
|
}
|
|
78
79
|
|
|
79
80
|
const NativeReactNativeFeatureFlags: ?Spec = TurboModuleRegistry.get<Spec>(
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @flow strict-local
|
|
8
|
+
* @format
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import NativeReactDevToolsSettingsManager from '../specs/modules/NativeReactDevToolsSettingsManager';
|
|
12
|
+
|
|
13
|
+
module.exports = {
|
|
14
|
+
setGlobalHookSettings(settings: string) {
|
|
15
|
+
NativeReactDevToolsSettingsManager?.setGlobalHookSettings(settings);
|
|
16
|
+
},
|
|
17
|
+
getGlobalHookSettings(): ?string {
|
|
18
|
+
return NativeReactDevToolsSettingsManager?.getGlobalHookSettings();
|
|
19
|
+
},
|
|
20
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @flow strict-local
|
|
8
|
+
* @format
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import Settings from '../../../Libraries/Settings/Settings';
|
|
12
|
+
|
|
13
|
+
const GLOBAL_HOOK_SETTINGS = 'ReactDevTools::HookSettings';
|
|
14
|
+
|
|
15
|
+
const ReactDevToolsSettingsManager = {
|
|
16
|
+
setGlobalHookSettings(settings: string): void {
|
|
17
|
+
Settings.set({
|
|
18
|
+
[GLOBAL_HOOK_SETTINGS]: settings,
|
|
19
|
+
});
|
|
20
|
+
},
|
|
21
|
+
getGlobalHookSettings(): ?string {
|
|
22
|
+
const value = Settings.get(GLOBAL_HOOK_SETTINGS);
|
|
23
|
+
if (typeof value === 'string') {
|
|
24
|
+
return value;
|
|
25
|
+
}
|
|
26
|
+
return null;
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
module.exports = ReactDevToolsSettingsManager;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @flow strict-local
|
|
8
|
+
* @format
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import NativeReactDevToolsSettingsManager from '../specs/modules/NativeReactDevToolsSettingsManager';
|
|
12
|
+
|
|
13
|
+
module.exports = {
|
|
14
|
+
setGlobalHookSettings(settings: string) {
|
|
15
|
+
NativeReactDevToolsSettingsManager?.setGlobalHookSettings(settings);
|
|
16
|
+
},
|
|
17
|
+
getGlobalHookSettings(): ?string {
|
|
18
|
+
return NativeReactDevToolsSettingsManager?.getGlobalHookSettings();
|
|
19
|
+
},
|
|
20
|
+
};
|
|
@@ -13,12 +13,10 @@ import type {TurboModule} from '../../../../Libraries/TurboModule/RCTExport';
|
|
|
13
13
|
import * as TurboModuleRegistry from '../../../../Libraries/TurboModule/TurboModuleRegistry';
|
|
14
14
|
|
|
15
15
|
export interface Spec extends TurboModule {
|
|
16
|
-
+
|
|
17
|
-
+
|
|
18
|
-
+setProfilingSettings?: (newProfilingSettings: string) => void;
|
|
19
|
-
+getProfilingSettings?: () => ?string;
|
|
16
|
+
+setGlobalHookSettings: (settings: string) => void;
|
|
17
|
+
+getGlobalHookSettings: () => ?string;
|
|
20
18
|
}
|
|
21
19
|
|
|
22
20
|
export default (TurboModuleRegistry.get<Spec>(
|
|
23
|
-
'
|
|
21
|
+
'ReactDevToolsSettingsManager',
|
|
24
22
|
): ?Spec);
|
|
@@ -16,7 +16,7 @@ import type {
|
|
|
16
16
|
} from './PerformanceEntry';
|
|
17
17
|
|
|
18
18
|
import {PerformanceEntry} from './PerformanceEntry';
|
|
19
|
-
import {warnNoNativePerformanceObserver} from './
|
|
19
|
+
import {warnNoNativePerformanceObserver} from './Utilities';
|
|
20
20
|
import NativePerformanceObserver from './specs/NativePerformanceObserver';
|
|
21
21
|
|
|
22
22
|
export type PerformanceEventTimingJSON = {
|
|
@@ -17,11 +17,10 @@ import type {
|
|
|
17
17
|
import type {PerformanceEntryList} from './PerformanceObserver';
|
|
18
18
|
import type {DetailType, PerformanceMarkOptions} from './UserTiming';
|
|
19
19
|
|
|
20
|
-
import warnOnce from '../../../../Libraries/Utilities/warnOnce';
|
|
21
20
|
import {EventCounts} from './EventTiming';
|
|
22
21
|
import MemoryInfo from './MemoryInfo';
|
|
23
22
|
import {ALWAYS_LOGGED_ENTRY_TYPES} from './PerformanceEntry';
|
|
24
|
-
import {warnNoNativePerformanceObserver} from './
|
|
23
|
+
import {warnNoNativePerformanceObserver} from './Utilities';
|
|
25
24
|
import {
|
|
26
25
|
performanceEntryTypeToRaw,
|
|
27
26
|
rawToPerformanceEntry,
|
|
@@ -31,6 +30,7 @@ import ReactNativeStartupTiming from './ReactNativeStartupTiming';
|
|
|
31
30
|
import NativePerformance from './specs/NativePerformance';
|
|
32
31
|
import NativePerformanceObserver from './specs/NativePerformanceObserver';
|
|
33
32
|
import {PerformanceMark, PerformanceMeasure} from './UserTiming';
|
|
33
|
+
import {warnNoNativePerformance} from './Utilities';
|
|
34
34
|
|
|
35
35
|
declare var global: {
|
|
36
36
|
// This value is defined directly via JSI, if available.
|
|
@@ -40,24 +40,6 @@ declare var global: {
|
|
|
40
40
|
const getCurrentTimeStamp: () => DOMHighResTimeStamp =
|
|
41
41
|
NativePerformance?.now ?? global.nativePerformanceNow ?? (() => Date.now());
|
|
42
42
|
|
|
43
|
-
// We want some of the performance entry types to be always logged,
|
|
44
|
-
// even if they are not currently observed - this is either to be able to
|
|
45
|
-
// retrieve them at any time via Performance.getEntries* or to refer by other entries
|
|
46
|
-
// (such as when measures may refer to marks, even if the latter are not observed)
|
|
47
|
-
if (NativePerformanceObserver?.setIsBuffered) {
|
|
48
|
-
NativePerformanceObserver?.setIsBuffered(
|
|
49
|
-
ALWAYS_LOGGED_ENTRY_TYPES.map(performanceEntryTypeToRaw),
|
|
50
|
-
true,
|
|
51
|
-
);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
function warnNoNativePerformance() {
|
|
55
|
-
warnOnce(
|
|
56
|
-
'missing-native-performance',
|
|
57
|
-
'Missing native implementation of Performance',
|
|
58
|
-
);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
43
|
export type PerformanceMeasureOptions = {
|
|
62
44
|
detail?: DetailType,
|
|
63
45
|
start?: DOMHighResTimeStamp,
|
|
@@ -145,7 +127,7 @@ export default class Performance {
|
|
|
145
127
|
return;
|
|
146
128
|
}
|
|
147
129
|
|
|
148
|
-
NativePerformanceObserver
|
|
130
|
+
NativePerformanceObserver.clearEntries(
|
|
149
131
|
RawPerformanceEntryTypeValues.MARK,
|
|
150
132
|
markName,
|
|
151
133
|
);
|
|
@@ -13,7 +13,6 @@ import type {
|
|
|
13
13
|
PerformanceEntryType,
|
|
14
14
|
} from './PerformanceEntry';
|
|
15
15
|
|
|
16
|
-
import warnOnce from '../../../../Libraries/Utilities/warnOnce';
|
|
17
16
|
import {PerformanceEventTiming} from './EventTiming';
|
|
18
17
|
import {PerformanceEntry} from './PerformanceEntry';
|
|
19
18
|
import {
|
|
@@ -22,6 +21,8 @@ import {
|
|
|
22
21
|
rawToPerformanceEntryType,
|
|
23
22
|
} from './RawPerformanceEntry';
|
|
24
23
|
import NativePerformanceObserver from './specs/NativePerformanceObserver';
|
|
24
|
+
import type {OpaqueNativeObserverHandle} from './specs/NativePerformanceObserver';
|
|
25
|
+
import {warnNoNativePerformanceObserver} from './Utilities';
|
|
25
26
|
|
|
26
27
|
export type PerformanceEntryList = $ReadOnlyArray<PerformanceEntry>;
|
|
27
28
|
|
|
@@ -56,89 +57,24 @@ export class PerformanceObserverEntryList {
|
|
|
56
57
|
}
|
|
57
58
|
}
|
|
58
59
|
|
|
60
|
+
export type PerformanceObserverCallbackOptions = {
|
|
61
|
+
droppedEntriesCount: number,
|
|
62
|
+
};
|
|
63
|
+
|
|
59
64
|
export type PerformanceObserverCallback = (
|
|
60
65
|
list: PerformanceObserverEntryList,
|
|
61
66
|
observer: PerformanceObserver,
|
|
62
67
|
// The number of buffered entries which got dropped from the buffer due to the buffer being full:
|
|
63
|
-
|
|
68
|
+
options?: PerformanceObserverCallbackOptions,
|
|
64
69
|
) => void;
|
|
65
70
|
|
|
66
|
-
export type PerformanceObserverInit =
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
type: PerformanceEntryType,
|
|
72
|
-
durationThreshold?: DOMHighResTimeStamp,
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
type PerformanceObserverConfig = {|
|
|
76
|
-
callback: PerformanceObserverCallback,
|
|
77
|
-
entryTypes: $ReadOnlySet<PerformanceEntryType>,
|
|
78
|
-
durationThreshold: ?number,
|
|
79
|
-
|};
|
|
80
|
-
|
|
81
|
-
const observerCountPerEntryType: Map<PerformanceEntryType, number> = new Map();
|
|
82
|
-
const registeredObservers: Map<PerformanceObserver, PerformanceObserverConfig> =
|
|
83
|
-
new Map();
|
|
84
|
-
let isOnPerformanceEntryCallbackSet: boolean = false;
|
|
85
|
-
|
|
86
|
-
// This is a callback that gets scheduled and periodically called from the native side
|
|
87
|
-
const onPerformanceEntry = () => {
|
|
88
|
-
if (!NativePerformanceObserver) {
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
|
-
const entryResult = NativePerformanceObserver.popPendingEntries();
|
|
92
|
-
const rawEntries = entryResult?.entries ?? [];
|
|
93
|
-
const droppedEntriesCount = entryResult?.droppedEntriesCount;
|
|
94
|
-
if (rawEntries.length === 0) {
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
const entries = rawEntries.map(rawToPerformanceEntry);
|
|
98
|
-
for (const [observer, observerConfig] of registeredObservers.entries()) {
|
|
99
|
-
const entriesForObserver: PerformanceEntryList = entries.filter(entry => {
|
|
100
|
-
if (!observerConfig.entryTypes.has(entry.entryType)) {
|
|
101
|
-
return false;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
if (
|
|
105
|
-
entry.entryType === 'event' &&
|
|
106
|
-
observerConfig.durationThreshold != null
|
|
107
|
-
) {
|
|
108
|
-
return entry.duration >= observerConfig.durationThreshold;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
return true;
|
|
112
|
-
});
|
|
113
|
-
if (entriesForObserver.length !== 0) {
|
|
114
|
-
try {
|
|
115
|
-
observerConfig.callback(
|
|
116
|
-
new PerformanceObserverEntryList(entriesForObserver),
|
|
117
|
-
observer,
|
|
118
|
-
droppedEntriesCount,
|
|
119
|
-
);
|
|
120
|
-
} catch (error) {
|
|
121
|
-
console.error(error);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
}
|
|
71
|
+
export type PerformanceObserverInit = {
|
|
72
|
+
entryTypes?: Array<PerformanceEntryType>,
|
|
73
|
+
type?: PerformanceEntryType,
|
|
74
|
+
buffered?: boolean,
|
|
75
|
+
durationThreshold?: DOMHighResTimeStamp,
|
|
125
76
|
};
|
|
126
77
|
|
|
127
|
-
export function warnNoNativePerformanceObserver() {
|
|
128
|
-
warnOnce(
|
|
129
|
-
'missing-native-performance-observer',
|
|
130
|
-
'Missing native implementation of PerformanceObserver',
|
|
131
|
-
);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
function applyDurationThresholds() {
|
|
135
|
-
const durationThresholds = Array.from(registeredObservers.values())
|
|
136
|
-
.map(observerConfig => observerConfig.durationThreshold)
|
|
137
|
-
.filter(Boolean);
|
|
138
|
-
|
|
139
|
-
return Math.min(...durationThresholds);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
78
|
function getSupportedPerformanceEntryTypes(): $ReadOnlyArray<PerformanceEntryType> {
|
|
143
79
|
if (!NativePerformanceObserver) {
|
|
144
80
|
return Object.freeze([]);
|
|
@@ -175,111 +111,96 @@ function getSupportedPerformanceEntryTypes(): $ReadOnlyArray<PerformanceEntryTyp
|
|
|
175
111
|
* observer.observe({ type: "event" });
|
|
176
112
|
*/
|
|
177
113
|
export class PerformanceObserver {
|
|
114
|
+
#nativeObserverHandle: OpaqueNativeObserverHandle | null = null;
|
|
178
115
|
#callback: PerformanceObserverCallback;
|
|
179
116
|
#type: 'single' | 'multiple' | void;
|
|
117
|
+
#calledAtLeastOnce = false;
|
|
180
118
|
|
|
181
119
|
constructor(callback: PerformanceObserverCallback) {
|
|
182
120
|
this.#callback = callback;
|
|
183
121
|
}
|
|
184
122
|
|
|
185
123
|
observe(options: PerformanceObserverInit): void {
|
|
186
|
-
if (
|
|
124
|
+
if (
|
|
125
|
+
!NativePerformanceObserver ||
|
|
126
|
+
NativePerformanceObserver.observe == null
|
|
127
|
+
) {
|
|
187
128
|
warnNoNativePerformanceObserver();
|
|
188
129
|
return;
|
|
189
130
|
}
|
|
190
131
|
|
|
191
132
|
this.#validateObserveOptions(options);
|
|
192
133
|
|
|
193
|
-
|
|
134
|
+
if (this.#nativeObserverHandle == null) {
|
|
135
|
+
this.#nativeObserverHandle = this.#createNativeObserver();
|
|
136
|
+
}
|
|
194
137
|
|
|
195
138
|
if (options.entryTypes) {
|
|
196
139
|
this.#type = 'multiple';
|
|
197
|
-
|
|
198
|
-
|
|
140
|
+
NativePerformanceObserver.observe?.(this.#nativeObserverHandle, {
|
|
141
|
+
entryTypes: options.entryTypes.map(performanceEntryTypeToRaw),
|
|
142
|
+
});
|
|
143
|
+
} else if (options.type) {
|
|
199
144
|
this.#type = 'single';
|
|
200
|
-
|
|
145
|
+
NativePerformanceObserver.observe?.(this.#nativeObserverHandle, {
|
|
146
|
+
type: performanceEntryTypeToRaw(options.type),
|
|
147
|
+
buffered: options.buffered,
|
|
148
|
+
durationThreshold: options.durationThreshold,
|
|
149
|
+
});
|
|
201
150
|
}
|
|
151
|
+
}
|
|
202
152
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
const nextEntryTypes = currentEntryTypes
|
|
207
|
-
? union(requestedEntryTypes, currentEntryTypes)
|
|
208
|
-
: requestedEntryTypes;
|
|
209
|
-
|
|
210
|
-
// This `observe` call is a no-op because there are no new things to observe.
|
|
211
|
-
if (currentEntryTypes && currentEntryTypes.size === nextEntryTypes.size) {
|
|
153
|
+
disconnect(): void {
|
|
154
|
+
if (!NativePerformanceObserver) {
|
|
155
|
+
warnNoNativePerformanceObserver();
|
|
212
156
|
return;
|
|
213
157
|
}
|
|
214
158
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
});
|
|
221
|
-
|
|
222
|
-
if (!isOnPerformanceEntryCallbackSet) {
|
|
223
|
-
NativePerformanceObserver.setOnPerformanceEntryCallback(
|
|
224
|
-
onPerformanceEntry,
|
|
225
|
-
);
|
|
226
|
-
isOnPerformanceEntryCallbackSet = true;
|
|
159
|
+
if (
|
|
160
|
+
this.#nativeObserverHandle == null ||
|
|
161
|
+
!NativePerformanceObserver.disconnect
|
|
162
|
+
) {
|
|
163
|
+
return;
|
|
227
164
|
}
|
|
228
165
|
|
|
229
|
-
|
|
230
|
-
// this observer.
|
|
231
|
-
const newEntryTypes = currentEntryTypes
|
|
232
|
-
? difference(
|
|
233
|
-
new Set(requestedEntryTypes.keys()),
|
|
234
|
-
new Set(currentEntryTypes.keys()),
|
|
235
|
-
)
|
|
236
|
-
: new Set(requestedEntryTypes.keys());
|
|
237
|
-
for (const type of newEntryTypes) {
|
|
238
|
-
if (!observerCountPerEntryType.has(type)) {
|
|
239
|
-
const rawType = performanceEntryTypeToRaw(type);
|
|
240
|
-
NativePerformanceObserver.startReporting(rawType);
|
|
241
|
-
}
|
|
242
|
-
observerCountPerEntryType.set(
|
|
243
|
-
type,
|
|
244
|
-
(observerCountPerEntryType.get(type) ?? 0) + 1,
|
|
245
|
-
);
|
|
246
|
-
}
|
|
247
|
-
applyDurationThresholds();
|
|
166
|
+
NativePerformanceObserver.disconnect(this.#nativeObserverHandle);
|
|
248
167
|
}
|
|
249
168
|
|
|
250
|
-
|
|
251
|
-
if (
|
|
169
|
+
#createNativeObserver(): OpaqueNativeObserverHandle {
|
|
170
|
+
if (
|
|
171
|
+
!NativePerformanceObserver ||
|
|
172
|
+
!NativePerformanceObserver.createObserver
|
|
173
|
+
) {
|
|
252
174
|
warnNoNativePerformanceObserver();
|
|
253
175
|
return;
|
|
254
176
|
}
|
|
255
177
|
|
|
256
|
-
|
|
257
|
-
if (!observerConfig) {
|
|
258
|
-
return;
|
|
259
|
-
}
|
|
178
|
+
this.#calledAtLeastOnce = false;
|
|
260
179
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
const
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
);
|
|
270
|
-
} else if (numberOfObserversForThisType !== 0) {
|
|
271
|
-
observerCountPerEntryType.set(type, numberOfObserversForThisType - 1);
|
|
180
|
+
return NativePerformanceObserver.createObserver(() => {
|
|
181
|
+
// $FlowNotNull
|
|
182
|
+
const rawEntries = NativePerformanceObserver.takeRecords?.(
|
|
183
|
+
this.#nativeObserverHandle,
|
|
184
|
+
true, // sort records
|
|
185
|
+
);
|
|
186
|
+
if (!rawEntries) {
|
|
187
|
+
return;
|
|
272
188
|
}
|
|
273
|
-
}
|
|
274
189
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
190
|
+
const entries = rawEntries.map(rawToPerformanceEntry);
|
|
191
|
+
const entryList = new PerformanceObserverEntryList(entries);
|
|
192
|
+
|
|
193
|
+
let droppedEntriesCount = 0;
|
|
194
|
+
if (!this.#calledAtLeastOnce) {
|
|
195
|
+
droppedEntriesCount =
|
|
196
|
+
NativePerformanceObserver.getDroppedEntriesCount?.(
|
|
197
|
+
this.#nativeObserverHandle,
|
|
198
|
+
) ?? 0;
|
|
199
|
+
this.#calledAtLeastOnce = true;
|
|
200
|
+
}
|
|
281
201
|
|
|
282
|
-
|
|
202
|
+
this.#callback(entryList, this, {droppedEntriesCount});
|
|
203
|
+
});
|
|
283
204
|
}
|
|
284
205
|
|
|
285
206
|
#validateObserveOptions(options: PerformanceObserverInit): void {
|
|
@@ -309,7 +230,7 @@ export class PerformanceObserver {
|
|
|
309
230
|
);
|
|
310
231
|
}
|
|
311
232
|
|
|
312
|
-
if (entryTypes && durationThreshold
|
|
233
|
+
if (entryTypes && durationThreshold != null) {
|
|
313
234
|
throw new TypeError(
|
|
314
235
|
"Failed to execute 'observe' on 'PerformanceObserver': An observe() call must not include both entryTypes and durationThreshold arguments.",
|
|
315
236
|
);
|
|
@@ -320,12 +241,4 @@ export class PerformanceObserver {
|
|
|
320
241
|
getSupportedPerformanceEntryTypes();
|
|
321
242
|
}
|
|
322
243
|
|
|
323
|
-
function union<T>(a: $ReadOnlySet<T>, b: $ReadOnlySet<T>): Set<T> {
|
|
324
|
-
return new Set([...a, ...b]);
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
function difference<T>(a: $ReadOnlySet<T>, b: $ReadOnlySet<T>): Set<T> {
|
|
328
|
-
return new Set([...a].filter(x => !b.has(x)));
|
|
329
|
-
}
|
|
330
|
-
|
|
331
244
|
export {PerformanceEventTiming};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @format
|
|
8
|
+
* @flow strict
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import warnOnce from '../../../../Libraries/Utilities/warnOnce';
|
|
12
|
+
|
|
13
|
+
export function warnNoNativePerformance() {
|
|
14
|
+
warnOnce(
|
|
15
|
+
'missing-native-performance',
|
|
16
|
+
'Missing native implementation of Performance',
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function warnNoNativePerformanceObserver() {
|
|
21
|
+
warnOnce(
|
|
22
|
+
'missing-native-performance-observer',
|
|
23
|
+
'Missing native implementation of PerformanceObserver',
|
|
24
|
+
);
|
|
25
|
+
}
|