This commit is contained in:
Yamozha
2021-04-02 02:24:13 +03:00
parent c23950b545
commit 7256d79e2c
31493 changed files with 3036630 additions and 0 deletions

View File

@ -0,0 +1,42 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
* @flow
*/
'use strict';
import NativeSourceCode from '../../NativeModules/specs/NativeSourceCode';
let _cachedDevServerURL: ?string;
const FALLBACK = 'http://localhost:8081/';
type DevServerInfo = {
url: string,
bundleLoadedFromServer: boolean,
...
};
/**
* Many RN development tools rely on the development server (packager) running
* @return URL to packager with trailing slash
*/
function getDevServer(): DevServerInfo {
if (_cachedDevServerURL === undefined) {
const match = NativeSourceCode.getConstants().scriptURL.match(
/^https?:\/\/.*?\//,
);
_cachedDevServerURL = match ? match[0] : null;
}
return {
url: _cachedDevServerURL || FALLBACK,
bundleLoadedFromServer: _cachedDevServerURL !== null,
};
}
module.exports = getDevServer;

View File

@ -0,0 +1,22 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
* @flow strict-local
*/
'use strict';
const getDevServer = require('./getDevServer');
function openFileInEditor(file: string, lineNumber: number) {
fetch(getDevServer().url + 'open-stack-frame', {
method: 'POST',
body: JSON.stringify({file, lineNumber}),
});
}
module.exports = openFileInEditor;

View File

@ -0,0 +1,22 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
* @flow strict-local
*/
'use strict';
const getDevServer = require('./getDevServer');
function openURLInBrowser(url: string) {
fetch(getDevServer().url + 'open-url', {
method: 'POST',
body: JSON.stringify({url}),
});
}
module.exports = openURLInBrowser;

View File

@ -0,0 +1,68 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
* @flow
*/
'use strict';
import type {StackFrame} from '../NativeExceptionsManager';
import type {HermesParsedStack} from './parseHermesStack';
const parseHermesStack = require('./parseHermesStack');
export type ExtendedError = Error & {
jsEngine?: string,
preventSymbolication?: boolean,
componentStack?: string,
forceRedbox?: boolean,
isComponentError?: boolean,
...
};
function convertHermesStack(stack: HermesParsedStack): Array<StackFrame> {
const frames = [];
for (const entry of stack.entries) {
if (entry.type !== 'FRAME') {
continue;
}
const {location, functionName} = entry;
if (location.type === 'NATIVE') {
continue;
}
frames.push({
methodName: functionName,
file: location.sourceUrl,
lineNumber: location.line1Based,
column:
location.type === 'SOURCE'
? location.column1Based - 1
: location.virtualOffset0Based,
});
}
return frames;
}
function parseErrorStack(e: ExtendedError): Array<StackFrame> {
if (!e || !e.stack) {
return [];
}
const stacktraceParser = require('stacktrace-parser');
const stack = Array.isArray(e.stack)
? e.stack
: global.HermesInternal
? convertHermesStack(parseHermesStack(e.stack))
: stacktraceParser.parse(e.stack).map(frame => ({
...frame,
column: frame.column != null ? frame.column - 1 : null,
}));
return stack;
}
module.exports = parseErrorStack;

View File

@ -0,0 +1,120 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
* @flow strict-local
*/
'use strict';
type HermesStackLocationNative = {|
+type: 'NATIVE',
|};
type HermesStackLocationSource = {|
+type: 'SOURCE',
+sourceUrl: string,
+line1Based: number,
+column1Based: number,
|};
type HermesStackLocationBytecode = {|
+type: 'BYTECODE',
+sourceUrl: string,
+line1Based: number,
+virtualOffset0Based: number,
|};
type HermesStackLocation =
| HermesStackLocationNative
| HermesStackLocationSource
| HermesStackLocationBytecode;
type HermesStackEntryFrame = {|
+type: 'FRAME',
+location: HermesStackLocation,
+functionName: string,
|};
type HermesStackEntrySkipped = {|
+type: 'SKIPPED',
+count: number,
|};
type HermesStackEntry = HermesStackEntryFrame | HermesStackEntrySkipped;
export type HermesParsedStack = {|
+message: string,
+entries: $ReadOnlyArray<HermesStackEntry>,
|};
// Capturing groups:
// 1. function name
// 2. is this a native stack frame?
// 3. is this a bytecode address or a source location?
// 4. source URL (filename)
// 5. line number (1 based)
// 6. column number (1 based) or virtual offset (0 based)
const RE_FRAME = /^ {4}at (.+?)(?: \((native)\)?| \((address at )?(.+?):(\d+):(\d+)\))$/;
// Capturing groups:
// 1. count of skipped frames
const RE_SKIPPED = /^ {4}... skipping (\d+) frames$/;
function parseLine(line: string): ?HermesStackEntry {
const asFrame = line.match(RE_FRAME);
if (asFrame) {
return {
type: 'FRAME',
functionName: asFrame[1],
location:
asFrame[2] === 'native'
? {type: 'NATIVE'}
: asFrame[3] === 'address at '
? {
type: 'BYTECODE',
sourceUrl: asFrame[4],
line1Based: Number.parseInt(asFrame[5], 10),
virtualOffset0Based: Number.parseInt(asFrame[6], 10),
}
: {
type: 'SOURCE',
sourceUrl: asFrame[4],
line1Based: Number.parseInt(asFrame[5], 10),
column1Based: Number.parseInt(asFrame[6], 10),
},
};
}
const asSkipped = line.match(RE_SKIPPED);
if (asSkipped) {
return {
type: 'SKIPPED',
count: Number.parseInt(asSkipped[1], 10),
};
}
}
module.exports = function parseHermesStack(stack: string): HermesParsedStack {
const lines = stack.split(/\n/);
let entries = [];
let lastMessageLine = -1;
for (let i = 0; i < lines.length; ++i) {
const line = lines[i];
if (!line) {
continue;
}
const entry = parseLine(line);
if (entry) {
entries.push(entry);
continue;
}
// No match - we're still in the message
lastMessageLine = i;
entries = [];
}
const message = lines.slice(0, lastMessageLine + 1).join('\n');
return {message, entries};
};

View File

