UNPKG

17.2 kBJavaScriptView Raw
1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Tobias Koppers @sokra
4*/
5/*global $hash$ $requestTimeout$ installedModules $require$ hotDownloadManifest hotDownloadUpdateChunk hotDisposeChunk modules */
6module.exports = function() {
7 var hotApplyOnUpdate = true;
8 // eslint-disable-next-line no-unused-vars
9 var hotCurrentHash = $hash$;
10 var hotRequestTimeout = $requestTimeout$;
11 var hotCurrentModuleData = {};
12 var hotCurrentChildModule;
13 // eslint-disable-next-line no-unused-vars
14 var hotCurrentParents = [];
15 // eslint-disable-next-line no-unused-vars
16 var hotCurrentParentsTemp = [];
17
18 // eslint-disable-next-line no-unused-vars
19 function hotCreateRequire(moduleId) {
20 var me = installedModules[moduleId];
21 if (!me) return $require$;
22 var fn = function(request) {
23 if (me.hot.active) {
24 if (installedModules[request]) {
25 if (installedModules[request].parents.indexOf(moduleId) === -1) {
26 installedModules[request].parents.push(moduleId);
27 }
28 } else {
29 hotCurrentParents = [moduleId];
30 hotCurrentChildModule = request;
31 }
32 if (me.children.indexOf(request) === -1) {
33 me.children.push(request);
34 }
35 } else {
36 console.warn(
37 "[HMR] unexpected require(" +
38 request +
39 ") from disposed module " +
40 moduleId
41 );
42 hotCurrentParents = [];
43 }
44 return $require$(request);
45 };
46 var ObjectFactory = function ObjectFactory(name) {
47 return {
48 configurable: true,
49 enumerable: true,
50 get: function() {
51 return $require$[name];
52 },
53 set: function(value) {
54 $require$[name] = value;
55 }
56 };
57 };
58 for (var name in $require$) {
59 if (
60 Object.prototype.hasOwnProperty.call($require$, name) &&
61 name !== "e" &&
62 name !== "t"
63 ) {
64 Object.defineProperty(fn, name, ObjectFactory(name));
65 }
66 }
67 fn.e = function(chunkId) {
68 if (hotStatus === "ready") hotSetStatus("prepare");
69 hotChunksLoading++;
70 return $require$.e(chunkId).then(finishChunkLoading, function(err) {
71 finishChunkLoading();
72 throw err;
73 });
74
75 function finishChunkLoading() {
76 hotChunksLoading--;
77 if (hotStatus === "prepare") {
78 if (!hotWaitingFilesMap[chunkId]) {
79 hotEnsureUpdateChunk(chunkId);
80 }
81 if (hotChunksLoading === 0 && hotWaitingFiles === 0) {
82 hotUpdateDownloaded();
83 }
84 }
85 }
86 };
87 fn.t = function(value, mode) {
88 if (mode & 1) value = fn(value);
89 return $require$.t(value, mode & ~1);
90 };
91 return fn;
92 }
93
94 // eslint-disable-next-line no-unused-vars
95 function hotCreateModule(moduleId) {
96 var hot = {
97 // private stuff
98 _acceptedDependencies: {},
99 _declinedDependencies: {},
100 _selfAccepted: false,
101 _selfDeclined: false,
102 _disposeHandlers: [],
103 _main: hotCurrentChildModule !== moduleId,
104
105 // Module API
106 active: true,
107 accept: function(dep, callback) {
108 if (dep === undefined) hot._selfAccepted = true;
109 else if (typeof dep === "function") hot._selfAccepted = dep;
110 else if (typeof dep === "object")
111 for (var i = 0; i < dep.length; i++)
112 hot._acceptedDependencies[dep[i]] = callback || function() {};
113 else hot._acceptedDependencies[dep] = callback || function() {};
114 },
115 decline: function(dep) {
116 if (dep === undefined) hot._selfDeclined = true;
117 else if (typeof dep === "object")
118 for (var i = 0; i < dep.length; i++)
119 hot._declinedDependencies[dep[i]] = true;
120 else hot._declinedDependencies[dep] = true;
121 },
122 dispose: function(callback) {
123 hot._disposeHandlers.push(callback);
124 },
125 addDisposeHandler: function(callback) {
126 hot._disposeHandlers.push(callback);
127 },
128 removeDisposeHandler: function(callback) {
129 var idx = hot._disposeHandlers.indexOf(callback);
130 if (idx >= 0) hot._disposeHandlers.splice(idx, 1);
131 },
132
133 // Management API
134 check: hotCheck,
135 apply: hotApply,
136 status: function(l) {
137 if (!l) return hotStatus;
138 hotStatusHandlers.push(l);
139 },
140 addStatusHandler: function(l) {
141 hotStatusHandlers.push(l);
142 },
143 removeStatusHandler: function(l) {
144 var idx = hotStatusHandlers.indexOf(l);
145 if (idx >= 0) hotStatusHandlers.splice(idx, 1);
146 },
147
148 //inherit from previous dispose call
149 data: hotCurrentModuleData[moduleId]
150 };
151 hotCurrentChildModule = undefined;
152 return hot;
153 }
154
155 var hotStatusHandlers = [];
156 var hotStatus = "idle";
157
158 function hotSetStatus(newStatus) {
159 hotStatus = newStatus;
160 for (var i = 0; i < hotStatusHandlers.length; i++)
161 hotStatusHandlers[i].call(null, newStatus);
162 }
163
164 // while downloading
165 var hotWaitingFiles = 0;
166 var hotChunksLoading = 0;
167 var hotWaitingFilesMap = {};
168 var hotRequestedFilesMap = {};
169 var hotAvailableFilesMap = {};
170 var hotDeferred;
171
172 // The update info
173 var hotUpdate, hotUpdateNewHash;
174
175 function toModuleId(id) {
176 var isNumber = +id + "" === id;
177 return isNumber ? +id : id;
178 }
179
180 function hotCheck(apply) {
181 if (hotStatus !== "idle") {
182 throw new Error("check() is only allowed in idle status");
183 }
184 hotApplyOnUpdate = apply;
185 hotSetStatus("check");
186 return hotDownloadManifest(hotRequestTimeout).then(function(update) {
187 if (!update) {
188 hotSetStatus("idle");
189 return null;
190 }
191 hotRequestedFilesMap = {};
192 hotWaitingFilesMap = {};
193 hotAvailableFilesMap = update.c;
194 hotUpdateNewHash = update.h;
195
196 hotSetStatus("prepare");
197 var promise = new Promise(function(resolve, reject) {
198 hotDeferred = {
199 resolve: resolve,
200 reject: reject
201 };
202 });
203 hotUpdate = {};
204 /*foreachInstalledChunks*/
205 // eslint-disable-next-line no-lone-blocks
206 {
207 /*globals chunkId */
208 hotEnsureUpdateChunk(chunkId);
209 }
210 if (
211 hotStatus === "prepare" &&
212 hotChunksLoading === 0 &&
213 hotWaitingFiles === 0
214 ) {
215 hotUpdateDownloaded();
216 }
217 return promise;
218 });
219 }
220
221 // eslint-disable-next-line no-unused-vars
222 function hotAddUpdateChunk(chunkId, moreModules) {
223 if (!hotAvailableFilesMap[chunkId] || !hotRequestedFilesMap[chunkId])
224 return;
225 hotRequestedFilesMap[chunkId] = false;
226 for (var moduleId in moreModules) {
227 if (Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {
228 hotUpdate[moduleId] = moreModules[moduleId];
229 }
230 }
231 if (--hotWaitingFiles === 0 && hotChunksLoading === 0) {
232 hotUpdateDownloaded();
233 }
234 }
235
236 function hotEnsureUpdateChunk(chunkId) {
237 if (!hotAvailableFilesMap[chunkId]) {
238 hotWaitingFilesMap[chunkId] = true;
239 } else {
240 hotRequestedFilesMap[chunkId] = true;
241 hotWaitingFiles++;
242 hotDownloadUpdateChunk(chunkId);
243 }
244 }
245
246 function hotUpdateDownloaded() {
247 hotSetStatus("ready");
248 var deferred = hotDeferred;
249 hotDeferred = null;
250 if (!deferred) return;
251 if (hotApplyOnUpdate) {
252 // Wrap deferred object in Promise to mark it as a well-handled Promise to
253 // avoid triggering uncaught exception warning in Chrome.
254 // See https://bugs.chromium.org/p/chromium/issues/detail?id=465666
255 Promise.resolve()
256 .then(function() {
257 return hotApply(hotApplyOnUpdate);
258 })
259 .then(
260 function(result) {
261 deferred.resolve(result);
262 },
263 function(err) {
264 deferred.reject(err);
265 }
266 );
267 } else {
268 var outdatedModules = [];
269 for (var id in hotUpdate) {
270 if (Object.prototype.hasOwnProperty.call(hotUpdate, id)) {
271 outdatedModules.push(toModuleId(id));
272 }
273 }
274 deferred.resolve(outdatedModules);
275 }
276 }
277
278 function hotApply(options) {
279 if (hotStatus !== "ready")
280 throw new Error("apply() is only allowed in ready status");
281 options = options || {};
282
283 var cb;
284 var i;
285 var j;
286 var module;
287 var moduleId;
288
289 function getAffectedStuff(updateModuleId) {
290 var outdatedModules = [updateModuleId];
291 var outdatedDependencies = {};
292
293 var queue = outdatedModules.map(function(id) {
294 return {
295 chain: [id],
296 id: id
297 };
298 });
299 while (queue.length > 0) {
300 var queueItem = queue.pop();
301 var moduleId = queueItem.id;
302 var chain = queueItem.chain;
303 module = installedModules[moduleId];
304 if (!module || module.hot._selfAccepted) continue;
305 if (module.hot._selfDeclined) {
306 return {
307 type: "self-declined",
308 chain: chain,
309 moduleId: moduleId
310 };
311 }
312 if (module.hot._main) {
313 return {
314 type: "unaccepted",
315 chain: chain,
316 moduleId: moduleId
317 };
318 }
319 for (var i = 0; i < module.parents.length; i++) {
320 var parentId = module.parents[i];
321 var parent = installedModules[parentId];
322 if (!parent) continue;
323 if (parent.hot._declinedDependencies[moduleId]) {
324 return {
325 type: "declined",
326 chain: chain.concat([parentId]),
327 moduleId: moduleId,
328 parentId: parentId
329 };
330 }
331 if (outdatedModules.indexOf(parentId) !== -1) continue;
332 if (parent.hot._acceptedDependencies[moduleId]) {
333 if (!outdatedDependencies[parentId])
334 outdatedDependencies[parentId] = [];
335 addAllToSet(outdatedDependencies[parentId], [moduleId]);
336 continue;
337 }
338 delete outdatedDependencies[parentId];
339 outdatedModules.push(parentId);
340 queue.push({
341 chain: chain.concat([parentId]),
342 id: parentId
343 });
344 }
345 }
346
347 return {
348 type: "accepted",
349 moduleId: updateModuleId,
350 outdatedModules: outdatedModules,
351 outdatedDependencies: outdatedDependencies
352 };
353 }
354
355 function addAllToSet(a, b) {
356 for (var i = 0; i < b.length; i++) {
357 var item = b[i];
358 if (a.indexOf(item) === -1) a.push(item);
359 }
360 }
361
362 // at begin all updates modules are outdated
363 // the "outdated" status can propagate to parents if they don't accept the children
364 var outdatedDependencies = {};
365 var outdatedModules = [];
366 var appliedUpdate = {};
367
368 var warnUnexpectedRequire = function warnUnexpectedRequire() {
369 console.warn(
370 "[HMR] unexpected require(" + result.moduleId + ") to disposed module"
371 );
372 };
373
374 for (var id in hotUpdate) {
375 if (Object.prototype.hasOwnProperty.call(hotUpdate, id)) {
376 moduleId = toModuleId(id);
377 /** @type {TODO} */
378 var result;
379 if (hotUpdate[id]) {
380 result = getAffectedStuff(moduleId);
381 } else {
382 result = {
383 type: "disposed",
384 moduleId: id
385 };
386 }
387 /** @type {Error|false} */
388 var abortError = false;
389 var doApply = false;
390 var doDispose = false;
391 var chainInfo = "";
392 if (result.chain) {
393 chainInfo = "\nUpdate propagation: " + result.chain.join(" -> ");
394 }
395 switch (result.type) {
396 case "self-declined":
397 if (options.onDeclined) options.onDeclined(result);
398 if (!options.ignoreDeclined)
399 abortError = new Error(
400 "Aborted because of self decline: " +
401 result.moduleId +
402 chainInfo
403 );
404 break;
405 case "declined":
406 if (options.onDeclined) options.onDeclined(result);
407 if (!options.ignoreDeclined)
408 abortError = new Error(
409 "Aborted because of declined dependency: " +
410 result.moduleId +
411 " in " +
412 result.parentId +
413 chainInfo
414 );
415 break;
416 case "unaccepted":
417 if (options.onUnaccepted) options.onUnaccepted(result);
418 if (!options.ignoreUnaccepted)
419 abortError = new Error(
420 "Aborted because " + moduleId + " is not accepted" + chainInfo
421 );
422 break;
423 case "accepted":
424 if (options.onAccepted) options.onAccepted(result);
425 doApply = true;
426 break;
427 case "disposed":
428 if (options.onDisposed) options.onDisposed(result);
429 doDispose = true;
430 break;
431 default:
432 throw new Error("Unexception type " + result.type);
433 }
434 if (abortError) {
435 hotSetStatus("abort");
436 return Promise.reject(abortError);
437 }
438 if (doApply) {
439 appliedUpdate[moduleId] = hotUpdate[moduleId];
440 addAllToSet(outdatedModules, result.outdatedModules);
441 for (moduleId in result.outdatedDependencies) {
442 if (
443 Object.prototype.hasOwnProperty.call(
444 result.outdatedDependencies,
445 moduleId
446 )
447 ) {
448 if (!outdatedDependencies[moduleId])
449 outdatedDependencies[moduleId] = [];
450 addAllToSet(
451 outdatedDependencies[moduleId],
452 result.outdatedDependencies[moduleId]
453 );
454 }
455 }
456 }
457 if (doDispose) {
458 addAllToSet(outdatedModules, [result.moduleId]);
459 appliedUpdate[moduleId] = warnUnexpectedRequire;
460 }
461 }
462 }
463
464 // Store self accepted outdated modules to require them later by the module system
465 var outdatedSelfAcceptedModules = [];
466 for (i = 0; i < outdatedModules.length; i++) {
467 moduleId = outdatedModules[i];
468 if (
469 installedModules[moduleId] &&
470 installedModules[moduleId].hot._selfAccepted &&
471 // removed self-accepted modules should not be required
472 appliedUpdate[moduleId] !== warnUnexpectedRequire
473 ) {
474 outdatedSelfAcceptedModules.push({
475 module: moduleId,
476 errorHandler: installedModules[moduleId].hot._selfAccepted
477 });
478 }
479 }
480
481 // Now in "dispose" phase
482 hotSetStatus("dispose");
483 Object.keys(hotAvailableFilesMap).forEach(function(chunkId) {
484 if (hotAvailableFilesMap[chunkId] === false) {
485 hotDisposeChunk(chunkId);
486 }
487 });
488
489 var idx;
490 var queue = outdatedModules.slice();
491 while (queue.length > 0) {
492 moduleId = queue.pop();
493 module = installedModules[moduleId];
494 if (!module) continue;
495
496 var data = {};
497
498 // Call dispose handlers
499 var disposeHandlers = module.hot._disposeHandlers;
500 for (j = 0; j < disposeHandlers.length; j++) {
501 cb = disposeHandlers[j];
502 cb(data);
503 }
504 hotCurrentModuleData[moduleId] = data;
505
506 // disable module (this disables requires from this module)
507 module.hot.active = false;
508
509 // remove module from cache
510 delete installedModules[moduleId];
511
512 // when disposing there is no need to call dispose handler
513 delete outdatedDependencies[moduleId];
514
515 // remove "parents" references from all children
516 for (j = 0; j < module.children.length; j++) {
517 var child = installedModules[module.children[j]];
518 if (!child) continue;
519 idx = child.parents.indexOf(moduleId);
520 if (idx >= 0) {
521 child.parents.splice(idx, 1);
522 }
523 }
524 }
525
526 // remove outdated dependency from module children
527 var dependency;
528 var moduleOutdatedDependencies;
529 for (moduleId in outdatedDependencies) {
530 if (
531 Object.prototype.hasOwnProperty.call(outdatedDependencies, moduleId)
532 ) {
533 module = installedModules[moduleId];
534 if (module) {
535 moduleOutdatedDependencies = outdatedDependencies[moduleId];
536 for (j = 0; j < moduleOutdatedDependencies.length; j++) {
537 dependency = moduleOutdatedDependencies[j];
538 idx = module.children.indexOf(dependency);
539 if (idx >= 0) module.children.splice(idx, 1);
540 }
541 }
542 }
543 }
544
545 // Now in "apply" phase
546 hotSetStatus("apply");
547
548 hotCurrentHash = hotUpdateNewHash;
549
550 // insert new code
551 for (moduleId in appliedUpdate) {
552 if (Object.prototype.hasOwnProperty.call(appliedUpdate, moduleId)) {
553 modules[moduleId] = appliedUpdate[moduleId];
554 }
555 }
556
557 // call accept handlers
558 var error = null;
559 for (moduleId in outdatedDependencies) {
560 if (
561 Object.prototype.hasOwnProperty.call(outdatedDependencies, moduleId)
562 ) {
563 module = installedModules[moduleId];
564 if (module) {
565 moduleOutdatedDependencies = outdatedDependencies[moduleId];
566 var callbacks = [];
567 for (i = 0; i < moduleOutdatedDependencies.length; i++) {
568 dependency = moduleOutdatedDependencies[i];
569 cb = module.hot._acceptedDependencies[dependency];
570 if (cb) {
571 if (callbacks.indexOf(cb) !== -1) continue;
572 callbacks.push(cb);
573 }
574 }
575 for (i = 0; i < callbacks.length; i++) {
576 cb = callbacks[i];
577 try {
578 cb(moduleOutdatedDependencies);
579 } catch (err) {
580 if (options.onErrored) {
581 options.onErrored({
582 type: "accept-errored",
583 moduleId: moduleId,
584 dependencyId: moduleOutdatedDependencies[i],
585 error: err
586 });
587 }
588 if (!options.ignoreErrored) {
589 if (!error) error = err;
590 }
591 }
592 }
593 }
594 }
595 }
596
597 // Load self accepted modules
598 for (i = 0; i < outdatedSelfAcceptedModules.length; i++) {
599 var item = outdatedSelfAcceptedModules[i];
600 moduleId = item.module;
601 hotCurrentParents = [moduleId];
602 try {
603 $require$(moduleId);
604 } catch (err) {
605 if (typeof item.errorHandler === "function") {
606 try {
607 item.errorHandler(err);
608 } catch (err2) {
609 if (options.onErrored) {
610 options.onErrored({
611 type: "self-accept-error-handler-errored",
612 moduleId: moduleId,
613 error: err2,
614 originalError: err
615 });
616 }
617 if (!options.ignoreErrored) {
618 if (!error) error = err2;
619 }
620 if (!error) error = err;
621 }
622 } else {
623 if (options.onErrored) {
624 options.onErrored({
625 type: "self-accept-errored",
626 moduleId: moduleId,
627 error: err
628 });
629 }
630 if (!options.ignoreErrored) {
631 if (!error) error = err;
632 }
633 }
634 }
635 }
636
637 // handle errors in accept handlers and self accepted module load
638 if (error) {
639 hotSetStatus("fail");
640 return Promise.reject(error);
641 }
642
643 hotSetStatus("idle");
644 return new Promise(function(resolve) {
645 resolve(outdatedModules);
646 });
647 }
648};