1 | "use strict";
|
2 |
|
3 | var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
4 |
|
5 | var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
6 |
|
7 | var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
8 |
|
9 | const http = require('http');
|
10 |
|
11 | const https = require('https');
|
12 |
|
13 | const WebSocket = require('ws');
|
14 |
|
15 | const generateCertificate = require('./utils/generateCertificate');
|
16 |
|
17 | const getCertificate = require('./utils/getCertificate');
|
18 |
|
19 | const logger = require('@parcel/logger');
|
20 |
|
21 | class HMRServer {
|
22 | start(options = {}) {
|
23 | var _this = this;
|
24 |
|
25 | return (0, _asyncToGenerator2.default)(function* () {
|
26 | yield new Promise(
|
27 |
|
28 | function () {
|
29 | var _ref = (0, _asyncToGenerator2.default)(function* (resolve) {
|
30 | if (!options.https) {
|
31 | _this.server = http.createServer();
|
32 | } else if (typeof options.https === 'boolean') {
|
33 | _this.server = https.createServer(generateCertificate(options));
|
34 | } else {
|
35 | _this.server = https.createServer((yield getCertificate(options.https)));
|
36 | }
|
37 |
|
38 | let websocketOptions = {
|
39 | server: _this.server
|
40 | };
|
41 |
|
42 | if (options.hmrHostname) {
|
43 | websocketOptions.origin = `${options.https ? 'https' : 'http'}://${options.hmrHostname}`;
|
44 | }
|
45 |
|
46 | _this.wss = new WebSocket.Server(websocketOptions);
|
47 |
|
48 | _this.server.listen(options.hmrPort, resolve);
|
49 | });
|
50 |
|
51 | return function (_x) {
|
52 | return _ref.apply(this, arguments);
|
53 | };
|
54 | }());
|
55 |
|
56 | _this.wss.on('connection', ws => {
|
57 | ws.onerror = _this.handleSocketError;
|
58 |
|
59 | if (_this.unresolvedError) {
|
60 | ws.send(JSON.stringify(_this.unresolvedError));
|
61 | }
|
62 | });
|
63 |
|
64 | _this.wss.on('error', _this.handleSocketError);
|
65 |
|
66 | return _this.wss._server.address().port;
|
67 | })();
|
68 | }
|
69 |
|
70 | stop() {
|
71 | this.wss.close();
|
72 | this.server.close();
|
73 | }
|
74 |
|
75 | emitError(err) {
|
76 | let _logger$formatError = logger.formatError(err),
|
77 | message = _logger$formatError.message,
|
78 | stack = _logger$formatError.stack;
|
79 |
|
80 |
|
81 |
|
82 | this.unresolvedError = {
|
83 | type: 'error',
|
84 | error: {
|
85 | message,
|
86 | stack
|
87 | }
|
88 | };
|
89 | this.broadcast(this.unresolvedError);
|
90 | }
|
91 |
|
92 | emitUpdate(assets, reload = false) {
|
93 | if (this.unresolvedError) {
|
94 | this.unresolvedError = null;
|
95 | this.broadcast({
|
96 | type: 'error-resolved'
|
97 | });
|
98 | }
|
99 |
|
100 | const shouldReload = reload || assets.some(asset => asset.hmrPageReload);
|
101 |
|
102 | if (shouldReload) {
|
103 | this.broadcast({
|
104 | type: 'reload'
|
105 | });
|
106 | } else {
|
107 | this.broadcast({
|
108 | type: 'update',
|
109 | assets: assets.map(asset => {
|
110 | let deps = {};
|
111 | var _iteratorNormalCompletion = true;
|
112 | var _didIteratorError = false;
|
113 | var _iteratorError = undefined;
|
114 |
|
115 | try {
|
116 | for (var _iterator = asset.depAssets[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
117 | let _step$value = (0, _slicedToArray2.default)(_step.value, 2),
|
118 | dep = _step$value[0],
|
119 | depAsset = _step$value[1];
|
120 |
|
121 | deps[dep.name] = depAsset.id;
|
122 | }
|
123 | } catch (err) {
|
124 | _didIteratorError = true;
|
125 | _iteratorError = err;
|
126 | } finally {
|
127 | try {
|
128 | if (!_iteratorNormalCompletion && _iterator.return != null) {
|
129 | _iterator.return();
|
130 | }
|
131 | } finally {
|
132 | if (_didIteratorError) {
|
133 | throw _iteratorError;
|
134 | }
|
135 | }
|
136 | }
|
137 |
|
138 | return {
|
139 | id: asset.id,
|
140 | type: asset.type,
|
141 | generated: asset.generated,
|
142 | deps: deps
|
143 | };
|
144 | })
|
145 | });
|
146 | }
|
147 | }
|
148 |
|
149 | handleSocketError(err) {
|
150 | if (err.error.code === 'ECONNRESET') {
|
151 |
|
152 | return;
|
153 | }
|
154 |
|
155 | logger.warn(err);
|
156 | }
|
157 |
|
158 | broadcast(msg) {
|
159 | const json = JSON.stringify(msg);
|
160 | var _iteratorNormalCompletion2 = true;
|
161 | var _didIteratorError2 = false;
|
162 | var _iteratorError2 = undefined;
|
163 |
|
164 | try {
|
165 | for (var _iterator2 = this.wss.clients[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
|
166 | let ws = _step2.value;
|
167 | ws.send(json);
|
168 | }
|
169 | } catch (err) {
|
170 | _didIteratorError2 = true;
|
171 | _iteratorError2 = err;
|
172 | } finally {
|
173 | try {
|
174 | if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
|
175 | _iterator2.return();
|
176 | }
|
177 | } finally {
|
178 | if (_didIteratorError2) {
|
179 | throw _iteratorError2;
|
180 | }
|
181 | }
|
182 | }
|
183 | }
|
184 |
|
185 | }
|
186 |
|
187 | module.exports = HMRServer; |
\ | No newline at end of file |