@ -0,0 +1,95 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
* @flow
*/
'use strict';
const getDevServer = require('./getDevServer');
import NativeSourceCode from '../../NativeModules/specs/NativeSourceCode';
// Avoid requiring fetch on load of this module; see symbolicateStackTrace
let fetch;
import type {StackFrame} from '../NativeExceptionsManager';
export type CodeFrame = $ReadOnly<{|
content: string,
location: ?{
row: number,
column: number,
...
},
fileName: string,
|}>;
export type SymbolicatedStackTrace = $ReadOnly<{|
stack: Array<StackFrame>,
codeFrame: ?CodeFrame,
|}>;
function isSourcedFromDisk(sourcePath: string): boolean {
return !/^http/.test(sourcePath) && /[\\/]/.test(sourcePath);
}
async function symbolicateStackTrace(
stack: Array<StackFrame>,
): Promise<SymbolicatedStackTrace> {
// RN currently lazy loads whatwg-fetch using a custom fetch module, which,
// when called for the first time, requires and re-exports 'whatwg-fetch'.
// However, when a dependency of the project tries to require whatwg-fetch
// either directly or indirectly, whatwg-fetch is required before
// RN can lazy load whatwg-fetch. As whatwg-fetch checks
// for a fetch polyfill before loading, it will in turn try to load
// RN's fetch module, which immediately tries to import whatwg-fetch AGAIN.
// This causes a circular require which results in RN's fetch module
// exporting fetch as 'undefined'.
// The fix below postpones trying to load fetch until the first call to symbolicateStackTrace.
// At that time, we will have either global.fetch (whatwg-fetch) or RN's fetch.
if (!fetch) {
fetch = global.fetch || require('../../Network/fetch').fetch;
}
const devServer = getDevServer();
if (!devServer.bundleLoadedFromServer) {
throw new Error('Bundle was not loaded from the packager');
}
let stackCopy = stack;
const {scriptURL} = NativeSourceCode.getConstants();
if (scriptURL) {
let foundInternalSource: boolean = false;
stackCopy = stack.map((frame: StackFrame) => {
if (frame.file == null) {
return frame;
}
// If the sources exist on disk rather than appearing to come from the packager,
// replace the location with the packager URL until we reach an internal source
// which does not have a path (no slashes), indicating a switch from within
// the application to a surrounding debugging environment.
if (!foundInternalSource && isSourcedFromDisk(frame.file)) {
// Copy frame into new object and replace 'file' property
return {...frame, file: scriptURL};
}
foundInternalSource = true;
return frame;
});
}
const response = await fetch(devServer.url + 'symbolicate', {
method: 'POST',
body: JSON.stringify({stack: stackCopy}),
});
return await response.json();
}
module.exports = symbolicateStackTrace;

View File

@ -0,0 +1,266 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
* @flow strict-local
*/
'use strict';
import type {ExtendedError} from './Devtools/parseErrorStack';
import * as LogBoxData from '../LogBox/Data/LogBoxData';
import type {ExceptionData} from './NativeExceptionsManager';
class SyntheticError extends Error {
name: string = '';
}
type ExceptionDecorator = ExceptionData => ExceptionData;
let userExceptionDecorator: ?ExceptionDecorator;
let inUserExceptionDecorator = false;
/**
* Allows the app to add information to the exception report before it is sent
* to native. This API is not final.
*/
function unstable_setExceptionDecorator(
exceptionDecorator: ?ExceptionDecorator,
) {
userExceptionDecorator = exceptionDecorator;
}
function preprocessException(data: ExceptionData): ExceptionData {
if (userExceptionDecorator && !inUserExceptionDecorator) {
inUserExceptionDecorator = true;
try {
return userExceptionDecorator(data);
} catch {
// Fall through
} finally {
inUserExceptionDecorator = false;
}
}
return data;
}
/**
* Handles the developer-visible aspect of errors and exceptions
*/
let exceptionID = 0;
function reportException(
e: ExtendedError,
isFatal: boolean,
reportToConsole: boolean, // only true when coming from handleException; the error has not yet been logged
) {
const NativeExceptionsManager = require('./NativeExceptionsManager').default;
if (NativeExceptionsManager) {
const parseErrorStack = require('./Devtools/parseErrorStack');
const stack = parseErrorStack(e);
const currentExceptionID = ++exceptionID;
const originalMessage = e.message || '';
let message = originalMessage;
if (e.componentStack != null) {
message += `\n\nThis error is located at:${e.componentStack}`;
}
const namePrefix = e.name == null || e.name === '' ? '' : `${e.name}: `;
if (!message.startsWith(namePrefix)) {
message = namePrefix + message;
}
message =
e.jsEngine == null ? message : `${message}, js engine: ${e.jsEngine}`;
const isHandledByLogBox = e.forceRedbox !== true;
const data = preprocessException({
message,
originalMessage: message === originalMessage ? null : originalMessage,
name: e.name == null || e.name === '' ? null : e.name,
componentStack:
typeof e.componentStack === 'string' ? e.componentStack : null,
stack,
id: currentExceptionID,
isFatal,
extraData: {
jsEngine: e.jsEngine,
rawStack: e.stack,
// Hack to hide native redboxes when in the LogBox experiment.
// This is intentionally untyped and stuffed here, because it is temporary.
suppressRedBox: isHandledByLogBox,
},
});
if (reportToConsole) {
// we feed back into console.error, to make sure any methods that are
// monkey patched on top of console.error are called when coming from
// handleException
console.error(data.message);
}
if (isHandledByLogBox) {
LogBoxData.addException({
...data,
isComponentError: !!e.isComponentError,
});
}
NativeExceptionsManager.reportException(data);
if (__DEV__) {
if (e.preventSymbolication === true) {
return;
}
const symbolicateStackTrace = require('./Devtools/symbolicateStackTrace');
symbolicateStackTrace(stack)
.then(({stack: prettyStack}) => {
if (prettyStack) {
NativeExceptionsManager.updateExceptionMessage(
data.message,
prettyStack,
currentExceptionID,
);
} else {
throw new Error('The stack is null');
}
})
.catch(error => {
console.log('Unable to symbolicate stack trace: ' + error.message);
});
}
} else if (reportToConsole) {
// we feed back into console.error, to make sure any methods that are
// monkey patched on top of console.error are called when coming from
// handleException
console.error(e);
}
}
declare var console: typeof console & {
_errorOriginal: typeof console.error,
reportErrorsAsExceptions: boolean,
...
};
// If we trigger console.error _from_ handleException,
// we do want to make sure that console.error doesn't trigger error reporting again
let inExceptionHandler = false;
/**
* Logs exceptions to the (native) console and displays them
*/
function handleException(e: mixed, isFatal: boolean) {
let error: Error;
if (e instanceof Error) {
error = e;
} else {
// Workaround for reporting errors caused by `throw 'some string'`
// Unfortunately there is no way to figure out the stacktrace in this
// case, so if you ended up here trying to trace an error, look for
// `throw '<error message>'` somewhere in your codebase.
error = new SyntheticError(e);
}
try {
inExceptionHandler = true;
reportException(error, isFatal, /*reportToConsole*/ true);
} finally {
inExceptionHandler = false;
}
}
function reactConsoleErrorHandler() {
// bubble up to any original handlers
console._errorOriginal.apply(console, arguments);
if (!console.reportErrorsAsExceptions) {
return;
}
if (inExceptionHandler) {
// The fundamental trick here is that are multiple entry point to logging errors:
// (see D19743075 for more background)
//
// 1. An uncaught exception being caught by the global handler
// 2. An error being logged throw console.error
//
// However, console.error is monkey patched multiple times: by this module, and by the
// DevTools setup that sends messages to Metro.
// The patching order cannot be relied upon.
//
// So, some scenarios that are handled by this flag:
//
// Logging an error:
// 1. console.error called from user code
// 2. (possibly) arrives _first_ at DevTool handler, send to Metro
// 3. Bubbles to here
// 4. goes into report Exception.
// 5. should not trigger console.error again, to avoid looping / logging twice
// 6. should still bubble up to original console
// (which might either be console.log, or the DevTools handler in case it patched _earlier_ and (2) didn't happen)
//
// Throwing an uncaught exception:
// 1. exception thrown
// 2. picked up by handleException
// 3. should be send to console.error (not console._errorOriginal, as DevTools might have patched _later_ and it needs to send it to Metro)
// 4. that _might_ bubble again to the `reactConsoleErrorHandle` defined here
// -> should not handle exception _again_, to avoid looping / showing twice (this code branch)
// 5. should still bubble up to original console (which might either be console.log, or the DevTools handler in case that one patched _earlier_)
return;
}
if (arguments[0] && arguments[0].stack) {
// reportException will console.error this with high enough fidelity.
reportException(
arguments[0],
/* isFatal */ false,
/*reportToConsole*/ false,
);
} else {
const stringifySafe = require('../Utilities/stringifySafe').default;
const str = Array.prototype.map
.call(arguments, value =>
typeof value === 'string' ? value : stringifySafe(value),
)
.join(' ');
if (str.slice(0, 9) === 'Warning: ') {
// React warnings use console.error so that a stack trace is shown, but
// we don't (currently) want these to show a redbox
// (Note: Logic duplicated in polyfills/console.js.)
return;
}
const error: ExtendedError = new SyntheticError(str);
error.name = 'console.error';
reportException(error, /* isFatal */ false, /*reportToConsole*/ false);
}
}
/**
* Shows a redbox with stacktrace for all console.error messages. Disable by
* setting `console.reportErrorsAsExceptions = false;` in your app.
*/
function installConsoleErrorReporter() {
// Enable reportErrorsAsExceptions
if (console._errorOriginal) {
return; // already installed
}
// Flow doesn't like it when you set arbitrary values on a global object
console._errorOriginal = console.error.bind(console);
console.error = reactConsoleErrorHandler;
if (console.reportErrorsAsExceptions === undefined) {
// Individual apps can disable this
// Flow doesn't like it when you set arbitrary values on a global object
console.reportErrorsAsExceptions = true;
}
}
module.exports = {
handleException,
installConsoleErrorReporter,
SyntheticError,
unstable_setExceptionDecorator,
};

