react-native 0.85.0-rc.0 → 0.85.0-rc.5
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/Core/setUpReactDevTools.js +23 -6
- package/Libraries/Network/RCTHTTPRequestHandler.h +9 -0
- package/Libraries/Network/RCTHTTPRequestHandler.mm +15 -1
- package/React/Base/RCTMultipartDataTask.h +9 -0
- package/React/Base/RCTMultipartDataTask.m +16 -1
- package/React/Base/RCTVersion.m +1 -1
- package/React/CoreModules/RCTWebSocketModule.h +6 -0
- package/React/CoreModules/RCTWebSocketModule.mm +14 -1
- package/React/DevSupport/RCTInspectorDevServerHelper.mm +31 -22
- package/ReactAndroid/gradle.properties +1 -1
- package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.kt +1 -1
- package/ReactAndroid/src/main/java/com/facebook/react/modules/websocket/WebSocketModule.kt +3 -4
- package/ReactAndroid/src/main/jni/CMakeLists.txt +3 -0
- package/ReactCommon/cxxreact/ReactNativeVersion.h +1 -1
- package/ReactCommon/jsinspector-modern/InspectorInterfaces.cpp +6 -0
- package/ReactCommon/react/nativemodule/defaults/CMakeLists.txt +1 -0
- package/ReactCommon/react/nativemodule/defaults/DefaultTurboModules.cpp +8 -0
- package/ReactCommon/react/nativemodule/defaults/React-defaultsnativemodule.podspec +1 -0
- package/ReactCommon/react/renderer/animated/NativeAnimatedNodesManagerProvider.cpp +79 -71
- package/ReactCommon/react/renderer/animationbackend/AnimatedPropsRegistry.cpp +3 -1
- package/ReactCommon/react/renderer/animationbackend/AnimatedPropsRegistry.h +3 -3
- package/ReactCommon/react/renderer/animationbackend/AnimationBackend.cpp +3 -2
- package/ReactCommon/react/renderer/animationbackend/AnimationBackendCommitHook.cpp +4 -3
- package/ReactCommon/react/renderer/core/ShadowNode.cpp +14 -13
- package/ReactCommon/react/renderer/core/ShadowNode.h +1 -1
- package/ReactCommon/react/renderer/core/tests/ShadowNodeTest.cpp +4 -4
- package/package.json +9 -9
|
@@ -29,7 +29,7 @@ export default class ReactNativeVersion {
|
|
|
29
29
|
static major: number = 0;
|
|
30
30
|
static minor: number = 85;
|
|
31
31
|
static patch: number = 0;
|
|
32
|
-
static prerelease: string | null = 'rc.
|
|
32
|
+
static prerelease: string | null = 'rc.5';
|
|
33
33
|
|
|
34
34
|
static getVersionString(): string {
|
|
35
35
|
return `${this.major}.${this.minor}.${this.patch}${this.prerelease != null ? `-${this.prerelease}` : ''}`;
|
|
@@ -146,17 +146,34 @@ if (__DEV__) {
|
|
|
146
146
|
? guessHostFromDevServerUrl(devServer.url)
|
|
147
147
|
: 'localhost';
|
|
148
148
|
|
|
149
|
-
//
|
|
150
|
-
//
|
|
151
|
-
|
|
149
|
+
// Derive scheme and port from the dev server URL when possible,
|
|
150
|
+
// falling back to ws://host:8097 for local development.
|
|
151
|
+
let wsScheme = 'ws';
|
|
152
|
+
let port = 8097;
|
|
153
|
+
|
|
154
|
+
if (
|
|
152
155
|
// $FlowFixMe[prop-missing]
|
|
153
156
|
// $FlowFixMe[incompatible-use]
|
|
154
157
|
window.__REACT_DEVTOOLS_PORT__ != null
|
|
155
|
-
|
|
156
|
-
|
|
158
|
+
) {
|
|
159
|
+
// $FlowFixMe[prop-missing]
|
|
160
|
+
port = window.__REACT_DEVTOOLS_PORT__;
|
|
161
|
+
} else if (devServer.bundleLoadedFromServer) {
|
|
162
|
+
try {
|
|
163
|
+
const devUrl = new URL(devServer.url);
|
|
164
|
+
if (devUrl.protocol === 'https:') {
|
|
165
|
+
wsScheme = 'wss';
|
|
166
|
+
}
|
|
167
|
+
if (devUrl.port) {
|
|
168
|
+
port = parseInt(devUrl.port, 10);
|
|
169
|
+
} else if (devUrl.protocol === 'https:') {
|
|
170
|
+
port = 443;
|
|
171
|
+
}
|
|
172
|
+
} catch (e) {}
|
|
173
|
+
}
|
|
157
174
|
|
|
158
175
|
const WebSocket = require('../WebSocket/WebSocket').default;
|
|
159
|
-
ws = new WebSocket('
|
|
176
|
+
ws = new WebSocket(wsScheme + '://' + host + ':' + port);
|
|
160
177
|
ws.addEventListener('close', event => {
|
|
161
178
|
isWebSocketOpen = false;
|
|
162
179
|
});
|
|
@@ -14,6 +14,15 @@ typedef NSURLSessionConfiguration * (^NSURLSessionConfigurationProvider)(void);
|
|
|
14
14
|
* app.
|
|
15
15
|
*/
|
|
16
16
|
RCT_EXTERN void RCTSetCustomNSURLSessionConfigurationProvider(NSURLSessionConfigurationProvider /*provider*/);
|
|
17
|
+
|
|
18
|
+
typedef NSURLRequest *_Nullable (^RCTHTTPRequestInterceptor)(NSURLRequest *request);
|
|
19
|
+
/**
|
|
20
|
+
* The block provided via this function can inspect/modify HTTP requests before
|
|
21
|
+
* they are sent. Return a modified request to override, or nil to use the
|
|
22
|
+
* original request unchanged.
|
|
23
|
+
*/
|
|
24
|
+
RCT_EXTERN void RCTSetCustomHTTPRequestInterceptor(RCTHTTPRequestInterceptor /*interceptor*/);
|
|
25
|
+
|
|
17
26
|
/**
|
|
18
27
|
* This is the default RCTURLRequestHandler implementation for HTTP requests.
|
|
19
28
|
*/
|
|
@@ -25,6 +25,13 @@ void RCTSetCustomNSURLSessionConfigurationProvider(NSURLSessionConfigurationProv
|
|
|
25
25
|
urlSessionConfigurationProvider = provider;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
+
static RCTHTTPRequestInterceptor httpRequestInterceptor;
|
|
29
|
+
|
|
30
|
+
void RCTSetCustomHTTPRequestInterceptor(RCTHTTPRequestInterceptor interceptor)
|
|
31
|
+
{
|
|
32
|
+
httpRequestInterceptor = interceptor;
|
|
33
|
+
}
|
|
34
|
+
|
|
28
35
|
@implementation RCTHTTPRequestHandler {
|
|
29
36
|
NSMapTable *_delegates;
|
|
30
37
|
NSURLSession *_session;
|
|
@@ -99,7 +106,14 @@ RCT_EXPORT_MODULE()
|
|
|
99
106
|
valueOptions:NSPointerFunctionsStrongMemory
|
|
100
107
|
capacity:0];
|
|
101
108
|
}
|
|
102
|
-
|
|
109
|
+
NSURLRequest *finalRequest = request;
|
|
110
|
+
if (httpRequestInterceptor != nullptr) {
|
|
111
|
+
NSURLRequest *intercepted = httpRequestInterceptor(request);
|
|
112
|
+
if (intercepted != nil) {
|
|
113
|
+
finalRequest = intercepted;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
NSURLSessionDataTask *task = [_session dataTaskWithRequest:finalRequest];
|
|
103
117
|
[_delegates setObject:delegate forKey:task];
|
|
104
118
|
[task resume];
|
|
105
119
|
return task;
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
#import <Foundation/Foundation.h>
|
|
9
9
|
|
|
10
|
+
#import <React/RCTDefines.h>
|
|
10
11
|
#import <React/RCTMultipartStreamReader.h>
|
|
11
12
|
|
|
12
13
|
typedef void (^RCTMultipartDataTaskCallback)(
|
|
@@ -16,6 +17,14 @@ typedef void (^RCTMultipartDataTaskCallback)(
|
|
|
16
17
|
NSError *error,
|
|
17
18
|
BOOL done);
|
|
18
19
|
|
|
20
|
+
typedef NSURLRequest * _Nullable (^RCTMultipartDataTaskRequestInterceptor)(NSURLRequest *request);
|
|
21
|
+
/**
|
|
22
|
+
* The block provided via this function can inspect/modify multipart data task
|
|
23
|
+
* requests before they are sent. Return a modified request to override, or nil
|
|
24
|
+
* to use the original request unchanged.
|
|
25
|
+
*/
|
|
26
|
+
RCT_EXTERN void RCTSetCustomMultipartDataTaskRequestInterceptor(RCTMultipartDataTaskRequestInterceptor /*interceptor*/);
|
|
27
|
+
|
|
19
28
|
@interface RCTMultipartDataTask : NSObject
|
|
20
29
|
|
|
21
30
|
- (instancetype)initWithURL:(NSURL *)url
|
|
@@ -7,6 +7,13 @@
|
|
|
7
7
|
|
|
8
8
|
#import "RCTMultipartDataTask.h"
|
|
9
9
|
|
|
10
|
+
static RCTMultipartDataTaskRequestInterceptor multipartRequestInterceptor;
|
|
11
|
+
|
|
12
|
+
void RCTSetCustomMultipartDataTaskRequestInterceptor(RCTMultipartDataTaskRequestInterceptor interceptor)
|
|
13
|
+
{
|
|
14
|
+
multipartRequestInterceptor = interceptor;
|
|
15
|
+
}
|
|
16
|
+
|
|
10
17
|
#import "RCTDevSupportHttpHeaders.h"
|
|
11
18
|
|
|
12
19
|
@interface RCTMultipartDataTask () <NSURLSessionDataDelegate, NSURLSessionDataDelegate>
|
|
@@ -43,7 +50,15 @@
|
|
|
43
50
|
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:_url];
|
|
44
51
|
[request addValue:@"multipart/mixed" forHTTPHeaderField:@"Accept"];
|
|
45
52
|
[[RCTDevSupportHttpHeaders sharedInstance] applyHeadersToRequest:request];
|
|
46
|
-
|
|
53
|
+
NSURLRequest *finalRequest = request;
|
|
54
|
+
if (multipartRequestInterceptor != nil) {
|
|
55
|
+
NSURLRequest *intercepted = multipartRequestInterceptor(request);
|
|
56
|
+
if (intercepted != nil) {
|
|
57
|
+
finalRequest = intercepted;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
NSLog(@"[RCTMultipartDataTask] %@ %@", finalRequest.HTTPMethod ?: @"GET", finalRequest.URL.absoluteString);
|
|
61
|
+
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:finalRequest];
|
|
47
62
|
[dataTask resume];
|
|
48
63
|
[session finishTasksAndInvalidate];
|
|
49
64
|
}
|
package/React/Base/RCTVersion.m
CHANGED
|
@@ -18,6 +18,12 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
18
18
|
|
|
19
19
|
@end
|
|
20
20
|
|
|
21
|
+
@class SRWebSocket;
|
|
22
|
+
|
|
23
|
+
typedef SRWebSocket * (^SRWebSocketProvider)(NSURLRequest *request);
|
|
24
|
+
|
|
25
|
+
RCT_EXTERN void RCTSetCustomSRWebSocketProvider(SRWebSocketProvider provider);
|
|
26
|
+
|
|
21
27
|
@interface RCTWebSocketModule : RCTEventEmitter
|
|
22
28
|
|
|
23
29
|
// Register a custom handler for a specific websocket. The handler will be strongly held by the WebSocketModule.
|
|
@@ -34,6 +34,13 @@
|
|
|
34
34
|
|
|
35
35
|
@end
|
|
36
36
|
|
|
37
|
+
static SRWebSocketProvider srWebSocketProvider;
|
|
38
|
+
|
|
39
|
+
void RCTSetCustomSRWebSocketProvider(SRWebSocketProvider provider)
|
|
40
|
+
{
|
|
41
|
+
srWebSocketProvider = provider;
|
|
42
|
+
}
|
|
43
|
+
|
|
37
44
|
@implementation RCTWebSocketModule {
|
|
38
45
|
NSMutableDictionary<NSNumber *, SRWebSocket *> *_sockets;
|
|
39
46
|
NSMutableDictionary<NSNumber *, id<RCTWebSocketContentHandler>> *_contentHandlers;
|
|
@@ -88,7 +95,13 @@ RCT_EXPORT_METHOD(
|
|
|
88
95
|
}];
|
|
89
96
|
}
|
|
90
97
|
|
|
91
|
-
SRWebSocket *webSocket
|
|
98
|
+
SRWebSocket *webSocket;
|
|
99
|
+
if (srWebSocketProvider != nullptr) {
|
|
100
|
+
webSocket = srWebSocketProvider(request);
|
|
101
|
+
}
|
|
102
|
+
if (webSocket == nil) {
|
|
103
|
+
webSocket = [[SRWebSocket alloc] initWithURLRequest:request protocols:protocols];
|
|
104
|
+
}
|
|
92
105
|
[webSocket setDelegateDispatchQueue:[self methodQueue]];
|
|
93
106
|
webSocket.delegate = self;
|
|
94
107
|
webSocket.reactTag = @(socketID);
|
|
@@ -20,28 +20,33 @@
|
|
|
20
20
|
#import <jsinspector-modern/InspectorFlags.h>
|
|
21
21
|
|
|
22
22
|
static NSString *const kDebuggerMsgDisable = @"{ \"id\":1,\"method\":\"Debugger.disable\" }";
|
|
23
|
+
static const int kDefaultMetroPort = 8081;
|
|
23
24
|
|
|
24
25
|
static NSString *getServerHost(NSURL *bundleURL)
|
|
25
26
|
{
|
|
26
|
-
NSNumber *port = @8081;
|
|
27
|
-
NSString *portStr = [[[NSProcessInfo processInfo] environment] objectForKey:@"RCT_METRO_PORT"];
|
|
28
|
-
if ((portStr != nullptr) && [portStr length] > 0) {
|
|
29
|
-
port = [NSNumber numberWithInt:[portStr intValue]];
|
|
30
|
-
}
|
|
31
|
-
if ([bundleURL port] != nullptr) {
|
|
32
|
-
port = [bundleURL port];
|
|
33
|
-
}
|
|
34
27
|
NSString *host = [bundleURL host];
|
|
35
28
|
if (host == nullptr) {
|
|
36
29
|
host = @"localhost";
|
|
37
30
|
}
|
|
38
31
|
|
|
39
|
-
//
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
32
|
+
// Use explicit port from URL if available
|
|
33
|
+
if ([bundleURL port] != nullptr) {
|
|
34
|
+
return [NSString stringWithFormat:@"%@:%@", host, [bundleURL port]];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Check environment variable
|
|
38
|
+
NSString *portStr = [[[NSProcessInfo processInfo] environment] objectForKey:@"RCT_METRO_PORT"];
|
|
39
|
+
if ((portStr != nullptr) && [portStr length] > 0) {
|
|
40
|
+
return [NSString stringWithFormat:@"%@:%@", host, portStr];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// For https, omit port — the scheme implies 443
|
|
44
|
+
if ([[bundleURL scheme] isEqualToString:@"https"]) {
|
|
45
|
+
return host;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Default to 8081 for local development (Metro's default port)
|
|
49
|
+
return [NSString stringWithFormat:@"%@:%d", host, kDefaultMetroPort];
|
|
45
50
|
}
|
|
46
51
|
|
|
47
52
|
static NSString *getSHA256(NSString *string)
|
|
@@ -112,13 +117,15 @@ static NSURL *getInspectorDeviceUrl(NSURL *bundleURL)
|
|
|
112
117
|
NSString *escapedInspectorDeviceId = [getInspectorDeviceId()
|
|
113
118
|
stringByAddingPercentEncodingWithAllowedCharacters:NSCharacterSet.URLQueryAllowedCharacterSet];
|
|
114
119
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
120
|
+
NSString *scheme = [bundleURL scheme] != nullptr ? [bundleURL scheme] : @"http";
|
|
121
|
+
return
|
|
122
|
+
[NSURL URLWithString:[NSString stringWithFormat:@"%@://%@/inspector/device?name=%@&app=%@&device=%@&profiling=%@",
|
|
123
|
+
scheme,
|
|
124
|
+
getServerHost(bundleURL),
|
|
125
|
+
escapedDeviceName,
|
|
126
|
+
escapedAppName,
|
|
127
|
+
escapedInspectorDeviceId,
|
|
128
|
+
isProfilingBuild ? @"true" : @"false"]];
|
|
122
129
|
}
|
|
123
130
|
|
|
124
131
|
@implementation RCTInspectorDevServerHelper
|
|
@@ -150,7 +157,9 @@ static void sendEventToAllConnections(NSString *event)
|
|
|
150
157
|
NSString *escapedInspectorDeviceId = [getInspectorDeviceId()
|
|
151
158
|
stringByAddingPercentEncodingWithAllowedCharacters:NSCharacterSet.URLQueryAllowedCharacterSet];
|
|
152
159
|
|
|
153
|
-
|
|
160
|
+
NSString *scheme = [bundleURL scheme] != nullptr ? [bundleURL scheme] : @"http";
|
|
161
|
+
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@://%@/open-debugger?device=%@",
|
|
162
|
+
scheme,
|
|
154
163
|
getServerHost(bundleURL),
|
|
155
164
|
escapedInspectorDeviceId]];
|
|
156
165
|
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
|
|
@@ -22,6 +22,7 @@ import com.facebook.react.common.ReactConstants
|
|
|
22
22
|
import com.facebook.react.module.annotations.ReactModule
|
|
23
23
|
import com.facebook.react.modules.network.CustomClientBuilder
|
|
24
24
|
import com.facebook.react.modules.network.ForwardingCookieHandler
|
|
25
|
+
import com.facebook.react.modules.network.OkHttpClientProvider
|
|
25
26
|
import java.io.IOException
|
|
26
27
|
import java.net.URI
|
|
27
28
|
import java.net.URISyntaxException
|
|
@@ -80,7 +81,8 @@ public class WebSocketModule(context: ReactApplicationContext) :
|
|
|
80
81
|
) {
|
|
81
82
|
val id = socketID.toInt()
|
|
82
83
|
val okHttpBuilder =
|
|
83
|
-
|
|
84
|
+
OkHttpClientProvider.getOkHttpClient()
|
|
85
|
+
.newBuilder()
|
|
84
86
|
.connectTimeout(10, TimeUnit.SECONDS)
|
|
85
87
|
.writeTimeout(10, TimeUnit.SECONDS)
|
|
86
88
|
.readTimeout(0, TimeUnit.MINUTES) // Disable timeouts for read
|
|
@@ -198,9 +200,6 @@ public class WebSocketModule(context: ReactApplicationContext) :
|
|
|
198
200
|
}
|
|
199
201
|
},
|
|
200
202
|
)
|
|
201
|
-
|
|
202
|
-
// Trigger shutdown of the dispatcher's executor so this process can exit cleanly
|
|
203
|
-
client.dispatcher().executorService().shutdown()
|
|
204
203
|
}
|
|
205
204
|
|
|
206
205
|
override fun close(code: Double, reason: String?, socketID: Double) {
|
|
@@ -82,6 +82,7 @@ add_react_common_subdir(react/debug)
|
|
|
82
82
|
add_react_common_subdir(react/featureflags)
|
|
83
83
|
add_react_common_subdir(react/performance/cdpmetrics)
|
|
84
84
|
add_react_common_subdir(react/performance/timeline)
|
|
85
|
+
add_react_common_subdir(react/renderer/animated)
|
|
85
86
|
add_react_common_subdir(react/renderer/animationbackend)
|
|
86
87
|
add_react_common_subdir(react/renderer/animations)
|
|
87
88
|
add_react_common_subdir(react/renderer/attributedstring)
|
|
@@ -201,6 +202,7 @@ add_library(reactnative
|
|
|
201
202
|
$<TARGET_OBJECTS:react_newarchdefaults>
|
|
202
203
|
$<TARGET_OBJECTS:react_performance_cdpmetrics>
|
|
203
204
|
$<TARGET_OBJECTS:react_performance_timeline>
|
|
205
|
+
$<TARGET_OBJECTS:react_renderer_animated>
|
|
204
206
|
$<TARGET_OBJECTS:react_renderer_animationbackend>
|
|
205
207
|
$<TARGET_OBJECTS:react_renderer_animations>
|
|
206
208
|
$<TARGET_OBJECTS:react_renderer_attributedstring>
|
|
@@ -295,6 +297,7 @@ target_include_directories(reactnative
|
|
|
295
297
|
$<TARGET_PROPERTY:react_newarchdefaults,INTERFACE_INCLUDE_DIRECTORIES>
|
|
296
298
|
$<TARGET_PROPERTY:react_performance_cdpmetrics,INTERFACE_INCLUDE_DIRECTORIES>
|
|
297
299
|
$<TARGET_PROPERTY:react_performance_timeline,INTERFACE_INCLUDE_DIRECTORIES>
|
|
300
|
+
$<TARGET_PROPERTY:react_renderer_animated,INTERFACE_INCLUDE_DIRECTORIES>
|
|
298
301
|
$<TARGET_PROPERTY:react_renderer_animationbackend,INTERFACE_INCLUDE_DIRECTORIES>
|
|
299
302
|
$<TARGET_PROPERTY:react_renderer_animations,INTERFACE_INCLUDE_DIRECTORIES>
|
|
300
303
|
$<TARGET_PROPERTY:react_renderer_attributedstring,INTERFACE_INCLUDE_DIRECTORIES>
|
|
@@ -142,6 +142,12 @@ int InspectorImpl::addPage(
|
|
|
142
142
|
pageId,
|
|
143
143
|
Page{pageId, description, vm, std::move(connectFunc), capabilities});
|
|
144
144
|
|
|
145
|
+
for (const auto& listenerWeak : listeners_) {
|
|
146
|
+
if (auto listener = listenerWeak.lock()) {
|
|
147
|
+
listener->unstable_onHostTargetAdded();
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
145
151
|
return pageId;
|
|
146
152
|
}
|
|
147
153
|
|
|
@@ -23,6 +23,7 @@ target_link_libraries(react_nativemodule_defaults
|
|
|
23
23
|
react_nativemodule_idlecallbacks
|
|
24
24
|
react_nativemodule_intersectionobserver
|
|
25
25
|
react_nativemodule_webperformance
|
|
26
|
+
react_renderer_animated
|
|
26
27
|
)
|
|
27
28
|
target_compile_reactnative_options(react_nativemodule_defaults PRIVATE)
|
|
28
29
|
target_compile_options(react_nativemodule_defaults PRIVATE -Wpedantic)
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
#include <react/nativemodule/intersectionobserver/NativeIntersectionObserver.h>
|
|
14
14
|
#include <react/nativemodule/microtasks/NativeMicrotasks.h>
|
|
15
15
|
#include <react/nativemodule/webperformance/NativePerformance.h>
|
|
16
|
+
#include <react/renderer/animated/AnimatedModule.h>
|
|
16
17
|
|
|
17
18
|
#ifdef REACT_NATIVE_DEBUGGER_ENABLED_DEVONLY
|
|
18
19
|
#include <react/nativemodule/devtoolsruntimesettings/DevToolsRuntimeSettingsModule.h>
|
|
@@ -49,6 +50,13 @@ namespace facebook::react {
|
|
|
49
50
|
}
|
|
50
51
|
}
|
|
51
52
|
|
|
53
|
+
if (ReactNativeFeatureFlags::cxxNativeAnimatedEnabled() &&
|
|
54
|
+
ReactNativeFeatureFlags::useSharedAnimatedBackend() &&
|
|
55
|
+
name == AnimatedModule::kModuleName) {
|
|
56
|
+
return std::make_shared<AnimatedModule>(
|
|
57
|
+
jsInvoker, std::make_shared<NativeAnimatedNodesManagerProvider>());
|
|
58
|
+
}
|
|
59
|
+
|
|
52
60
|
#ifdef REACT_NATIVE_DEBUGGER_ENABLED_DEVONLY
|
|
53
61
|
if (name == DevToolsRuntimeSettingsModule::kModuleName) {
|
|
54
62
|
return std::make_shared<DevToolsRuntimeSettingsModule>(jsInvoker);
|
|
@@ -54,6 +54,7 @@ Pod::Spec.new do |s|
|
|
|
54
54
|
s.dependency "React-idlecallbacksnativemodule"
|
|
55
55
|
s.dependency "React-intersectionobservernativemodule"
|
|
56
56
|
s.dependency "React-webperformancenativemodule"
|
|
57
|
+
s.dependency "React-Fabric/animated"
|
|
57
58
|
add_dependency(s, "React-RCTFBReactNativeSpec")
|
|
58
59
|
add_dependency(s, "React-featureflags")
|
|
59
60
|
add_dependency(s, "React-featureflagsnativemodule")
|
|
@@ -45,8 +45,16 @@ std::shared_ptr<NativeAnimatedNodesManager>
|
|
|
45
45
|
NativeAnimatedNodesManagerProvider::getOrCreate(
|
|
46
46
|
jsi::Runtime& runtime,
|
|
47
47
|
std::shared_ptr<CallInvoker> jsInvoker) {
|
|
48
|
-
if (nativeAnimatedNodesManager_
|
|
49
|
-
|
|
48
|
+
if (nativeAnimatedNodesManager_ != nullptr) {
|
|
49
|
+
return nativeAnimatedNodesManager_;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
auto* uiManager = &UIManagerBinding::getBinding(runtime)->getUIManager();
|
|
53
|
+
|
|
54
|
+
if (!ReactNativeFeatureFlags::useSharedAnimatedBackend()) {
|
|
55
|
+
// === PATH 1: Legacy Backend (useSharedAnimatedBackend = false) ===
|
|
56
|
+
// Uses the architecture with MergedValueDispatcher and
|
|
57
|
+
// AnimatedMountingOverrideDelegate
|
|
50
58
|
|
|
51
59
|
mergedValueDispatcher_ = std::make_unique<MergedValueDispatcher>(
|
|
52
60
|
[jsInvoker](std::function<void()>&& func) {
|
|
@@ -84,78 +92,78 @@ NativeAnimatedNodesManagerProvider::getOrCreate(
|
|
|
84
92
|
}
|
|
85
93
|
};
|
|
86
94
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
uiManager->addEventListener(
|
|
114
|
-
std::make_shared<EventListener>(
|
|
115
|
-
[eventEmitterListenerContainerWeak =
|
|
116
|
-
std::weak_ptr<EventEmitterListenerContainer>(
|
|
117
|
-
eventEmitterListenerContainer_)](
|
|
118
|
-
const RawEvent& rawEvent) {
|
|
119
|
-
const auto& eventTarget = rawEvent.eventTarget;
|
|
120
|
-
const auto& eventPayload = rawEvent.eventPayload;
|
|
121
|
-
if (eventTarget && eventPayload) {
|
|
122
|
-
if (auto eventEmitterListenerContainer =
|
|
123
|
-
eventEmitterListenerContainerWeak.lock();
|
|
124
|
-
eventEmitterListenerContainer != nullptr) {
|
|
125
|
-
return eventEmitterListenerContainer->willDispatchEvent(
|
|
126
|
-
eventTarget->getTag(), rawEvent.type, *eventPayload);
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
return false;
|
|
130
|
-
}));
|
|
95
|
+
nativeAnimatedNodesManager_ = std::make_shared<NativeAnimatedNodesManager>(
|
|
96
|
+
std::move(directManipulationCallback),
|
|
97
|
+
std::move(fabricCommitCallback),
|
|
98
|
+
std::move(resolvePlatformColor),
|
|
99
|
+
std::move(startOnRenderCallback_),
|
|
100
|
+
std::move(stopOnRenderCallback_),
|
|
101
|
+
std::move(frameRateListenerCallback_));
|
|
102
|
+
|
|
103
|
+
nativeAnimatedDelegate_ =
|
|
104
|
+
std::make_shared<UIManagerNativeAnimatedDelegateImpl>(
|
|
105
|
+
nativeAnimatedNodesManager_);
|
|
106
|
+
|
|
107
|
+
animatedMountingOverrideDelegate_ =
|
|
108
|
+
std::make_shared<AnimatedMountingOverrideDelegate>(
|
|
109
|
+
*nativeAnimatedNodesManager_, *scheduler);
|
|
110
|
+
|
|
111
|
+
// Register on existing surfaces
|
|
112
|
+
uiManager->getShadowTreeRegistry().enumerate(
|
|
113
|
+
[animatedMountingOverrideDelegate =
|
|
114
|
+
std::weak_ptr<const AnimatedMountingOverrideDelegate>(
|
|
115
|
+
animatedMountingOverrideDelegate_)](
|
|
116
|
+
const ShadowTree& shadowTree, bool& /*stop*/) {
|
|
117
|
+
shadowTree.getMountingCoordinator()->setMountingOverrideDelegate(
|
|
118
|
+
animatedMountingOverrideDelegate);
|
|
119
|
+
});
|
|
131
120
|
|
|
132
|
-
|
|
121
|
+
// Register on surfaces started in the future
|
|
122
|
+
uiManager->setOnSurfaceStartCallback(
|
|
123
|
+
[animatedMountingOverrideDelegate =
|
|
124
|
+
std::weak_ptr<const AnimatedMountingOverrideDelegate>(
|
|
125
|
+
animatedMountingOverrideDelegate_)](
|
|
126
|
+
const ShadowTree& shadowTree) {
|
|
127
|
+
shadowTree.getMountingCoordinator()->setMountingOverrideDelegate(
|
|
128
|
+
animatedMountingOverrideDelegate);
|
|
129
|
+
});
|
|
133
130
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
});
|
|
148
|
-
// Register on surfaces started in the future
|
|
149
|
-
uiManager->setOnSurfaceStartCallback(
|
|
150
|
-
[animatedMountingOverrideDelegate =
|
|
151
|
-
std::weak_ptr<const AnimatedMountingOverrideDelegate>(
|
|
152
|
-
animatedMountingOverrideDelegate_)](
|
|
153
|
-
const ShadowTree& shadowTree) {
|
|
154
|
-
shadowTree.getMountingCoordinator()->setMountingOverrideDelegate(
|
|
155
|
-
animatedMountingOverrideDelegate);
|
|
156
|
-
});
|
|
157
|
-
}
|
|
131
|
+
uiManager->setNativeAnimatedDelegate(nativeAnimatedDelegate_);
|
|
132
|
+
} else {
|
|
133
|
+
// === PATH 2: Shared AnimationBackend (useSharedAnimatedBackend = true) ===
|
|
134
|
+
// Uses the shared AnimationBackend from UIManager. The backend handles all
|
|
135
|
+
// animation commits and platform integration internally.
|
|
136
|
+
|
|
137
|
+
auto animationBackend = uiManager->unstable_getAnimationBackend().lock();
|
|
138
|
+
react_native_assert(
|
|
139
|
+
animationBackend != nullptr && "animationBackend is nullptr");
|
|
140
|
+
animationBackend->registerJSInvoker(jsInvoker);
|
|
141
|
+
|
|
142
|
+
nativeAnimatedNodesManager_ =
|
|
143
|
+
std::make_shared<NativeAnimatedNodesManager>(animationBackend);
|
|
158
144
|
}
|
|
145
|
+
|
|
146
|
+
addEventEmitterListener(
|
|
147
|
+
nativeAnimatedNodesManager_->getEventEmitterListener());
|
|
148
|
+
|
|
149
|
+
uiManager->addEventListener(
|
|
150
|
+
std::make_shared<EventListener>(
|
|
151
|
+
[eventEmitterListenerContainerWeak =
|
|
152
|
+
std::weak_ptr<EventEmitterListenerContainer>(
|
|
153
|
+
eventEmitterListenerContainer_)](const RawEvent& rawEvent) {
|
|
154
|
+
const auto& eventTarget = rawEvent.eventTarget;
|
|
155
|
+
const auto& eventPayload = rawEvent.eventPayload;
|
|
156
|
+
if (eventTarget && eventPayload) {
|
|
157
|
+
if (auto eventEmitterListenerContainer =
|
|
158
|
+
eventEmitterListenerContainerWeak.lock();
|
|
159
|
+
eventEmitterListenerContainer != nullptr) {
|
|
160
|
+
return eventEmitterListenerContainer->willDispatchEvent(
|
|
161
|
+
eventTarget->getTag(), rawEvent.type, *eventPayload);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return false;
|
|
165
|
+
}));
|
|
166
|
+
|
|
159
167
|
return nativeAnimatedNodesManager_;
|
|
160
168
|
}
|
|
161
169
|
|
|
@@ -55,7 +55,9 @@ void AnimatedPropsRegistry::update(
|
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
std::pair<
|
|
58
|
+
std::pair<
|
|
59
|
+
std::unordered_set<std::shared_ptr<const ShadowNodeFamily>>&,
|
|
60
|
+
SnapshotMap&>
|
|
59
61
|
AnimatedPropsRegistry::getMap(SurfaceId surfaceId) {
|
|
60
62
|
auto lock = std::lock_guard(mutex_);
|
|
61
63
|
auto& [pendingMap, map, pendingFamilies, families] =
|
|
@@ -24,11 +24,11 @@ struct PropsSnapshot {
|
|
|
24
24
|
|
|
25
25
|
struct SurfaceContext {
|
|
26
26
|
std::unordered_map<Tag, std::unique_ptr<PropsSnapshot>> pendingMap, map;
|
|
27
|
-
std::unordered_set<const ShadowNodeFamily
|
|
27
|
+
std::unordered_set<std::shared_ptr<const ShadowNodeFamily>> pendingFamilies, families;
|
|
28
28
|
};
|
|
29
29
|
|
|
30
30
|
struct SurfaceUpdates {
|
|
31
|
-
std::unordered_set<const ShadowNodeFamily
|
|
31
|
+
std::unordered_set<std::shared_ptr<const ShadowNodeFamily>> families;
|
|
32
32
|
std::unordered_map<Tag, AnimatedProps> propsMap;
|
|
33
33
|
bool hasLayoutUpdates{false};
|
|
34
34
|
};
|
|
@@ -39,7 +39,7 @@ class AnimatedPropsRegistry {
|
|
|
39
39
|
public:
|
|
40
40
|
void update(const std::unordered_map<SurfaceId, SurfaceUpdates> &surfaceUpdates);
|
|
41
41
|
void clear(SurfaceId surfaceId);
|
|
42
|
-
std::pair<std::unordered_set<const ShadowNodeFamily
|
|
42
|
+
std::pair<std::unordered_set<std::shared_ptr<const ShadowNodeFamily>> &, SnapshotMap &> getMap(SurfaceId surfaceId);
|
|
43
43
|
|
|
44
44
|
private:
|
|
45
45
|
std::unordered_map<SurfaceId, SurfaceContext> surfaceContexts_;
|
|
@@ -71,7 +71,7 @@ void AnimationBackend::onAnimationFrame(AnimationTimestamp timestamp) {
|
|
|
71
71
|
auto& [families, updates, hasLayoutUpdates] =
|
|
72
72
|
surfaceUpdates[family->getSurfaceId()];
|
|
73
73
|
hasLayoutUpdates |= mutation.hasLayoutUpdates;
|
|
74
|
-
families.insert(family
|
|
74
|
+
families.insert(family);
|
|
75
75
|
updates[mutation.tag] = std::move(mutation.props);
|
|
76
76
|
}
|
|
77
77
|
}
|
|
@@ -146,7 +146,8 @@ void AnimationBackend::commitUpdates(
|
|
|
146
146
|
const ShadowNode& shadowNode,
|
|
147
147
|
const ShadowNodeFragment& fragment) {
|
|
148
148
|
auto newProps = ShadowNodeFragment::propsPlaceholder();
|
|
149
|
-
if (surfaceFamilies.contains(
|
|
149
|
+
if (surfaceFamilies.contains(
|
|
150
|
+
shadowNode.getFamilyShared())) {
|
|
150
151
|
auto& animatedProps = updates.at(shadowNode.getTag());
|
|
151
152
|
newProps = cloneProps(animatedProps, shadowNode);
|
|
152
153
|
}
|
|
@@ -43,9 +43,10 @@ RootShadowNode::Unshared AnimationBackendCommitHook::shadowTreeWillCommit(
|
|
|
43
43
|
const ShadowNodeFragment& fragment) {
|
|
44
44
|
auto newProps = ShadowNodeFragment::propsPlaceholder();
|
|
45
45
|
std::shared_ptr<BaseViewProps> viewProps = nullptr;
|
|
46
|
-
if (
|
|
47
|
-
updates.
|
|
48
|
-
|
|
46
|
+
if (auto updatesIter = updates.find(shadowNode.getTag());
|
|
47
|
+
updatesIter != updates.end() &&
|
|
48
|
+
surfaceFamilies.contains(shadowNode.getFamilyShared())) {
|
|
49
|
+
auto& snapshot = updatesIter->second;
|
|
49
50
|
if (!snapshot->propNames.empty() || snapshot->rawProps) {
|
|
50
51
|
PropsParserContext propsParserContext{
|
|
51
52
|
shadowNode.getSurfaceId(),
|
|
@@ -413,17 +413,16 @@ namespace {
|
|
|
413
413
|
|
|
414
414
|
std::shared_ptr<ShadowNode> cloneMultipleRecursive(
|
|
415
415
|
const ShadowNode& shadowNode,
|
|
416
|
-
const std::unordered_map<
|
|
416
|
+
const std::unordered_map<Tag, int>& childrenCount,
|
|
417
417
|
const std::function<std::shared_ptr<
|
|
418
418
|
ShadowNode>(const ShadowNode&, const ShadowNodeFragment&)>& callback) {
|
|
419
|
-
const auto* family = &shadowNode.getFamily();
|
|
420
419
|
auto& children = shadowNode.getChildren();
|
|
421
420
|
std::shared_ptr<std::vector<std::shared_ptr<const ShadowNode>>> newChildren;
|
|
422
|
-
auto count = childrenCount.at(
|
|
421
|
+
auto count = childrenCount.at(shadowNode.getTag());
|
|
423
422
|
|
|
424
423
|
for (size_t i = 0; count > 0 && i < children.size(); i++) {
|
|
425
|
-
const auto
|
|
426
|
-
if (childrenCount.contains(
|
|
424
|
+
const auto childTag = children[i]->getTag();
|
|
425
|
+
if (childrenCount.contains(childTag)) {
|
|
427
426
|
count--;
|
|
428
427
|
if (!newChildren) {
|
|
429
428
|
newChildren =
|
|
@@ -441,37 +440,39 @@ std::shared_ptr<ShadowNode> cloneMultipleRecursive(
|
|
|
441
440
|
} // namespace
|
|
442
441
|
|
|
443
442
|
std::shared_ptr<ShadowNode> ShadowNode::cloneMultiple(
|
|
444
|
-
const std::unordered_set<const ShadowNodeFamily
|
|
443
|
+
const std::unordered_set<std::shared_ptr<const ShadowNodeFamily>>&
|
|
444
|
+
familiesToUpdate,
|
|
445
445
|
const std::function<std::shared_ptr<ShadowNode>(
|
|
446
446
|
const ShadowNode& oldShadowNode,
|
|
447
447
|
const ShadowNodeFragment& fragment)>& callback) const {
|
|
448
|
-
std::unordered_map<
|
|
448
|
+
std::unordered_map<Tag, int> childrenCount;
|
|
449
449
|
|
|
450
450
|
for (const auto& family : familiesToUpdate) {
|
|
451
|
-
if (childrenCount.contains(family)) {
|
|
451
|
+
if (childrenCount.contains(family->getTag())) {
|
|
452
452
|
continue;
|
|
453
453
|
}
|
|
454
454
|
|
|
455
|
-
childrenCount[family] = 0;
|
|
455
|
+
childrenCount[family->getTag()] = 0;
|
|
456
456
|
|
|
457
457
|
auto ancestor = family->parent_.lock();
|
|
458
458
|
while ((ancestor != nullptr) && ancestor != family_) {
|
|
459
|
-
auto
|
|
459
|
+
auto ancestorTag = ancestor->getTag();
|
|
460
|
+
auto ancestorIt = childrenCount.find(ancestorTag);
|
|
460
461
|
if (ancestorIt != childrenCount.end()) {
|
|
461
462
|
ancestorIt->second++;
|
|
462
463
|
break;
|
|
463
464
|
}
|
|
464
|
-
childrenCount[
|
|
465
|
+
childrenCount[ancestorTag] = 1;
|
|
465
466
|
|
|
466
467
|
ancestor = ancestor->parent_.lock();
|
|
467
468
|
}
|
|
468
469
|
|
|
469
470
|
if (ancestor == family_) {
|
|
470
|
-
childrenCount[ancestor
|
|
471
|
+
childrenCount[ancestor->getTag()]++;
|
|
471
472
|
}
|
|
472
473
|
}
|
|
473
474
|
|
|
474
|
-
if (!childrenCount.contains(
|
|
475
|
+
if (!childrenCount.contains(getTag())) {
|
|
475
476
|
return nullptr;
|
|
476
477
|
}
|
|
477
478
|
|
|
@@ -109,7 +109,7 @@ class ShadowNode : public Sealable, public DebugStringConvertible, public jsi::N
|
|
|
109
109
|
* Returns `nullptr` if the operation cannot be performed successfully.
|
|
110
110
|
*/
|
|
111
111
|
std::shared_ptr<ShadowNode> cloneMultiple(
|
|
112
|
-
const std::unordered_set<const ShadowNodeFamily
|
|
112
|
+
const std::unordered_set<std::shared_ptr<const ShadowNodeFamily>> &familiesToUpdate,
|
|
113
113
|
const std::function<
|
|
114
114
|
std::shared_ptr<ShadowNode>(const ShadowNode &oldShadowNode, const ShadowNodeFragment &fragment)> &callback)
|
|
115
115
|
const;
|
|
@@ -316,7 +316,7 @@ TEST_F(ShadowNodeTest, handleRuntimeReferenceTransferOnClone) {
|
|
|
316
316
|
TEST_F(ShadowNodeTest, cloneMultiple) {
|
|
317
317
|
auto newProps = std::make_shared<const TestProps>();
|
|
318
318
|
auto newRoot = nodeA_->cloneMultiple(
|
|
319
|
-
{
|
|
319
|
+
{nodeA_->getFamilyShared(), nodeAB_->getFamilyShared()},
|
|
320
320
|
[&](const ShadowNode& oldShadowNode, const ShadowNodeFragment& fragment) {
|
|
321
321
|
return oldShadowNode.clone({
|
|
322
322
|
.props = newProps,
|
|
@@ -346,7 +346,7 @@ TEST_F(ShadowNodeTest, cloneMultiple) {
|
|
|
346
346
|
TEST_F(ShadowNodeTest, cloneMultipleWithSingleFamily) {
|
|
347
347
|
auto newProps = std::make_shared<const TestProps>();
|
|
348
348
|
auto newRoot = nodeA_->cloneMultiple(
|
|
349
|
-
{
|
|
349
|
+
{nodeAB_->getFamilyShared()},
|
|
350
350
|
[&](const ShadowNode& oldShadowNode, const ShadowNodeFragment& fragment) {
|
|
351
351
|
return oldShadowNode.clone({
|
|
352
352
|
.props = newProps,
|
|
@@ -379,7 +379,7 @@ TEST_F(ShadowNodeTest, cloneMultipleReturnsNullptrWhenFamilyHasNoPathToRoot) {
|
|
|
379
379
|
auto newProps = std::make_shared<const TestProps>();
|
|
380
380
|
// nodeZ_ is not part of nodeA_'s tree
|
|
381
381
|
auto result = nodeA_->cloneMultiple(
|
|
382
|
-
{
|
|
382
|
+
{nodeZ_->getFamilyShared()},
|
|
383
383
|
[&](const ShadowNode& oldShadowNode, const ShadowNodeFragment& fragment) {
|
|
384
384
|
return oldShadowNode.clone({
|
|
385
385
|
.props = newProps,
|
|
@@ -396,7 +396,7 @@ TEST_F(ShadowNodeTest, cloneMultipleWithMixOfValidAndInvalidFamilies) {
|
|
|
396
396
|
auto newProps = std::make_shared<const TestProps>();
|
|
397
397
|
// nodeAB_ is in the tree, nodeZ_ is not
|
|
398
398
|
auto result = nodeA_->cloneMultiple(
|
|
399
|
-
{
|
|
399
|
+
{nodeAB_->getFamilyShared(), nodeZ_->getFamilyShared()},
|
|
400
400
|
[&](const ShadowNode& oldShadowNode, const ShadowNodeFragment& fragment) {
|
|
401
401
|
return oldShadowNode.clone({
|
|
402
402
|
.props = newProps,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native",
|
|
3
|
-
"version": "0.85.0-rc.
|
|
3
|
+
"version": "0.85.0-rc.5",
|
|
4
4
|
"description": "A framework for building native apps using React",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -149,7 +149,7 @@
|
|
|
149
149
|
"featureflags": "node ./scripts/featureflags/index.js"
|
|
150
150
|
},
|
|
151
151
|
"peerDependencies": {
|
|
152
|
-
"@react-native/jest-preset": "0.85.0-rc.
|
|
152
|
+
"@react-native/jest-preset": "0.85.0-rc.5",
|
|
153
153
|
"@types/react": "^19.1.1",
|
|
154
154
|
"react": "^19.2.3"
|
|
155
155
|
},
|
|
@@ -162,13 +162,13 @@
|
|
|
162
162
|
}
|
|
163
163
|
},
|
|
164
164
|
"dependencies": {
|
|
165
|
-
"@react-native/assets-registry": "0.85.0-rc.
|
|
166
|
-
"@react-native/codegen": "0.85.0-rc.
|
|
167
|
-
"@react-native/community-cli-plugin": "0.85.0-rc.
|
|
168
|
-
"@react-native/gradle-plugin": "0.85.0-rc.
|
|
169
|
-
"@react-native/js-polyfills": "0.85.0-rc.
|
|
170
|
-
"@react-native/normalize-colors": "0.85.0-rc.
|
|
171
|
-
"@react-native/virtualized-lists": "0.85.0-rc.
|
|
165
|
+
"@react-native/assets-registry": "0.85.0-rc.5",
|
|
166
|
+
"@react-native/codegen": "0.85.0-rc.5",
|
|
167
|
+
"@react-native/community-cli-plugin": "0.85.0-rc.5",
|
|
168
|
+
"@react-native/gradle-plugin": "0.85.0-rc.5",
|
|
169
|
+
"@react-native/js-polyfills": "0.85.0-rc.5",
|
|
170
|
+
"@react-native/normalize-colors": "0.85.0-rc.5",
|
|
171
|
+
"@react-native/virtualized-lists": "0.85.0-rc.5",
|
|
172
172
|
"abort-controller": "^3.0.0",
|
|
173
173
|
"anser": "^1.4.9",
|
|
174
174
|
"ansi-regex": "^5.0.0",
|