@atlaspack/runtime-browser-hmr 2.12.1-canary.3354
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/lib/HMRRuntime.js +62 -0
- package/lib/loaders/hmr-runtime.js +506 -0
- package/package.json +23 -0
- package/src/HMRRuntime.js +64 -0
- package/src/loaders/.eslintrc.json +3 -0
- package/src/loaders/hmr-runtime.js +636 -0
|
@@ -0,0 +1,506 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/* global HMR_HOST, HMR_PORT, HMR_ENV_HASH, HMR_SECURE, HMR_USE_SSE, chrome, browser, __atlaspack__import__, __atlaspack__importScripts__, ServiceWorkerGlobalScope */
|
|
4
|
+
/*::
|
|
5
|
+
import type {
|
|
6
|
+
HMRAsset,
|
|
7
|
+
HMRMessage,
|
|
8
|
+
} from '@atlaspack/reporter-dev-server/src/HMRServer.js';
|
|
9
|
+
interface AtlaspackRequire {
|
|
10
|
+
(string): mixed;
|
|
11
|
+
cache: {|[string]: AtlaspackModule|};
|
|
12
|
+
hotData: {|[string]: mixed|};
|
|
13
|
+
Module: any;
|
|
14
|
+
parent: ?AtlaspackRequire;
|
|
15
|
+
isAtlaspackRequire: true;
|
|
16
|
+
modules: {|[string]: [Function, {|[string]: string|}]|};
|
|
17
|
+
HMR_BUNDLE_ID: string;
|
|
18
|
+
root: AtlaspackRequire;
|
|
19
|
+
}
|
|
20
|
+
interface AtlaspackModule {
|
|
21
|
+
hot: {|
|
|
22
|
+
data: mixed,
|
|
23
|
+
accept(cb: (Function) => void): void,
|
|
24
|
+
dispose(cb: (mixed) => void): void,
|
|
25
|
+
// accept(deps: Array<string> | string, cb: (Function) => void): void,
|
|
26
|
+
// decline(): void,
|
|
27
|
+
_acceptCallbacks: Array<(Function) => void>,
|
|
28
|
+
_disposeCallbacks: Array<(mixed) => void>,
|
|
29
|
+
|};
|
|
30
|
+
}
|
|
31
|
+
interface ExtensionContext {
|
|
32
|
+
runtime: {|
|
|
33
|
+
reload(): void,
|
|
34
|
+
getURL(url: string): string;
|
|
35
|
+
getManifest(): {manifest_version: number, ...};
|
|
36
|
+
|};
|
|
37
|
+
}
|
|
38
|
+
declare var module: {bundle: AtlaspackRequire, ...};
|
|
39
|
+
declare var HMR_HOST: string;
|
|
40
|
+
declare var HMR_PORT: string;
|
|
41
|
+
declare var HMR_ENV_HASH: string;
|
|
42
|
+
declare var HMR_SECURE: boolean;
|
|
43
|
+
declare var HMR_USE_SSE: boolean;
|
|
44
|
+
declare var chrome: ExtensionContext;
|
|
45
|
+
declare var browser: ExtensionContext;
|
|
46
|
+
declare var __atlaspack__import__: (string) => Promise<void>;
|
|
47
|
+
declare var __atlaspack__importScripts__: (string) => Promise<void>;
|
|
48
|
+
declare var globalThis: typeof self;
|
|
49
|
+
declare var ServiceWorkerGlobalScope: Object;
|
|
50
|
+
*/
|
|
51
|
+
var OVERLAY_ID = '__atlaspack__error__overlay__';
|
|
52
|
+
var OldModule = module.bundle.Module;
|
|
53
|
+
function Module(moduleName) {
|
|
54
|
+
OldModule.call(this, moduleName);
|
|
55
|
+
this.hot = {
|
|
56
|
+
data: module.bundle.hotData[moduleName],
|
|
57
|
+
_acceptCallbacks: [],
|
|
58
|
+
_disposeCallbacks: [],
|
|
59
|
+
accept: function (fn) {
|
|
60
|
+
this._acceptCallbacks.push(fn || function () {});
|
|
61
|
+
},
|
|
62
|
+
dispose: function (fn) {
|
|
63
|
+
this._disposeCallbacks.push(fn);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
module.bundle.hotData[moduleName] = undefined;
|
|
67
|
+
}
|
|
68
|
+
module.bundle.Module = Module;
|
|
69
|
+
module.bundle.hotData = {};
|
|
70
|
+
var checkedAssets /*: {|[string]: boolean|} */, assetsToDispose /*: Array<[AtlaspackRequire, string]> */, assetsToAccept /*: Array<[AtlaspackRequire, string]> */;
|
|
71
|
+
|
|
72
|
+
function getHostname() {
|
|
73
|
+
return HMR_HOST || (location.protocol.indexOf('http') === 0 ? location.hostname : 'localhost');
|
|
74
|
+
}
|
|
75
|
+
function getPort() {
|
|
76
|
+
return HMR_PORT || location.port;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// eslint-disable-next-line no-redeclare
|
|
80
|
+
var parent = module.bundle.parent;
|
|
81
|
+
if ((!parent || !parent.isAtlaspackRequire) && typeof WebSocket !== 'undefined') {
|
|
82
|
+
var hostname = getHostname();
|
|
83
|
+
var port = getPort();
|
|
84
|
+
var protocol = HMR_SECURE || location.protocol == 'https:' && !['localhost', '127.0.0.1', '0.0.0.0'].includes(hostname) ? 'wss' : 'ws';
|
|
85
|
+
var ws;
|
|
86
|
+
if (HMR_USE_SSE) {
|
|
87
|
+
ws = new EventSource('/__atlaspack_hmr');
|
|
88
|
+
} else {
|
|
89
|
+
try {
|
|
90
|
+
ws = new WebSocket(protocol + '://' + hostname + (port ? ':' + port : '') + '/');
|
|
91
|
+
} catch (err) {
|
|
92
|
+
if (err.message) {
|
|
93
|
+
console.error(err.message);
|
|
94
|
+
}
|
|
95
|
+
ws = {};
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Web extension context
|
|
100
|
+
var extCtx = typeof browser === 'undefined' ? typeof chrome === 'undefined' ? null : chrome : browser;
|
|
101
|
+
|
|
102
|
+
// Safari doesn't support sourceURL in error stacks.
|
|
103
|
+
// eval may also be disabled via CSP, so do a quick check.
|
|
104
|
+
var supportsSourceURL = false;
|
|
105
|
+
try {
|
|
106
|
+
(0, eval)('throw new Error("test"); //# sourceURL=test.js');
|
|
107
|
+
} catch (err) {
|
|
108
|
+
supportsSourceURL = err.stack.includes('test.js');
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// $FlowFixMe
|
|
112
|
+
ws.onmessage = async function (event /*: {data: string, ...} */) {
|
|
113
|
+
checkedAssets = {} /*: {|[string]: boolean|} */;
|
|
114
|
+
assetsToAccept = [];
|
|
115
|
+
assetsToDispose = [];
|
|
116
|
+
var data /*: HMRMessage */ = JSON.parse(event.data);
|
|
117
|
+
if (data.type === 'reload') {
|
|
118
|
+
fullReload();
|
|
119
|
+
} else if (data.type === 'update') {
|
|
120
|
+
// Remove error overlay if there is one
|
|
121
|
+
if (typeof document !== 'undefined') {
|
|
122
|
+
removeErrorOverlay();
|
|
123
|
+
}
|
|
124
|
+
let assets = data.assets.filter(asset => asset.envHash === HMR_ENV_HASH);
|
|
125
|
+
|
|
126
|
+
// Handle HMR Update
|
|
127
|
+
let handled = assets.every(asset => {
|
|
128
|
+
return asset.type === 'css' || asset.type === 'js' && hmrAcceptCheck(module.bundle.root, asset.id, asset.depsByBundle);
|
|
129
|
+
});
|
|
130
|
+
if (handled) {
|
|
131
|
+
console.clear();
|
|
132
|
+
|
|
133
|
+
// Dispatch custom event so other runtimes (e.g React Refresh) are aware.
|
|
134
|
+
if (typeof window !== 'undefined' && typeof CustomEvent !== 'undefined') {
|
|
135
|
+
window.dispatchEvent(new CustomEvent('atlaspackhmraccept'));
|
|
136
|
+
}
|
|
137
|
+
await hmrApplyUpdates(assets);
|
|
138
|
+
|
|
139
|
+
// Dispose all old assets.
|
|
140
|
+
let processedAssets = {} /*: {|[string]: boolean|} */;
|
|
141
|
+
for (let i = 0; i < assetsToDispose.length; i++) {
|
|
142
|
+
let id = assetsToDispose[i][1];
|
|
143
|
+
if (!processedAssets[id]) {
|
|
144
|
+
hmrDispose(assetsToDispose[i][0], id);
|
|
145
|
+
processedAssets[id] = true;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Run accept callbacks. This will also re-execute other disposed assets in topological order.
|
|
150
|
+
processedAssets = {};
|
|
151
|
+
for (let i = 0; i < assetsToAccept.length; i++) {
|
|
152
|
+
let id = assetsToAccept[i][1];
|
|
153
|
+
if (!processedAssets[id]) {
|
|
154
|
+
hmrAccept(assetsToAccept[i][0], id);
|
|
155
|
+
processedAssets[id] = true;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
} else fullReload();
|
|
159
|
+
}
|
|
160
|
+
if (data.type === 'error') {
|
|
161
|
+
// Log atlaspack errors to console
|
|
162
|
+
for (let ansiDiagnostic of data.diagnostics.ansi) {
|
|
163
|
+
let stack = ansiDiagnostic.codeframe ? ansiDiagnostic.codeframe : ansiDiagnostic.stack;
|
|
164
|
+
console.error('🚨 [atlaspack]: ' + ansiDiagnostic.message + '\n' + stack + '\n\n' + ansiDiagnostic.hints.join('\n'));
|
|
165
|
+
}
|
|
166
|
+
if (typeof document !== 'undefined') {
|
|
167
|
+
// Render the fancy html overlay
|
|
168
|
+
removeErrorOverlay();
|
|
169
|
+
var overlay = createErrorOverlay(data.diagnostics.html);
|
|
170
|
+
// $FlowFixMe
|
|
171
|
+
document.body.appendChild(overlay);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
if (ws instanceof WebSocket) {
|
|
176
|
+
ws.onerror = function (e) {
|
|
177
|
+
if (e.message) {
|
|
178
|
+
console.error(e.message);
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
ws.onclose = function () {
|
|
182
|
+
console.warn('[atlaspack] 🚨 Connection to the HMR server was lost');
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
function removeErrorOverlay() {
|
|
187
|
+
var overlay = document.getElementById(OVERLAY_ID);
|
|
188
|
+
if (overlay) {
|
|
189
|
+
overlay.remove();
|
|
190
|
+
console.log('[atlaspack] ✨ Error resolved');
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
function createErrorOverlay(diagnostics) {
|
|
194
|
+
var overlay = document.createElement('div');
|
|
195
|
+
overlay.id = OVERLAY_ID;
|
|
196
|
+
let errorHTML = '<div style="background: black; opacity: 0.85; font-size: 16px; color: white; position: fixed; height: 100%; width: 100%; top: 0px; left: 0px; padding: 30px; font-family: Menlo, Consolas, monospace; z-index: 9999;">';
|
|
197
|
+
for (let diagnostic of diagnostics) {
|
|
198
|
+
let stack = diagnostic.frames.length ? diagnostic.frames.reduce((p, frame) => {
|
|
199
|
+
return `${p}
|
|
200
|
+
<a href="/__atlaspack_launch_editor?file=${encodeURIComponent(frame.location)}" style="text-decoration: underline; color: #888" onclick="fetch(this.href); return false">${frame.location}</a>
|
|
201
|
+
${frame.code}`;
|
|
202
|
+
}, '') : diagnostic.stack;
|
|
203
|
+
errorHTML += `
|
|
204
|
+
<div>
|
|
205
|
+
<div style="font-size: 18px; font-weight: bold; margin-top: 20px;">
|
|
206
|
+
🚨 ${diagnostic.message}
|
|
207
|
+
</div>
|
|
208
|
+
<pre>${stack}</pre>
|
|
209
|
+
<div>
|
|
210
|
+
${diagnostic.hints.map(hint => '<div>💡 ' + hint + '</div>').join('')}
|
|
211
|
+
</div>
|
|
212
|
+
${diagnostic.documentation ? `<div>📝 <a style="color: violet" href="${diagnostic.documentation}" target="_blank">Learn more</a></div>` : ''}
|
|
213
|
+
</div>
|
|
214
|
+
`;
|
|
215
|
+
}
|
|
216
|
+
errorHTML += '</div>';
|
|
217
|
+
overlay.innerHTML = errorHTML;
|
|
218
|
+
return overlay;
|
|
219
|
+
}
|
|
220
|
+
function fullReload() {
|
|
221
|
+
if ('reload' in location) {
|
|
222
|
+
location.reload();
|
|
223
|
+
} else if (extCtx && extCtx.runtime && extCtx.runtime.reload) {
|
|
224
|
+
extCtx.runtime.reload();
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
function getParents(bundle, id) /*: Array<[AtlaspackRequire, string]> */{
|
|
228
|
+
var modules = bundle.modules;
|
|
229
|
+
if (!modules) {
|
|
230
|
+
return [];
|
|
231
|
+
}
|
|
232
|
+
var parents = [];
|
|
233
|
+
var k, d, dep;
|
|
234
|
+
for (k in modules) {
|
|
235
|
+
for (d in modules[k][1]) {
|
|
236
|
+
dep = modules[k][1][d];
|
|
237
|
+
if (dep === id || Array.isArray(dep) && dep[dep.length - 1] === id) {
|
|
238
|
+
parents.push([bundle, k]);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
if (bundle.parent) {
|
|
243
|
+
parents = parents.concat(getParents(bundle.parent, id));
|
|
244
|
+
}
|
|
245
|
+
return parents;
|
|
246
|
+
}
|
|
247
|
+
function updateLink(link) {
|
|
248
|
+
var href = link.getAttribute('href');
|
|
249
|
+
if (!href) {
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
var newLink = link.cloneNode();
|
|
253
|
+
newLink.onload = function () {
|
|
254
|
+
if (link.parentNode !== null) {
|
|
255
|
+
// $FlowFixMe
|
|
256
|
+
link.parentNode.removeChild(link);
|
|
257
|
+
}
|
|
258
|
+
};
|
|
259
|
+
newLink.setAttribute('href',
|
|
260
|
+
// $FlowFixMe
|
|
261
|
+
href.split('?')[0] + '?' + Date.now());
|
|
262
|
+
// $FlowFixMe
|
|
263
|
+
link.parentNode.insertBefore(newLink, link.nextSibling);
|
|
264
|
+
}
|
|
265
|
+
var cssTimeout = null;
|
|
266
|
+
function reloadCSS() {
|
|
267
|
+
if (cssTimeout) {
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
cssTimeout = setTimeout(function () {
|
|
271
|
+
var links = document.querySelectorAll('link[rel="stylesheet"]');
|
|
272
|
+
for (var i = 0; i < links.length; i++) {
|
|
273
|
+
// $FlowFixMe[incompatible-type]
|
|
274
|
+
var href /*: string */ = links[i].getAttribute('href');
|
|
275
|
+
var hostname = getHostname();
|
|
276
|
+
var servedFromHMRServer = hostname === 'localhost' ? new RegExp('^(https?:\\/\\/(0.0.0.0|127.0.0.1)|localhost):' + getPort()).test(href) : href.indexOf(hostname + ':' + getPort());
|
|
277
|
+
var absolute = /^https?:\/\//i.test(href) && href.indexOf(location.origin) !== 0 && !servedFromHMRServer;
|
|
278
|
+
if (!absolute) {
|
|
279
|
+
updateLink(links[i]);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
cssTimeout = null;
|
|
283
|
+
}, 50);
|
|
284
|
+
}
|
|
285
|
+
function hmrDownload(asset) {
|
|
286
|
+
if (asset.type === 'js') {
|
|
287
|
+
if (typeof document !== 'undefined') {
|
|
288
|
+
let script = document.createElement('script');
|
|
289
|
+
script.src = asset.url + '?t=' + Date.now();
|
|
290
|
+
if (asset.outputFormat === 'esmodule') {
|
|
291
|
+
script.type = 'module';
|
|
292
|
+
}
|
|
293
|
+
return new Promise((resolve, reject) => {
|
|
294
|
+
var _document$head;
|
|
295
|
+
script.onload = () => resolve(script);
|
|
296
|
+
script.onerror = reject;
|
|
297
|
+
(_document$head = document.head) === null || _document$head === void 0 || _document$head.appendChild(script);
|
|
298
|
+
});
|
|
299
|
+
} else if (typeof importScripts === 'function') {
|
|
300
|
+
// Worker scripts
|
|
301
|
+
if (asset.outputFormat === 'esmodule') {
|
|
302
|
+
return __atlaspack__import__(asset.url + '?t=' + Date.now());
|
|
303
|
+
} else {
|
|
304
|
+
return new Promise((resolve, reject) => {
|
|
305
|
+
try {
|
|
306
|
+
__atlaspack__importScripts__(asset.url + '?t=' + Date.now());
|
|
307
|
+
resolve();
|
|
308
|
+
} catch (err) {
|
|
309
|
+
reject(err);
|
|
310
|
+
}
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
async function hmrApplyUpdates(assets) {
|
|
317
|
+
global.atlaspackHotUpdate = Object.create(null);
|
|
318
|
+
let scriptsToRemove;
|
|
319
|
+
try {
|
|
320
|
+
// If sourceURL comments aren't supported in eval, we need to load
|
|
321
|
+
// the update from the dev server over HTTP so that stack traces
|
|
322
|
+
// are correct in errors/logs. This is much slower than eval, so
|
|
323
|
+
// we only do it if needed (currently just Safari).
|
|
324
|
+
// https://bugs.webkit.org/show_bug.cgi?id=137297
|
|
325
|
+
// This path is also taken if a CSP disallows eval.
|
|
326
|
+
if (!supportsSourceURL) {
|
|
327
|
+
let promises = assets.map(asset => {
|
|
328
|
+
var _hmrDownload;
|
|
329
|
+
return (_hmrDownload = hmrDownload(asset)) === null || _hmrDownload === void 0 ? void 0 : _hmrDownload.catch(err => {
|
|
330
|
+
// Web extension fix
|
|
331
|
+
if (extCtx && extCtx.runtime && extCtx.runtime.getManifest().manifest_version == 3 && typeof ServiceWorkerGlobalScope != 'undefined' && global instanceof ServiceWorkerGlobalScope) {
|
|
332
|
+
extCtx.runtime.reload();
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
throw err;
|
|
336
|
+
});
|
|
337
|
+
});
|
|
338
|
+
scriptsToRemove = await Promise.all(promises);
|
|
339
|
+
}
|
|
340
|
+
assets.forEach(function (asset) {
|
|
341
|
+
hmrApply(module.bundle.root, asset);
|
|
342
|
+
});
|
|
343
|
+
} finally {
|
|
344
|
+
delete global.atlaspackHotUpdate;
|
|
345
|
+
if (scriptsToRemove) {
|
|
346
|
+
scriptsToRemove.forEach(script => {
|
|
347
|
+
if (script) {
|
|
348
|
+
var _document$head2;
|
|
349
|
+
(_document$head2 = document.head) === null || _document$head2 === void 0 || _document$head2.removeChild(script);
|
|
350
|
+
}
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
function hmrApply(bundle /*: AtlaspackRequire */, asset /*: HMRAsset */) {
|
|
356
|
+
var modules = bundle.modules;
|
|
357
|
+
if (!modules) {
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
if (asset.type === 'css') {
|
|
361
|
+
reloadCSS();
|
|
362
|
+
} else if (asset.type === 'js') {
|
|
363
|
+
let deps = asset.depsByBundle[bundle.HMR_BUNDLE_ID];
|
|
364
|
+
if (deps) {
|
|
365
|
+
if (modules[asset.id]) {
|
|
366
|
+
// Remove dependencies that are removed and will become orphaned.
|
|
367
|
+
// This is necessary so that if the asset is added back again, the cache is gone, and we prevent a full page reload.
|
|
368
|
+
let oldDeps = modules[asset.id][1];
|
|
369
|
+
for (let dep in oldDeps) {
|
|
370
|
+
if (!deps[dep] || deps[dep] !== oldDeps[dep]) {
|
|
371
|
+
let id = oldDeps[dep];
|
|
372
|
+
let parents = getParents(module.bundle.root, id);
|
|
373
|
+
if (parents.length === 1) {
|
|
374
|
+
hmrDelete(module.bundle.root, id);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
if (supportsSourceURL) {
|
|
380
|
+
// Global eval. We would use `new Function` here but browser
|
|
381
|
+
// support for source maps is better with eval.
|
|
382
|
+
(0, eval)(asset.output);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
// $FlowFixMe
|
|
386
|
+
let fn = global.atlaspackHotUpdate[asset.id];
|
|
387
|
+
modules[asset.id] = [fn, deps];
|
|
388
|
+
} else if (bundle.parent) {
|
|
389
|
+
hmrApply(bundle.parent, asset);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
function hmrDelete(bundle, id) {
|
|
394
|
+
let modules = bundle.modules;
|
|
395
|
+
if (!modules) {
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
if (modules[id]) {
|
|
399
|
+
// Collect dependencies that will become orphaned when this module is deleted.
|
|
400
|
+
let deps = modules[id][1];
|
|
401
|
+
let orphans = [];
|
|
402
|
+
for (let dep in deps) {
|
|
403
|
+
let parents = getParents(module.bundle.root, deps[dep]);
|
|
404
|
+
if (parents.length === 1) {
|
|
405
|
+
orphans.push(deps[dep]);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
// Delete the module. This must be done before deleting dependencies in case of circular dependencies.
|
|
410
|
+
delete modules[id];
|
|
411
|
+
delete bundle.cache[id];
|
|
412
|
+
|
|
413
|
+
// Now delete the orphans.
|
|
414
|
+
orphans.forEach(id => {
|
|
415
|
+
hmrDelete(module.bundle.root, id);
|
|
416
|
+
});
|
|
417
|
+
} else if (bundle.parent) {
|
|
418
|
+
hmrDelete(bundle.parent, id);
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
function hmrAcceptCheck(bundle /*: AtlaspackRequire */, id /*: string */, depsByBundle /*: ?{ [string]: { [string]: string } }*/) {
|
|
422
|
+
if (hmrAcceptCheckOne(bundle, id, depsByBundle)) {
|
|
423
|
+
return true;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
// Traverse parents breadth first. All possible ancestries must accept the HMR update, or we'll reload.
|
|
427
|
+
let parents = getParents(module.bundle.root, id);
|
|
428
|
+
let accepted = false;
|
|
429
|
+
while (parents.length > 0) {
|
|
430
|
+
let v = parents.shift();
|
|
431
|
+
let a = hmrAcceptCheckOne(v[0], v[1], null);
|
|
432
|
+
if (a) {
|
|
433
|
+
// If this parent accepts, stop traversing upward, but still consider siblings.
|
|
434
|
+
accepted = true;
|
|
435
|
+
} else {
|
|
436
|
+
// Otherwise, queue the parents in the next level upward.
|
|
437
|
+
let p = getParents(module.bundle.root, v[1]);
|
|
438
|
+
if (p.length === 0) {
|
|
439
|
+
// If there are no parents, then we've reached an entry without accepting. Reload.
|
|
440
|
+
accepted = false;
|
|
441
|
+
break;
|
|
442
|
+
}
|
|
443
|
+
parents.push(...p);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
return accepted;
|
|
447
|
+
}
|
|
448
|
+
function hmrAcceptCheckOne(bundle /*: AtlaspackRequire */, id /*: string */, depsByBundle /*: ?{ [string]: { [string]: string } }*/) {
|
|
449
|
+
var modules = bundle.modules;
|
|
450
|
+
if (!modules) {
|
|
451
|
+
return;
|
|
452
|
+
}
|
|
453
|
+
if (depsByBundle && !depsByBundle[bundle.HMR_BUNDLE_ID]) {
|
|
454
|
+
// If we reached the root bundle without finding where the asset should go,
|
|
455
|
+
// there's nothing to do. Mark as "accepted" so we don't reload the page.
|
|
456
|
+
if (!bundle.parent) {
|
|
457
|
+
return true;
|
|
458
|
+
}
|
|
459
|
+
return hmrAcceptCheck(bundle.parent, id, depsByBundle);
|
|
460
|
+
}
|
|
461
|
+
if (checkedAssets[id]) {
|
|
462
|
+
return true;
|
|
463
|
+
}
|
|
464
|
+
checkedAssets[id] = true;
|
|
465
|
+
var cached = bundle.cache[id];
|
|
466
|
+
assetsToDispose.push([bundle, id]);
|
|
467
|
+
if (!cached || cached.hot && cached.hot._acceptCallbacks.length) {
|
|
468
|
+
assetsToAccept.push([bundle, id]);
|
|
469
|
+
return true;
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
function hmrDispose(bundle /*: AtlaspackRequire */, id /*: string */) {
|
|
473
|
+
var cached = bundle.cache[id];
|
|
474
|
+
bundle.hotData[id] = {};
|
|
475
|
+
if (cached && cached.hot) {
|
|
476
|
+
cached.hot.data = bundle.hotData[id];
|
|
477
|
+
}
|
|
478
|
+
if (cached && cached.hot && cached.hot._disposeCallbacks.length) {
|
|
479
|
+
cached.hot._disposeCallbacks.forEach(function (cb) {
|
|
480
|
+
cb(bundle.hotData[id]);
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
delete bundle.cache[id];
|
|
484
|
+
}
|
|
485
|
+
function hmrAccept(bundle /*: AtlaspackRequire */, id /*: string */) {
|
|
486
|
+
// Execute the module.
|
|
487
|
+
bundle(id);
|
|
488
|
+
|
|
489
|
+
// Run the accept callbacks in the new version of the module.
|
|
490
|
+
var cached = bundle.cache[id];
|
|
491
|
+
if (cached && cached.hot && cached.hot._acceptCallbacks.length) {
|
|
492
|
+
cached.hot._acceptCallbacks.forEach(function (cb) {
|
|
493
|
+
var assetsToAlsoAccept = cb(function () {
|
|
494
|
+
return getParents(module.bundle.root, id);
|
|
495
|
+
});
|
|
496
|
+
if (assetsToAlsoAccept && assetsToAccept.length) {
|
|
497
|
+
assetsToAlsoAccept.forEach(function (a) {
|
|
498
|
+
hmrDispose(a[0], a[1]);
|
|
499
|
+
});
|
|
500
|
+
|
|
501
|
+
// $FlowFixMe[method-unbinding]
|
|
502
|
+
assetsToAccept.push.apply(assetsToAccept, assetsToAlsoAccept);
|
|
503
|
+
}
|
|
504
|
+
});
|
|
505
|
+
}
|
|
506
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@atlaspack/runtime-browser-hmr",
|
|
3
|
+
"version": "2.12.1-canary.3354+7bb54d46a",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "public"
|
|
7
|
+
},
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/atlassian-labs/atlaspack.git"
|
|
11
|
+
},
|
|
12
|
+
"main": "lib/HMRRuntime.js",
|
|
13
|
+
"source": "src/HMRRuntime.js",
|
|
14
|
+
"engines": {
|
|
15
|
+
"node": ">= 16.0.0",
|
|
16
|
+
"atlaspack": "2.12.1-canary.3354+7bb54d46a"
|
|
17
|
+
},
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@atlaspack/plugin": "2.12.1-canary.3354+7bb54d46a",
|
|
20
|
+
"@atlaspack/utils": "2.12.1-canary.3354+7bb54d46a"
|
|
21
|
+
},
|
|
22
|
+
"gitHead": "7bb54d46a00c5ba9cdbc2ee426dcbe82c8d79a3e"
|
|
23
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// @flow strict-local
|
|
2
|
+
|
|
3
|
+
import {Runtime} from '@atlaspack/plugin';
|
|
4
|
+
import fs from 'fs';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
|
|
7
|
+
// Without this, the hmr-runtime.js is transpiled with the React Refresh swc transform because it
|
|
8
|
+
// lives in `/app/packages/runtimes/...` and thus the `config` in the JSTransformer is actually the
|
|
9
|
+
// user's package.json, and hmr-runtime.js is transpiled as a JSX asset.
|
|
10
|
+
const FILENAME =
|
|
11
|
+
// $FlowFixMe
|
|
12
|
+
process.env.ATLASPACK_BUILD_REPL && process.browser
|
|
13
|
+
? '/' + __filename
|
|
14
|
+
: __filename;
|
|
15
|
+
|
|
16
|
+
const HMR_RUNTIME = fs.readFileSync(
|
|
17
|
+
path.join(__dirname, './loaders/hmr-runtime.js'),
|
|
18
|
+
'utf8',
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
export default (new Runtime({
|
|
22
|
+
apply({bundle, options}) {
|
|
23
|
+
if (
|
|
24
|
+
bundle.type !== 'js' ||
|
|
25
|
+
!options.hmrOptions ||
|
|
26
|
+
bundle.env.isLibrary ||
|
|
27
|
+
bundle.env.isWorklet() ||
|
|
28
|
+
bundle.env.sourceType === 'script'
|
|
29
|
+
) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const {host, port} = options.hmrOptions;
|
|
34
|
+
return {
|
|
35
|
+
filePath: FILENAME,
|
|
36
|
+
code:
|
|
37
|
+
`var HMR_HOST = ${JSON.stringify(
|
|
38
|
+
host != null && host !== '0.0.0.0' ? host : null,
|
|
39
|
+
)};` +
|
|
40
|
+
`var HMR_PORT = ${JSON.stringify(
|
|
41
|
+
port != null &&
|
|
42
|
+
// Default to the HTTP port in the browser, only override
|
|
43
|
+
// in watch mode or if hmr port != serve port
|
|
44
|
+
(!options.serveOptions || options.serveOptions.port !== port)
|
|
45
|
+
? port
|
|
46
|
+
: null,
|
|
47
|
+
)};` +
|
|
48
|
+
`var HMR_SECURE = ${JSON.stringify(
|
|
49
|
+
!!(options.serveOptions && options.serveOptions.https),
|
|
50
|
+
)};` +
|
|
51
|
+
`var HMR_ENV_HASH = "${bundle.env.id}";` +
|
|
52
|
+
`var HMR_USE_SSE = ${JSON.stringify(
|
|
53
|
+
// $FlowFixMe
|
|
54
|
+
!!(process.env.ATLASPACK_BUILD_REPL && process.browser),
|
|
55
|
+
)};` +
|
|
56
|
+
`module.bundle.HMR_BUNDLE_ID = ${JSON.stringify(bundle.id)};` +
|
|
57
|
+
HMR_RUNTIME,
|
|
58
|
+
isEntry: true,
|
|
59
|
+
env: {
|
|
60
|
+
sourceType: 'module',
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
},
|
|
64
|
+
}): Runtime);
|