123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286 |
- /* global __webpack_require__ */
- var Refresh = require('react-refresh/runtime');
- /**
- * Extracts exports from a webpack module object.
- * @param {string} moduleId A Webpack module ID.
- * @returns {*} An exports object from the module.
- */
- function getModuleExports(moduleId) {
- if (typeof moduleId === 'undefined') {
- // `moduleId` is unavailable, which indicates that this module is not in the cache,
- // which means we won't be able to capture any exports,
- // and thus they cannot be refreshed safely.
- // These are likely runtime or dynamically generated modules.
- return {};
- }
- var maybeModule = __webpack_require__.c[moduleId];
- if (typeof maybeModule === 'undefined') {
- // `moduleId` is available but the module in cache is unavailable,
- // which indicates the module is somehow corrupted (e.g. broken Webpacak `module` globals).
- // We will warn the user (as this is likely a mistake) and assume they cannot be refreshed.
- console.warn('[React Refresh] Failed to get exports for module: ' + moduleId + '.');
- return {};
- }
- var exportsOrPromise = maybeModule.exports;
- if (typeof Promise !== 'undefined' && exportsOrPromise instanceof Promise) {
- return exportsOrPromise.then(function (exports) {
- return exports;
- });
- }
- return exportsOrPromise;
- }
- /**
- * Calculates the signature of a React refresh boundary.
- * If this signature changes, it's unsafe to accept the boundary.
- *
- * This implementation is based on the one in [Metro](https://github.com/facebook/metro/blob/907d6af22ac6ebe58572be418e9253a90665ecbd/packages/metro/src/lib/polyfills/require.js#L795-L816).
- * @param {*} moduleExports A Webpack module exports object.
- * @returns {string[]} A React refresh boundary signature array.
- */
- function getReactRefreshBoundarySignature(moduleExports) {
- var signature = [];
- signature.push(Refresh.getFamilyByType(moduleExports));
- if (moduleExports == null || typeof moduleExports !== 'object') {
- // Exit if we can't iterate over exports.
- return signature;
- }
- for (var key in moduleExports) {
- if (key === '__esModule') {
- continue;
- }
- signature.push(key);
- signature.push(Refresh.getFamilyByType(moduleExports[key]));
- }
- return signature;
- }
- /**
- * Creates a data object to be retained across refreshes.
- * This object should not transtively reference previous exports,
- * which can form infinite chain of objects across refreshes, which can pressure RAM.
- *
- * @param {*} moduleExports A Webpack module exports object.
- * @returns {*} A React refresh boundary signature array.
- */
- function getWebpackHotData(moduleExports) {
- return {
- signature: getReactRefreshBoundarySignature(moduleExports),
- isReactRefreshBoundary: isReactRefreshBoundary(moduleExports),
- };
- }
- /**
- * Creates a helper that performs a delayed React refresh.
- * @returns {function(function(): void): void} A debounced React refresh function.
- */
- function createDebounceUpdate() {
- /**
- * A cached setTimeout handler.
- * @type {number | undefined}
- */
- var refreshTimeout;
- /**
- * Performs react refresh on a delay and clears the error overlay.
- * @param {function(): void} callback
- * @returns {void}
- */
- function enqueueUpdate(callback) {
- if (typeof refreshTimeout === 'undefined') {
- refreshTimeout = setTimeout(function () {
- refreshTimeout = undefined;
- Refresh.performReactRefresh();
- callback();
- }, 30);
- }
- }
- return enqueueUpdate;
- }
- /**
- * Checks if all exports are likely a React component.
- *
- * This implementation is based on the one in [Metro](https://github.com/facebook/metro/blob/febdba2383113c88296c61e28e4ef6a7f4939fda/packages/metro/src/lib/polyfills/require.js#L748-L774).
- * @param {*} moduleExports A Webpack module exports object.
- * @returns {boolean} Whether the exports are React component like.
- */
- function isReactRefreshBoundary(moduleExports) {
- if (Refresh.isLikelyComponentType(moduleExports)) {
- return true;
- }
- if (moduleExports === undefined || moduleExports === null || typeof moduleExports !== 'object') {
- // Exit if we can't iterate over exports.
- return false;
- }
- var hasExports = false;
- var areAllExportsComponents = true;
- for (var key in moduleExports) {
- hasExports = true;
- // This is the ES Module indicator flag
- if (key === '__esModule') {
- continue;
- }
- // We can (and have to) safely execute getters here,
- // as Webpack manually assigns harmony exports to getters,
- // without any side-effects attached.
- // Ref: https://github.com/webpack/webpack/blob/b93048643fe74de2a6931755911da1212df55897/lib/MainTemplate.js#L281
- var exportValue = moduleExports[key];
- if (!Refresh.isLikelyComponentType(exportValue)) {
- areAllExportsComponents = false;
- }
- }
- return hasExports && areAllExportsComponents;
- }
- /**
- * Checks if exports are likely a React component and registers them.
- *
- * This implementation is based on the one in [Metro](https://github.com/facebook/metro/blob/febdba2383113c88296c61e28e4ef6a7f4939fda/packages/metro/src/lib/polyfills/require.js#L818-L835).
- * @param {*} moduleExports A Webpack module exports object.
- * @param {string} moduleId A Webpack module ID.
- * @returns {void}
- */
- function registerExportsForReactRefresh(moduleExports, moduleId) {
- if (Refresh.isLikelyComponentType(moduleExports)) {
- // Register module.exports if it is likely a component
- Refresh.register(moduleExports, moduleId + ' %exports%');
- }
- if (moduleExports === undefined || moduleExports === null || typeof moduleExports !== 'object') {
- // Exit if we can't iterate over the exports.
- return;
- }
- for (var key in moduleExports) {
- // Skip registering the ES Module indicator
- if (key === '__esModule') {
- continue;
- }
- var exportValue = moduleExports[key];
- if (Refresh.isLikelyComponentType(exportValue)) {
- var typeID = moduleId + ' %exports% ' + key;
- Refresh.register(exportValue, typeID);
- }
- }
- }
- /**
- * Compares previous and next module objects to check for mutated boundaries.
- *
- * This implementation is based on the one in [Metro](https://github.com/facebook/metro/blob/907d6af22ac6ebe58572be418e9253a90665ecbd/packages/metro/src/lib/polyfills/require.js#L776-L792).
- * @param {*} prevSignature The signature of the current Webpack module exports object.
- * @param {*} nextSignature The signature of the next Webpack module exports object.
- * @returns {boolean} Whether the React refresh boundary should be invalidated.
- */
- function shouldInvalidateReactRefreshBoundary(prevSignature, nextSignature) {
- if (prevSignature.length !== nextSignature.length) {
- return true;
- }
- for (var i = 0; i < nextSignature.length; i += 1) {
- if (prevSignature[i] !== nextSignature[i]) {
- return true;
- }
- }
- return false;
- }
- var enqueueUpdate = createDebounceUpdate();
- function executeRuntime(moduleExports, moduleId, webpackHot, refreshOverlay, isTest) {
- registerExportsForReactRefresh(moduleExports, moduleId);
- if (webpackHot) {
- var isHotUpdate = !!webpackHot.data;
- var prevData;
- if (isHotUpdate) {
- prevData = webpackHot.data.prevData;
- }
- if (isReactRefreshBoundary(moduleExports)) {
- webpackHot.dispose(
- /**
- * A callback to performs a full refresh if React has unrecoverable errors,
- * and also caches the to-be-disposed module.
- * @param {*} data A hot module data object from Webpack HMR.
- * @returns {void}
- */
- function hotDisposeCallback(data) {
- // We have to mutate the data object to get data registered and cached
- data.prevData = getWebpackHotData(moduleExports);
- }
- );
- webpackHot.accept(
- /**
- * An error handler to allow self-recovering behaviours.
- * @param {Error} error An error occurred during evaluation of a module.
- * @returns {void}
- */
- function hotErrorHandler(error) {
- if (typeof refreshOverlay !== 'undefined' && refreshOverlay) {
- refreshOverlay.handleRuntimeError(error);
- }
- if (typeof isTest !== 'undefined' && isTest) {
- if (window.onHotAcceptError) {
- window.onHotAcceptError(error.message);
- }
- }
- __webpack_require__.c[moduleId].hot.accept(hotErrorHandler);
- }
- );
- if (isHotUpdate) {
- if (
- prevData &&
- prevData.isReactRefreshBoundary &&
- shouldInvalidateReactRefreshBoundary(
- prevData.signature,
- getReactRefreshBoundarySignature(moduleExports)
- )
- ) {
- webpackHot.invalidate();
- } else {
- enqueueUpdate(
- /**
- * A function to dismiss the error overlay after performing React refresh.
- * @returns {void}
- */
- function updateCallback() {
- if (typeof refreshOverlay !== 'undefined' && refreshOverlay) {
- refreshOverlay.clearRuntimeErrors();
- }
- }
- );
- }
- }
- } else {
- if (isHotUpdate && typeof prevData !== 'undefined') {
- webpackHot.invalidate();
- }
- }
- }
- }
- module.exports = Object.freeze({
- enqueueUpdate: enqueueUpdate,
- executeRuntime: executeRuntime,
- getModuleExports: getModuleExports,
- isReactRefreshBoundary: isReactRefreshBoundary,
- registerExportsForReactRefresh: registerExportsForReactRefresh,
- });
|