UNPKG

5.63 kBJavaScriptView Raw
1'use strict';
2
3var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
4
5function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6
7var Rax = require('rax');
8
9var _require = require('react-proxy'),
10 createProxy = _require.createProxy;
11
12var global = require('global');
13
14var ComponentMap = function () {
15 function ComponentMap(useWeakMap) {
16 _classCallCheck(this, ComponentMap);
17
18 if (useWeakMap) {
19 this.wm = new WeakMap();
20 } else {
21 this.slots = {};
22 }
23 }
24
25 _createClass(ComponentMap, [{
26 key: 'getSlot',
27 value: function getSlot(type) {
28 var key = type.displayName || type.name || 'Unknown';
29 if (!this.slots[key]) {
30 this.slots[key] = [];
31 }
32 return this.slots[key];
33 }
34 }, {
35 key: 'get',
36 value: function get(type) {
37 if (this.wm) {
38 return this.wm.get(type);
39 }
40
41 var slot = this.getSlot(type);
42 for (var i = 0; i < slot.length; i++) {
43 if (slot[i].key === type) {
44 return slot[i].value;
45 }
46 }
47
48 return undefined;
49 }
50 }, {
51 key: 'set',
52 value: function set(type, value) {
53 if (this.wm) {
54 this.wm.set(type, value);
55 } else {
56 var slot = this.getSlot(type);
57 for (var i = 0; i < slot.length; i++) {
58 if (slot[i].key === type) {
59 slot[i].value = value;
60 return;
61 }
62 }
63 slot.push({ key: type, value: value });
64 }
65 }
66 }, {
67 key: 'has',
68 value: function has(type) {
69 if (this.wm) {
70 return this.wm.has(type);
71 }
72
73 var slot = this.getSlot(type);
74 for (var i = 0; i < slot.length; i++) {
75 if (slot[i].key === type) {
76 return true;
77 }
78 }
79 return false;
80 }
81 }]);
82
83 return ComponentMap;
84}();
85
86var proxiesByID = void 0;
87var didWarnAboutID = void 0;
88var hasCreatedElementsByType = void 0;
89var idsByType = void 0;
90
91var hooks = {
92 register: function register(type, uniqueLocalName, fileName) {
93 if (typeof type !== 'function') {
94 return;
95 }
96 if (!uniqueLocalName || !fileName) {
97 return;
98 }
99 if (typeof uniqueLocalName !== 'string' || typeof fileName !== 'string') {
100 return;
101 }
102 var id = fileName + '#' + uniqueLocalName; // eslint-disable-line prefer-template
103 if (!idsByType.has(type) && hasCreatedElementsByType.has(type)) {
104 if (!didWarnAboutID[id]) {
105 didWarnAboutID[id] = true;
106 var baseName = fileName.replace(/^.*[\\\/]/, '');
107 console.error('Rax Hot Loader: ' + uniqueLocalName + ' in ' + fileName + ' will not hot reload ' + ('correctly because ' + baseName + ' uses <' + uniqueLocalName + ' /> during ') + ('module definition. For hot reloading to work, move ' + uniqueLocalName + ' ') + ('into a separate file and import it from ' + baseName + '.'));
108 }
109 return;
110 }
111
112 // Remember the ID.
113 idsByType.set(type, id);
114
115 // console.log(id, proxiesByID[id], type);
116 // We use React Proxy to generate classes that behave almost
117 // the same way as the original classes but are updatable with
118 // new versions without destroying original instances.
119 if (!proxiesByID[id]) {
120 proxiesByID[id] = createProxy(type);
121 } else {
122 proxiesByID[id].update(type);
123 }
124 },
125 reset: function reset(useWeakMap) {
126 proxiesByID = {};
127 didWarnAboutID = {};
128 hasCreatedElementsByType = new ComponentMap(useWeakMap);
129 idsByType = new ComponentMap(useWeakMap);
130 }
131};
132
133hooks.reset(typeof WeakMap === 'function');
134
135function resolveType(type) {
136 // We only care about composite components
137 if (typeof type !== 'function') {
138 return type;
139 }
140
141 hasCreatedElementsByType.set(type, true);
142
143 // When available, give proxy class to React instead of the real class.
144 var id = idsByType.get(type);
145 if (!id) {
146 return type;
147 }
148
149 var proxy = proxiesByID[id];
150 if (!proxy) {
151 return type;
152 }
153
154 return proxy.get();
155}
156var createElement = Rax.createElement;
157function patchedCreateElement(type) {
158 // Trick React into rendering a proxy so that
159 // its state is preserved when the class changes.
160 // This will update the proxy if it's for a known type.
161 var resolvedType = resolveType(type);
162
163 for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
164 args[_key - 1] = arguments[_key];
165 }
166
167 return createElement.apply(undefined, [resolvedType].concat(args));
168}
169patchedCreateElement.isPatchedByReactHotLoader = true;
170
171function patchedCreateFactory(type) {
172 // Patch Rax.createFactory to use patched createElement
173 // because the original implementation uses the internal,
174 // unpatched ReactElement.createElement
175 var factory = patchedCreateElement.bind(null, type);
176 factory.type = type;
177 return factory;
178}
179patchedCreateFactory.isPatchedByReactHotLoader = true;
180
181if (typeof global.__RAX_HOT_LOADER__ === 'undefined') {
182 Rax.createElement = patchedCreateElement;
183 Rax.createFactory = patchedCreateFactory;
184 global.__RAX_HOT_LOADER__ = hooks;
185}
\No newline at end of file