View File

@ -0,0 +1,56 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
* @flow strict-local
*/
/* globals window: true */
/**
* Sets up global variables typical in most JavaScript environments.
*
* 1. Global timers (via `setTimeout` etc).
* 2. Global console object.
* 3. Hooks for printing stack traces with source maps.
*
* Leaves enough room in the environment for implementing your own:
*
* 1. Require system.
* 2. Bridged modules.
*
*/
'use strict';
const start = Date.now();
require('./setUpGlobals');
require('./setUpPerformance');
require('./setUpSystrace');
require('./setUpErrorHandling');
require('./polyfillPromise');
require('./setUpRegeneratorRuntime');
require('./setUpTimers');
require('./setUpXHR');
require('./setUpAlert');
require('./setUpNavigator');
require('./setUpBatchedBridge');
require('./setUpSegmentFetcher');
if (__DEV__) {
require('./checkNativeVersion');
require('./setUpDeveloperTools');
}
const GlobalPerformanceLogger = require('../Utilities/GlobalPerformanceLogger');
// We could just call GlobalPerformanceLogger.markPoint at the top of the file,
// but then we'd be excluding the time it took to require the logger.
// Instead, we just use Date.now and backdate the timestamp.
GlobalPerformanceLogger.markPoint(
'initializeCore_start',
GlobalPerformanceLogger.currentTimestamp() - (Date.now() - start),
);
GlobalPerformanceLogger.markPoint('initializeCore_end');

View File

@ -0,0 +1,108 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @format
*/
'use strict';
import type {TurboModule} from '../TurboModule/RCTExport';
import * as TurboModuleRegistry from '../TurboModule/TurboModuleRegistry';
export type StackFrame = {|
column: ?number,
file: ?string,
lineNumber: ?number,
methodName: string,
collapse?: boolean,
|};
export type ExceptionData = {
message: string,
originalMessage: ?string,
name: ?string,
componentStack: ?string,
stack: Array<StackFrame>,
id: number,
isFatal: boolean,
// flowlint-next-line unclear-type:off
extraData?: Object,
...
};
export interface Spec extends TurboModule {
// Deprecated: Use `reportException`
+reportFatalException: (
message: string,
stack: Array<StackFrame>,
exceptionId: number,
) => void;
// Deprecated: Use `reportException`
+reportSoftException: (
message: string,
stack: Array<StackFrame>,
exceptionId: number,
) => void;
// TODO(T53311281): This is a noop on iOS now. Implement it.
+reportException?: (data: ExceptionData) => void;
+updateExceptionMessage: (
message: string,
stack: Array<StackFrame>,
exceptionId: number,
) => void;
// TODO(T53311281): This is a noop on iOS now. Implement it.
+dismissRedbox?: () => void;
}
const Platform = require('../Utilities/Platform');
const NativeModule = TurboModuleRegistry.getEnforcing<Spec>(
'ExceptionsManager',
);
const ExceptionsManager = {
reportFatalException(
message: string,
stack: Array<StackFrame>,
exceptionId: number,
) {
NativeModule.reportFatalException(message, stack, exceptionId);
},
reportSoftException(
message: string,
stack: Array<StackFrame>,
exceptionId: number,
) {
NativeModule.reportSoftException(message, stack, exceptionId);
},
updateExceptionMessage(
message: string,
stack: Array<StackFrame>,
exceptionId: number,
) {
NativeModule.updateExceptionMessage(message, stack, exceptionId);
},
dismissRedbox(): void {
if (Platform.OS !== 'ios' && NativeModule.dismissRedbox) {
// TODO(T53311281): This is a noop on iOS now. Implement it.
NativeModule.dismissRedbox();
}
},
reportException(data: ExceptionData): void {
if (NativeModule.reportException) {
NativeModule.reportException(data);
return;
}
if (data.isFatal) {
ExceptionsManager.reportFatalException(data.message, data.stack, data.id);
} else {
ExceptionsManager.reportSoftException(data.message, data.stack, data.id);
}
},
};
export default ExceptionsManager;

View File

