mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/48889 ## Motivation Modernising the react-native codebase to allow for ingestion by modern Flow tooling. ## This diff - Updates files in `Libraries/Core` to use `export` syntax - `export default` for qualified objects, many `export` statements for collections - Appends `.default` to requires of the changed files. - Changed `* as ExceptionsManager` to `ExceptionsManager` in import statements throughout product code. - Updates test files. - Updates the public API snapshot (intented breaking change) Changelog: [General][Breaking] - Files inside `Libraries/Core` use `export` syntax, which requires the addition of `.default` when imported with the CJS `require` syntax. [General][Breaking] - `Libraries/Core/ExceptionsManager` now exports a default `ExceptionsManager` object, and `SyntheticError` as a secondary export. Reviewed By: huntie Differential Revision: D68553694 fbshipit-source-id: 51c9a404b2762cb1cdb5f56cae3a683ccdfffc7f
155 lines
4.1 KiB
JavaScript
155 lines
4.1 KiB
JavaScript
/**
|
|
* 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.
|
|
*
|
|
* @flow strict-local
|
|
* @format
|
|
* @oncall react_native
|
|
*/
|
|
|
|
import Networking from '../../Network/RCTNetworking';
|
|
import DevLoadingView from '../../Utilities/DevLoadingView';
|
|
import HMRClient from '../../Utilities/HMRClient';
|
|
import getDevServer from './getDevServer';
|
|
|
|
declare var global: {globalEvalWithSourceUrl?: (string, string) => mixed, ...};
|
|
|
|
let pendingRequests = 0;
|
|
|
|
const cachedPromisesByUrl = new Map<string, Promise<void>>();
|
|
|
|
function asyncRequest(
|
|
url: string,
|
|
): Promise<{body: string, headers: {[string]: string}}> {
|
|
let id = null;
|
|
let responseText = null;
|
|
let headers = null;
|
|
let dataListener;
|
|
let completeListener;
|
|
let responseListener;
|
|
let incrementalDataListener;
|
|
return new Promise<{body: string, headers: {[string]: string}}>(
|
|
(resolve, reject) => {
|
|
dataListener = Networking.addListener(
|
|
'didReceiveNetworkData',
|
|
([requestId, response]) => {
|
|
if (requestId === id) {
|
|
responseText = response;
|
|
}
|
|
},
|
|
);
|
|
incrementalDataListener = Networking.addListener(
|
|
'didReceiveNetworkIncrementalData',
|
|
([requestId, data]) => {
|
|
if (requestId === id) {
|
|
if (responseText != null) {
|
|
responseText += data;
|
|
} else {
|
|
responseText = data;
|
|
}
|
|
}
|
|
},
|
|
);
|
|
responseListener = Networking.addListener(
|
|
'didReceiveNetworkResponse',
|
|
([requestId, status, responseHeaders]) => {
|
|
if (requestId === id) {
|
|
headers = responseHeaders;
|
|
}
|
|
},
|
|
);
|
|
completeListener = Networking.addListener(
|
|
'didCompleteNetworkResponse',
|
|
([requestId, error]) => {
|
|
if (requestId === id) {
|
|
if (error) {
|
|
reject(error);
|
|
} else {
|
|
//$FlowFixMe[incompatible-call]
|
|
resolve({body: responseText, headers});
|
|
}
|
|
}
|
|
},
|
|
);
|
|
Networking.sendRequest(
|
|
'GET',
|
|
'asyncRequest',
|
|
url,
|
|
{},
|
|
'',
|
|
'text',
|
|
true,
|
|
0,
|
|
requestId => {
|
|
id = requestId;
|
|
},
|
|
true,
|
|
);
|
|
},
|
|
).finally(() => {
|
|
dataListener?.remove();
|
|
completeListener?.remove();
|
|
responseListener?.remove();
|
|
incrementalDataListener?.remove();
|
|
});
|
|
}
|
|
|
|
function buildUrlForBundle(bundlePathAndQuery: string) {
|
|
const {url: serverUrl} = getDevServer();
|
|
return (
|
|
serverUrl.replace(/\/+$/, '') + '/' + bundlePathAndQuery.replace(/^\/+/, '')
|
|
);
|
|
}
|
|
|
|
export default function loadBundleFromServer(
|
|
bundlePathAndQuery: string,
|
|
): Promise<void> {
|
|
const requestUrl = buildUrlForBundle(bundlePathAndQuery);
|
|
let loadPromise = cachedPromisesByUrl.get(requestUrl);
|
|
|
|
if (loadPromise) {
|
|
return loadPromise;
|
|
}
|
|
DevLoadingView.showMessage('Downloading...', 'load');
|
|
++pendingRequests;
|
|
|
|
loadPromise = asyncRequest(requestUrl)
|
|
.then<void>(({body, headers}) => {
|
|
if (
|
|
headers['Content-Type'] != null &&
|
|
headers['Content-Type'].indexOf('application/json') >= 0
|
|
) {
|
|
// Errors are returned as JSON.
|
|
throw new Error(
|
|
JSON.parse(body).message ||
|
|
`Unknown error fetching '${bundlePathAndQuery}'`,
|
|
);
|
|
}
|
|
|
|
HMRClient.registerBundle(requestUrl);
|
|
|
|
// Some engines do not support `sourceURL` as a comment. We expose a
|
|
// `globalEvalWithSourceUrl` function to handle updates in that case.
|
|
if (global.globalEvalWithSourceUrl) {
|
|
global.globalEvalWithSourceUrl(body, requestUrl);
|
|
} else {
|
|
// eslint-disable-next-line no-eval
|
|
eval(body);
|
|
}
|
|
})
|
|
.catch<void>(e => {
|
|
cachedPromisesByUrl.delete(requestUrl);
|
|
throw e;
|
|
})
|
|
.finally(() => {
|
|
if (!--pendingRequests) {
|
|
DevLoadingView.hide();
|
|
}
|
|
});
|
|
|
|
cachedPromisesByUrl.set(requestUrl, loadPromise);
|
|
return loadPromise;
|
|
}
|