@atlaspack/reporter-dev-server 2.14.5-canary.49 → 2.14.5-canary.490

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