@ -0,0 +1,52 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
* @flow strict-local
*/
export type CapturedError = {
+componentStack: string,
+error: mixed,
+errorBoundary: ?{...},
...
};
import type {ExtendedError} from './Devtools/parseErrorStack';
import {handleException, SyntheticError} from './ExceptionsManager';
/**
* Intercept lifecycle errors and ensure they are shown with the correct stack
* trace within the native redbox component.
*/
function showErrorDialog(capturedError: CapturedError): boolean {
const {componentStack, error} = capturedError;
let errorToHandle;
// Typically Errors are thrown but eg strings or null can be thrown as well.
if (error instanceof Error) {
errorToHandle = (error: ExtendedError);
} else if (typeof error === 'string') {
errorToHandle = (new SyntheticError(error): ExtendedError);
} else {
errorToHandle = (new SyntheticError('Unspecified error'): ExtendedError);
}
try {
errorToHandle.componentStack = componentStack;
errorToHandle.isComponentError = true;
} catch (e) {}
handleException(errorToHandle, false);
// Return false here to prevent ReactFiberErrorLogger default behavior of
// logging error details to console.error. Calls to console.error are
// automatically routed to the native redbox controller, which we've already
// done above by calling ExceptionsManager.
return false;
}
module.exports = {showErrorDialog};

View File

@ -0,0 +1,17 @@
/**
* @generated by scripts/bump-oss-version.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/
exports.version = {
major: 0,
minor: 63,
patch: 4,
prerelease: null,
};

View File

@ -0,0 +1,49 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @format
*/
'use strict';
import Platform from '../Utilities/Platform';
const ReactNativeVersion = require('./ReactNativeVersion');
/**
* Checks that the version of this React Native JS is compatible with the native
* code, throwing an error if it isn't.
*
* The existence of this module is part of the public interface of React Native
* even though it is used only internally within React Native. React Native
* implementations for other platforms (ex: Windows) may override this module
* and rely on its existence as a separate module.
*/
exports.checkVersions = function checkVersions(): void {
const nativeVersion = Platform.constants.reactNativeVersion;
if (
ReactNativeVersion.version.major !== nativeVersion.major ||
ReactNativeVersion.version.minor !== nativeVersion.minor
) {
console.error(
`React Native version mismatch.\n\nJavaScript version: ${_formatVersion(
ReactNativeVersion.version,
)}\n` +
`Native version: ${_formatVersion(nativeVersion)}\n\n` +
'Make sure that you have rebuilt the native code. If the problem ' +
'persists try clearing the Watchman and packager caches with ' +
'`watchman watch-del-all && react-native start --reset-cache`.',
);
}
};
function _formatVersion(version): string {
return (
`${version.major}.${version.minor}.${version.patch}` +
// eslint-disable-next-line eqeqeq
(version.prerelease != undefined ? `-${version.prerelease}` : '')
);
}

View File

@ -0,0 +1,29 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @format
*/
'use strict';
import type {TurboModule} from '../../TurboModule/RCTExport';
import * as TurboModuleRegistry from '../../TurboModule/TurboModuleRegistry';
export interface Spec extends TurboModule {
+fetchSegment: (
segmentId: number,
options: Object, // flowlint-line unclear-type: off
callback: (error: ?Object) => void, // flowlint-line unclear-type: off
) => void;
+getSegment?: (
segmentId: number,
options: Object, // flowlint-line unclear-type: off
callback: (error: ?Object, path: ?string) => void, // flowlint-line unclear-type: off
) => void;
}
export default (TurboModuleRegistry.getEnforcing<Spec>('SegmentFetcher'): Spec);

View File

