source: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/lib/runtime/RefreshUtils.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 12 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 9.3 KB
Line 
1/* global __webpack_require__ */
2var Refresh = require('react-refresh/runtime');
3
4/**
5 * Extracts exports from a webpack module object.
6 * @param {string} moduleId A Webpack module ID.
7 * @returns {*} An exports object from the module.
8 */
9function getModuleExports(moduleId) {
10 if (typeof moduleId === 'undefined') {
11 // `moduleId` is unavailable, which indicates that this module is not in the cache,
12 // which means we won't be able to capture any exports,
13 // and thus they cannot be refreshed safely.
14 // These are likely runtime or dynamically generated modules.
15 return {};
16 }
17
18 var maybeModule = __webpack_require__.c[moduleId];
19 if (typeof maybeModule === 'undefined') {
20 // `moduleId` is available but the module in cache is unavailable,
21 // which indicates the module is somehow corrupted (e.g. broken Webpacak `module` globals).
22 // We will warn the user (as this is likely a mistake) and assume they cannot be refreshed.
23 console.warn('[React Refresh] Failed to get exports for module: ' + moduleId + '.');
24 return {};
25 }
26
27 var exportsOrPromise = maybeModule.exports;
28 if (typeof Promise !== 'undefined' && exportsOrPromise instanceof Promise) {
29 return exportsOrPromise.then(function (exports) {
30 return exports;
31 });
32 }
33 return exportsOrPromise;
34}
35
36/**
37 * Calculates the signature of a React refresh boundary.
38 * If this signature changes, it's unsafe to accept the boundary.
39 *
40 * 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).
41 * @param {*} moduleExports A Webpack module exports object.
42 * @returns {string[]} A React refresh boundary signature array.
43 */
44function getReactRefreshBoundarySignature(moduleExports) {
45 var signature = [];
46 signature.push(Refresh.getFamilyByType(moduleExports));
47
48 if (moduleExports == null || typeof moduleExports !== 'object') {
49 // Exit if we can't iterate over exports.
50 return signature;
51 }
52
53 for (var key in moduleExports) {
54 if (key === '__esModule') {
55 continue;
56 }
57
58 signature.push(key);
59 signature.push(Refresh.getFamilyByType(moduleExports[key]));
60 }
61
62 return signature;
63}
64
65/**
66 * Creates a data object to be retained across refreshes.
67 * This object should not transtively reference previous exports,
68 * which can form infinite chain of objects across refreshes, which can pressure RAM.
69 *
70 * @param {*} moduleExports A Webpack module exports object.
71 * @returns {*} A React refresh boundary signature array.
72 */
73function getWebpackHotData(moduleExports) {
74 return {
75 signature: getReactRefreshBoundarySignature(moduleExports),
76 isReactRefreshBoundary: isReactRefreshBoundary(moduleExports),
77 };
78}
79
80/**
81 * Creates a helper that performs a delayed React refresh.
82 * @returns {function(function(): void): void} A debounced React refresh function.
83 */
84function createDebounceUpdate() {
85 /**
86 * A cached setTimeout handler.
87 * @type {number | undefined}
88 */
89 var refreshTimeout;
90
91 /**
92 * Performs react refresh on a delay and clears the error overlay.
93 * @param {function(): void} callback
94 * @returns {void}
95 */
96 function enqueueUpdate(callback) {
97 if (typeof refreshTimeout === 'undefined') {
98 refreshTimeout = setTimeout(function () {
99 refreshTimeout = undefined;
100 Refresh.performReactRefresh();
101 callback();
102 }, 30);
103 }
104 }
105
106 return enqueueUpdate;
107}
108
109/**
110 * Checks if all exports are likely a React component.
111 *
112 * 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).
113 * @param {*} moduleExports A Webpack module exports object.
114 * @returns {boolean} Whether the exports are React component like.
115 */
116function isReactRefreshBoundary(moduleExports) {
117 if (Refresh.isLikelyComponentType(moduleExports)) {
118 return true;
119 }
120 if (moduleExports === undefined || moduleExports === null || typeof moduleExports !== 'object') {
121 // Exit if we can't iterate over exports.
122 return false;
123 }
124
125 var hasExports = false;
126 var areAllExportsComponents = true;
127 for (var key in moduleExports) {
128 hasExports = true;
129
130 // This is the ES Module indicator flag
131 if (key === '__esModule') {
132 continue;
133 }
134
135 // We can (and have to) safely execute getters here,
136 // as Webpack manually assigns harmony exports to getters,
137 // without any side-effects attached.
138 // Ref: https://github.com/webpack/webpack/blob/b93048643fe74de2a6931755911da1212df55897/lib/MainTemplate.js#L281
139 var exportValue = moduleExports[key];
140 if (!Refresh.isLikelyComponentType(exportValue)) {
141 areAllExportsComponents = false;
142 }
143 }
144
145 return hasExports && areAllExportsComponents;
146}
147
148/**
149 * Checks if exports are likely a React component and registers them.
150 *
151 * 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).
152 * @param {*} moduleExports A Webpack module exports object.
153 * @param {string} moduleId A Webpack module ID.
154 * @returns {void}
155 */
156function registerExportsForReactRefresh(moduleExports, moduleId) {
157 if (Refresh.isLikelyComponentType(moduleExports)) {
158 // Register module.exports if it is likely a component
159 Refresh.register(moduleExports, moduleId + ' %exports%');
160 }
161
162 if (moduleExports === undefined || moduleExports === null || typeof moduleExports !== 'object') {
163 // Exit if we can't iterate over the exports.
164 return;
165 }
166
167 for (var key in moduleExports) {
168 // Skip registering the ES Module indicator
169 if (key === '__esModule') {
170 continue;
171 }
172
173 var exportValue = moduleExports[key];
174 if (Refresh.isLikelyComponentType(exportValue)) {
175 var typeID = moduleId + ' %exports% ' + key;
176 Refresh.register(exportValue, typeID);
177 }
178 }
179}
180
181/**
182 * Compares previous and next module objects to check for mutated boundaries.
183 *
184 * 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).
185 * @param {*} prevSignature The signature of the current Webpack module exports object.
186 * @param {*} nextSignature The signature of the next Webpack module exports object.
187 * @returns {boolean} Whether the React refresh boundary should be invalidated.
188 */
189function shouldInvalidateReactRefreshBoundary(prevSignature, nextSignature) {
190 if (prevSignature.length !== nextSignature.length) {
191 return true;
192 }
193
194 for (var i = 0; i < nextSignature.length; i += 1) {
195 if (prevSignature[i] !== nextSignature[i]) {
196 return true;
197 }
198 }
199
200 return false;
201}
202
203var enqueueUpdate = createDebounceUpdate();
204function executeRuntime(moduleExports, moduleId, webpackHot, refreshOverlay, isTest) {
205 registerExportsForReactRefresh(moduleExports, moduleId);
206
207 if (webpackHot) {
208 var isHotUpdate = !!webpackHot.data;
209 var prevData;
210 if (isHotUpdate) {
211 prevData = webpackHot.data.prevData;
212 }
213
214 if (isReactRefreshBoundary(moduleExports)) {
215 webpackHot.dispose(
216 /**
217 * A callback to performs a full refresh if React has unrecoverable errors,
218 * and also caches the to-be-disposed module.
219 * @param {*} data A hot module data object from Webpack HMR.
220 * @returns {void}
221 */
222 function hotDisposeCallback(data) {
223 // We have to mutate the data object to get data registered and cached
224 data.prevData = getWebpackHotData(moduleExports);
225 }
226 );
227 webpackHot.accept(
228 /**
229 * An error handler to allow self-recovering behaviours.
230 * @param {Error} error An error occurred during evaluation of a module.
231 * @returns {void}
232 */
233 function hotErrorHandler(error) {
234 if (typeof refreshOverlay !== 'undefined' && refreshOverlay) {
235 refreshOverlay.handleRuntimeError(error);
236 }
237
238 if (typeof isTest !== 'undefined' && isTest) {
239 if (window.onHotAcceptError) {
240 window.onHotAcceptError(error.message);
241 }
242 }
243
244 __webpack_require__.c[moduleId].hot.accept(hotErrorHandler);
245 }
246 );
247
248 if (isHotUpdate) {
249 if (
250 prevData &&
251 prevData.isReactRefreshBoundary &&
252 shouldInvalidateReactRefreshBoundary(
253 prevData.signature,
254 getReactRefreshBoundarySignature(moduleExports)
255 )
256 ) {
257 webpackHot.invalidate();
258 } else {
259 enqueueUpdate(
260 /**
261 * A function to dismiss the error overlay after performing React refresh.
262 * @returns {void}
263 */
264 function updateCallback() {
265 if (typeof refreshOverlay !== 'undefined' && refreshOverlay) {
266 refreshOverlay.clearRuntimeErrors();
267 }
268 }
269 );
270 }
271 }
272 } else {
273 if (isHotUpdate && typeof prevData !== 'undefined') {
274 webpackHot.invalidate();
275 }
276 }
277 }
278}
279
280module.exports = Object.freeze({
281 enqueueUpdate: enqueueUpdate,
282 executeRuntime: executeRuntime,
283 getModuleExports: getModuleExports,
284 isReactRefreshBoundary: isReactRefreshBoundary,
285 registerExportsForReactRefresh: registerExportsForReactRefresh,
286});
Note: See TracBrowser for help on using the repository browser.