react-native 0.71.0-rc.0 → 0.71.0-rc.1
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/Libraries/Core/ReactNativeVersion.js +1 -1
- package/Libraries/Text/BaseText/RCTBaseTextViewManager.m +1 -0
- package/Libraries/Text/RCTTextAttributes.h +2 -0
- package/Libraries/Text/RCTTextAttributes.m +9 -1
- package/Libraries/Text/Text/RCTDynamicTypeRamp.h +37 -0
- package/Libraries/Text/Text/RCTDynamicTypeRamp.m +82 -0
- package/Libraries/Text/Text.d.ts +17 -0
- package/Libraries/Text/TextNativeComponent.js +1 -0
- package/Libraries/Text/TextProps.js +17 -0
- package/Libraries/WebPerformance/NativePerformanceObserver.cpp +42 -0
- package/Libraries/WebPerformance/NativePerformanceObserver.h +64 -0
- package/Libraries/WebPerformance/NativePerformanceObserver.js +41 -0
- package/Libraries/WebPerformance/PerformanceObserver.js +223 -0
- package/React/Base/RCTVersion.m +1 -1
- package/React/CoreModules/CoreModulesPlugins.h +1 -0
- package/React/CoreModules/CoreModulesPlugins.mm +1 -0
- package/ReactAndroid/build.gradle +7 -5
- package/ReactAndroid/cmake-utils/ReactNative-application.cmake +1 -1
- package/ReactAndroid/cmake-utils/default-app-setup/OnLoad.cpp +12 -3
- package/ReactAndroid/gradle.properties +1 -1
- package/ReactAndroid/hermes-engine/build.gradle +13 -0
- package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.java +1 -1
- package/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.java +3 -1
- package/ReactAndroid/src/main/jni/react/newarchdefaults/DefaultTurboModuleManagerDelegate.cpp +15 -6
- package/ReactAndroid/src/main/jni/react/newarchdefaults/DefaultTurboModuleManagerDelegate.h +6 -1
- package/ReactCommon/ReactCommon.podspec +9 -2
- package/ReactCommon/cxxreact/ReactNativeVersion.h +1 -1
- package/ReactCommon/react/renderer/attributedstring/TextAttributes.cpp +6 -0
- package/ReactCommon/react/renderer/attributedstring/TextAttributes.h +1 -0
- package/ReactCommon/react/renderer/attributedstring/conversions.h +78 -0
- package/ReactCommon/react/renderer/attributedstring/primitives.h +21 -0
- package/ReactCommon/react/renderer/components/text/BaseTextProps.cpp +6 -0
- package/ReactCommon/react/renderer/textlayoutmanager/TextMeasureCache.h +3 -0
- package/ReactCommon/react/renderer/textlayoutmanager/platform/ios/RCTAttributedTextUtils.mm +78 -9
- package/ReactCommon/yoga/yoga/Yoga.cpp +19 -10
- package/index.js +16 -11
- package/package.json +7 -6
- package/scripts/cocoapods/codegen_utils.rb +12 -11
- package/scripts/cocoapods/jsengine.rb +16 -0
- package/scripts/cocoapods/new_architecture.rb +1 -0
- package/scripts/cocoapods/utils.rb +0 -12
- package/scripts/codegen/generate-specs-cli-executor.js +4 -4
- package/scripts/hermes/hermes-utils.js +3 -7
- package/scripts/react_native_pods.rb +4 -3
- package/sdks/hermes-engine/hermes-engine.podspec +8 -3
- package/sdks/hermes-engine/utils/build-hermesc-xcode.sh +1 -1
- package/sdks/hermes-engine/utils/copy-hermes-xcode.sh +12 -4
- package/sdks/hermesc/osx-bin/hermesc +0 -0
- package/sdks/hermesc/win64-bin/hermesc.exe +0 -0
- package/template/App.tsx +1 -1
- package/template/Gemfile +1 -1
- package/template/android/app/build.gradle +2 -2
- package/template/android/build.gradle +3 -3
- package/template/ios/HelloWorld/AppDelegate.h +1 -1
- package/template/package.json +4 -2
- package/types/index.d.ts +0 -1
- package/Libraries/Image/ImagePickerIOS.d.ts +0 -48
- package/Libraries/Image/ImagePickerIOS.js +0 -103
- package/Libraries/Image/NativeImagePickerIOS.js +0 -39
- package/Libraries/Performance/PerformanceObserver.js +0 -124
- package/ReactCommon/React-bridging.podspec +0 -43
|
@@ -36,6 +36,7 @@ RCT_REMAP_SHADOW_PROPERTY(fontWeight, textAttributes.fontWeight, NSString)
|
|
|
36
36
|
RCT_REMAP_SHADOW_PROPERTY(fontStyle, textAttributes.fontStyle, NSString)
|
|
37
37
|
RCT_REMAP_SHADOW_PROPERTY(fontVariant, textAttributes.fontVariant, NSArray)
|
|
38
38
|
RCT_REMAP_SHADOW_PROPERTY(allowFontScaling, textAttributes.allowFontScaling, BOOL)
|
|
39
|
+
RCT_REMAP_SHADOW_PROPERTY(dynamicTypeRamp, textAttributes.dynamicTypeRamp, RCTDynamicTypeRamp)
|
|
39
40
|
RCT_REMAP_SHADOW_PROPERTY(maxFontSizeMultiplier, textAttributes.maxFontSizeMultiplier, CGFloat)
|
|
40
41
|
RCT_REMAP_SHADOW_PROPERTY(letterSpacing, textAttributes.letterSpacing, CGFloat)
|
|
41
42
|
// Paragraph Styles
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
#import <UIKit/UIKit.h>
|
|
9
9
|
|
|
10
|
+
#import <React/RCTDynamicTypeRamp.h>
|
|
10
11
|
#import <React/RCTTextDecorationLineType.h>
|
|
11
12
|
|
|
12
13
|
#import "RCTTextTransform.h"
|
|
@@ -36,6 +37,7 @@ extern NSString *const RCTTextAttributesTagAttributeName;
|
|
|
36
37
|
@property (nonatomic, copy, nullable) NSString *fontStyle;
|
|
37
38
|
@property (nonatomic, copy, nullable) NSArray<NSString *> *fontVariant;
|
|
38
39
|
@property (nonatomic, assign) BOOL allowFontScaling;
|
|
40
|
+
@property (nonatomic, assign) RCTDynamicTypeRamp dynamicTypeRamp;
|
|
39
41
|
@property (nonatomic, assign) CGFloat letterSpacing;
|
|
40
42
|
// Paragraph Styles
|
|
41
43
|
@property (nonatomic, assign) CGFloat lineHeight;
|
|
@@ -59,6 +59,8 @@ NSString *const RCTTextAttributesTagAttributeName = @"RCTTextAttributesTagAttrib
|
|
|
59
59
|
_fontStyle = textAttributes->_fontStyle ?: _fontStyle;
|
|
60
60
|
_fontVariant = textAttributes->_fontVariant ?: _fontVariant;
|
|
61
61
|
_allowFontScaling = textAttributes->_allowFontScaling || _allowFontScaling; // *
|
|
62
|
+
_dynamicTypeRamp = textAttributes->_dynamicTypeRamp != RCTDynamicTypeRampUndefined ? textAttributes->_dynamicTypeRamp
|
|
63
|
+
: _dynamicTypeRamp;
|
|
62
64
|
_letterSpacing = !isnan(textAttributes->_letterSpacing) ? textAttributes->_letterSpacing : _letterSpacing;
|
|
63
65
|
|
|
64
66
|
// Paragraph Styles
|
|
@@ -230,6 +232,12 @@ NSString *const RCTTextAttributesTagAttributeName = @"RCTTextAttributesTagAttrib
|
|
|
230
232
|
|
|
231
233
|
if (fontScalingEnabled) {
|
|
232
234
|
CGFloat fontSizeMultiplier = !isnan(_fontSizeMultiplier) ? _fontSizeMultiplier : 1.0;
|
|
235
|
+
if (_dynamicTypeRamp != RCTDynamicTypeRampUndefined) {
|
|
236
|
+
UIFontMetrics *fontMetrics = RCTUIFontMetricsForDynamicTypeRamp(_dynamicTypeRamp);
|
|
237
|
+
// Using a specific font size reduces rounding errors from -scaledValueForValue:
|
|
238
|
+
CGFloat requestedSize = isnan(_fontSize) ? RCTBaseSizeForDynamicTypeRamp(_dynamicTypeRamp) : _fontSize;
|
|
239
|
+
fontSizeMultiplier = [fontMetrics scaledValueForValue:requestedSize] / requestedSize;
|
|
240
|
+
}
|
|
233
241
|
CGFloat maxFontSizeMultiplier = !isnan(_maxFontSizeMultiplier) ? _maxFontSizeMultiplier : 0.0;
|
|
234
242
|
return maxFontSizeMultiplier >= 1.0 ? fminf(maxFontSizeMultiplier, fontSizeMultiplier) : fontSizeMultiplier;
|
|
235
243
|
} else {
|
|
@@ -324,7 +332,7 @@ static NSString *capitalizeText(NSString *text)
|
|
|
324
332
|
RCTTextAttributesCompareFloats(_fontSizeMultiplier) && RCTTextAttributesCompareFloats(_maxFontSizeMultiplier) &&
|
|
325
333
|
RCTTextAttributesCompareStrings(_fontWeight) && RCTTextAttributesCompareObjects(_fontStyle) &&
|
|
326
334
|
RCTTextAttributesCompareObjects(_fontVariant) && RCTTextAttributesCompareOthers(_allowFontScaling) &&
|
|
327
|
-
RCTTextAttributesCompareFloats(_letterSpacing) &&
|
|
335
|
+
RCTTextAttributesCompareOthers(_dynamicTypeRamp) && RCTTextAttributesCompareFloats(_letterSpacing) &&
|
|
328
336
|
// Paragraph Styles
|
|
329
337
|
RCTTextAttributesCompareFloats(_lineHeight) && RCTTextAttributesCompareFloats(_alignment) &&
|
|
330
338
|
RCTTextAttributesCompareOthers(_baseWritingDirection) && RCTTextAttributesCompareOthers(_lineBreakStrategy) &&
|
|
@@ -0,0 +1,37 @@
|
|
|
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
|
+
|
|
8
|
+
#import <Foundation/Foundation.h>
|
|
9
|
+
|
|
10
|
+
#import <React/RCTConvert.h>
|
|
11
|
+
|
|
12
|
+
typedef NS_ENUM(NSInteger, RCTDynamicTypeRamp) {
|
|
13
|
+
RCTDynamicTypeRampUndefined,
|
|
14
|
+
RCTDynamicTypeRampCaption2,
|
|
15
|
+
RCTDynamicTypeRampCaption1,
|
|
16
|
+
RCTDynamicTypeRampFootnote,
|
|
17
|
+
RCTDynamicTypeRampSubheadline,
|
|
18
|
+
RCTDynamicTypeRampCallout,
|
|
19
|
+
RCTDynamicTypeRampBody,
|
|
20
|
+
RCTDynamicTypeRampHeadline,
|
|
21
|
+
RCTDynamicTypeRampTitle3,
|
|
22
|
+
RCTDynamicTypeRampTitle2,
|
|
23
|
+
RCTDynamicTypeRampTitle1,
|
|
24
|
+
RCTDynamicTypeRampLargeTitle
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
@interface RCTConvert (DynamicTypeRamp)
|
|
28
|
+
|
|
29
|
+
+ (RCTDynamicTypeRamp)RCTDynamicTypeRamp:(nullable id)json;
|
|
30
|
+
|
|
31
|
+
@end
|
|
32
|
+
|
|
33
|
+
/// Generates a `UIFontMetrics` instance representing a particular Dynamic Type ramp.
|
|
34
|
+
UIFontMetrics *_Nonnull RCTUIFontMetricsForDynamicTypeRamp(RCTDynamicTypeRamp dynamicTypeRamp);
|
|
35
|
+
/// The "reference" size for a particular font scale ramp, equal to a text element's size under default text size
|
|
36
|
+
/// settings.
|
|
37
|
+
CGFloat RCTBaseSizeForDynamicTypeRamp(RCTDynamicTypeRamp dynamicTypeRamp);
|
|
@@ -0,0 +1,82 @@
|
|
|
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
|
+
|
|
8
|
+
#import <React/RCTDynamicTypeRamp.h>
|
|
9
|
+
|
|
10
|
+
@implementation RCTConvert (DynamicTypeRamp)
|
|
11
|
+
|
|
12
|
+
RCT_ENUM_CONVERTER(
|
|
13
|
+
RCTDynamicTypeRamp,
|
|
14
|
+
(@{
|
|
15
|
+
@"caption2" : @(RCTDynamicTypeRampCaption2),
|
|
16
|
+
@"caption1" : @(RCTDynamicTypeRampCaption1),
|
|
17
|
+
@"footnote" : @(RCTDynamicTypeRampFootnote),
|
|
18
|
+
@"subheadline" : @(RCTDynamicTypeRampSubheadline),
|
|
19
|
+
@"callout" : @(RCTDynamicTypeRampCallout),
|
|
20
|
+
@"body" : @(RCTDynamicTypeRampBody),
|
|
21
|
+
@"headline" : @(RCTDynamicTypeRampHeadline),
|
|
22
|
+
@"title3" : @(RCTDynamicTypeRampTitle3),
|
|
23
|
+
@"title2" : @(RCTDynamicTypeRampTitle2),
|
|
24
|
+
@"title1" : @(RCTDynamicTypeRampTitle1),
|
|
25
|
+
@"largeTitle" : @(RCTDynamicTypeRampLargeTitle),
|
|
26
|
+
}),
|
|
27
|
+
RCTDynamicTypeRampUndefined,
|
|
28
|
+
integerValue)
|
|
29
|
+
|
|
30
|
+
@end
|
|
31
|
+
|
|
32
|
+
UIFontMetrics *RCTUIFontMetricsForDynamicTypeRamp(RCTDynamicTypeRamp dynamicTypeRamp)
|
|
33
|
+
{
|
|
34
|
+
static NSDictionary<NSNumber *, UIFontTextStyle> *mapping;
|
|
35
|
+
static dispatch_once_t onceToken;
|
|
36
|
+
dispatch_once(&onceToken, ^{
|
|
37
|
+
mapping = @{
|
|
38
|
+
@(RCTDynamicTypeRampCaption2) : UIFontTextStyleCaption2,
|
|
39
|
+
@(RCTDynamicTypeRampCaption1) : UIFontTextStyleCaption1,
|
|
40
|
+
@(RCTDynamicTypeRampFootnote) : UIFontTextStyleFootnote,
|
|
41
|
+
@(RCTDynamicTypeRampSubheadline) : UIFontTextStyleSubheadline,
|
|
42
|
+
@(RCTDynamicTypeRampCallout) : UIFontTextStyleCallout,
|
|
43
|
+
@(RCTDynamicTypeRampBody) : UIFontTextStyleBody,
|
|
44
|
+
@(RCTDynamicTypeRampHeadline) : UIFontTextStyleHeadline,
|
|
45
|
+
@(RCTDynamicTypeRampTitle3) : UIFontTextStyleTitle3,
|
|
46
|
+
@(RCTDynamicTypeRampTitle2) : UIFontTextStyleTitle2,
|
|
47
|
+
@(RCTDynamicTypeRampTitle1) : UIFontTextStyleTitle1,
|
|
48
|
+
@(RCTDynamicTypeRampLargeTitle) : UIFontTextStyleLargeTitle,
|
|
49
|
+
};
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
id textStyle =
|
|
53
|
+
mapping[@(dynamicTypeRamp)] ?: UIFontTextStyleBody; // Default to body if we don't recognize the specified ramp
|
|
54
|
+
return [UIFontMetrics metricsForTextStyle:textStyle];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
CGFloat RCTBaseSizeForDynamicTypeRamp(RCTDynamicTypeRamp dynamicTypeRamp)
|
|
58
|
+
{
|
|
59
|
+
static NSDictionary<NSNumber *, NSNumber *> *mapping;
|
|
60
|
+
static dispatch_once_t onceToken;
|
|
61
|
+
dispatch_once(&onceToken, ^{
|
|
62
|
+
// Values taken from
|
|
63
|
+
// https://developer.apple.com/design/human-interface-guidelines/foundations/typography/#specifications
|
|
64
|
+
mapping = @{
|
|
65
|
+
@(RCTDynamicTypeRampCaption2) : @11,
|
|
66
|
+
@(RCTDynamicTypeRampCaption1) : @12,
|
|
67
|
+
@(RCTDynamicTypeRampFootnote) : @13,
|
|
68
|
+
@(RCTDynamicTypeRampSubheadline) : @15,
|
|
69
|
+
@(RCTDynamicTypeRampCallout) : @16,
|
|
70
|
+
@(RCTDynamicTypeRampBody) : @17,
|
|
71
|
+
@(RCTDynamicTypeRampHeadline) : @17,
|
|
72
|
+
@(RCTDynamicTypeRampTitle3) : @20,
|
|
73
|
+
@(RCTDynamicTypeRampTitle2) : @22,
|
|
74
|
+
@(RCTDynamicTypeRampTitle1) : @28,
|
|
75
|
+
@(RCTDynamicTypeRampLargeTitle) : @34,
|
|
76
|
+
};
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
NSNumber *baseSize =
|
|
80
|
+
mapping[@(dynamicTypeRamp)] ?: @17; // Default to body size if we don't recognize the specified ramp
|
|
81
|
+
return CGFLOAT_IS_DOUBLE ? [baseSize doubleValue] : [baseSize floatValue];
|
|
82
|
+
}
|
package/Libraries/Text/Text.d.ts
CHANGED
|
@@ -26,6 +26,23 @@ export interface TextPropsIOS {
|
|
|
26
26
|
*/
|
|
27
27
|
adjustsFontSizeToFit?: boolean | undefined;
|
|
28
28
|
|
|
29
|
+
/**
|
|
30
|
+
* The Dynamic Text scale ramp to apply to this element on iOS.
|
|
31
|
+
*/
|
|
32
|
+
dynamicTypeRamp?:
|
|
33
|
+
| 'caption2'
|
|
34
|
+
| 'caption1'
|
|
35
|
+
| 'footnote'
|
|
36
|
+
| 'subheadline'
|
|
37
|
+
| 'callout'
|
|
38
|
+
| 'body'
|
|
39
|
+
| 'headline'
|
|
40
|
+
| 'title3'
|
|
41
|
+
| 'title2'
|
|
42
|
+
| 'title1'
|
|
43
|
+
| 'largeTitle'
|
|
44
|
+
| undefined;
|
|
45
|
+
|
|
29
46
|
/**
|
|
30
47
|
* Specifies smallest possible scale a font can reach when adjustsFontSizeToFit is enabled. (values 0.01-1.0).
|
|
31
48
|
*/
|
|
@@ -229,6 +229,23 @@ export type TextProps = $ReadOnly<{|
|
|
|
229
229
|
*/
|
|
230
230
|
adjustsFontSizeToFit?: ?boolean,
|
|
231
231
|
|
|
232
|
+
/**
|
|
233
|
+
* The Dynamic Text scale ramp to apply to this element on iOS.
|
|
234
|
+
*/
|
|
235
|
+
dynamicTypeRamp?: ?(
|
|
236
|
+
| 'caption2'
|
|
237
|
+
| 'caption1'
|
|
238
|
+
| 'footnote'
|
|
239
|
+
| 'subheadline'
|
|
240
|
+
| 'callout'
|
|
241
|
+
| 'body'
|
|
242
|
+
| 'headline'
|
|
243
|
+
| 'title3'
|
|
244
|
+
| 'title2'
|
|
245
|
+
| 'title1'
|
|
246
|
+
| 'largeTitle'
|
|
247
|
+
),
|
|
248
|
+
|
|
232
249
|
/**
|
|
233
250
|
* Smallest possible scale a font can reach.
|
|
234
251
|
*
|
|
@@ -0,0 +1,42 @@
|
|
|
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
|
+
|
|
8
|
+
#include "NativePerformanceObserver.h"
|
|
9
|
+
#include <glog/logging.h>
|
|
10
|
+
|
|
11
|
+
namespace facebook::react {
|
|
12
|
+
|
|
13
|
+
NativePerformanceObserver::NativePerformanceObserver(
|
|
14
|
+
std::shared_ptr<CallInvoker> jsInvoker)
|
|
15
|
+
: NativePerformanceObserverCxxSpec(std::move(jsInvoker)) {}
|
|
16
|
+
|
|
17
|
+
void NativePerformanceObserver::startReporting(
|
|
18
|
+
jsi::Runtime &rt,
|
|
19
|
+
std::string entryType) {
|
|
20
|
+
LOG(INFO) << "Started reporting perf entry type: " << entryType;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
void NativePerformanceObserver::stopReporting(
|
|
24
|
+
jsi::Runtime &rt,
|
|
25
|
+
std::string entryType) {
|
|
26
|
+
LOG(INFO) << "Stopped reporting perf entry type: " << entryType;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
std::vector<RawPerformanceEntry> NativePerformanceObserver::getPendingEntries(
|
|
30
|
+
jsi::Runtime &rt) {
|
|
31
|
+
return std::vector<RawPerformanceEntry>{};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
void NativePerformanceObserver::setOnPerformanceEntryCallback(
|
|
35
|
+
jsi::Runtime &rt,
|
|
36
|
+
std::optional<AsyncCallback<>> callback) {
|
|
37
|
+
callback_ = callback;
|
|
38
|
+
LOG(INFO) << "setOnPerformanceEntryCallback: "
|
|
39
|
+
<< (callback ? "non-empty" : "empty");
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
} // namespace facebook::react
|
|
@@ -0,0 +1,64 @@
|
|
|
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
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#include <FBReactNativeSpec/FBReactNativeSpecJSI.h>
|
|
11
|
+
#include <functional>
|
|
12
|
+
#include <memory>
|
|
13
|
+
#include <optional>
|
|
14
|
+
#include <string>
|
|
15
|
+
#include <vector>
|
|
16
|
+
|
|
17
|
+
namespace facebook::react {
|
|
18
|
+
|
|
19
|
+
#pragma mark - Structs
|
|
20
|
+
|
|
21
|
+
using RawPerformanceEntry = NativePerformanceObserverCxxBaseRawPerformanceEntry<
|
|
22
|
+
std::string,
|
|
23
|
+
int32_t,
|
|
24
|
+
double,
|
|
25
|
+
double,
|
|
26
|
+
// For "event" entries only:
|
|
27
|
+
std::optional<double>,
|
|
28
|
+
std::optional<double>,
|
|
29
|
+
std::optional<double>>;
|
|
30
|
+
|
|
31
|
+
template <>
|
|
32
|
+
struct Bridging<RawPerformanceEntry>
|
|
33
|
+
: NativePerformanceObserverCxxBaseRawPerformanceEntryBridging<
|
|
34
|
+
std::string,
|
|
35
|
+
int32_t,
|
|
36
|
+
double,
|
|
37
|
+
double,
|
|
38
|
+
std::optional<double>,
|
|
39
|
+
std::optional<double>,
|
|
40
|
+
std::optional<double>> {};
|
|
41
|
+
|
|
42
|
+
#pragma mark - implementation
|
|
43
|
+
|
|
44
|
+
class NativePerformanceObserver
|
|
45
|
+
: public NativePerformanceObserverCxxSpec<NativePerformanceObserver>,
|
|
46
|
+
std::enable_shared_from_this<NativePerformanceObserver> {
|
|
47
|
+
public:
|
|
48
|
+
NativePerformanceObserver(std::shared_ptr<CallInvoker> jsInvoker);
|
|
49
|
+
|
|
50
|
+
void startReporting(jsi::Runtime &rt, std::string entryType);
|
|
51
|
+
|
|
52
|
+
void stopReporting(jsi::Runtime &rt, std::string entryType);
|
|
53
|
+
|
|
54
|
+
std::vector<RawPerformanceEntry> getPendingEntries(jsi::Runtime &rt);
|
|
55
|
+
|
|
56
|
+
void setOnPerformanceEntryCallback(
|
|
57
|
+
jsi::Runtime &rt,
|
|
58
|
+
std::optional<AsyncCallback<>> callback);
|
|
59
|
+
|
|
60
|
+
private:
|
|
61
|
+
std::optional<AsyncCallback<>> callback_;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
} // namespace facebook::react
|
|
@@ -0,0 +1,41 @@
|
|
|
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
|
|
8
|
+
* @format
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type {TurboModule} from '../TurboModule/RCTExport';
|
|
12
|
+
|
|
13
|
+
import * as TurboModuleRegistry from '../TurboModule/TurboModuleRegistry';
|
|
14
|
+
|
|
15
|
+
export const RawPerformanceEntryTypeValues = {
|
|
16
|
+
UNDEFINED: 0,
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export type RawPerformanceEntryType = number;
|
|
20
|
+
|
|
21
|
+
export type RawPerformanceEntry = {|
|
|
22
|
+
name: string,
|
|
23
|
+
entryType: RawPerformanceEntryType,
|
|
24
|
+
startTime: number,
|
|
25
|
+
duration: number,
|
|
26
|
+
// For "event" entries only:
|
|
27
|
+
processingStart?: number,
|
|
28
|
+
processingEnd?: number,
|
|
29
|
+
interactionId?: number,
|
|
30
|
+
|};
|
|
31
|
+
|
|
32
|
+
export interface Spec extends TurboModule {
|
|
33
|
+
+startReporting: (entryType: string) => void;
|
|
34
|
+
+stopReporting: (entryType: string) => void;
|
|
35
|
+
+getPendingEntries: () => $ReadOnlyArray<RawPerformanceEntry>;
|
|
36
|
+
+setOnPerformanceEntryCallback: (callback?: () => void) => void;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export default (TurboModuleRegistry.get<Spec>(
|
|
40
|
+
'NativePerformanceObserverCxx',
|
|
41
|
+
): ?Spec);
|
|
@@ -0,0 +1,223 @@
|
|
|
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 type {
|
|
12
|
+
RawPerformanceEntry,
|
|
13
|
+
RawPerformanceEntryType,
|
|
14
|
+
} from './NativePerformanceObserver';
|
|
15
|
+
|
|
16
|
+
import warnOnce from '../Utilities/warnOnce';
|
|
17
|
+
import NativePerformanceObserver from './NativePerformanceObserver';
|
|
18
|
+
|
|
19
|
+
export type HighResTimeStamp = number;
|
|
20
|
+
// TODO: Extend once new types (such as event) are supported.
|
|
21
|
+
// TODO: Get rid of the "undefined" once there is at least one type supported.
|
|
22
|
+
export type PerformanceEntryType = 'undefined';
|
|
23
|
+
|
|
24
|
+
export class PerformanceEntry {
|
|
25
|
+
name: string;
|
|
26
|
+
entryType: PerformanceEntryType;
|
|
27
|
+
startTime: HighResTimeStamp;
|
|
28
|
+
duration: number;
|
|
29
|
+
|
|
30
|
+
constructor(init: {
|
|
31
|
+
name: string,
|
|
32
|
+
entryType: PerformanceEntryType,
|
|
33
|
+
startTime: HighResTimeStamp,
|
|
34
|
+
duration: number,
|
|
35
|
+
}) {
|
|
36
|
+
this.name = init.name;
|
|
37
|
+
this.entryType = init.entryType;
|
|
38
|
+
this.startTime = init.startTime;
|
|
39
|
+
this.duration = init.duration;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// $FlowIgnore: Flow(unclear-type)
|
|
43
|
+
toJSON(): Object {
|
|
44
|
+
return {
|
|
45
|
+
name: this.name,
|
|
46
|
+
entryType: this.entryType,
|
|
47
|
+
startTime: this.startTime,
|
|
48
|
+
duration: this.duration,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function rawToPerformanceEntryType(
|
|
54
|
+
type: RawPerformanceEntryType,
|
|
55
|
+
): PerformanceEntryType {
|
|
56
|
+
return 'undefined';
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function rawToPerformanceEntry(entry: RawPerformanceEntry): PerformanceEntry {
|
|
60
|
+
return new PerformanceEntry({
|
|
61
|
+
name: entry.name,
|
|
62
|
+
entryType: rawToPerformanceEntryType(entry.entryType),
|
|
63
|
+
startTime: entry.startTime,
|
|
64
|
+
duration: entry.duration,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export type PerformanceEntryList = $ReadOnlyArray<PerformanceEntry>;
|
|
69
|
+
|
|
70
|
+
export class PerformanceObserverEntryList {
|
|
71
|
+
_entries: PerformanceEntryList;
|
|
72
|
+
|
|
73
|
+
constructor(entries: PerformanceEntryList) {
|
|
74
|
+
this._entries = entries;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
getEntries(): PerformanceEntryList {
|
|
78
|
+
return this._entries;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
getEntriesByType(type: PerformanceEntryType): PerformanceEntryList {
|
|
82
|
+
return this._entries.filter(entry => entry.entryType === type);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
getEntriesByName(
|
|
86
|
+
name: string,
|
|
87
|
+
type?: PerformanceEntryType,
|
|
88
|
+
): PerformanceEntryList {
|
|
89
|
+
if (type === undefined) {
|
|
90
|
+
return this._entries.filter(entry => entry.name === name);
|
|
91
|
+
} else {
|
|
92
|
+
return this._entries.filter(
|
|
93
|
+
entry => entry.name === name && entry.entryType === type,
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export type PerformanceObserverCallback = (
|
|
100
|
+
list: PerformanceObserverEntryList,
|
|
101
|
+
observer: PerformanceObserver,
|
|
102
|
+
) => void;
|
|
103
|
+
|
|
104
|
+
export type PerformanceObserverInit =
|
|
105
|
+
| {
|
|
106
|
+
entryTypes: Array<PerformanceEntryType>,
|
|
107
|
+
}
|
|
108
|
+
| {
|
|
109
|
+
type: PerformanceEntryType,
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
let _observedEntryTypeRefCount: Map<PerformanceEntryType, number> = new Map();
|
|
113
|
+
|
|
114
|
+
let _observers: Set<PerformanceObserver> = new Set();
|
|
115
|
+
|
|
116
|
+
let _onPerformanceEntryCallbackIsSet: boolean = false;
|
|
117
|
+
|
|
118
|
+
function warnNoNativePerformanceObserver() {
|
|
119
|
+
warnOnce(
|
|
120
|
+
'missing-native-performance-observer',
|
|
121
|
+
'Missing native implementation of PerformanceObserver',
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Implementation of the PerformanceObserver interface for RN,
|
|
127
|
+
* corresponding to the standard in https://www.w3.org/TR/performance-timeline/
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* const observer = new PerformanceObserver((list, _observer) => {
|
|
131
|
+
* const entries = list.getEntries();
|
|
132
|
+
* entries.forEach(entry => {
|
|
133
|
+
* reportEvent({
|
|
134
|
+
* eventName: entry.name,
|
|
135
|
+
* startTime: entry.startTime,
|
|
136
|
+
* endTime: entry.startTime + entry.duration,
|
|
137
|
+
* processingStart: entry.processingStart,
|
|
138
|
+
* processingEnd: entry.processingEnd,
|
|
139
|
+
* interactionId: entry.interactionId,
|
|
140
|
+
* });
|
|
141
|
+
* });
|
|
142
|
+
* });
|
|
143
|
+
* observer.observe({ type: "event" });
|
|
144
|
+
*/
|
|
145
|
+
export default class PerformanceObserver {
|
|
146
|
+
_callback: PerformanceObserverCallback;
|
|
147
|
+
_entryTypes: $ReadOnlySet<PerformanceEntryType>;
|
|
148
|
+
|
|
149
|
+
constructor(callback: PerformanceObserverCallback) {
|
|
150
|
+
this._callback = callback;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
observe(options: PerformanceObserverInit) {
|
|
154
|
+
if (!NativePerformanceObserver) {
|
|
155
|
+
warnNoNativePerformanceObserver();
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
if (!_onPerformanceEntryCallbackIsSet) {
|
|
159
|
+
NativePerformanceObserver.setOnPerformanceEntryCallback(
|
|
160
|
+
onPerformanceEntry,
|
|
161
|
+
);
|
|
162
|
+
_onPerformanceEntryCallbackIsSet = true;
|
|
163
|
+
}
|
|
164
|
+
if (options.entryTypes) {
|
|
165
|
+
this._entryTypes = new Set(options.entryTypes);
|
|
166
|
+
} else {
|
|
167
|
+
this._entryTypes = new Set([options.type]);
|
|
168
|
+
}
|
|
169
|
+
this._entryTypes.forEach(type => {
|
|
170
|
+
if (!_observedEntryTypeRefCount.has(type)) {
|
|
171
|
+
NativePerformanceObserver.startReporting(type);
|
|
172
|
+
}
|
|
173
|
+
_observedEntryTypeRefCount.set(
|
|
174
|
+
type,
|
|
175
|
+
(_observedEntryTypeRefCount.get(type) ?? 0) + 1,
|
|
176
|
+
);
|
|
177
|
+
});
|
|
178
|
+
_observers.add(this);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
disconnect(): void {
|
|
182
|
+
if (!NativePerformanceObserver) {
|
|
183
|
+
warnNoNativePerformanceObserver();
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
this._entryTypes.forEach(type => {
|
|
187
|
+
const entryTypeRefCount = _observedEntryTypeRefCount.get(type) ?? 0;
|
|
188
|
+
if (entryTypeRefCount === 1) {
|
|
189
|
+
_observedEntryTypeRefCount.delete(type);
|
|
190
|
+
NativePerformanceObserver.stopReporting(type);
|
|
191
|
+
} else if (entryTypeRefCount !== 0) {
|
|
192
|
+
_observedEntryTypeRefCount.set(type, entryTypeRefCount - 1);
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
_observers.delete(this);
|
|
196
|
+
if (_observers.size === 0) {
|
|
197
|
+
NativePerformanceObserver.setOnPerformanceEntryCallback(undefined);
|
|
198
|
+
_onPerformanceEntryCallbackIsSet = false;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
static supportedEntryTypes: $ReadOnlyArray<PerformanceEntryType> =
|
|
203
|
+
// TODO: add types once they are fully supported
|
|
204
|
+
Object.freeze([]);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// This is a callback that gets scheduled and periodically called from the native side
|
|
208
|
+
function onPerformanceEntry() {
|
|
209
|
+
if (!NativePerformanceObserver) {
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
const rawEntries = NativePerformanceObserver.getPendingEntries();
|
|
213
|
+
const entries = rawEntries.map(rawToPerformanceEntry);
|
|
214
|
+
_observers.forEach(observer => {
|
|
215
|
+
const entriesForObserver: PerformanceEntryList = entries.filter(entry =>
|
|
216
|
+
observer._entryTypes.has(entry.entryType),
|
|
217
|
+
);
|
|
218
|
+
observer._callback(
|
|
219
|
+
new PerformanceObserverEntryList(entriesForObserver),
|
|
220
|
+
observer,
|
|
221
|
+
);
|
|
222
|
+
});
|
|
223
|
+
}
|
package/React/Base/RCTVersion.m
CHANGED
|
@@ -53,6 +53,7 @@ Class RCTWebSocketModuleCls(void) __attribute__((used));
|
|
|
53
53
|
Class RCTDevLoadingViewCls(void) __attribute__((used));
|
|
54
54
|
Class RCTDevSplitBundleLoaderCls(void) __attribute__((used));
|
|
55
55
|
Class RCTEventDispatcherCls(void) __attribute__((used));
|
|
56
|
+
Class RCTBlobManagerCls(void) __attribute__((used));
|
|
56
57
|
|
|
57
58
|
#ifdef __cplusplus
|
|
58
59
|
}
|
|
@@ -43,6 +43,7 @@ Class RCTCoreModulesClassProvider(const char *name) {
|
|
|
43
43
|
{"DevLoadingView", RCTDevLoadingViewCls},
|
|
44
44
|
{"DevSplitBundleLoader", RCTDevSplitBundleLoaderCls},
|
|
45
45
|
{"EventDispatcher", RCTEventDispatcherCls},
|
|
46
|
+
{"BlobModule", RCTBlobManagerCls},
|
|
46
47
|
};
|
|
47
48
|
|
|
48
49
|
auto p = sCoreModuleClassMap->find(name);
|
|
@@ -363,8 +363,8 @@ task installArchives {
|
|
|
363
363
|
}
|
|
364
364
|
|
|
365
365
|
android {
|
|
366
|
-
buildToolsVersion = "
|
|
367
|
-
compileSdkVersion
|
|
366
|
+
buildToolsVersion = "33.0.0"
|
|
367
|
+
compileSdkVersion 33
|
|
368
368
|
|
|
369
369
|
// Used to override the NDK path/version on internal CI or by allowing
|
|
370
370
|
// users to customize the NDK path/version from their root project (e.g. for M1 support)
|
|
@@ -377,7 +377,7 @@ android {
|
|
|
377
377
|
|
|
378
378
|
defaultConfig {
|
|
379
379
|
minSdkVersion(21)
|
|
380
|
-
targetSdkVersion(
|
|
380
|
+
targetSdkVersion(33)
|
|
381
381
|
versionCode(1)
|
|
382
382
|
versionName("1.0")
|
|
383
383
|
|
|
@@ -616,11 +616,13 @@ apply plugin: "org.jetbrains.kotlin.android"
|
|
|
616
616
|
apply from: "./publish.gradle"
|
|
617
617
|
|
|
618
618
|
// We need to override the artifact ID as this project is called `ReactAndroid` but
|
|
619
|
-
// the maven coordinates are on `react-
|
|
619
|
+
// the maven coordinates are on `react-android`.
|
|
620
|
+
// Please note that the original coordinates, `react-native`, have been voided
|
|
621
|
+
// as they caused https://github.com/facebook/react-native/issues/35210
|
|
620
622
|
publishing {
|
|
621
623
|
publications {
|
|
622
624
|
getByName("release") {
|
|
623
|
-
artifactId 'react-
|
|
625
|
+
artifactId 'react-android'
|
|
624
626
|
}
|
|
625
627
|
}
|
|
626
628
|
}
|