@ -0,0 +1,513 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
* @flow
*/
'use strict';
const BatchedBridge = require('../../BatchedBridge/BatchedBridge');
const Platform = require('../../Utilities/Platform');
const Systrace = require('../../Performance/Systrace');
const invariant = require('invariant');
import NativeTiming from './NativeTiming';
let _performanceNow = null;
function performanceNow() {
if (!_performanceNow) {
_performanceNow = require('fbjs/lib/performanceNow');
}
return _performanceNow();
}
/**
* JS implementation of timer functions. Must be completely driven by an
* external clock signal, all that's stored here is timerID, timer type, and
* callback.
*/
export type JSTimerType =
| 'setTimeout'
| 'setInterval'
| 'requestAnimationFrame'
| 'setImmediate'
| 'requestIdleCallback';
// These timing constants should be kept in sync with the ones in native ios and
// android `RCTTiming` module.
const FRAME_DURATION = 1000 / 60;
const IDLE_CALLBACK_FRAME_DEADLINE = 1;
const MAX_TIMER_DURATION_MS = 60 * 1000;
const IS_ANDROID = Platform.OS === 'android';
const ANDROID_LONG_TIMER_MESSAGE =
'Setting a timer for a long period of time, i.e. multiple minutes, is a ' +
'performance and correctness issue on Android as it keeps the timer ' +
'module awake, and timers can only be called when the app is in the foreground. ' +
'See https://github.com/facebook/react-native/issues/12981 for more info.';
// Parallel arrays
const callbacks: Array<?Function> = [];
const types: Array<?JSTimerType> = [];
const timerIDs: Array<?number> = [];
let immediates: Array<number> = [];
let requestIdleCallbacks: Array<number> = [];
const requestIdleCallbackTimeouts: {[number]: number, ...} = {};
let GUID = 1;
let errors: ?Array<Error> = null;
let hasEmittedTimeDriftWarning = false;
// Returns a free index if one is available, and the next consecutive index otherwise.
function _getFreeIndex(): number {
let freeIndex = timerIDs.indexOf(null);
if (freeIndex === -1) {
freeIndex = timerIDs.length;
}
return freeIndex;
}
function _allocateCallback(func: Function, type: JSTimerType): number {
const id = GUID++;
const freeIndex = _getFreeIndex();
timerIDs[freeIndex] = id;
callbacks[freeIndex] = func;
types[freeIndex] = type;
return id;
}
/**
* Calls the callback associated with the ID. Also unregister that callback
* if it was a one time timer (setTimeout), and not unregister it if it was
* recurring (setInterval).
*/
function _callTimer(timerID: number, frameTime: number, didTimeout: ?boolean) {
require('fbjs/lib/warning')(
timerID <= GUID,
'Tried to call timer with ID %s but no such timer exists.',
timerID,
);
// timerIndex of -1 means that no timer with that ID exists. There are
// two situations when this happens, when a garbage timer ID was given
// and when a previously existing timer was deleted before this callback
// fired. In both cases we want to ignore the timer id, but in the former
// case we warn as well.
const timerIndex = timerIDs.indexOf(timerID);
if (timerIndex === -1) {
return;
}
const type = types[timerIndex];
const callback = callbacks[timerIndex];
if (!callback || !type) {
console.error('No callback found for timerID ' + timerID);
return;
}
if (__DEV__) {
Systrace.beginEvent(type + ' [invoke]');
}
// Clear the metadata
if (type !== 'setInterval') {
_clearIndex(timerIndex);
}
try {
if (
type === 'setTimeout' ||
type === 'setInterval' ||
type === 'setImmediate'
) {
callback();
} else if (type === 'requestAnimationFrame') {
callback(performanceNow());
} else if (type === 'requestIdleCallback') {
callback({
timeRemaining: function() {
// TODO: Optimisation: allow running for longer than one frame if
// there are no pending JS calls on the bridge from native. This
// would require a way to check the bridge queue synchronously.
return Math.max(0, FRAME_DURATION - (performanceNow() - frameTime));
},
didTimeout: !!didTimeout,
});
} else {
console.error('Tried to call a callback with invalid type: ' + type);
}
} catch (e) {
// Don't rethrow so that we can run all timers.
if (!errors) {
errors = [e];
} else {
errors.push(e);
}
}
if (__DEV__) {
Systrace.endEvent();
}
}
/**
* Performs a single pass over the enqueued immediates. Returns whether
* more immediates are queued up (can be used as a condition a while loop).
*/
function _callImmediatesPass() {
if (immediates.length === 0) {
return false;
}
if (__DEV__) {
Systrace.beginEvent('callImmediatesPass()');
}
// The main reason to extract a single pass is so that we can track
// in the system trace
const passImmediates = immediates;
immediates = [];
// Use for loop rather than forEach as per @vjeux's advice
// https://github.com/facebook/react-native/commit/c8fd9f7588ad02d2293cac7224715f4af7b0f352#commitcomment-14570051
for (let i = 0; i < passImmediates.length; ++i) {
_callTimer(passImmediates[i], 0);
}
if (__DEV__) {
Systrace.endEvent();
}
return immediates.length > 0;
}
function _clearIndex(i: number) {
timerIDs[i] = null;
callbacks[i] = null;
types[i] = null;
}
function _freeCallback(timerID: number) {
// timerIDs contains nulls after timers have been removed;
// ignore nulls upfront so indexOf doesn't find them
if (timerID == null) {
return;
}
const index = timerIDs.indexOf(timerID);
// See corresponding comment in `callTimers` for reasoning behind this
if (index !== -1) {
const type = types[index];
_clearIndex(index);
if (type !== 'setImmediate' && type !== 'requestIdleCallback') {
deleteTimer(timerID);
}
}
}
/**
* JS implementation of timer functions. Must be completely driven by an
* external clock signal, all that's stored here is timerID, timer type, and
* callback.
*/
const JSTimers = {
/**
* @param {function} func Callback to be invoked after `duration` ms.
* @param {number} duration Number of milliseconds.
*/
setTimeout: function(func: Function, duration: number, ...args: any): number {
if (__DEV__ && IS_ANDROID && duration > MAX_TIMER_DURATION_MS) {
console.warn(
ANDROID_LONG_TIMER_MESSAGE +
'\n' +
'(Saw setTimeout with duration ' +
duration +
'ms)',
);
}
const id = _allocateCallback(
() => func.apply(undefined, args),
'setTimeout',
);
createTimer(id, duration || 0, Date.now(), /* recurring */ false);
return id;
},
/**
* @param {function} func Callback to be invoked every `duration` ms.
* @param {number} duration Number of milliseconds.
*/
setInterval: function(
func: Function,
duration: number,
...args: any
): number {
if (__DEV__ && IS_ANDROID && duration > MAX_TIMER_DURATION_MS) {
console.warn(
ANDROID_LONG_TIMER_MESSAGE +
'\n' +
'(Saw setInterval with duration ' +
duration +
'ms)',
);
}
const id = _allocateCallback(
() => func.apply(undefined, args),
'setInterval',
);
createTimer(id, duration || 0, Date.now(), /* recurring */ true);
return id;
},
/**
* @param {function} func Callback to be invoked before the end of the
* current JavaScript execution loop.
*/
setImmediate: function(func: Function, ...args: any) {
const id = _allocateCallback(
() => func.apply(undefined, args),
'setImmediate',
);
immediates.push(id);
return id;
},
/**
* @param {function} func Callback to be invoked every frame.
*/
requestAnimationFrame: function(func: Function) {
const id = _allocateCallback(func, 'requestAnimationFrame');
createTimer(id, 1, Date.now(), /* recurring */ false);
return id;
},
/**
* @param {function} func Callback to be invoked every frame and provided
* with time remaining in frame.
* @param {?object} options
*/
requestIdleCallback: function(func: Function, options: ?Object) {
if (requestIdleCallbacks.length === 0) {
setSendIdleEvents(true);
}
const timeout = options && options.timeout;
const id = _allocateCallback(
timeout != null
? deadline => {
const timeoutId = requestIdleCallbackTimeouts[id];
if (timeoutId) {
JSTimers.clearTimeout(timeoutId);
delete requestIdleCallbackTimeouts[id];
}
return func(deadline);
}
: func,
'requestIdleCallback',
);
requestIdleCallbacks.push(id);
if (timeout != null) {
const timeoutId = JSTimers.setTimeout(() => {
const index = requestIdleCallbacks.indexOf(id);
if (index > -1) {
requestIdleCallbacks.splice(index, 1);
_callTimer(id, performanceNow(), true);
}
delete requestIdleCallbackTimeouts[id];
if (requestIdleCallbacks.length === 0) {
setSendIdleEvents(false);
}
}, timeout);
requestIdleCallbackTimeouts[id] = timeoutId;
}
return id;
},
cancelIdleCallback: function(timerID: number) {
_freeCallback(timerID);
const index = requestIdleCallbacks.indexOf(timerID);
if (index !== -1) {
requestIdleCallbacks.splice(index, 1);
}
const timeoutId = requestIdleCallbackTimeouts[timerID];
if (timeoutId) {
JSTimers.clearTimeout(timeoutId);
delete requestIdleCallbackTimeouts[timerID];
}
if (requestIdleCallbacks.length === 0) {
setSendIdleEvents(false);
}
},
clearTimeout: function(timerID: number) {
_freeCallback(timerID);
},
clearInterval: function(timerID: number) {
_freeCallback(timerID);
},
clearImmediate: function(timerID: number) {
_freeCallback(timerID);
const index = immediates.indexOf(timerID);
if (index !== -1) {
immediates.splice(index, 1);
}
},
cancelAnimationFrame: function(timerID: number) {
_freeCallback(timerID);
},
/**
* This is called from the native side. We are passed an array of timerIDs,
* and
*/
callTimers: function(timersToCall: Array<number>) {
invariant(
timersToCall.length !== 0,
'Cannot call `callTimers` with an empty list of IDs.',
);
errors = (null: ?Array<Error>);
for (let i = 0; i < timersToCall.length; i++) {
_callTimer(timersToCall[i], 0);
}
if (errors) {
const errorCount = errors.length;
if (errorCount > 1) {
// Throw all the other errors in a setTimeout, which will throw each
// error one at a time
for (let ii = 1; ii < errorCount; ii++) {
JSTimers.setTimeout(
(error => {
throw error;
}).bind(null, errors[ii]),
0,
);
}
}
throw errors[0];
}
},
callIdleCallbacks: function(frameTime: number) {
if (
FRAME_DURATION - (performanceNow() - frameTime) <
IDLE_CALLBACK_FRAME_DEADLINE
) {
return;
}
errors = (null: ?Array<Error>);
if (requestIdleCallbacks.length > 0) {
const passIdleCallbacks = requestIdleCallbacks;
requestIdleCallbacks = [];
for (let i = 0; i < passIdleCallbacks.length; ++i) {
_callTimer(passIdleCallbacks[i], frameTime);
}
}
if (requestIdleCallbacks.length === 0) {
setSendIdleEvents(false);
}
if (errors) {
errors.forEach(error =>
JSTimers.setTimeout(() => {
throw error;
}, 0),
);
}
},
/**
* This is called after we execute any command we receive from native but
* before we hand control back to native.
*/
callImmediates() {
errors = (null: ?Array<Error>);
while (_callImmediatesPass()) {}
if (errors) {
errors.forEach(error =>
JSTimers.setTimeout(() => {
throw error;
}, 0),
);
}
},
/**
* Called from native (in development) when environment times are out-of-sync.
*/
emitTimeDriftWarning(warningMessage: string) {
if (hasEmittedTimeDriftWarning) {
return;
}
hasEmittedTimeDriftWarning = true;
console.warn(warningMessage);
},
};
function createTimer(
callbackID: number,
duration: number,
jsSchedulingTime: number,
repeats: boolean,
): void {
invariant(NativeTiming, 'NativeTiming is available');
NativeTiming.createTimer(callbackID, duration, jsSchedulingTime, repeats);
}
function deleteTimer(timerID: number): void {
invariant(NativeTiming, 'NativeTiming is available');
NativeTiming.deleteTimer(timerID);
}
function setSendIdleEvents(sendIdleEvents: boolean): void {
invariant(NativeTiming, 'NativeTiming is available');
NativeTiming.setSendIdleEvents(sendIdleEvents);
}
let ExportedJSTimers: {|
callIdleCallbacks: (frameTime: number) => any | void,
callImmediates: () => void,
callTimers: (timersToCall: Array<number>) => any | void,
cancelAnimationFrame: (timerID: number) => void,
cancelIdleCallback: (timerID: number) => void,
clearImmediate: (timerID: number) => void,
clearInterval: (timerID: number) => void,
clearTimeout: (timerID: number) => void,
emitTimeDriftWarning: (warningMessage: string) => any | void,
requestAnimationFrame: (func: any) => any | number,
requestIdleCallback: (func: any, options: ?any) => any | number,
setImmediate: (func: any, ...args: any) => number,
setInterval: (func: any, duration: number, ...args: any) => number,
setTimeout: (func: any, duration: number, ...args: any) => number,
|};
if (!NativeTiming) {
console.warn("Timing native module is not available, can't set timers.");
// $FlowFixMe: we can assume timers are generally available
ExportedJSTimers = ({
callImmediates: JSTimers.callImmediates,
setImmediate: JSTimers.setImmediate,
}: typeof JSTimers);
} else {
ExportedJSTimers = JSTimers;
}
BatchedBridge.setImmediatesCallback(JSTimers.callImmediates);
module.exports = ExportedJSTimers;

