@atlaspack/reporter-dev-server 2.14.18-unified-f92fba5b6.0 → 2.14.18
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/CHANGELOG.md +13 -0
- package/lib/HMRServer.js +263 -0
- package/lib/Server.js +459 -0
- package/lib/ServerReporter.js +137 -17456
- package/lib/serverErrors.js +17 -0
- package/package.json +7 -8
- package/LICENSE +0 -201
- package/lib/ServerReporter.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# @atlaspack/reporter-dev-server
|
|
2
2
|
|
|
3
|
+
## 2.14.18
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#645](https://github.com/atlassian-labs/atlaspack/pull/645) [`de23e0c`](https://github.com/atlassian-labs/atlaspack/commit/de23e0ce49d5504fe3947ac26640a3d951087da3) Thanks [@alshdavid](https://github.com/alshdavid)! - Updated build system and added some extra test-specific code
|
|
8
|
+
|
|
9
|
+
- [#682](https://github.com/atlassian-labs/atlaspack/pull/682) [`a5ed1b4`](https://github.com/atlassian-labs/atlaspack/commit/a5ed1b414498560f393ff491af4da25b6e8dde56) Thanks [@alshdavid](https://github.com/alshdavid)! - Updating build system
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [[`dbb4072`](https://github.com/atlassian-labs/atlaspack/commit/dbb40721ebeb45990a14ba04e6b44e7f836fb32d), [`de23e0c`](https://github.com/atlassian-labs/atlaspack/commit/de23e0ce49d5504fe3947ac26640a3d951087da3), [`18a57cf`](https://github.com/atlassian-labs/atlaspack/commit/18a57cf8a4789b2de5ad8e2676f317a26cc91417), [`a5ed1b4`](https://github.com/atlassian-labs/atlaspack/commit/a5ed1b414498560f393ff491af4da25b6e8dde56)]:
|
|
12
|
+
- @atlaspack/utils@2.17.0
|
|
13
|
+
- @atlaspack/types@2.15.8
|
|
14
|
+
- @atlaspack/plugin@2.14.18
|
|
15
|
+
|
|
3
16
|
## 2.14.17
|
|
4
17
|
|
|
5
18
|
### Patch Changes
|
package/lib/HMRServer.js
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _Server = require("./Server");
|
|
8
|
+
function _nullthrows() {
|
|
9
|
+
const data = _interopRequireDefault(require("nullthrows"));
|
|
10
|
+
_nullthrows = function () {
|
|
11
|
+
return data;
|
|
12
|
+
};
|
|
13
|
+
return data;
|
|
14
|
+
}
|
|
15
|
+
function _url() {
|
|
16
|
+
const data = _interopRequireDefault(require("url"));
|
|
17
|
+
_url = function () {
|
|
18
|
+
return data;
|
|
19
|
+
};
|
|
20
|
+
return data;
|
|
21
|
+
}
|
|
22
|
+
function _mimeTypes() {
|
|
23
|
+
const data = _interopRequireDefault(require("mime-types"));
|
|
24
|
+
_mimeTypes = function () {
|
|
25
|
+
return data;
|
|
26
|
+
};
|
|
27
|
+
return data;
|
|
28
|
+
}
|
|
29
|
+
function _ws() {
|
|
30
|
+
const data = _interopRequireDefault(require("ws"));
|
|
31
|
+
_ws = function () {
|
|
32
|
+
return data;
|
|
33
|
+
};
|
|
34
|
+
return data;
|
|
35
|
+
}
|
|
36
|
+
function _assert() {
|
|
37
|
+
const data = _interopRequireDefault(require("assert"));
|
|
38
|
+
_assert = function () {
|
|
39
|
+
return data;
|
|
40
|
+
};
|
|
41
|
+
return data;
|
|
42
|
+
}
|
|
43
|
+
function _utils() {
|
|
44
|
+
const data = require("@atlaspack/utils");
|
|
45
|
+
_utils = function () {
|
|
46
|
+
return data;
|
|
47
|
+
};
|
|
48
|
+
return data;
|
|
49
|
+
}
|
|
50
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
51
|
+
const FS_CONCURRENCY = 64;
|
|
52
|
+
const HMR_ENDPOINT = '/__parcel_hmr';
|
|
53
|
+
const BROADCAST_MAX_ASSETS = 10000;
|
|
54
|
+
class HMRServer {
|
|
55
|
+
unresolvedError = null;
|
|
56
|
+
bundleGraph = null;
|
|
57
|
+
constructor(options) {
|
|
58
|
+
this.options = options;
|
|
59
|
+
}
|
|
60
|
+
async start() {
|
|
61
|
+
let server = this.options.devServer;
|
|
62
|
+
if (!server) {
|
|
63
|
+
let result = await (0, _utils().createHTTPServer)({
|
|
64
|
+
https: this.options.https,
|
|
65
|
+
inputFS: this.options.inputFS,
|
|
66
|
+
outputFS: this.options.outputFS,
|
|
67
|
+
cacheDir: this.options.cacheDir,
|
|
68
|
+
listener: (req, res) => {
|
|
69
|
+
(0, _Server.setHeaders)(res);
|
|
70
|
+
if (!this.handle(req, res)) {
|
|
71
|
+
res.statusCode = 404;
|
|
72
|
+
res.end();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
server = result.server;
|
|
77
|
+
server.listen(this.options.port, this.options.host);
|
|
78
|
+
this.stopServer = result.stop;
|
|
79
|
+
} else {
|
|
80
|
+
var _this$options$addMidd, _this$options;
|
|
81
|
+
(_this$options$addMidd = (_this$options = this.options).addMiddleware) === null || _this$options$addMidd === void 0 || _this$options$addMidd.call(_this$options, (req, res) => this.handle(req, res));
|
|
82
|
+
}
|
|
83
|
+
this.wss = new (_ws().default.Server)({
|
|
84
|
+
server
|
|
85
|
+
});
|
|
86
|
+
this.wss.on('connection', ws => {
|
|
87
|
+
if (this.unresolvedError) {
|
|
88
|
+
ws.send(JSON.stringify(this.unresolvedError));
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
// $FlowFixMe[incompatible-exact]
|
|
93
|
+
this.wss.on('error', err => this.handleSocketError(err));
|
|
94
|
+
}
|
|
95
|
+
handle(req, res) {
|
|
96
|
+
let {
|
|
97
|
+
pathname
|
|
98
|
+
} = _url().default.parse(req.originalUrl || req.url);
|
|
99
|
+
if (pathname != null && pathname.startsWith(HMR_ENDPOINT)) {
|
|
100
|
+
let id = pathname.slice(HMR_ENDPOINT.length + 1);
|
|
101
|
+
let bundleGraph = (0, _nullthrows().default)(this.bundleGraph);
|
|
102
|
+
let asset = bundleGraph.getAssetById(id);
|
|
103
|
+
this.getHotAssetContents(asset).then(output => {
|
|
104
|
+
res.setHeader('Content-Type', _mimeTypes().default.contentType(asset.type));
|
|
105
|
+
res.end(output);
|
|
106
|
+
});
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
async stop() {
|
|
112
|
+
if (this.stopServer != null) {
|
|
113
|
+
await this.stopServer();
|
|
114
|
+
this.stopServer = null;
|
|
115
|
+
}
|
|
116
|
+
this.wss.close();
|
|
117
|
+
}
|
|
118
|
+
async emitError(options, diagnostics) {
|
|
119
|
+
let renderedDiagnostics = await Promise.all(diagnostics.map(d => (0, _utils().prettyDiagnostic)(d, options)));
|
|
120
|
+
|
|
121
|
+
// store the most recent error so we can notify new connections
|
|
122
|
+
// and so we can broadcast when the error is resolved
|
|
123
|
+
this.unresolvedError = {
|
|
124
|
+
type: 'error',
|
|
125
|
+
diagnostics: {
|
|
126
|
+
ansi: renderedDiagnostics,
|
|
127
|
+
html: renderedDiagnostics.map((d, i) => {
|
|
128
|
+
return {
|
|
129
|
+
message: (0, _utils().ansiHtml)(d.message),
|
|
130
|
+
stack: (0, _utils().ansiHtml)(d.stack),
|
|
131
|
+
frames: d.frames.map(f => ({
|
|
132
|
+
location: f.location,
|
|
133
|
+
code: (0, _utils().ansiHtml)(f.code)
|
|
134
|
+
})),
|
|
135
|
+
hints: d.hints.map(hint => (0, _utils().ansiHtml)(hint)),
|
|
136
|
+
documentation: diagnostics[i].documentationURL ?? ''
|
|
137
|
+
};
|
|
138
|
+
})
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
this.broadcast(this.unresolvedError);
|
|
142
|
+
}
|
|
143
|
+
async emitUpdate(event) {
|
|
144
|
+
this.unresolvedError = null;
|
|
145
|
+
this.bundleGraph = event.bundleGraph;
|
|
146
|
+
let changedAssets = new Set(event.changedAssets.values());
|
|
147
|
+
if (changedAssets.size === 0) return;
|
|
148
|
+
let queue = new (_utils().PromiseQueue)({
|
|
149
|
+
maxConcurrent: FS_CONCURRENCY
|
|
150
|
+
});
|
|
151
|
+
for (let asset of changedAssets) {
|
|
152
|
+
if (asset.type !== 'js' && asset.type !== 'css') {
|
|
153
|
+
// If all of the incoming dependencies of the asset actually resolve to a JS asset
|
|
154
|
+
// rather than the original, we can mark the runtimes as changed instead. URL runtimes
|
|
155
|
+
// have a cache busting query param added with HMR enabled which will trigger a reload.
|
|
156
|
+
let runtimes = new Set();
|
|
157
|
+
let incomingDeps = event.bundleGraph.getIncomingDependencies(asset);
|
|
158
|
+
let isOnlyReferencedByRuntimes = incomingDeps.every(dep => {
|
|
159
|
+
let resolved = event.bundleGraph.getResolvedAsset(dep);
|
|
160
|
+
let isRuntime = (resolved === null || resolved === void 0 ? void 0 : resolved.type) === 'js' && resolved !== asset;
|
|
161
|
+
if (resolved && isRuntime) {
|
|
162
|
+
runtimes.add(resolved);
|
|
163
|
+
}
|
|
164
|
+
return isRuntime;
|
|
165
|
+
});
|
|
166
|
+
if (isOnlyReferencedByRuntimes) {
|
|
167
|
+
for (let runtime of runtimes) {
|
|
168
|
+
changedAssets.add(runtime);
|
|
169
|
+
}
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
queue.add(async () => {
|
|
174
|
+
let dependencies = event.bundleGraph.getDependencies(asset);
|
|
175
|
+
let depsByBundle = {};
|
|
176
|
+
for (let bundle of event.bundleGraph.getBundlesWithAsset(asset)) {
|
|
177
|
+
let deps = {};
|
|
178
|
+
for (let dep of dependencies) {
|
|
179
|
+
let resolved = event.bundleGraph.getResolvedAsset(dep, bundle);
|
|
180
|
+
if (resolved) {
|
|
181
|
+
deps[getSpecifier(dep)] = event.bundleGraph.getAssetPublicId(resolved);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
depsByBundle[bundle.id] = deps;
|
|
185
|
+
}
|
|
186
|
+
return {
|
|
187
|
+
id: event.bundleGraph.getAssetPublicId(asset),
|
|
188
|
+
url: this.getSourceURL(asset),
|
|
189
|
+
type: asset.type,
|
|
190
|
+
// No need to send the contents of non-JS assets to the client.
|
|
191
|
+
output: asset.type === 'js' ? await this.getHotAssetContents(asset) : '',
|
|
192
|
+
envHash: asset.env.id,
|
|
193
|
+
outputFormat: asset.env.outputFormat,
|
|
194
|
+
depsByBundle
|
|
195
|
+
};
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
let assets = await queue.run();
|
|
199
|
+
if (assets.length >= BROADCAST_MAX_ASSETS) {
|
|
200
|
+
// Too many assets to send via an update without errors, just reload instead
|
|
201
|
+
this.broadcast({
|
|
202
|
+
type: 'reload'
|
|
203
|
+
});
|
|
204
|
+
} else {
|
|
205
|
+
this.broadcast({
|
|
206
|
+
type: 'update',
|
|
207
|
+
assets
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
async getHotAssetContents(asset) {
|
|
212
|
+
let output = await asset.getCode();
|
|
213
|
+
let bundleGraph = (0, _nullthrows().default)(this.bundleGraph);
|
|
214
|
+
if (asset.type === 'js') {
|
|
215
|
+
let publicId = bundleGraph.getAssetPublicId(asset);
|
|
216
|
+
output = `parcelHotUpdate['${publicId}'] = function (require, module, exports) {${output}}`;
|
|
217
|
+
}
|
|
218
|
+
let sourcemap = await asset.getMap();
|
|
219
|
+
if (sourcemap) {
|
|
220
|
+
let sourcemapStringified = await sourcemap.stringify({
|
|
221
|
+
format: 'inline',
|
|
222
|
+
sourceRoot: _Server.SOURCES_ENDPOINT + '/',
|
|
223
|
+
// $FlowFixMe
|
|
224
|
+
fs: asset.fs
|
|
225
|
+
});
|
|
226
|
+
(0, _assert().default)(typeof sourcemapStringified === 'string');
|
|
227
|
+
output += `\n//# sourceMappingURL=${sourcemapStringified}`;
|
|
228
|
+
output += `\n//# sourceURL=${encodeURI(this.getSourceURL(asset))}\n`;
|
|
229
|
+
}
|
|
230
|
+
return output;
|
|
231
|
+
}
|
|
232
|
+
getSourceURL(asset) {
|
|
233
|
+
let origin = '';
|
|
234
|
+
if (!this.options.devServer) {
|
|
235
|
+
origin = `http://${this.options.host || 'localhost'}:${this.options.port}`;
|
|
236
|
+
}
|
|
237
|
+
return origin + HMR_ENDPOINT + '/' + asset.id;
|
|
238
|
+
}
|
|
239
|
+
handleSocketError(err) {
|
|
240
|
+
if (err.code === 'ECONNRESET') {
|
|
241
|
+
// This gets triggered on page refresh, ignore this
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
this.options.logger.warn({
|
|
245
|
+
origin: '@atlaspack/reporter-dev-server',
|
|
246
|
+
message: `[${err.code}]: ${err.message}`,
|
|
247
|
+
stack: err.stack
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
broadcast(msg) {
|
|
251
|
+
const json = JSON.stringify(msg);
|
|
252
|
+
for (let ws of this.wss.clients) {
|
|
253
|
+
ws.send(json);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
exports.default = HMRServer;
|
|
258
|
+
function getSpecifier(dep) {
|
|
259
|
+
if (typeof dep.meta.placeholder === 'string') {
|
|
260
|
+
return dep.meta.placeholder;
|
|
261
|
+
}
|
|
262
|
+
return dep.specifier;
|
|
263
|
+
}
|