Compare commits

..
1 Commits
Author SHA1 Message Date
David Vacca fe69515571 Migrate ReactLegacyArchitectureProcessor to kotlin (#49571)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/49571

Migrate ReactLegacyArchitectureProcessor to kotlin

changelog: [internal] internal

Reviewed By: cortinico

Differential Revision: D69929877

fbshipit-source-id: 448c8de54cbb1f72eeee747edaf4cbb2a5fd365d
2025-02-21 19:24:12 +00:00
65 changed files with 756 additions and 906 deletions
+1 -5
View File
@@ -68,10 +68,6 @@ module.exports.verifyPublishedTemplate = async (
latest = false,
retries = MAX_RETRIES,
) => {
if (version.startsWith('v')) {
version = version.slice(1);
}
log(`🔍 Is ${TEMPLATE_NPM_PKG}@${version} on npm?`);
let count = retries;
@@ -90,7 +86,7 @@ module.exports.verifyPublishedTemplate = async (
return;
}
log(
`🐌 ${TEMPLATE_NPM_PKG}@latest → ${json.version} on npm and not ${version} as expected, retrying...`,
`🐌 ${TEMPLATE_NPM_PKG}@latest → ${pkg.version} on npm and not ${version} as expected, retrying...`,
);
} catch (e) {
log(`Nope, fetch failed: ${e.message}`);
+5 -5
View File
@@ -49,8 +49,8 @@
"@babel/preset-flow": "^7.24.7",
"@definitelytyped/dtslint": "^0.0.127",
"@jest/create-cache-key-function": "^29.6.3",
"@react-native/metro-babel-transformer": "0.78.2",
"@react-native/metro-config": "0.78.2",
"@react-native/metro-babel-transformer": "0.78.0",
"@react-native/metro-config": "0.78.0",
"@tsconfig/node18": "1.0.1",
"@types/react": "^19.0.0",
"@typescript-eslint/parser": "^7.1.1",
@@ -87,9 +87,9 @@
"jest-junit": "^10.0.0",
"jest-snapshot": "^29.7.0",
"jscodeshift": "^0.14.0",
"metro-babel-register": "^0.81.3",
"metro-memory-fs": "^0.81.3",
"metro-transform-plugins": "^0.81.3",
"metro-babel-register": "^0.81.0",
"metro-memory-fs": "^0.81.0",
"metro-transform-plugins": "^0.81.0",
"micromatch": "^4.0.4",
"node-fetch": "^2.2.0",
"nullthrows": "^1.1.1",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@react-native/assets-registry",
"version": "0.78.2",
"version": "0.78.0",
"description": "Asset support code for React Native.",
"license": "MIT",
"repository": {
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@react-native/babel-plugin-codegen",
"version": "0.78.2",
"version": "0.78.0",
"description": "Babel plugin to generate native module and view manager code for React Native.",
"license": "MIT",
"repository": {
@@ -26,7 +26,7 @@
],
"dependencies": {
"@babel/traverse": "^7.25.3",
"@react-native/codegen": "0.78.2"
"@react-native/codegen": "0.78.0"
},
"devDependencies": {
"@babel/core": "^7.25.2"
+9 -9
View File
@@ -1,6 +1,6 @@
{
"name": "@react-native/community-cli-plugin",
"version": "0.78.2",
"version": "0.78.0",
"description": "Core CLI commands for React Native",
"keywords": [
"react-native",
@@ -22,25 +22,25 @@
"dist"
],
"dependencies": {
"@react-native/dev-middleware": "0.78.2",
"@react-native/metro-babel-transformer": "0.78.2",
"@react-native/dev-middleware": "0.78.0",
"@react-native/metro-babel-transformer": "0.78.0",
"chalk": "^4.0.0",
"debug": "^2.2.0",
"invariant": "^2.2.4",
"metro": "^0.81.3",
"metro-config": "^0.81.3",
"metro-core": "^0.81.3",
"metro": "^0.81.0",
"metro-config": "^0.81.0",
"metro-core": "^0.81.0",
"readline": "^1.3.0",
"semver": "^7.1.3"
},
"devDependencies": {
"metro-resolver": "^0.81.3"
"metro-resolver": "^0.81.0"
},
"peerDependencies": {
"@react-native-community/cli": "*"
"@react-native-community/cli-server-api": "*"
},
"peerDependenciesMeta": {
"@react-native-community/cli": {
"@react-native-community/cli-server-api": {
"optional": true
}
},
@@ -9,8 +9,7 @@
* @oncall react_native
*/
import typeof * as CLIServerAPI from '@react-native-community/cli-server-api';
import type {Server} from 'connect';
import type {NextHandleFunction, Server} from 'connect';
import type {TerminalReportableEvent} from 'metro/src/lib/TerminalReporter';
const debug = require('debug')('ReactNative:CommunityCliPlugin');
@@ -31,6 +30,10 @@ type MiddlewareReturn = {
...
};
const noopNextHandle: NextHandleFunction = (req, res, next) => {
next();
};
// $FlowFixMe
const unusedStubWSServer: ws$WebSocketServer = {};
// $FlowFixMe
@@ -42,12 +45,6 @@ const communityMiddlewareFallback = {
port: number,
watchFolders: $ReadOnlyArray<string>,
}): MiddlewareReturn => ({
// FIXME: Several features will break without community middleware and
// should be migrated into core.
// e.g. used by Libraries/Core/Devtools:
// - /open-stack-frame
// - /open-url
// - /symbolicate
middleware: unusedMiddlewareStub,
websocketEndpoints: {},
messageSocketEndpoint: {
@@ -62,30 +59,17 @@ const communityMiddlewareFallback = {
reportEvent: (event: TerminalReportableEvent) => {},
},
}),
indexPageMiddleware: noopNextHandle,
};
// Attempt to use the community middleware if it exists, but fallback to
// the stubs if it doesn't.
try {
// `@react-native-community/cli` is an optional peer dependency of this
// package, and should be a dev dependency of the host project (via the
// community template's package.json).
const communityCliPath = require.resolve('@react-native-community/cli');
// `@react-native-community/cli-server-api` is a dependency of
// `@react-native-community/cli`, but is not re-exported by it, so we need
// to resolve the former through the latter.
const communityCliServerApiPath = require.resolve(
'@react-native-community/cli-server-api',
{paths: [communityCliPath]},
);
// $FlowIgnore[unsupported-syntax] dynamic import
const communityCliServerApi: CLIServerAPI = require(
communityCliServerApiPath,
);
// $FlowIgnore[unsupported-syntax] dynamic import
const community = require('@react-native-community/cli-server-api');
communityMiddlewareFallback.indexPageMiddleware =
community.indexPageMiddleware;
communityMiddlewareFallback.createDevServerMiddleware =
communityCliServerApi.createDevServerMiddleware;
community.createDevServerMiddleware;
} catch {
debug(`⚠️ Unable to find @react-native-community/cli-server-api
Starting the server without the community middleware.`);
@@ -93,3 +77,5 @@ Starting the server without the community middleware.`);
export const createDevServerMiddleware =
communityMiddlewareFallback.createDevServerMiddleware;
export const indexPageMiddleware =
communityMiddlewareFallback.indexPageMiddleware;
@@ -19,7 +19,7 @@ import isDevServerRunning from '../../utils/isDevServerRunning';
import loadMetroConfig from '../../utils/loadMetroConfig';
import * as version from '../../utils/version';
import attachKeyHandlers from './attachKeyHandlers';
import {createDevServerMiddleware} from './middleware';
import {createDevServerMiddleware, indexPageMiddleware} from './middleware';
import {createDevMiddleware} from '@react-native/dev-middleware';
import chalk from 'chalk';
import Metro from 'metro';
@@ -152,7 +152,11 @@ async function runServer(
secure: args.https,
secureCert: args.cert,
secureKey: args.key,
unstable_extraMiddleware: [communityMiddleware, middleware],
unstable_extraMiddleware: [
communityMiddleware,
indexPageMiddleware,
middleware,
],
websocketEndpoints: {
...communityWebsocketEndpoints,
...websocketEndpoints,
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@react-native/core-cli-utils",
"version": "0.78.2",
"version": "0.78.0",
"description": "React Native CLI library for Frameworks to build on",
"license": "MIT",
"main": "./src/index.flow.js",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@react-native/debugger-frontend",
"version": "0.78.2",
"version": "0.78.0",
"description": "Debugger frontend for React Native based on Chrome DevTools",
"keywords": [
"react-native",
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@react-native/dev-middleware",
"version": "0.78.2",
"version": "0.78.0",
"description": "Dev server middleware for React Native",
"keywords": [
"react-native",
@@ -23,7 +23,7 @@
],
"dependencies": {
"@isaacs/ttlcache": "^1.4.1",
"@react-native/debugger-frontend": "0.78.2",
"@react-native/debugger-frontend": "0.78.0",
"chrome-launcher": "^0.15.2",
"chromium-edge-launcher": "^0.2.0",
"connect": "^3.6.5",
@@ -39,7 +39,7 @@ const WS_DEBUGGER_URL = '/inspector/debug';
const PAGES_LIST_JSON_URL = '/json';
const PAGES_LIST_JSON_URL_2 = '/json/list';
const PAGES_LIST_JSON_VERSION_URL = '/json/version';
const MAX_PONG_LATENCY_MS = 60000;
const MAX_PONG_LATENCY_MS = 5000;
const DEBUGGER_HEARTBEAT_INTERVAL_MS = 10000;
const INTERNAL_ERROR_CODE = 1011;
@@ -1,6 +1,6 @@
{
"name": "@react-native/eslint-config",
"version": "0.78.2",
"version": "0.78.0",
"description": "ESLint config for React Native",
"license": "MIT",
"repository": {
@@ -22,7 +22,7 @@
"dependencies": {
"@babel/core": "^7.25.2",
"@babel/eslint-parser": "^7.25.1",
"@react-native/eslint-plugin": "0.78.2",
"@react-native/eslint-plugin": "0.78.0",
"@typescript-eslint/eslint-plugin": "^7.1.1",
"@typescript-eslint/parser": "^7.1.1",
"eslint-config-prettier": "^8.5.0",
@@ -1,6 +1,6 @@
{
"name": "@react-native/eslint-plugin",
"version": "0.78.2",
"version": "0.78.0",
"description": "ESLint rules for @react-native/eslint-config",
"license": "MIT",
"repository": {
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@react-native/eslint-plugin-specs",
"version": "0.78.2",
"version": "0.78.0",
"description": "ESLint rules to validate NativeModule and Component Specs",
"license": "MIT",
"repository": {
@@ -26,7 +26,7 @@
"dependencies": {
"@babel/core": "^7.25.2",
"@babel/plugin-transform-flow-strip-types": "^7.25.2",
"@react-native/codegen": "0.78.2",
"@react-native/codegen": "0.78.0",
"make-dir": "^2.1.0",
"pirates": "^4.0.1",
"source-map-support": "0.5.0"
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@react-native/gradle-plugin",
"version": "0.78.2",
"version": "0.78.0",
"description": "Gradle Plugin for React Native",
"license": "MIT",
"repository": {
+6 -6
View File
@@ -1,6 +1,6 @@
{
"name": "helloworld",
"version": "0.78.2",
"version": "0.78.0",
"private": true,
"scripts": {
"bootstrap": "node ./cli.js bootstrap",
@@ -13,16 +13,16 @@
},
"dependencies": {
"react": "19.0.0",
"react-native": "0.78.2"
"react-native": "0.78.0"
},
"devDependencies": {
"@babel/core": "^7.25.2",
"@babel/preset-env": "^7.25.3",
"@babel/runtime": "^7.25.0",
"@react-native/babel-preset": "0.78.2",
"@react-native/core-cli-utils": "0.78.2",
"@react-native/eslint-config": "0.78.2",
"@react-native/metro-config": "0.78.2",
"@react-native/babel-preset": "0.78.0",
"@react-native/core-cli-utils": "0.78.0",
"@react-native/eslint-config": "0.78.0",
"@react-native/metro-config": "0.78.0",
"chalk": "^4.1.2",
"commander": "^12.0.0",
"eslint": "^8.19.0",
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@react-native/metro-config",
"version": "0.78.2",
"version": "0.78.0",
"description": "Metro configuration for React Native.",
"license": "MIT",
"repository": {
@@ -26,9 +26,9 @@
"dist"
],
"dependencies": {
"@react-native/js-polyfills": "0.78.2",
"@react-native/metro-babel-transformer": "0.78.2",
"metro-config": "^0.81.3",
"metro-runtime": "^0.81.3"
"@react-native/js-polyfills": "0.78.0",
"@react-native/metro-babel-transformer": "0.78.0",
"metro-config": "^0.81.0",
"metro-runtime": "^0.81.0"
}
}
+1 -1
View File
@@ -54,7 +54,7 @@ export function getDefaultConfig(projectRoot: string): ConfigT {
resolver: {
resolverMainFields: ['react-native', 'browser', 'main'],
platforms: ['android', 'ios'],
unstable_conditionNames: ['react-native'],
unstable_conditionNames: ['require', 'import', 'react-native'],
},
serializer: {
// Note: This option is overridden in cli-plugin-metro (getOverrideConfig)
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@react-native/normalize-colors",
"version": "0.78.2",
"version": "0.78.0",
"description": "Color normalization for React Native.",
"license": "MIT",
"repository": {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@react-native/js-polyfills",
"version": "0.78.2",
"version": "0.78.0",
"description": "Polyfills for React Native.",
"license": "MIT",
"repository": {
@@ -1,6 +1,6 @@
{
"name": "@react-native/babel-preset",
"version": "0.78.2",
"version": "0.78.0",
"description": "Babel preset for React Native applications",
"main": "src/index.js",
"repository": {
@@ -55,7 +55,7 @@
"@babel/plugin-transform-typescript": "^7.25.2",
"@babel/plugin-transform-unicode-regex": "^7.24.7",
"@babel/template": "^7.25.0",
"@react-native/babel-plugin-codegen": "0.78.2",
"@react-native/babel-plugin-codegen": "0.78.0",
"babel-plugin-syntax-hermes-parser": "0.25.1",
"babel-plugin-transform-flow-enums": "^0.0.2",
"react-refresh": "^0.14.0"
@@ -1,6 +1,6 @@
{
"name": "@react-native/metro-babel-transformer",
"version": "0.78.2",
"version": "0.78.0",
"description": "Babel transformer for React Native applications.",
"main": "src/index.js",
"repository": {
@@ -16,7 +16,7 @@
"license": "MIT",
"dependencies": {
"@babel/core": "^7.25.2",
"@react-native/babel-preset": "0.78.2",
"@react-native/babel-preset": "0.78.0",
"hermes-parser": "0.25.1",
"nullthrows": "^1.1.1"
},
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@react-native/bots",
"description": "React Native Bots",
"version": "0.78.2",
"version": "0.78.0",
"private": true,
"license": "MIT",
"repository": {
@@ -1,6 +1,6 @@
{
"name": "@react-native/codegen-typescript-test",
"version": "0.78.2",
"version": "0.78.0",
"private": true,
"description": "TypeScript related unit test for @react-native/codegen",
"license": "MIT",
@@ -19,7 +19,7 @@
"prepare": "yarn run build"
},
"dependencies": {
"@react-native/codegen": "0.78.2"
"@react-native/codegen": "0.78.0"
},
"devDependencies": {
"@babel/core": "^7.25.2",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@react-native/codegen",
"version": "0.78.2",
"version": "0.78.0",
"description": "Code generation tools for React Native",
"license": "MIT",
"repository": {
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@react-native/fantom",
"private": true,
"version": "0.78.2",
"version": "0.78.0",
"main": "src/index.js",
"description": "Internal integration testing and benchmarking tool for React Native",
"peerDependencies": {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "react-native-info",
"version": "0.78.2",
"version": "0.78.0",
"main": "build/index.js",
"license": "MIT",
"private": true,
@@ -1,6 +1,6 @@
{
"name": "@react-native/popup-menu-android",
"version": "0.78.2",
"version": "0.78.0",
"description": "PopupMenu for the Android platform",
"main": "index.js",
"files": [
@@ -17,7 +17,7 @@
],
"license": "MIT",
"devDependencies": {
"@react-native/codegen": "0.78.2"
"@react-native/codegen": "0.78.0"
},
"peerDependencies": {
"@types/react": "^19.0.0",
@@ -1,6 +1,6 @@
{
"name": "@react-native/oss-library-example",
"version": "0.78.2",
"version": "0.78.0",
"private": true,
"description": "Package that includes native module exapmle, native component example, targets both the old and the new architecture. It should serve as an example of a real-world OSS library.",
"license": "MIT",
@@ -26,8 +26,8 @@
],
"devDependencies": {
"@babel/core": "^7.25.2",
"@react-native/babel-preset": "0.78.2",
"react-native": "0.78.2"
"@react-native/babel-preset": "0.78.0",
"react-native": "0.78.0"
},
"peerDependencies": {
"react": "*",
@@ -118,11 +118,4 @@
return nullptr;
}
- (void)loadSourceForBridge:(RCTBridge *)bridge
onProgress:(RCTSourceLoadProgressBlock)onProgress
onComplete:(RCTSourceLoadBlock)loadCallback
{
[RCTJavaScriptLoader loadBundleAtURL:[self sourceURLForBridge:bridge] onProgress:onProgress onComplete:loadCallback];
}
@end
@@ -156,15 +156,6 @@ using namespace facebook::react;
return RCTAppSetupDefaultModuleFromClass(moduleClass, self.delegate.dependencyProvider);
}
- (NSArray<id<RCTBridgeModule>> *)extraModulesForBridge:(RCTBridge *)bridge
{
if ([_delegate respondsToSelector:@selector(extraModulesForBridge:)]) {
return [_delegate extraModulesForBridge:bridge];
}
return @[];
}
#pragma mark - RCTComponentViewFactoryComponentProvider
- (NSDictionary<NSString *, Class<RCTComponentViewProtocol>> *)thirdPartyFabricComponents
@@ -237,21 +228,6 @@ using namespace facebook::react;
};
}
if ([self.delegate respondsToSelector:@selector(loadSourceForBridge:onProgress:onComplete:)]) {
configuration.loadSourceForBridgeWithProgress =
^(RCTBridge *_Nonnull bridge,
RCTSourceLoadProgressBlock _Nonnull onProgress,
RCTSourceLoadBlock _Nonnull loadCallback) {
[weakSelf.delegate loadSourceForBridge:bridge onProgress:onProgress onComplete:loadCallback];
};
}
if ([self.delegate respondsToSelector:@selector(loadSourceForBridge:withBlock:)]) {
configuration.loadSourceForBridge = ^(RCTBridge *_Nonnull bridge, RCTSourceLoadBlock _Nonnull loadCallback) {
[weakSelf.delegate loadSourceForBridge:bridge withBlock:loadCallback];
};
}
return [[RCTRootViewFactory alloc] initWithTurboModuleDelegate:self hostDelegate:self configuration:configuration];
}
@@ -31,11 +31,6 @@ typedef NSURL *_Nullable (^RCTBundleURLBlock)(void);
typedef NSArray<id<RCTBridgeModule>> *_Nonnull (^RCTExtraModulesForBridgeBlock)(RCTBridge *bridge);
typedef NSDictionary<NSString *, Class> *_Nonnull (^RCTExtraLazyModuleClassesForBridge)(RCTBridge *bridge);
typedef BOOL (^RCTBridgeDidNotFindModuleBlock)(RCTBridge *bridge, NSString *moduleName);
typedef void (^RCTLoadSourceForBridgeWithProgressBlock)(
RCTBridge *bridge,
RCTSourceLoadProgressBlock onProgress,
RCTSourceLoadBlock loadCallback);
typedef void (^RCTLoadSourceForBridgeBlock)(RCTBridge *bridge, RCTSourceLoadBlock loadCallback);
#pragma mark - RCTRootViewFactory Configuration
@interface RCTRootViewFactoryConfiguration : NSObject
@@ -150,19 +145,6 @@ typedef void (^RCTLoadSourceForBridgeBlock)(RCTBridge *bridge, RCTSourceLoadBloc
*/
@property (nonatomic, nullable) RCTBridgeDidNotFindModuleBlock bridgeDidNotFindModule;
/**
* The bridge will automatically attempt to load the JS source code from the
* location specified by the `sourceURLForBridge:` method, however, if you want
* to handle loading the JS yourself, you can do so by setting this property.
*/
@property (nonatomic, nullable) RCTLoadSourceForBridgeWithProgressBlock loadSourceForBridgeWithProgress;
/**
* Similar to loadSourceForBridgeWithProgress but without progress
* reporting.
*/
@property (nonatomic, nullable) RCTLoadSourceForBridgeBlock loadSourceForBridge;
@end
#pragma mark - RCTRootViewFactory
@@ -302,22 +302,6 @@
return NO;
}
- (void)loadSourceForBridge:(RCTBridge *)bridge withBlock:(RCTSourceLoadBlock)loadCallback
{
if (_configuration.loadSourceForBridge != nil) {
_configuration.loadSourceForBridge(bridge, loadCallback);
}
}
- (void)loadSourceForBridge:(RCTBridge *)bridge
onProgress:(RCTSourceLoadProgressBlock)onProgress
onComplete:(RCTSourceLoadBlock)loadCallback
{
if (_configuration.loadSourceForBridgeWithProgress != nil) {
_configuration.loadSourceForBridgeWithProgress(bridge, onProgress, loadCallback);
}
}
- (NSURL *)bundleURL
{
return self->_configuration.bundleURLBlock();
@@ -1019,7 +1019,7 @@ function useTextInputStateSynchronization_STATE({
mostRecentEventCount: number,
selection: ?Selection,
inputRef: React.RefObject<null | HostInstance>,
text?: string,
text: string,
viewCommands: ViewCommands,
}): {
setLastNativeText: string => void,
@@ -1100,7 +1100,7 @@ function useTextInputStateSynchronization_REFS({
mostRecentEventCount: number,
selection: ?Selection,
inputRef: React.RefObject<null | HostInstance>,
text?: string,
text: string,
viewCommands: ViewCommands,
}): {
setLastNativeText: string => void,
@@ -1314,7 +1314,7 @@ function InternalTextInput(props: Props): React.Node {
? props.value
: typeof props.defaultValue === 'string'
? props.defaultValue
: undefined;
: '';
const viewCommands =
AndroidTextInputCommands ||
@@ -7,7 +7,7 @@
* @format
*/
const {create, update} = require('../../../../jest/renderer');
const {create} = require('../../../../jest/renderer');
const ReactNativeFeatureFlags = require('../../../../src/private/featureflags/ReactNativeFeatureFlags');
const ReactNative = require('../../../ReactNative/RendererProxy');
const {
@@ -20,14 +20,8 @@ const ReactTestRenderer = require('react-test-renderer');
jest.unmock('../TextInput');
[
{useRefsForTextInputState: true, useTextChildren: true},
{useRefsForTextInputState: false, useTextChildren: true},
{useRefsForTextInputState: true, useTextChildren: false},
{useRefsForTextInputState: false, useTextChildren: false},
].forEach(testCase => {
const {useRefsForTextInputState, useTextChildren} = testCase;
describe(`TextInput tests (useRefsForTextInputState = ${useRefsForTextInputState}) useTextChildren = ${useTextChildren}`, () => {
[true, false].forEach(useRefsForTextInputState => {
describe(`TextInput tests (useRefsForTextInputState = ${useRefsForTextInputState}`, () => {
let input;
let inputRef;
let onChangeListener;
@@ -49,16 +43,15 @@ jest.unmock('../TextInput');
return (
<TextInput
ref={inputRef}
value={useTextChildren ? undefined : state.text}
value={state.text}
onChangeText={text => {
onChangeTextListener(text);
setState({text});
}}
onChange={event => {
onChangeListener(event);
}}>
{useTextChildren ? state.text : undefined}
</TextInput>
}}
/>
);
}
const renderTree = await create(<TextInputWrapper />);
@@ -82,20 +75,12 @@ jest.unmock('../TextInput');
);
});
it('calls onChange callbacks', () => {
if (!useTextChildren) {
expect(input.props.value).toBe(initialValue);
} else {
expect(input.props.children).toBe(initialValue);
}
expect(input.props.value).toBe(initialValue);
const message = 'This is a test message';
ReactTestRenderer.act(() => {
enter(input, message);
});
if (!useTextChildren) {
expect(input.props.value).toBe(message);
} else {
expect(input.props.children).toBe(message);
}
expect(input.props.value).toBe(message);
expect(onChangeTextListener).toHaveBeenCalledWith(message);
expect(onChangeListener).toHaveBeenCalledWith({
nativeEvent: {text: message},
@@ -105,12 +90,7 @@ jest.unmock('../TextInput');
async function createTextInput(extraProps) {
const textInputRef = React.createRef(null);
await create(
<TextInput
ref={textInputRef}
value={useTextChildren ? undefined : 'value1'}
{...extraProps}>
{useTextChildren ? 'value1' : undefined}
</TextInput>,
<TextInput ref={textInputRef} value="value1" {...extraProps} />,
);
return textInputRef;
}
@@ -154,55 +134,14 @@ jest.unmock('../TextInput');
expect(TextInput.State.currentlyFocusedInput()).toBe(null);
});
it('change selection keeps content', async () => {
const defaultValue = 'value1';
// create content
let renderTree = await create(
<TextInput
value={useTextChildren ? undefined : defaultValue}
position={{start: 1, end: 1}}>
{useTextChildren ? defaultValue : undefined}
</TextInput>,
);
input = renderTree.root.findByType(TextInput);
expect(
useTextChildren ? input.children[0].props.children : input.props.value,
).toBe(defaultValue);
expect(input.props.position.start).toBe(1);
expect(input.props.position.end).toBe(1);
// update position
renderTree = await update(
renderTree,
<TextInput
value={useTextChildren ? undefined : defaultValue}
position={{start: 2, end: 2}}>
{useTextChildren ? defaultValue : undefined}
</TextInput>,
);
expect(
useTextChildren ? input.children[0].props.children : input.props.value,
).toBe(defaultValue);
expect(input.props.position.start).toBe(2);
expect(input.props.position.end).toBe(2);
});
it('should unfocus when other TextInput is focused', async () => {
const textInputRe1 = React.createRef(null);
const textInputRe2 = React.createRef(null);
await create(
<>
<TextInput
ref={textInputRe1}
value={useTextChildren ? undefined : 'value1'}>
{useTextChildren ? 'value1' : undefined}
</TextInput>
<TextInput
ref={textInputRe2}
value={useTextChildren ? undefined : 'value2'}>
{useTextChildren ? 'value2' : undefined}
</TextInput>
<TextInput ref={textInputRe1} value="value1" />
<TextInput ref={textInputRe2} value="value2" />
</>,
);
ReactNative.findNodeHandle = jest.fn().mockImplementation(ref => {
@@ -271,6 +210,7 @@ jest.unmock('../TextInput');
rejectResponderTermination={true}
selection={null}
submitBehavior="blurAndSubmit"
text=""
textContentType="emailAddress"
underlineColorAndroid="transparent"
/>
@@ -315,6 +255,7 @@ jest.unmock('../TextInput');
rejectResponderTermination={true}
selection={null}
submitBehavior="blurAndSubmit"
text=""
underlineColorAndroid="transparent"
/>
`);
@@ -360,6 +301,7 @@ jest.unmock('../TextInput');
selection={null}
submitBehavior="blurAndSubmit"
testID="testID"
text=""
underlineColorAndroid="transparent"
/>
`);
@@ -490,6 +432,7 @@ jest.unmock('../TextInput');
role="main"
selection={null}
submitBehavior="blurAndSubmit"
text=""
underlineColorAndroid="transparent"
/>
`);
@@ -546,6 +489,7 @@ jest.unmock('../TextInput');
]
}
submitBehavior="blurAndSubmit"
text=""
underlineColorAndroid="transparent"
/>
`);
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`TextInput tests (useRefsForTextInputState = false) useTextChildren = false should render as expected: should deep render when mocked (please verify output manually) 1`] = `
exports[`TextInput tests (useRefsForTextInputState = false should render as expected: should deep render when mocked (please verify output manually) 1`] = `
<RCTSinglelineTextInputView
accessible={true}
allowFontScaling={true}
@@ -23,11 +23,12 @@ exports[`TextInput tests (useRefsForTextInputState = false) useTextChildren = fa
rejectResponderTermination={true}
selection={null}
submitBehavior="blurAndSubmit"
text=""
underlineColorAndroid="transparent"
/>
`;
exports[`TextInput tests (useRefsForTextInputState = false) useTextChildren = false should render as expected: should deep render when not mocked (please verify output manually) 1`] = `
exports[`TextInput tests (useRefsForTextInputState = false should render as expected: should deep render when not mocked (please verify output manually) 1`] = `
<RCTSinglelineTextInputView
accessible={true}
allowFontScaling={true}
@@ -50,11 +51,12 @@ exports[`TextInput tests (useRefsForTextInputState = false) useTextChildren = fa
rejectResponderTermination={true}
selection={null}
submitBehavior="blurAndSubmit"
text=""
underlineColorAndroid="transparent"
/>
`;
exports[`TextInput tests (useRefsForTextInputState = false) useTextChildren = true should render as expected: should deep render when mocked (please verify output manually) 1`] = `
exports[`TextInput tests (useRefsForTextInputState = true should render as expected: should deep render when mocked (please verify output manually) 1`] = `
<RCTSinglelineTextInputView
accessible={true}
allowFontScaling={true}
@@ -77,119 +79,12 @@ exports[`TextInput tests (useRefsForTextInputState = false) useTextChildren = tr
rejectResponderTermination={true}
selection={null}
submitBehavior="blurAndSubmit"
text=""
underlineColorAndroid="transparent"
/>
`;
exports[`TextInput tests (useRefsForTextInputState = false) useTextChildren = true should render as expected: should deep render when not mocked (please verify output manually) 1`] = `
<RCTSinglelineTextInputView
accessible={true}
allowFontScaling={true}
focusable={true}
forwardedRef={null}
mostRecentEventCount={0}
onBlur={[Function]}
onChange={[Function]}
onClick={[Function]}
onFocus={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onScroll={[Function]}
onSelectionChange={[Function]}
onSelectionChangeShouldSetResponder={[Function]}
onStartShouldSetResponder={[Function]}
rejectResponderTermination={true}
selection={null}
submitBehavior="blurAndSubmit"
underlineColorAndroid="transparent"
/>
`;
exports[`TextInput tests (useRefsForTextInputState = true) useTextChildren = false should render as expected: should deep render when mocked (please verify output manually) 1`] = `
<RCTSinglelineTextInputView
accessible={true}
allowFontScaling={true}
focusable={true}
forwardedRef={null}
mostRecentEventCount={0}
onBlur={[Function]}
onChange={[Function]}
onClick={[Function]}
onFocus={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onScroll={[Function]}
onSelectionChange={[Function]}
onSelectionChangeShouldSetResponder={[Function]}
onStartShouldSetResponder={[Function]}
rejectResponderTermination={true}
selection={null}
submitBehavior="blurAndSubmit"
underlineColorAndroid="transparent"
/>
`;
exports[`TextInput tests (useRefsForTextInputState = true) useTextChildren = false should render as expected: should deep render when not mocked (please verify output manually) 1`] = `
<RCTSinglelineTextInputView
accessible={true}
allowFontScaling={true}
focusable={true}
forwardedRef={null}
mostRecentEventCount={0}
onBlur={[Function]}
onChange={[Function]}
onClick={[Function]}
onFocus={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onScroll={[Function]}
onSelectionChange={[Function]}
onSelectionChangeShouldSetResponder={[Function]}
onStartShouldSetResponder={[Function]}
rejectResponderTermination={true}
selection={null}
submitBehavior="blurAndSubmit"
underlineColorAndroid="transparent"
/>
`;
exports[`TextInput tests (useRefsForTextInputState = true) useTextChildren = true should render as expected: should deep render when mocked (please verify output manually) 1`] = `
<RCTSinglelineTextInputView
accessible={true}
allowFontScaling={true}
focusable={true}
forwardedRef={null}
mostRecentEventCount={0}
onBlur={[Function]}
onChange={[Function]}
onClick={[Function]}
onFocus={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onScroll={[Function]}
onSelectionChange={[Function]}
onSelectionChangeShouldSetResponder={[Function]}
onStartShouldSetResponder={[Function]}
rejectResponderTermination={true}
selection={null}
submitBehavior="blurAndSubmit"
underlineColorAndroid="transparent"
/>
`;
exports[`TextInput tests (useRefsForTextInputState = true) useTextChildren = true should render as expected: should deep render when not mocked (please verify output manually) 1`] = `
exports[`TextInput tests (useRefsForTextInputState = true should render as expected: should deep render when not mocked (please verify output manually) 1`] = `
<RCTSinglelineTextInputView
accessible={true}
allowFontScaling={true}
@@ -212,6 +107,7 @@ exports[`TextInput tests (useRefsForTextInputState = true) useTextChildren = tru
rejectResponderTermination={true}
selection={null}
submitBehavior="blurAndSubmit"
text=""
underlineColorAndroid="transparent"
/>
`;
+1 -1
View File
@@ -16,7 +16,7 @@ const version: $ReadOnly<{
}> = {
major: 0,
minor: 78,
patch: 2,
patch: 0,
prerelease: null,
};
@@ -133,7 +133,6 @@ let BaseImage: AbstractImageAndroid = React.forwardRef(
width: undefined,
height: undefined,
};
const defaultSource = resolveAssetSource(props.defaultSource);
const loadingIndicatorSource = resolveAssetSource(
props.loadingIndicatorSource,
);
@@ -179,7 +178,6 @@ let BaseImage: AbstractImageAndroid = React.forwardRef(
/* $FlowFixMe(>=0.78.0 site=react_native_android_fb) This issue was found
* when making Flow check .android.js files. */
headers: (source?.[0]?.headers || source?.headers: ?{[string]: string}),
defaultSource: defaultSource ? defaultSource.uri : null,
loadingIndicatorSrc: loadingIndicatorSource
? loadingIndicatorSource.uri
: null,
@@ -21,7 +21,6 @@ import type {
} from '../StyleSheet/StyleSheet';
import type {ResolvedAssetSource} from './AssetSourceResolver';
import type {ImageProps} from './ImageProps';
import type {ImageSource} from './ImageSource';
import * as NativeComponentRegistry from '../NativeComponent/NativeComponentRegistry';
import {ConditionallyIgnoredEventHandlers} from '../NativeComponent/ViewConfigIgnore';
@@ -43,7 +42,7 @@ type Props = $ReadOnly<{
| ?ResolvedAssetSource
| ?$ReadOnlyArray<?$ReadOnly<{uri?: ?string, ...}>>,
headers?: ?{[string]: string},
defaultSource?: ?ImageSource | ?string,
defaultSrc?: ?string,
loadingIndicatorSrc?: ?string,
}>;
@@ -83,7 +82,9 @@ export const __INTERNAL_VIEW_CONFIG: PartialViewConfig =
},
validAttributes: {
blurRadius: true,
defaultSource: true,
defaultSource: {
process: require('./resolveAssetSource'),
},
internal_analyticTag: true,
resizeMethod: true,
resizeMode: true,
@@ -8,8 +8,6 @@
#import <React/RCTDataRequestHandler.h>
#import <ReactCommon/RCTTurboModule.h>
#import <mutex>
#import "RCTNetworkPlugins.h"
@interface RCTDataRequestHandler () <RCTTurboModule>
@@ -17,22 +15,14 @@
@implementation RCTDataRequestHandler {
NSOperationQueue *_queue;
std::mutex _operationHandlerMutexLock;
}
RCT_EXPORT_MODULE()
- (void)invalidate
{
std::lock_guard<std::mutex> lock(_operationHandlerMutexLock);
if (_queue) {
for (NSOperation *operation in _queue.operations) {
if (!operation.isCancelled && !operation.isFinished) {
[operation cancel];
}
}
_queue = nil;
}
[_queue cancelAllOperations];
_queue = nil;
}
- (BOOL)canHandleRequest:(NSURLRequest *)request
@@ -42,7 +32,6 @@ RCT_EXPORT_MODULE()
- (NSOperation *)sendRequest:(NSURLRequest *)request withDelegate:(id<RCTURLRequestDelegate>)delegate
{
std::lock_guard<std::mutex> lock(_operationHandlerMutexLock);
// Lazy setup
if (!_queue) {
_queue = [NSOperationQueue new];
@@ -80,10 +69,7 @@ RCT_EXPORT_MODULE()
- (void)cancelRequest:(NSOperation *)op
{
std::lock_guard<std::mutex> lock(_operationHandlerMutexLock);
if (!op.isCancelled && !op.isFinished) {
[op cancel];
}
[op cancel];
}
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
@@ -7,8 +7,6 @@
#import <React/RCTFileRequestHandler.h>
#import <mutex>
#import <MobileCoreServices/MobileCoreServices.h>
#import <React/RCTUtils.h>
@@ -21,22 +19,14 @@
@implementation RCTFileRequestHandler {
NSOperationQueue *_fileQueue;
std::mutex _operationHandlerMutexLock;
}
RCT_EXPORT_MODULE()
- (void)invalidate
{
std::lock_guard<std::mutex> lock(_operationHandlerMutexLock);
if (_fileQueue) {
for (NSOperation *operation in _fileQueue.operations) {
if (!operation.isCancelled && !operation.isFinished) {
[operation cancel];
}
}
_fileQueue = nil;
}
[_fileQueue cancelAllOperations];
_fileQueue = nil;
}
- (BOOL)canHandleRequest:(NSURLRequest *)request
@@ -46,7 +36,6 @@ RCT_EXPORT_MODULE()
- (NSOperation *)sendRequest:(NSURLRequest *)request withDelegate:(id<RCTURLRequestDelegate>)delegate
{
std::lock_guard<std::mutex> lock(_operationHandlerMutexLock);
// Lazy setup
if (!_fileQueue) {
_fileQueue = [NSOperationQueue new];
@@ -94,10 +83,7 @@ RCT_EXPORT_MODULE()
- (void)cancelRequest:(NSOperation *)op
{
std::lock_guard<std::mutex> lock(_operationHandlerMutexLock);
if (!op.isCancelled && !op.isFinished) {
[op cancel];
}
[op cancel];
}
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
@@ -5065,7 +5065,7 @@ exports[`public API should not change unintentionally Libraries/Image/ImageViewN
| ?ResolvedAssetSource
| ?$ReadOnlyArray<?$ReadOnly<{ uri?: ?string, ... }>>,
headers?: ?{ [string]: string },
defaultSource?: ?ImageSource | ?string,
defaultSrc?: ?string,
loadingIndicatorSrc?: ?string,
}>;
interface NativeCommands {
@@ -23,7 +23,7 @@ NSDictionary* RCTGetReactNativeVersion(void)
__rnVersion = @{
RCTVersionMajor: @(0),
RCTVersionMinor: @(78),
RCTVersionPatch: @(2),
RCTVersionPatch: @(0),
RCTVersionPrerelease: [NSNull null],
};
});
@@ -101,7 +101,11 @@ static NSSet<NSNumber *> *returnKeyTypesSet;
NSMutableDictionary<NSAttributedStringKey, id> *defaultAttributes =
[_backedTextInputView.defaultTextAttributes mutableCopy];
defaultAttributes[RCTAttributedStringEventEmitterKey] = RCTWrapEventEmitter(_eventEmitter);
#if !TARGET_OS_MACCATALYST
RCTWeakEventEmitterWrapper *eventEmitterWrapper = [RCTWeakEventEmitterWrapper new];
eventEmitterWrapper.eventEmitter = _eventEmitter;
defaultAttributes[RCTAttributedStringEventEmitterKey] = eventEmitterWrapper;
#endif
_backedTextInputView.defaultTextAttributes = defaultAttributes;
}
@@ -262,8 +266,10 @@ static NSSet<NSNumber *> *returnKeyTypesSet;
if (newTextInputProps.textAttributes != oldTextInputProps.textAttributes) {
NSMutableDictionary<NSAttributedStringKey, id> *defaultAttributes =
RCTNSTextAttributesFromTextAttributes(newTextInputProps.getEffectiveTextAttributes(RCTFontSizeMultiplier()));
#if !TARGET_OS_MACCATALYST
defaultAttributes[RCTAttributedStringEventEmitterKey] =
_backedTextInputView.defaultTextAttributes[RCTAttributedStringEventEmitterKey];
#endif
_backedTextInputView.defaultTextAttributes = defaultAttributes;
}
@@ -1,4 +1,4 @@
VERSION_NAME=0.78.2
VERSION_NAME=0.78.0
react.internal.publishingGroup=com.facebook.react
android.useAndroidX=true
@@ -173,7 +173,7 @@ public class FabricUIManager
private final CopyOnWriteArrayList<UIManagerListener> mListeners = new CopyOnWriteArrayList<>();
private boolean mMountNotificationScheduled = false;
private List<Integer> mSurfaceIdsWithPendingMountNotification = new ArrayList<>();
private final List<Integer> mMountedSurfaceIds = new ArrayList<>();
@ThreadConfined(UI)
@NonNull
@@ -1250,15 +1250,12 @@ public class FabricUIManager
// Collect surface IDs for all the mount items
for (MountItem mountItem : mountItems) {
if (mountItem != null
&& !mSurfaceIdsWithPendingMountNotification.contains(mountItem.getSurfaceId())) {
mSurfaceIdsWithPendingMountNotification.add(mountItem.getSurfaceId());
if (mountItem != null && !mMountedSurfaceIds.contains(mountItem.getSurfaceId())) {
mMountedSurfaceIds.add(mountItem.getSurfaceId());
}
}
if (!mMountNotificationScheduled && !mSurfaceIdsWithPendingMountNotification.isEmpty()) {
mMountNotificationScheduled = true;
if (!mMountNotificationScheduled && !mMountedSurfaceIds.isEmpty()) {
// Notify mount when the effects are visible and prevent mount hooks to
// delay paint.
UiThreadUtil.getUiThreadHandler()
@@ -1268,19 +1265,17 @@ public class FabricUIManager
public void run() {
mMountNotificationScheduled = false;
// Create a copy in case mount hooks trigger more mutations
final List<Integer> surfaceIdsToReportMount =
mSurfaceIdsWithPendingMountNotification;
mSurfaceIdsWithPendingMountNotification = new ArrayList<>();
final @Nullable FabricUIManagerBinding binding = mBinding;
if (binding == null || mDestroyed) {
mMountedSurfaceIds.clear();
return;
}
for (int surfaceId : surfaceIdsToReportMount) {
for (int surfaceId : mMountedSurfaceIds) {
binding.reportMount(surfaceId);
}
mMountedSurfaceIds.clear();
}
});
}
@@ -17,6 +17,6 @@ public class ReactNativeVersion {
public static final Map<String, Object> VERSION = MapBuilder.<String, Object>of(
"major", 0,
"minor", 78,
"patch", 2,
"patch", 0,
"prerelease", null);
}
@@ -0,0 +1,48 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.processing
import com.facebook.annotationprocessors.common.ProcessorBase
import com.facebook.react.common.annotations.internal.LegacyArchitecture
import java.io.FileWriter
import java.io.IOException
import javax.annotation.processing.RoundEnvironment
import javax.annotation.processing.SupportedAnnotationTypes
import javax.annotation.processing.SupportedSourceVersion
import javax.lang.model.SourceVersion
import javax.lang.model.element.TypeElement
@SupportedAnnotationTypes("com.facebook.react.common.annotations.internal.LegacyArchitecture")
@SupportedSourceVersion(SourceVersion.RELEASE_11)
class ReactLegacyArchitectureProcessor : ProcessorBase() {
override fun processImpl(annotations: Set<TypeElement>, roundEnv: RoundEnvironment): Boolean {
val outputFileName = System.getenv()["RN_LEGACY_ARCH_OUTPUT_FILE_NAME"]
if (outputFileName.isNullOrEmpty()) {
return true
}
val elements = roundEnv.getElementsAnnotatedWith(LegacyArchitecture::class.java)
val classes: MutableList<String> = mutableListOf()
elements.forEach { element ->
val classType = element as TypeElement
val className = classType.qualifiedName.toString().replace(".", "/")
classes.add("type L$className;")
}
try {
FileWriter(outputFileName, true).use { writer ->
for (clazz in classes) {
writer.write(clazz + "\n")
}
}
} catch (e: IOException) {
throw RuntimeException(e)
}
return true
}
}
@@ -16,7 +16,6 @@ import android.graphics.drawable.LayerDrawable
import android.os.Build
import com.facebook.react.common.annotations.UnstableReactNativeAPI
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags
import com.facebook.react.uimanager.PixelUtil.dpToPx
import com.facebook.react.uimanager.style.BorderInsets
import com.facebook.react.uimanager.style.BorderRadiusStyle
@@ -199,17 +198,17 @@ internal class CompositeBackgroundDrawable(
computedBorderRadius?.let {
pathForOutline.addRoundRect(
RectF(bounds),
floatArrayOf(
(it.topLeft.horizontal + (computedBorderInsets?.left ?: 0f)).dpToPx(),
(it.topLeft.vertical + (computedBorderInsets?.top ?: 0f)).dpToPx(),
(it.topRight.horizontal + (computedBorderInsets?.right ?: 0f)).dpToPx(),
(it.topRight.vertical + (computedBorderInsets?.top ?: 0f)).dpToPx(),
(it.bottomRight.horizontal + (computedBorderInsets?.right ?: 0f)).dpToPx(),
(it.bottomRight.vertical + (computedBorderInsets?.bottom ?: 0f)).dpToPx(),
(it.bottomLeft.horizontal + (computedBorderInsets?.left ?: 0f)).dpToPx(),
(it.bottomLeft.vertical + (computedBorderInsets?.bottom ?: 0f)).dpToPx()),
Path.Direction.CW)
RectF(bounds),
floatArrayOf(
it.topLeft.horizontal + (computedBorderInsets?.left ?: 0f),
it.topLeft.vertical + (computedBorderInsets?.top ?: 0f),
it.topRight.horizontal + (computedBorderInsets?.right ?: 0f),
it.topRight.vertical + (computedBorderInsets?.top ?: 0f),
it.bottomRight.horizontal + (computedBorderInsets?.right ?: 0f),
it.bottomRight.vertical + (computedBorderInsets?.bottom ?: 0f),
it.bottomLeft.horizontal + (computedBorderInsets?.left ?: 0f),
it.bottomLeft.vertical) + (computedBorderInsets?.bottom ?: 0f),
Path.Direction.CW)
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
@@ -124,7 +124,7 @@ public constructor(
}
}
@ReactProp(name = "defaultSource")
@ReactProp(name = "defaultSource", customType = "ImageSource")
public fun setDefaultSource(view: ReactImageView, source: String?) {
view.setDefaultSource(source)
}
@@ -588,6 +588,9 @@ public class ReactViewGroup extends ViewGroup
UiThreadUtil.assertOnUiThread();
checkViewClippingTag(child, Boolean.TRUE);
if (!customDrawOrderDisabled()) {
if (indexOfChild(child) == -1) {
return;
}
getDrawingOrderHelper().handleRemoveView(child);
setChildrenDrawingOrderEnabled(getDrawingOrderHelper().shouldEnableCustomDrawingOrder());
} else {
@@ -17,7 +17,7 @@ namespace facebook::react {
constexpr struct {
int32_t Major = 0;
int32_t Minor = 78;
int32_t Patch = 2;
int32_t Patch = 0;
std::string_view Prerelease = "";
} ReactNativeVersion;
@@ -446,15 +446,6 @@ void ObjCInteropTurboModule::setInvocationArg(
if (objCArgType == @encode(id)) {
id arg = RCTConvertTo<id>(selector, objCArg);
// Handle the special case where there is an argument and it must be nil
// Without this check, the JS side will receive an object.
// See: discussion at
// https://github.com/facebook/react-native/pull/49250#issuecomment-2668465893
if (arg == [NSNull null]) {
return;
}
if (arg) {
[retainedObjectsForInvocation addObject:arg];
}
@@ -57,7 +57,7 @@ static jsi::Value convertNSNumberToJSINumber(jsi::Runtime &runtime, NSNumber *va
static jsi::String convertNSStringToJSIString(jsi::Runtime &runtime, NSString *value)
{
return jsi::String::createFromUtf8(runtime, [value UTF8String] ? [value UTF8String] : "");
return jsi::String::createFromUtf8(runtime, [value UTF8String] ?: "");
}
static jsi::Object convertNSDictionaryToJSIObject(jsi::Runtime &runtime, NSDictionary *value)
@@ -203,11 +203,7 @@ static jsi::Value createJSRuntimeError(jsi::Runtime &runtime, const std::string
/**
* Creates JSError with current JS runtime and NSException stack trace.
*/
static jsi::JSError convertNSExceptionToJSError(
jsi::Runtime &runtime,
NSException *exception,
const std::string &moduleName,
const std::string &methodName)
static jsi::JSError convertNSExceptionToJSError(jsi::Runtime &runtime, NSException *exception)
{
std::string reason = [exception.reason UTF8String];
@@ -218,8 +214,7 @@ static jsi::JSError convertNSExceptionToJSError(
cause.setProperty(
runtime, "stackReturnAddresses", convertNSArrayToJSIArray(runtime, exception.callStackReturnAddresses));
std::string message = moduleName + "." + methodName + " raised an exception: " + reason;
jsi::Value error = createJSRuntimeError(runtime, message);
jsi::Value error = createJSRuntimeError(runtime, "Exception in HostFunction: " + reason);
error.asObject(runtime).setProperty(runtime, "cause", std::move(cause));
return {runtime, std::move(error)};
}
@@ -351,34 +346,28 @@ id ObjCTurboModule::performMethodInvocation(
}
if (isSync) {
TurboModulePerfLogger::syncMethodCallExecutionStart(moduleName, methodName);
TurboModulePerfLogger::syncMethodCallExecutionStart(moduleName, methodNameStr.c_str());
} else {
TurboModulePerfLogger::asyncMethodCallExecutionStart(moduleName, methodName, asyncCallCounter);
TurboModulePerfLogger::asyncMethodCallExecutionStart(moduleName, methodNameStr.c_str(), asyncCallCounter);
}
@try {
[inv invokeWithTarget:strongModule];
} @catch (NSException *exception) {
if (isSync) {
// We can only convert NSException to JSError in sync method calls.
// See https://github.com/reactwg/react-native-new-architecture/discussions/276#discussioncomment-12567155
throw convertNSExceptionToJSError(runtime, exception, std::string{moduleName}, methodNameStr);
} else {
@throw exception;
}
throw convertNSExceptionToJSError(runtime, exception);
} @finally {
[retainedObjectsForInvocation removeAllObjects];
}
if (!isSync) {
TurboModulePerfLogger::asyncMethodCallExecutionEnd(moduleName, methodName, asyncCallCounter);
TurboModulePerfLogger::asyncMethodCallExecutionEnd(moduleName, methodNameStr.c_str(), asyncCallCounter);
return;
}
void *rawResult;
[inv getReturnValue:&rawResult];
result = (__bridge id)rawResult;
TurboModulePerfLogger::syncMethodCallExecutionEnd(moduleName, methodName);
TurboModulePerfLogger::syncMethodCallExecutionEnd(moduleName, methodNameStr.c_str());
};
if (isSync) {
@@ -420,23 +409,23 @@ void ObjCTurboModule::performVoidMethodInvocation(
}
if (shouldVoidMethodsExecuteSync_) {
TurboModulePerfLogger::syncMethodCallExecutionStart(moduleName, methodName);
TurboModulePerfLogger::syncMethodCallExecutionStart(moduleName, methodNameStr.c_str());
} else {
TurboModulePerfLogger::asyncMethodCallExecutionStart(moduleName, methodName, asyncCallCounter);
TurboModulePerfLogger::asyncMethodCallExecutionStart(moduleName, methodNameStr.c_str(), asyncCallCounter);
}
@try {
[inv invokeWithTarget:strongModule];
} @catch (NSException *exception) {
throw convertNSExceptionToJSError(runtime, exception, std::string{moduleName}, methodNameStr);
throw convertNSExceptionToJSError(runtime, exception);
} @finally {
[retainedObjectsForInvocation removeAllObjects];
}
if (shouldVoidMethodsExecuteSync_) {
TurboModulePerfLogger::syncMethodCallExecutionEnd(moduleName, methodName);
TurboModulePerfLogger::syncMethodCallExecutionEnd(moduleName, methodNameStr.c_str());
} else {
TurboModulePerfLogger::asyncMethodCallExecutionEnd(moduleName, methodName, asyncCallCounter);
TurboModulePerfLogger::asyncMethodCallExecutionEnd(moduleName, methodNameStr.c_str(), asyncCallCounter);
}
return;
@@ -52,29 +52,8 @@ BOOL RCTIsAttributedStringEffectivelySame(
NSDictionary<NSAttributedStringKey, id> *insensitiveAttributes,
const facebook::react::TextAttributes &baseTextAttributes);
static inline NSData *RCTWrapEventEmitter(const facebook::react::SharedEventEmitter &eventEmitter)
{
auto eventEmitterPtr = new std::weak_ptr<const facebook::react::EventEmitter>(eventEmitter);
return [[NSData alloc] initWithBytesNoCopy:eventEmitterPtr
length:sizeof(eventEmitterPtr)
deallocator:^(void *ptrToDelete, NSUInteger) {
delete (std::weak_ptr<facebook::react::EventEmitter> *)ptrToDelete;
}];
}
static inline facebook::react::SharedEventEmitter RCTUnwrapEventEmitter(NSData *data)
{
if (data.length == 0) {
return nullptr;
}
auto weakPtr = dynamic_cast<std::weak_ptr<const facebook::react::EventEmitter> *>(
(std::weak_ptr<const facebook::react::EventEmitter> *)data.bytes);
if (weakPtr) {
return weakPtr->lock();
}
return nullptr;
}
@interface RCTWeakEventEmitterWrapper : NSObject
@property (nonatomic, assign) facebook::react::SharedEventEmitter eventEmitter;
@end
NS_ASSUME_NONNULL_END
@@ -16,6 +16,45 @@
using namespace facebook::react;
@implementation RCTWeakEventEmitterWrapper {
std::weak_ptr<const EventEmitter> _weakEventEmitter;
}
- (void)setEventEmitter:(SharedEventEmitter)eventEmitter
{
_weakEventEmitter = eventEmitter;
}
- (SharedEventEmitter)eventEmitter
{
return _weakEventEmitter.lock();
}
- (void)dealloc
{
_weakEventEmitter.reset();
}
- (BOOL)isEqual:(id)object
{
// We consider the underlying EventEmitter as the identity
if (![object isKindOfClass:[self class]]) {
return NO;
}
auto thisEventEmitter = [self eventEmitter];
auto otherEventEmitter = [((RCTWeakEventEmitterWrapper *)object) eventEmitter];
return thisEventEmitter == otherEventEmitter;
}
- (NSUInteger)hash
{
// We consider the underlying EventEmitter as the identity
return (NSUInteger)_weakEventEmitter.lock().get();
}
@end
inline static UIFontWeight RCTUIFontWeightFromInteger(NSInteger fontWeight)
{
assert(fontWeight > 50);
@@ -370,8 +409,10 @@ static NSMutableAttributedString *RCTNSAttributedStringFragmentWithAttributesFro
{
auto nsAttributedStringFragment = RCTNSAttributedStringFragmentFromFragment(fragment, placeholderImage);
#if !TARGET_OS_MACCATALYST
if (fragment.parentShadowView.componentHandle) {
auto eventEmitterWrapper = RCTWrapEventEmitter(fragment.parentShadowView.eventEmitter);
RCTWeakEventEmitterWrapper *eventEmitterWrapper = [RCTWeakEventEmitterWrapper new];
eventEmitterWrapper.eventEmitter = fragment.parentShadowView.eventEmitter;
NSDictionary<NSAttributedStringKey, id> *additionalTextAttributes =
@{RCTAttributedStringEventEmitterKey : eventEmitterWrapper};
@@ -379,6 +420,7 @@ static NSMutableAttributedString *RCTNSAttributedStringFragmentWithAttributesFro
[nsAttributedStringFragment addAttributes:additionalTextAttributes
range:NSMakeRange(0, nsAttributedStringFragment.length)];
}
#endif
return nsAttributedStringFragment;
}
@@ -268,10 +268,11 @@ static NSLineBreakMode RCTNSLineBreakModeFromEllipsizeMode(EllipsizeMode ellipsi
// after (fraction == 1.0) the last character, then the attribute is valid.
if (textStorage.length > 0 && (fraction > 0 || characterIndex > 0) &&
(fraction < 1 || characterIndex < textStorage.length - 1)) {
NSData *eventEmitterWrapper = (NSData *)[textStorage attribute:RCTAttributedStringEventEmitterKey
atIndex:characterIndex
effectiveRange:NULL];
return RCTUnwrapEventEmitter(eventEmitterWrapper);
RCTWeakEventEmitterWrapper *eventEmitterWrapper =
(RCTWeakEventEmitterWrapper *)[textStorage attribute:RCTAttributedStringEventEmitterKey
atIndex:characterIndex
effectiveRange:NULL];
return eventEmitterWrapper.eventEmitter;
}
return nil;
+10 -10
View File
@@ -1,6 +1,6 @@
{
"name": "react-native",
"version": "0.78.2",
"version": "0.78.0",
"description": "A framework for building native apps using React",
"license": "MIT",
"repository": {
@@ -108,13 +108,13 @@
},
"dependencies": {
"@jest/create-cache-key-function": "^29.6.3",
"@react-native/assets-registry": "0.78.2",
"@react-native/codegen": "0.78.2",
"@react-native/community-cli-plugin": "0.78.2",
"@react-native/gradle-plugin": "0.78.2",
"@react-native/js-polyfills": "0.78.2",
"@react-native/normalize-colors": "0.78.2",
"@react-native/virtualized-lists": "0.78.2",
"@react-native/assets-registry": "0.78.0",
"@react-native/codegen": "0.78.0",
"@react-native/community-cli-plugin": "0.78.0",
"@react-native/gradle-plugin": "0.78.0",
"@react-native/js-polyfills": "0.78.0",
"@react-native/normalize-colors": "0.78.0",
"@react-native/virtualized-lists": "0.78.0",
"abort-controller": "^3.0.0",
"anser": "^1.4.9",
"ansi-regex": "^5.0.0",
@@ -129,8 +129,8 @@
"invariant": "^2.2.4",
"jest-environment-node": "^29.6.3",
"memoize-one": "^5.0.0",
"metro-runtime": "^0.81.3",
"metro-source-map": "^0.81.3",
"metro-runtime": "^0.81.0",
"metro-source-map": "^0.81.0",
"nullthrows": "^1.1.1",
"pretty-format": "^29.7.0",
"promise": "^8.3.0",
+21 -5
View File
@@ -44,11 +44,27 @@ try {
const commands = [];
const {
bundleCommand,
startCommand,
} = require('@react-native/community-cli-plugin');
commands.push(bundleCommand, startCommand);
try {
const {
bundleCommand,
startCommand,
} = require('@react-native/community-cli-plugin');
commands.push(bundleCommand, startCommand);
} catch (e) {
const known =
e.code === 'MODULE_NOT_FOUND' &&
e.message.includes('@react-native-community/cli-server-api');
if (!known) {
throw e;
}
if (verbose) {
console.warn(
'@react-native-community/cli-server-api not found, the react-native.config.js may be unusable.',
);
}
}
const codegenCommand = {
name: 'codegen',
File diff suppressed because it is too large Load Diff
@@ -76,6 +76,13 @@ static NSString *kBundlePath = @"js/RNTesterApp.ios";
return [RCTLinkingManager application:app openURL:url options:options];
}
- (void)loadSourceForBridge:(RCTBridge *)bridge
onProgress:(RCTSourceLoadProgressBlock)onProgress
onComplete:(RCTSourceLoadBlock)loadCallback
{
[RCTJavaScriptLoader loadBundleAtURL:[self sourceURLForBridge:bridge] onProgress:onProgress onComplete:loadCallback];
}
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
jsInvoker:(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker
{
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@react-native/tester",
"version": "0.78.2",
"version": "0.78.0",
"private": true,
"description": "React Native tester app.",
"license": "MIT",
@@ -27,8 +27,8 @@
"e2e-test-ios": "./scripts/maestro-test-ios.sh"
},
"dependencies": {
"@react-native/oss-library-example": "0.78.2",
"@react-native/popup-menu-android": "0.78.2",
"@react-native/oss-library-example": "0.78.0",
"@react-native/popup-menu-android": "0.78.0",
"flow-enums-runtime": "^0.0.6",
"invariant": "^2.2.4",
"nullthrows": "^1.1.1"
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@react-native/typescript-config",
"version": "0.78.2",
"version": "0.78.0",
"description": "Default TypeScript configuration for React Native apps",
"license": "MIT",
"repository": {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@react-native/virtualized-lists",
"version": "0.78.2",
"version": "0.78.0",
"description": "Virtualized lists for React Native.",
"license": "MIT",
"repository": {
+163 -121
View File
@@ -1064,6 +1064,17 @@
"@babel/plugin-transform-modules-commonjs" "^7.24.7"
"@babel/plugin-transform-typescript" "^7.24.7"
"@babel/register@7.22.5":
version "7.22.5"
resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.22.5.tgz#e4d8d0f615ea3233a27b5c6ada6750ee59559939"
integrity sha512-vV6pm/4CijSQ8Y47RH5SopXzursN35RQINfGJkmOlcpAtGuf94miFvIPhCKGQN7WGIcsgG1BHEX2KVdTYwTwUQ==
dependencies:
clone-deep "^4.0.1"
find-cache-dir "^2.0.0"
make-dir "^2.1.0"
pirates "^4.0.5"
source-map-support "^0.5.16"
"@babel/register@^7.13.16", "@babel/register@^7.24.6":
version "7.24.6"
resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.24.6.tgz#59e21dcc79e1d04eed5377633b0f88029a6bef9e"
@@ -1096,20 +1107,7 @@
"@babel/parser" "^7.25.0"
"@babel/types" "^7.25.0"
"@babel/traverse--for-generate-function-map@npm:@babel/traverse@^7.25.3":
version "7.25.6"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.6.tgz#04fad980e444f182ecf1520504941940a90fea41"
integrity sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==
dependencies:
"@babel/code-frame" "^7.24.7"
"@babel/generator" "^7.25.6"
"@babel/parser" "^7.25.6"
"@babel/template" "^7.25.0"
"@babel/types" "^7.25.6"
debug "^4.3.1"
globals "^11.1.0"
"@babel/traverse@^7.24.7", "@babel/traverse@^7.24.8", "@babel/traverse@^7.25.0", "@babel/traverse@^7.25.1", "@babel/traverse@^7.25.2", "@babel/traverse@^7.25.3", "@babel/traverse@^7.25.4":
"@babel/traverse--for-generate-function-map@npm:@babel/traverse@^7.25.3", "@babel/traverse@^7.24.7", "@babel/traverse@^7.24.8", "@babel/traverse@^7.25.0", "@babel/traverse@^7.25.1", "@babel/traverse@^7.25.2", "@babel/traverse@^7.25.3", "@babel/traverse@^7.25.4":
version "7.25.6"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.6.tgz#04fad980e444f182ecf1520504941940a90fea41"
integrity sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==
@@ -2780,6 +2778,13 @@ babel-plugin-replace-ts-export-assignment@^0.0.2:
resolved "https://registry.yarnpkg.com/babel-plugin-replace-ts-export-assignment/-/babel-plugin-replace-ts-export-assignment-0.0.2.tgz#927a30ba303fcf271108980a8d4f80a693e1d53f"
integrity sha512-BiTEG2Ro+O1spuheL5nB289y37FFmz0ISE6GjpNCG2JuA/WNcuEHSYw01+vN8quGf208sID3FnZFDwVyqX18YQ==
babel-plugin-syntax-hermes-parser@0.24.0:
version "0.24.0"
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-hermes-parser/-/babel-plugin-syntax-hermes-parser-0.24.0.tgz#79d0c73daae7bd7d4b07f64ee281c75aa48845cf"
integrity sha512-J4wETqz7ehbyYl2uge65zsfr0Ue+0yJYYMMkGAWpZc0fB02z4JAcx+mJEXVU14yiihGwqVUlR7oS4/gDYOxUdA==
dependencies:
hermes-parser "0.24.0"
babel-plugin-syntax-hermes-parser@0.25.1:
version "0.25.1"
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-hermes-parser/-/babel-plugin-syntax-hermes-parser-0.25.1.tgz#58b539df973427fcfbb5176a3aec7e5dee793cb0"
@@ -3604,6 +3609,11 @@ delegates@^1.0.0:
resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==
denodeify@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/denodeify/-/denodeify-1.2.1.tgz#3a36287f5034e699e7577901052c2e6c94251631"
integrity sha512-KNTihKNmQENUZeKu5fzfpzRqR5S2VMp4gl9RFHiWzj9DfvYQPMJ6XHKNaQxaGCXwPk6y9yme3aUoaiAe+KX+vg==
depd@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df"
@@ -4789,11 +4799,23 @@ hermes-eslint@0.25.1:
hermes-estree "0.25.1"
hermes-parser "0.25.1"
hermes-estree@0.24.0:
version "0.24.0"
resolved "https://registry.yarnpkg.com/hermes-estree/-/hermes-estree-0.24.0.tgz#487dc1ddc0bae698c2d79f34153ac9bf62d7b3c0"
integrity sha512-LyoXLB7IFzeZW0EvAbGZacbxBN7t6KKSDqFJPo3Ydow7wDlrDjXwsdiAHV6XOdvEN9MEuWXsSIFN4tzpyrXIHw==
hermes-estree@0.25.1:
version "0.25.1"
resolved "https://registry.yarnpkg.com/hermes-estree/-/hermes-estree-0.25.1.tgz#6aeec17d1983b4eabf69721f3aa3eb705b17f480"
integrity sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==
hermes-parser@0.24.0:
version "0.24.0"
resolved "https://registry.yarnpkg.com/hermes-parser/-/hermes-parser-0.24.0.tgz#2ed19d079efc0848eb1f800f0c393a074c4696fb"
integrity sha512-IJooSvvu2qNRe7oo9Rb04sUT4omtZqZqf9uq9WM25Tb6v3usmvA93UqfnnoWs5V0uYjEl9Al6MNU10MCGKLwpg==
dependencies:
hermes-estree "0.24.0"
hermes-parser@0.25.1:
version "0.25.1"
resolved "https://registry.yarnpkg.com/hermes-parser/-/hermes-parser-0.25.1.tgz#5be0e487b2090886c62bd8a11724cd766d5f54d1"
@@ -5714,7 +5736,7 @@ jest-validate@^24.9.0:
leven "^3.1.0"
pretty-format "^24.9.0"
jest-validate@^29.7.0:
jest-validate@^29.6.3, jest-validate@^29.7.0:
version "29.7.0"
resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.7.0.tgz#7bf705511c64da591d46b15fce41400d52147d9c"
integrity sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==
@@ -5740,7 +5762,7 @@ jest-watcher@^29.7.0:
jest-util "^29.7.0"
string-length "^4.0.1"
jest-worker@^29.7.0:
jest-worker@^29.6.3, jest-worker@^29.7.0:
version "29.7.0"
resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.7.0.tgz#acad073acbbaeb7262bd5389e1bcf43e10058d4a"
integrity sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==
@@ -6281,149 +6303,154 @@ merge2@^1.3.0, merge2@^1.4.1:
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
metro-babel-register@^0.81.3:
version "0.81.3"
resolved "https://registry.yarnpkg.com/metro-babel-register/-/metro-babel-register-0.81.3.tgz#8a514cc79f59e7efbf61fe0fc39f746ee6b1b8b8"
integrity sha512-Td4cVGZ+EbLCz5nMrW4qusS3c2Nd2qKceagFutaOZ7RZI0h6gHsBeqD+jDZ6Ytjm/ztdq9jHwOsc+ELu5Qh8dA==
metro-babel-register@^0.81.0:
version "0.81.0"
resolved "https://registry.yarnpkg.com/metro-babel-register/-/metro-babel-register-0.81.0.tgz#05e9deda5633e38aceb7120b1865cbbc63c5b8ef"
integrity sha512-CU9D49k9ti02ebHXuYlbDNPdBj0C4SnCDIGk328epmcO0p++WzFSWWO92cGc7i0HqKyzgeMskPGJV825Eh7zSg==
dependencies:
"@babel/core" "^7.25.2"
"@babel/plugin-proposal-export-namespace-from" "^7.18.9"
"@babel/plugin-transform-flow-strip-types" "^7.25.2"
"@babel/plugin-transform-modules-commonjs" "^7.24.8"
"@babel/preset-typescript" "^7.24.7"
"@babel/register" "^7.24.6"
"@babel/register" "7.22.5"
babel-plugin-replace-ts-export-assignment "^0.0.2"
babel-plugin-syntax-hermes-parser "0.25.1"
babel-plugin-syntax-hermes-parser "0.24.0"
babel-plugin-transform-flow-enums "^0.0.2"
escape-string-regexp "^1.0.5"
flow-enums-runtime "^0.0.6"
metro-babel-transformer@0.81.3:
version "0.81.3"
resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.81.3.tgz#908b8ed7ce07e34d44db2a24b282d8728f7f9c0c"
integrity sha512-ENqtnPy2mQZFOuKrbqHRcAwZuaYe43X+30xIF0xlkLuMyCvc0CsFzrrSK9EqrQwexhVlqaRALb0GQbBMcE/y8g==
metro-babel-transformer@0.81.0:
version "0.81.0"
resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.81.0.tgz#cf468eafea52e4d8a77844eb7257f8a76e9d9d94"
integrity sha512-Dc0QWK4wZIeHnyZ3sevWGTnnSkIDDn/SWyfrn99zbKbDOCoCYy71PAn9uCRrP/hduKLJQOy+tebd63Rr9D8tXg==
dependencies:
"@babel/core" "^7.25.2"
flow-enums-runtime "^0.0.6"
hermes-parser "0.25.1"
hermes-parser "0.24.0"
nullthrows "^1.1.1"
metro-cache-key@0.81.3:
version "0.81.3"
resolved "https://registry.yarnpkg.com/metro-cache-key/-/metro-cache-key-0.81.3.tgz#afbd48f2847419cf27b925d83def31758b17b049"
integrity sha512-KPsPSRUd6uRva7k7k/DqiiD8td7URQWx0RkX/Cj5+bed5zSXEg/XoQA+b+DmMxS5C7TqP61Fh3XvHx6TQRW82A==
metro-cache-key@0.81.0:
version "0.81.0"
resolved "https://registry.yarnpkg.com/metro-cache-key/-/metro-cache-key-0.81.0.tgz#5db34fa1a323a2310205bda7abd0df9614e36f45"
integrity sha512-qX/IwtknP9bQZL78OK9xeSvLM/xlGfrs6SlUGgHvrxtmGTRSsxcyqxR+c+7ch1xr05n62Gin/O44QKg5V70rNQ==
dependencies:
flow-enums-runtime "^0.0.6"
metro-cache@0.81.3:
version "0.81.3"
resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.81.3.tgz#8239ccc7fecd24aa6c76af8975aa03be95dfe4e9"
integrity sha512-6UelMQYjlto/79tTXu0vsTxAX4e+Bkf0tgtDL1BNx3wd68pBg8qKIYpJPaUlOIaNUzFXTBDjYwUverkEW0KAtA==
metro-cache@0.81.0:
version "0.81.0"
resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.81.0.tgz#90470d10d190ad708f04c6e337eec2c7cddb3db0"
integrity sha512-DyuqySicHXkHUDZFVJmh0ygxBSx6pCKUrTcSgb884oiscV/ROt1Vhye+x+OIHcsodyA10gzZtrVtxIFV4l9I4g==
dependencies:
exponential-backoff "^3.1.1"
flow-enums-runtime "^0.0.6"
metro-core "0.81.3"
metro-core "0.81.0"
metro-config@0.81.3, metro-config@^0.81.3:
version "0.81.3"
resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.81.3.tgz#8e6c3d1f377bf7fa840ba99f7f05bd7b91a21eae"
integrity sha512-WpTaT0iQr5juVY50Y/cyacG2ggZqF38VshEQepT+ovPK8E/xUVxlbO5yxLSXUxxUXX3Hka9r6g64+y2WC6c/xQ==
metro-config@0.81.0, metro-config@^0.81.0:
version "0.81.0"
resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.81.0.tgz#8f8074033cb7e9ddb5b0459642adf6880bc9fbc1"
integrity sha512-6CinEaBe3WLpRlKlYXXu8r1UblJhbwD6Gtnoib5U8j6Pjp7XxMG9h/DGMeNp9aGLDu1OieUqiXpFo7O0/rR5Kg==
dependencies:
connect "^3.6.5"
cosmiconfig "^5.0.5"
flow-enums-runtime "^0.0.6"
jest-validate "^29.7.0"
metro "0.81.3"
metro-cache "0.81.3"
metro-core "0.81.3"
metro-runtime "0.81.3"
jest-validate "^29.6.3"
metro "0.81.0"
metro-cache "0.81.0"
metro-core "0.81.0"
metro-runtime "0.81.0"
metro-core@0.81.3, metro-core@^0.81.3:
version "0.81.3"
resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.81.3.tgz#86c29bcd90fc3157f52abd7f94bf9d6d7fb03977"
integrity sha512-WZ+qohnpvvSWdPj1VJPUrZz+2ik29M+UUpMU6YrmzQUfDyZ6JYHhzlw5WVBtwpt/+2xTsIyrZ2C1fByT/DsLQA==
metro-core@0.81.0, metro-core@^0.81.0:
version "0.81.0"
resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.81.0.tgz#d0b634f9cf97849b7730c59457ab7a439811d4c8"
integrity sha512-CVkM5YCOAFkNMvJai6KzA0RpztzfEKRX62/PFMOJ9J7K0uq/UkOFLxcgpcncMIrfy0PbfEj811b69tjULUQe1Q==
dependencies:
flow-enums-runtime "^0.0.6"
lodash.throttle "^4.1.1"
metro-resolver "0.81.3"
metro-resolver "0.81.0"
metro-file-map@0.81.3:
version "0.81.3"
resolved "https://registry.yarnpkg.com/metro-file-map/-/metro-file-map-0.81.3.tgz#0204d8584c1115a94f38c07afeb0689629939c44"
integrity sha512-F+t4lnVRoauJxtr9xmI4pWIOE77/vl0IrHDGeJSI9cW6LmuqxkpOlZHTKpbs/hMAo6+KhG2JMJACQDvXDLd/GA==
metro-file-map@0.81.0:
version "0.81.0"
resolved "https://registry.yarnpkg.com/metro-file-map/-/metro-file-map-0.81.0.tgz#af0ccf4f8db4fd8429f78f231faa49dde2c402c3"
integrity sha512-zMDI5uYhQCyxbye/AuFx/pAbsz9K+vKL7h1ShUXdN2fz4VUPiyQYRsRqOoVG1DsiCgzd5B6LW0YW77NFpjDQeg==
dependencies:
anymatch "^3.0.3"
debug "^2.2.0"
fb-watchman "^2.0.0"
flow-enums-runtime "^0.0.6"
graceful-fs "^4.2.4"
invariant "^2.2.4"
jest-worker "^29.7.0"
jest-worker "^29.6.3"
micromatch "^4.0.4"
node-abort-controller "^3.1.1"
nullthrows "^1.1.1"
walker "^1.0.7"
optionalDependencies:
fsevents "^2.3.2"
metro-memory-fs@^0.81.3:
version "0.81.3"
resolved "https://registry.yarnpkg.com/metro-memory-fs/-/metro-memory-fs-0.81.3.tgz#8c3a00eb9346bd3541633935ac7e67542eba2d6c"
integrity sha512-r6bMg6G3GXSyJLEa7HxGl6dbThA2fQAXM4JwNV+rtmxUa2FfPHYjRlOuApz5RNZGriunE2HzGwptfphElftGnw==
metro-memory-fs@^0.81.0:
version "0.81.0"
resolved "https://registry.yarnpkg.com/metro-memory-fs/-/metro-memory-fs-0.81.0.tgz#f11ac95bb294f3fd4c933cf93ab9ee6da626d352"
integrity sha512-hbmyOuVigPU81Kd+CUCq7tXgEkrHmteWG1WJHTEwldoLHuYUzSeaoE8LlLUbqPF+OPW0asYx/cTDrfNM8KCuqw==
dependencies:
flow-enums-runtime "^0.0.6"
metro-minify-terser@0.81.3:
version "0.81.3"
resolved "https://registry.yarnpkg.com/metro-minify-terser/-/metro-minify-terser-0.81.3.tgz#68e15ffbcaa21d7daa01840405168704cd9b5b67"
integrity sha512-912AYv3OmwcbUwzCdWbdQRk+RV6kXXluHKlhBdYFD3kr4Ece691rzlofU/Mlt9qZrhHtctD5Q8cFqOEf9Z69bQ==
metro-minify-terser@0.81.0:
version "0.81.0"
resolved "https://registry.yarnpkg.com/metro-minify-terser/-/metro-minify-terser-0.81.0.tgz#8b0abe977d63a99b99fa94d53678ef3170d5b659"
integrity sha512-U2ramh3W822ZR1nfXgIk+emxsf5eZSg10GbQrT0ZizImK8IZ5BmJY+BHRIkQgHzWFpExOVxC7kWbGL1bZALswA==
dependencies:
flow-enums-runtime "^0.0.6"
terser "^5.15.0"
metro-resolver@0.81.3, metro-resolver@^0.81.3:
version "0.81.3"
resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.81.3.tgz#8a61df2c15d30336cd96cdc1918826dde0ff8938"
integrity sha512-XnjENY1c6jcsEfFVIjN/8McUIInCVgGxv5eva+9ZWeCTyiAE/L5HPj2ai/Myb349+6QuSMR0dscTkKCnOwWXdw==
metro-resolver@0.81.0, metro-resolver@^0.81.0:
version "0.81.0"
resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.81.0.tgz#141f4837e1e0c5a1810ea02f2d9be3c9f6cf3766"
integrity sha512-Uu2Q+buHhm571cEwpPek8egMbdSTqmwT/5U7ZVNpK6Z2ElQBBCxd7HmFAslKXa7wgpTO2FAn6MqGeERbAtVDUA==
dependencies:
flow-enums-runtime "^0.0.6"
metro-runtime@0.81.3, metro-runtime@^0.81.3:
version "0.81.3"
resolved "https://registry.yarnpkg.com/metro-runtime/-/metro-runtime-0.81.3.tgz#0cb5d8c8e5843fbf6fe6e9595821f0f434953aba"
integrity sha512-neuGRMC2pgGKIFPbmbrxW41/SmvL7OX4i1LN+saUY2t1cZfxf9haQHUMCGhO3498uEL2N+ulKRSlQrHt6XwGaw==
metro-runtime@0.81.0, metro-runtime@^0.81.0:
version "0.81.0"
resolved "https://registry.yarnpkg.com/metro-runtime/-/metro-runtime-0.81.0.tgz#63af9b3fec15d1f307d89ef4881f5ba2c592291e"
integrity sha512-6oYB5HOt37RuGz2eV4A6yhcl+PUTwJYLDlY9vhT+aVjbUWI6MdBCf69vc4f5K5Vpt+yOkjy+2LDwLS0ykWFwYw==
dependencies:
"@babel/runtime" "^7.25.0"
flow-enums-runtime "^0.0.6"
metro-source-map@0.81.3, metro-source-map@^0.81.3:
version "0.81.3"
resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.81.3.tgz#d0aed42b3bb0842cb6f71c2b8f3d58e96a5b8a05"
integrity sha512-BHJJurmDQRn3hCbBawh/UHzPz3duMpwpE3ofImO2DoWHYzn6nSg/D4wfCN4y14d9fFLE4e0I+BAOX1HWNP4jsw==
metro-source-map@0.81.0, metro-source-map@^0.81.0:
version "0.81.0"
resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.81.0.tgz#ca83964124bb227d5f0bdb1ee304dbfe635f869e"
integrity sha512-TzsVxhH83dyxg4A4+L1nzNO12I7ps5IHLjKGZH3Hrf549eiZivkdjYiq/S5lOB+p2HiQ+Ykcwtmcja95LIC62g==
dependencies:
"@babel/traverse" "^7.25.3"
"@babel/traverse--for-generate-function-map" "npm:@babel/traverse@^7.25.3"
"@babel/types" "^7.25.2"
flow-enums-runtime "^0.0.6"
invariant "^2.2.4"
metro-symbolicate "0.81.3"
metro-symbolicate "0.81.0"
nullthrows "^1.1.1"
ob1 "0.81.3"
ob1 "0.81.0"
source-map "^0.5.6"
vlq "^1.0.0"
metro-symbolicate@0.81.3:
version "0.81.3"
resolved "https://registry.yarnpkg.com/metro-symbolicate/-/metro-symbolicate-0.81.3.tgz#e68fa6a4f7f426dc9e99ceb01bcb138a48a8fbf4"
integrity sha512-LQLT6WopQmIz2SDSVh3Lw7nLzF58HpsrPYqRB7RpRXBYhYmPFIjiGaP8qqtKHXczM/5YAOJzpgt8t/OGZgh6Eg==
metro-symbolicate@0.81.0:
version "0.81.0"
resolved "https://registry.yarnpkg.com/metro-symbolicate/-/metro-symbolicate-0.81.0.tgz#b7b1eae8bfd6ad2a922fa2bcb9f2144e464adafb"
integrity sha512-C/1rWbNTPYp6yzID8IPuQPpVGzJ2rbWYBATxlvQ9dfK5lVNoxcwz77hjcY8ISLsRRR15hyd/zbjCNKPKeNgE1Q==
dependencies:
flow-enums-runtime "^0.0.6"
invariant "^2.2.4"
metro-source-map "0.81.3"
metro-source-map "0.81.0"
nullthrows "^1.1.1"
source-map "^0.5.6"
through2 "^2.0.1"
vlq "^1.0.0"
metro-transform-plugins@0.81.3, metro-transform-plugins@^0.81.3:
version "0.81.3"
resolved "https://registry.yarnpkg.com/metro-transform-plugins/-/metro-transform-plugins-0.81.3.tgz#04d168fa29cc4eee92d72cf6a2c27810adcf4273"
integrity sha512-4JMUXhBB5y4h3dyA272k7T7+U3+J4fSBcct0Y8Yur9ziZB/dK8fieEQg5ZPfEGsgOGI+54zTzOUqga6AgmZSNg==
metro-transform-plugins@0.81.0, metro-transform-plugins@^0.81.0:
version "0.81.0"
resolved "https://registry.yarnpkg.com/metro-transform-plugins/-/metro-transform-plugins-0.81.0.tgz#614c0e50593df545487b3f3383fed810c608fb32"
integrity sha512-uErLAPBvttGCrmGSCa0dNHlOTk3uJFVEVWa5WDg6tQ79PRmuYRwzUgLhVzn/9/kyr75eUX3QWXN79Jvu4txt6Q==
dependencies:
"@babel/core" "^7.25.2"
"@babel/generator" "^7.25.0"
@@ -6432,29 +6459,29 @@ metro-transform-plugins@0.81.3, metro-transform-plugins@^0.81.3:
flow-enums-runtime "^0.0.6"
nullthrows "^1.1.1"
metro-transform-worker@0.81.3:
version "0.81.3"
resolved "https://registry.yarnpkg.com/metro-transform-worker/-/metro-transform-worker-0.81.3.tgz#467839d40c12841fe140943a902013ef3118adb2"
integrity sha512-KZqm9sVyBKRygUxRm+yP4DguE9R1EEv28KJhIxghNp5dcdVXBYUPe1xHoc3QVdzD9c3tf8JFzA2FBlKTlwMwNg==
metro-transform-worker@0.81.0:
version "0.81.0"
resolved "https://registry.yarnpkg.com/metro-transform-worker/-/metro-transform-worker-0.81.0.tgz#43e63c95014f36786f0e1a132c778c6392950de7"
integrity sha512-HrQ0twiruhKy0yA+9nK5bIe3WQXZcC66PXTvRIos61/EASLAP2DzEmW7IxN/MGsfZegN2UzqL2CG38+mOB45vg==
dependencies:
"@babel/core" "^7.25.2"
"@babel/generator" "^7.25.0"
"@babel/parser" "^7.25.3"
"@babel/types" "^7.25.2"
flow-enums-runtime "^0.0.6"
metro "0.81.3"
metro-babel-transformer "0.81.3"
metro-cache "0.81.3"
metro-cache-key "0.81.3"
metro-minify-terser "0.81.3"
metro-source-map "0.81.3"
metro-transform-plugins "0.81.3"
metro "0.81.0"
metro-babel-transformer "0.81.0"
metro-cache "0.81.0"
metro-cache-key "0.81.0"
metro-minify-terser "0.81.0"
metro-source-map "0.81.0"
metro-transform-plugins "0.81.0"
nullthrows "^1.1.1"
metro@0.81.3, metro@^0.81.3:
version "0.81.3"
resolved "https://registry.yarnpkg.com/metro/-/metro-0.81.3.tgz#aed8815b45716003aa0cd17387c312c08ed4baf2"
integrity sha512-upilFs7z1uLKvdzFYHiVKrGT/uC7h7d53R0g/FaJoQvLfA8jQG2V69jeOcGi4wCsFYvl1zBSZvKxpQb0nA3giQ==
metro@0.81.0, metro@^0.81.0:
version "0.81.0"
resolved "https://registry.yarnpkg.com/metro/-/metro-0.81.0.tgz#cffe9b7d597728dee8b57903ca155417b7c13a4f"
integrity sha512-kzdzmpL0gKhEthZ9aOV7sTqvg6NuTxDV8SIm9pf9sO8VVEbKrQk5DNcwupOUjgPPFAuKUc2NkT0suyT62hm2xg==
dependencies:
"@babel/code-frame" "^7.24.7"
"@babel/core" "^7.25.2"
@@ -6468,31 +6495,33 @@ metro@0.81.3, metro@^0.81.3:
ci-info "^2.0.0"
connect "^3.6.5"
debug "^2.2.0"
denodeify "^1.2.1"
error-stack-parser "^2.0.6"
flow-enums-runtime "^0.0.6"
graceful-fs "^4.2.4"
hermes-parser "0.25.1"
hermes-parser "0.24.0"
image-size "^1.0.2"
invariant "^2.2.4"
jest-worker "^29.7.0"
jest-worker "^29.6.3"
jsc-safe-url "^0.2.2"
lodash.throttle "^4.1.1"
metro-babel-transformer "0.81.3"
metro-cache "0.81.3"
metro-cache-key "0.81.3"
metro-config "0.81.3"
metro-core "0.81.3"
metro-file-map "0.81.3"
metro-resolver "0.81.3"
metro-runtime "0.81.3"
metro-source-map "0.81.3"
metro-symbolicate "0.81.3"
metro-transform-plugins "0.81.3"
metro-transform-worker "0.81.3"
metro-babel-transformer "0.81.0"
metro-cache "0.81.0"
metro-cache-key "0.81.0"
metro-config "0.81.0"
metro-core "0.81.0"
metro-file-map "0.81.0"
metro-resolver "0.81.0"
metro-runtime "0.81.0"
metro-source-map "0.81.0"
metro-symbolicate "0.81.0"
metro-transform-plugins "0.81.0"
metro-transform-worker "0.81.0"
mime-types "^2.1.27"
nullthrows "^1.1.1"
serialize-error "^2.1.0"
source-map "^0.5.6"
strip-ansi "^6.0.0"
throat "^5.0.0"
ws "^7.5.10"
yargs "^17.6.2"
@@ -6660,6 +6689,11 @@ nocache@^3.0.1:
resolved "https://registry.yarnpkg.com/nocache/-/nocache-3.0.4.tgz#5b37a56ec6e09fc7d401dceaed2eab40c8bfdf79"
integrity sha512-WDD0bdg9mbq6F4mRxEYcPWwfA1vxd0mrvKOyxI7Xj/atfRHVeutzuWByG//jfm4uPzp0y4Kj051EORCBSQMycw==
node-abort-controller@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/node-abort-controller/-/node-abort-controller-3.1.1.tgz#a94377e964a9a37ac3976d848cb5c765833b8548"
integrity sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==
node-cleanup@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/node-cleanup/-/node-cleanup-2.1.2.tgz#7ac19abd297e09a7f72a71545d951b517e4dde2c"
@@ -6760,10 +6794,10 @@ oauth-sign@~0.9.0:
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==
ob1@0.81.3:
version "0.81.3"
resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.81.3.tgz#1b0c5138bc40aeac77bd8b7b9b344e6ad9693c95"
integrity sha512-wd8zdH0DWsn2iDVn2zT/QURihcqoc73K8FhNCmQ16qkJaoYJLNb/N+huOwdCgsbNP8Lk/s1+dPnDETx+RzsrWA==
ob1@0.81.0:
version "0.81.0"
resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.81.0.tgz#dc3154cca7aa9c2eb58f5ac63e9ee23ff4c6f520"
integrity sha512-6Cvrkxt1tqaRdWqTAMcVYEiO5i1xcF9y7t06nFdjFqkfPsEloCf8WwhXdwBpNUkVYSQlSGS7cDgVQR86miBfBQ==
dependencies:
flow-enums-runtime "^0.0.6"
@@ -7086,7 +7120,7 @@ pinpoint@^1.1.0:
resolved "https://registry.yarnpkg.com/pinpoint/-/pinpoint-1.1.0.tgz#0cf7757a6977f1bf7f6a32207b709e377388e874"
integrity sha512-+04FTD9x7Cls2rihLlo57QDCcHoLBGn5Dk51SwtFBWkUWLxZaBXyNVpCw1S+atvE7GmnFjeaRZ0WLq3UYuqAdg==
pirates@^4.0.1, pirates@^4.0.4, pirates@^4.0.6:
pirates@^4.0.1, pirates@^4.0.4, pirates@^4.0.5, pirates@^4.0.6:
version "4.0.6"
resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9"
integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==
@@ -7293,7 +7327,7 @@ react@19.0.0:
resolved "https://registry.yarnpkg.com/react/-/react-19.0.0.tgz#6e1969251b9f108870aa4bff37a0ce9ddfaaabdd"
integrity sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==
readable-stream@^2.0.6:
readable-stream@^2.0.6, readable-stream@~2.3.6:
version "2.3.8"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b"
integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==
@@ -8277,6 +8311,14 @@ throat@^5.0.0:
resolved "https://registry.yarnpkg.com/throat/-/throat-5.0.0.tgz#c5199235803aad18754a667d659b5e72ce16764b"
integrity sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==
through2@^2.0.1:
version "2.0.5"
resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd"
integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==
dependencies:
readable-stream "~2.3.6"
xtend "~4.0.1"
through@^2.3.6:
version "2.3.8"
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"