View File

@ -0,0 +1,27 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @format
*/
'use strict';
import type {TurboModule} from '../../TurboModule/RCTExport';
import * as TurboModuleRegistry from '../../TurboModule/TurboModuleRegistry';
export interface Spec extends TurboModule {
+createTimer: (
callbackID: number,
duration: number,
jsSchedulingTime: number,
repeats: boolean,
) => void;
+deleteTimer: (timerID: number) => void;
+setSendIdleEvents: (sendIdleEvents: boolean) => void;
}
export default (TurboModuleRegistry.get<Spec>('Timing'): ?Spec);

View File

@ -0,0 +1,33 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
// This mock only provides short-circuited methods of applyWithGuard and guard.
// A lot of modules rely on these two functions. This mock relieves their tests
// from depending on the real ErrorUtils module. If you need real error handling
// don't use this mock.
'use strict';
function execute(fun, context, args) {
return fun.apply(context, args);
}
function reportError(error) {
throw error;
}
const ErrorUtils = {
apply: jest.fn(execute),
applyWithGuard: jest.fn(execute),
guard: jest.fn(callback => callback),
inGuard: jest.fn().mockReturnValue(true),
reportError: jest.fn(reportError),
setGlobalHandler: jest.fn(),
};
module.exports = ErrorUtils;

View File

@ -0,0 +1,18 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @format
*/
'use strict';
/**
* Check for compatibility between the JS and native code.
* You can use this module directly, or just require InitializeCore.
*/
const ReactNativeVersionCheck = require('./ReactNativeVersionCheck');
ReactNativeVersionCheck.checkVersions();

View File

@ -0,0 +1,22 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @format
*/
'use strict';
const {polyfillGlobal} = require('../Utilities/PolyfillFunctions');
/**
* Set up Promise. The native Promise implementation throws the following error:
* ERROR: Event loop not supported.
*
* If you don't need these polyfills, don't use InitializeCore; just directly
* require the modules you need from InitializeCore for setup.
*/
polyfillGlobal('Promise', () => require('../Promise'));

23
node_modules/react-native/Libraries/Core/setUpAlert.js generated vendored Normal file
View File

@ -0,0 +1,23 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @format
*/
'use strict';
/**
* Set up alert().
* You can use this module directly, or just require InitializeCore.
*/
if (!global.alert) {
global.alert = function(text) {
// Require Alert on demand. Requiring it too early can lead to issues
// with things like Platform not being fully initialized.
require('../Alert/Alert').alert('Alert', '' + text);
};
}

View File

