Spaces:
Sleeping
Sleeping
classifieur
/
frontend
/node_modules
/@pmmmwh
/react-refresh-webpack-plugin
/lib
/runtime
/RefreshUtils.js
/* 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, | |
}); | |