-
Notifications
You must be signed in to change notification settings - Fork 638
/
hot-reload.js
117 lines (98 loc) · 3.12 KB
/
hot-reload.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
var runtime = require(".");
var queueMicrotask = require("../queueMicrotask");
var util = require("../components/util");
var registry = require("../components/registry");
var updateManager = require("../components/update-manager");
var createTemplate = runtime.t;
var createComponent = registry.___createComponent;
var registered = {};
var queue;
runtime.t = function (typeName) {
if (registered[typeName]) {
return registered[typeName];
}
var renderFn;
var template = (registered[typeName] = createTemplate(typeName));
var instances = (template.___instances = []);
Object.defineProperty(template, "_", {
get: function () {
return renderFn && proxyRenderer;
},
set: function (v) {
renderFn = v;
if (instances.length) {
if (!queue) {
queue = [];
queueMicrotask(batchUpdate);
}
queue.push(function () {
var newProto = registry.___getComponentClass(typeName).prototype;
instances.forEach(function (instance) {
if (hasLifecycleChanged(instance.__proto__, newProto)) {
var startNode = instance.___rootNode.startNode;
var endNode = instance.___rootNode.endNode;
var parentNode = startNode.parentNode;
var curNode;
instance.___hmrDestroyed = true;
instance.___emitDestroy();
instance.___removeDOMEventListeners();
if (instance.___subscriptions) {
instance.___subscriptions.removeAllListeners();
instance.___subscriptions = null;
}
while ((curNode = startNode.nextSibling) !== endNode) {
util.___destroyNodeRecursive(curNode);
parentNode.removeChild(curNode);
}
instance.___hmrDestroyed = false;
instance.___mounted = false;
}
instance.__proto__ = newProto;
instance
.___rerender(instance.___input, false)
.afterInsert(instance.___document);
});
});
}
}
});
return template;
function proxyRenderer() {
return renderFn.apply(this, arguments);
}
};
registry.___createComponent = function (typeName, id) {
var instances = registered[typeName].___instances;
var instance = createComponent(typeName, id);
instances.push(instance);
instance.once("destroy", function () {
if (!instance.___hmrDestroyed) {
instances.splice(1, instances.indexOf(instance));
}
});
return instance;
};
function hasLifecycleChanged(oldProto, newProto) {
return (
hasMethodChanged("onCreate") ||
hasMethodChanged("onInput") ||
hasMethodChanged("onRender") ||
hasMethodChanged("onMount")
);
function hasMethodChanged(method) {
return (
(oldProto[method] && oldProto[method].toString()) !==
(newProto[method] && newProto[method].toString())
);
}
}
function batchUpdate() {
updateManager.___batchUpdate(function () {
var pending = queue;
queue = undefined;
for (var i = 0; i < pending.length; i++) {
pending[i]();
}
});
}
module.exports = runtime;