@ -0,0 +1,46 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @format
*/
'use strict';
let registerModule;
if (global.RN$Bridgeless && global.RN$registerCallableModule) {
registerModule = global.RN$registerCallableModule;
} else {
const BatchedBridge = require('../BatchedBridge/BatchedBridge');
registerModule = (moduleName, factory) =>
BatchedBridge.registerLazyCallableModule(moduleName, factory);
}
registerModule('Systrace', () => require('../Performance/Systrace'));
registerModule('JSTimers', () => require('./Timers/JSTimers'));
registerModule('HeapCapture', () => require('../HeapCapture/HeapCapture'));
registerModule('SamplingProfiler', () =>
require('../Performance/SamplingProfiler'),
);
registerModule('RCTLog', () => require('../Utilities/RCTLog'));
registerModule('RCTDeviceEventEmitter', () =>
require('../EventEmitter/RCTDeviceEventEmitter'),
);
registerModule('RCTNativeAppEventEmitter', () =>
require('../EventEmitter/RCTNativeAppEventEmitter'),
);
registerModule('GlobalPerformanceLogger', () =>
require('../Utilities/GlobalPerformanceLogger'),
);
registerModule('JSDevSupportModule', () =>
require('../Utilities/JSDevSupportModule'),
);
if (__DEV__ && !global.__RCTProfileIsProfiling) {
registerModule('HMRClient', () => require('../Utilities/HMRClient'));
} else {
registerModule('HMRClient', () => require('../Utilities/HMRClientProdShim'));
}

View File

@ -0,0 +1,84 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @format
*/
'use strict';
import Platform from '../Utilities/Platform';
declare var console: typeof console & {_isPolyfilled: boolean, ...};
/**
* Sets up developer tools for React Native.
* You can use this module directly, or just require InitializeCore.
*/
if (__DEV__) {
// TODO (T45803484) Enable devtools for bridgeless RN
if (!global.RN$Bridgeless) {
if (!global.__RCTProfileIsProfiling) {
require('./setUpReactDevTools');
// Set up inspector
const JSInspector = require('../JSInspector/JSInspector');
JSInspector.registerAgent(require('../JSInspector/NetworkAgent'));
}
// Note we can't check if console is "native" because it would appear "native" in JSC and Hermes.
// We also can't check any properties that don't exist in the Chrome worker environment.
// So we check a navigator property that's set to a particular value ("Netscape") in all real browsers.
const isLikelyARealBrowser =
global.navigator != null &&
/* _
* | |
* _ __ ___| |_ ___ ___ __ _ _ __ ___
* | '_ \ / _ \ __/ __|/ __/ _` | '_ \ / _ \
* | | | | __/ |_\__ \ (_| (_| | |_) | __/
* |_| |_|\___|\__|___/\___\__,_| .__/ \___|
* | |
* |_|
*/
global.navigator.appName === 'Netscape'; // Any real browser
if (!Platform.isTesting) {
const HMRClient = require('../Utilities/HMRClient');
if (console._isPolyfilled) {
// We assume full control over the console and send JavaScript logs to Metro.
[
'trace',
'info',
'warn',
'error',
'log',
'group',
'groupCollapsed',
'groupEnd',
'debug',
].forEach(level => {
const originalFunction = console[level];
console[level] = function(...args) {
HMRClient.log(level, args);
originalFunction.apply(console, args);
};
});
} else {
// We assume the environment has a real rich console (like Chrome), and don't hijack it to log to Metro.
// It's likely the developer is using rich console to debug anyway, and hijacking it would
// lose the filenames in console.log calls: https://github.com/facebook/react-native/issues/26788.
HMRClient.log('log', [
`JavaScript logs will appear in your ${
isLikelyARealBrowser ? 'browser' : 'environment'
} console`,
]);
}
}
require('./setUpReactRefresh');
}
}

View File

@ -0,0 +1,33 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @format
*/
'use strict';
/**
* Sets up the console and exception handling (redbox) for React Native.
* You can use this module directly, or just require InitializeCore.
*/
const ExceptionsManager = require('./ExceptionsManager');
ExceptionsManager.installConsoleErrorReporter();
// Set up error handler
if (!global.__fbDisableExceptionsManager) {
const handleError = (e, isFatal) => {
try {
ExceptionsManager.handleException(e, isFatal);
} catch (ee) {
console.log('Failed to print error: ', ee.message);
throw e;
}
};
const ErrorUtils = require('../vendor/core/ErrorUtils');
ErrorUtils.setGlobalHandler(handleError);
}

View File

@ -0,0 +1,34 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @format
*/
'use strict';
/**
* Sets up global variables for React Native.
* You can use this module directly, or just require InitializeCore.
*/
if (global.GLOBAL === undefined) {
global.GLOBAL = global;
}
if (global.window === undefined) {
global.window = global;
}
if (global.self === undefined) {
global.self = global;
}
// Set up process
global.process = global.process || {};
global.process.env = global.process.env || {};
if (!global.process.env.NODE_ENV) {
global.process.env.NODE_ENV = __DEV__ ? 'development' : 'production';
}

View File

@ -0,0 +1,21 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @format
*/
'use strict';
const {polyfillObjectProperty} = require('../Utilities/PolyfillFunctions');
let navigator = global.navigator;
if (navigator === undefined) {
global.navigator = navigator = {};
}
// see https://github.com/facebook/react-native/issues/10881
polyfillObjectProperty(navigator, 'product', () => 'ReactNative');

View File

@ -0,0 +1,26 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @format
*/
'use strict';
if (!global.performance) {
global.performance = {};
}
/**
* Returns a double, measured in milliseconds.
* https://developer.mozilla.org/en-US/docs/Web/API/Performance/now
*/
if (typeof global.performance.now !== 'function') {
global.performance.now = function() {
const performanceNow = global.nativePerformanceNow || Date.now;
return performanceNow();
};
}

View File

@ -0,0 +1,59 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
* @format
*/
'use strict';
if (__DEV__) {
const reactDevTools = require('react-devtools-core');
const connectToDevTools = () => {
// not when debugging in chrome
// TODO(t12832058) This check is broken
if (!window.document) {
const AppState = require('../AppState/AppState');
const getDevServer = require('./Devtools/getDevServer');
// Don't steal the DevTools from currently active app.
// Note: if you add any AppState subscriptions to this file,
// you will also need to guard against `AppState.isAvailable`,
// or the code will throw for bundles that don't have it.
const isAppActive = () => AppState.currentState !== 'background';
// Get hostname from development server (packager)
const devServer = getDevServer();
const host = devServer.bundleLoadedFromServer
? devServer.url.replace(/https?:\/\//, '').split(':')[0]
: 'localhost';
// Read the optional global variable for backward compatibility.
// It was added in https://github.com/facebook/react-native/commit/bf2b435322e89d0aeee8792b1c6e04656c2719a0.
const port =
window.__REACT_DEVTOOLS_PORT__ != null
? window.__REACT_DEVTOOLS_PORT__
: 8097;
const WebSocket = require('../WebSocket/WebSocket');
const ws = new WebSocket('ws://' + host + ':' + port);
const viewConfig = require('../Components/View/ReactNativeViewViewConfig');
reactDevTools.connectToDevTools({
isAppActive,
resolveRNStyle: require('../StyleSheet/flattenStyle'),
nativeStyleEditorValidAttributes: Object.keys(
viewConfig.validAttributes.style,
),
websocket: ws,
});
}
};
const RCTNativeAppEventEmitter = require('../EventEmitter/RCTNativeAppEventEmitter');
RCTNativeAppEventEmitter.addListener('RCTDevMenuShown', connectToDevTools);
connectToDevTools(); // Try connecting once on load
}

View File

@ -0,0 +1,49 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
* @format
*/
'use strict';
if (__DEV__) {
const DevSettings = require('../Utilities/DevSettings');
if (typeof DevSettings.reload !== 'function') {
throw new Error('Could not find the reload() implementation.');
}
// This needs to run before the renderer initializes.
const ReactRefreshRuntime = require('react-refresh/runtime');
ReactRefreshRuntime.injectIntoGlobalHook(global);
const Refresh = {
performFullRefresh(reason: string) {
DevSettings.reload(reason);
},
createSignatureFunctionForTransform:
ReactRefreshRuntime.createSignatureFunctionForTransform,
isLikelyComponentType: ReactRefreshRuntime.isLikelyComponentType,
getFamilyByType: ReactRefreshRuntime.getFamilyByType,
register: ReactRefreshRuntime.register,
performReactRefresh() {
if (ReactRefreshRuntime.hasUnrecoverableErrors()) {
DevSettings.reload('Fast Refresh - Unrecoverable');
return;
}
ReactRefreshRuntime.performReactRefresh();
DevSettings.onFastRefresh();
},
};
(require: any).Refresh = Refresh;
}

View File

@ -0,0 +1,27 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @format
*/
'use strict';
const {polyfillGlobal} = require('../Utilities/PolyfillFunctions');
/**
* Set up regenerator.
* You can use this module directly, or just require InitializeCore.
*/
polyfillGlobal('regeneratorRuntime', () => {
// The require just sets up the global, so make sure when we first
// invoke it the global does not exist
delete global.regeneratorRuntime;
// regenerator-runtime/runtime exports the regeneratorRuntime object, so we
// can return it safely.
return require('regenerator-runtime/runtime'); // flowlint-line untyped-import:off
});

View File

@ -0,0 +1,91 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @format
*/
'use strict';
export type FetchSegmentFunction = typeof __fetchSegment;
export type GetSegmentFunction = typeof __getSegment;
/**
* Set up SegmentFetcher.
* You can use this module directly, or just require InitializeCore.
*/
function __fetchSegment(
segmentId: number,
options: {|
+otaBuildNumber: ?string,
+requestedModuleName?: ?string,
|},
callback: (?Error) => void,
) {
const SegmentFetcher = require('./SegmentFetcher/NativeSegmentFetcher')
.default;
SegmentFetcher.fetchSegment(
segmentId,
options,
(
errorObject: ?{
message: string,
code: string,
...
},
) => {
if (errorObject) {
const error = new Error(errorObject.message);
(error: any).code = errorObject.code; // flowlint-line unclear-type: off
callback(error);
}
callback(null);
},
);
}
global.__fetchSegment = __fetchSegment;
function __getSegment(
segmentId: number,
options: {|
+otaBuildNumber: ?string,
+requestedModuleName?: ?string,
|},
callback: (?Error, ?string) => void,
) {
const SegmentFetcher = require('./SegmentFetcher/NativeSegmentFetcher')
.default;
if (!SegmentFetcher.getSegment) {
throw new Error('SegmentFetcher.getSegment must be defined');
}
SegmentFetcher.getSegment(
segmentId,
options,
(
errorObject: ?{
message: string,
code: string,
...
},
path: ?string,
) => {
if (errorObject) {
const error = new Error(errorObject.message);
(error: any).code = errorObject.code; // flowlint-line unclear-type: off
callback(error);
}
callback(null, path);
},
);
}
global.__getSegment = __getSegment;

View File

@ -0,0 +1,21 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @format
*/
'use strict';
/**
* Set up Systrace profiling hooks if necessary.
* You can use this module directly, or just require InitializeCore.
*/
if (global.__RCTProfileIsProfiling) {
const Systrace = require('../Performance/Systrace');
Systrace.installReactHook();
Systrace.setEnabled(true);
}

View File

@ -0,0 +1,34 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @format
*/
'use strict';
// In bridgeless mode, timers are host functions installed from cpp.
if (!global.RN$Bridgeless) {
const {polyfillGlobal} = require('../Utilities/PolyfillFunctions');
/**
* Set up timers.
* You can use this module directly, or just require InitializeCore.
*/
const defineLazyTimer = name => {
polyfillGlobal(name, () => require('./Timers/JSTimers')[name]);
};
defineLazyTimer('setTimeout');
defineLazyTimer('setInterval');
defineLazyTimer('setImmediate');
defineLazyTimer('clearTimeout');
defineLazyTimer('clearInterval');
defineLazyTimer('clearImmediate');
defineLazyTimer('requestAnimationFrame');
defineLazyTimer('cancelAnimationFrame');
defineLazyTimer('requestIdleCallback');
defineLazyTimer('cancelIdleCallback');
}

41
node_modules/react-native/Libraries/Core/setUpXHR.js generated vendored Normal file
View File

@ -0,0 +1,41 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @format
*/
'use strict';
const {polyfillGlobal} = require('../Utilities/PolyfillFunctions');
/**
* Set up XMLHttpRequest. The native XMLHttpRequest in Chrome dev tools is CORS
* aware and won't let you fetch anything from the internet.
*
* You can use this module directly, or just require InitializeCore.
*/
polyfillGlobal('XMLHttpRequest', () => require('../Network/XMLHttpRequest'));
polyfillGlobal('FormData', () => require('../Network/FormData'));
polyfillGlobal('fetch', () => require('../Network/fetch').fetch); // flowlint-line untyped-import:off
polyfillGlobal('Headers', () => require('../Network/fetch').Headers); // flowlint-line untyped-import:off
polyfillGlobal('Request', () => require('../Network/fetch').Request); // flowlint-line untyped-import:off
polyfillGlobal('Response', () => require('../Network/fetch').Response); // flowlint-line untyped-import:off
polyfillGlobal('WebSocket', () => require('../WebSocket/WebSocket'));
polyfillGlobal('Blob', () => require('../Blob/Blob'));
polyfillGlobal('File', () => require('../Blob/File'));
polyfillGlobal('FileReader', () => require('../Blob/FileReader'));
polyfillGlobal('URL', () => require('../Blob/URL').URL); // flowlint-line untyped-import:off
polyfillGlobal('URLSearchParams', () => require('../Blob/URL').URLSearchParams); // flowlint-line untyped-import:off
polyfillGlobal(
'AbortController',
() => require('abort-controller/dist/abort-controller').AbortController, // flowlint-line untyped-import:off
);
polyfillGlobal(
'AbortSignal',
() => require('abort-controller/dist/abort-controller').AbortSignal, // flowlint-line untyped-import:off
);