@jsenv/core 38.4.17 → 38.4.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.
@@ -0,0 +1,18 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Directory explorer</title>
5
+ <meta charset="utf-8">
6
+ <link rel="icon" href="data:,">
7
+ </head>
8
+
9
+ <body>
10
+ <h1>
11
+ <a jsenv-ignore="" href="/${directoryRelativeUrl}">/${directoryRelativeUrl}</a>
12
+ directory content:
13
+ </h1>
14
+ <ul>
15
+ ${directoryContent}
16
+ </ul>
17
+ </body>
18
+ </html>
@@ -0,0 +1,19 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>404 ENOENT</title>
5
+ <meta charset="utf-8">
6
+ <link rel="icon" href="data:,">
7
+ </head>
8
+
9
+ <body>
10
+ <p>No entry on the filesystem for <strong>/${fileRelativeUrl}</strong></p>
11
+ <p>
12
+ <a jsenv-ignore="" href="/${parentDirectoryRelativeUrl}">/${parentDirectoryRelativeUrl}</a>
13
+ directory content:
14
+ </p>
15
+ <ul>
16
+ ${parentDirectoryContent}
17
+ </ul>
18
+ </body>
19
+ </html>
@@ -0,0 +1,16 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>404 ENOENT</title>
5
+ <meta charset="utf-8">
6
+ <link rel="icon" href="data:,">
7
+ </head>
8
+
9
+ <body>
10
+ <p>No entry on the filesystem for <strong>/${fileRelativeUrl}</strong></p>
11
+ <p>
12
+ <a jsenv-ignore="" href="/${parentDirectoryRelativeUrl}">/${parentDirectoryRelativeUrl}</a>
13
+ directory is empty.
14
+ </p>
15
+ </body>
16
+ </html>
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Syntax error in HTML</title>
5
+ <meta charset="utf-8">
6
+ <link rel="icon" href="data:,">
7
+ </head>
8
+
9
+ <body>
10
+ <p>Syntax error: <strong>${reasonCode}</strong></p>
11
+ <a jsenv-ignore="" href="${errorLinkHref}">${errorLinkText}</a>
12
+ <pre>${syntaxError}</pre>
13
+ </body>
14
+ </html>
@@ -146,130 +146,130 @@ const reloadJsImport = async (url, hot) => {
146
146
  return namespace;
147
147
  };
148
148
 
149
- const reloader = {
150
- urlHotMetas,
151
- status: {
152
- value: "idle",
153
- onchange: () => {},
154
- goTo: (value) => {
155
- reloader.status.value = value;
156
- reloader.status.onchange();
149
+ const initAutoreload = ({ mainFilePath }) => {
150
+ const reloader = {
151
+ urlHotMetas,
152
+ status: {
153
+ value: "idle",
154
+ onchange: () => {},
155
+ goTo: (value) => {
156
+ reloader.status.value = value;
157
+ reloader.status.onchange();
158
+ },
157
159
  },
158
- },
159
- autoreload: {
160
- enabled: ["1", null].includes(window.localStorage.getItem("autoreload")),
161
- onchange: () => {},
162
- enable: () => {
163
- reloader.autoreload.enabled = true;
164
- window.localStorage.setItem("autoreload", "1");
165
- reloader.autoreload.onchange();
160
+ autoreload: {
161
+ enabled: ["1", null].includes(window.localStorage.getItem("autoreload")),
162
+ onchange: () => {},
163
+ enable: () => {
164
+ reloader.autoreload.enabled = true;
165
+ window.localStorage.setItem("autoreload", "1");
166
+ reloader.autoreload.onchange();
167
+ },
168
+ disable: () => {
169
+ reloader.autoreload.enabled = false;
170
+ window.localStorage.setItem("autoreload", "0");
171
+ reloader.autoreload.onchange();
172
+ },
166
173
  },
167
- disable: () => {
168
- reloader.autoreload.enabled = false;
169
- window.localStorage.setItem("autoreload", "0");
170
- reloader.autoreload.onchange();
174
+ changes: {
175
+ value: [],
176
+ onchange: () => {},
177
+ add: (reloadMessage) => {
178
+ reloader.changes.value.push(reloadMessage);
179
+ reloader.changes.onchange();
180
+ if (reloader.autoreload.enabled) {
181
+ reloader.reload();
182
+ } else {
183
+ reloader.status.goTo("can_reload");
184
+ }
185
+ },
186
+ remove: (reloadMessage) => {
187
+ const index = reloader.changes.value.indexOf(reloadMessage);
188
+ if (index > -1) {
189
+ reloader.changes.value.splice(index, 1);
190
+ if (reloader.changes.value.length === 0) {
191
+ reloader.status.goTo("idle");
192
+ }
193
+ reloader.changes.onchange();
194
+ }
195
+ },
171
196
  },
172
- },
173
- changes: {
174
- value: [],
175
- onchange: () => {},
176
- add: (reloadMessage) => {
177
- reloader.changes.value.push(reloadMessage);
178
- reloader.changes.onchange();
179
- if (reloader.autoreload.enabled) {
180
- reloader.reload();
181
- } else {
182
- reloader.status.goTo("can_reload");
197
+ currentExecution: null,
198
+ reload: () => {
199
+ const someEffectIsFullReload = reloader.changes.value.some(
200
+ (reloadMessage) => reloadMessage.type === "full",
201
+ );
202
+ if (someEffectIsFullReload) {
203
+ reloadHtmlPage();
204
+ return;
183
205
  }
184
- },
185
- remove: (reloadMessage) => {
186
- const index = reloader.changes.value.indexOf(reloadMessage);
187
- if (index > -1) {
188
- reloader.changes.value.splice(index, 1);
189
- if (reloader.changes.value.length === 0) {
190
- reloader.status.goTo("idle");
206
+ reloader.status.goTo("reloading");
207
+ const onApplied = (reloadMessage) => {
208
+ reloader.changes.remove(reloadMessage);
209
+ };
210
+ const setReloadMessagePromise = (reloadMessage, promise) => {
211
+ promise.then(
212
+ () => {
213
+ onApplied(reloadMessage);
214
+ reloader.currentExecution = null;
215
+ },
216
+ (e) => {
217
+ reloader.status.goTo("failed");
218
+ if (typeof window.reportError === "function") {
219
+ window.reportError(e);
220
+ } else {
221
+ console.error(e);
222
+ }
223
+ console.error(
224
+ `[jsenv] Hot reload failed after ${reloadMessage.reason}.
225
+ This could be due to syntax errors or importing non-existent modules (see errors in console)`,
226
+ );
227
+ reloader.currentExecution = null;
228
+ },
229
+ );
230
+ };
231
+ reloader.changes.value.forEach((reloadMessage) => {
232
+ if (reloadMessage.type === "hot") {
233
+ const promise = addToHotQueue(() => {
234
+ return applyHotReload(reloadMessage);
235
+ });
236
+ setReloadMessagePromise(reloadMessage, promise);
237
+ } else {
238
+ setReloadMessagePromise(reloadMessage, Promise.resolve());
191
239
  }
192
- reloader.changes.onchange();
193
- }
240
+ });
194
241
  },
195
- },
196
- currentExecution: null,
197
- reload: () => {
198
- const someEffectIsFullReload = reloader.changes.value.some(
199
- (reloadMessage) => reloadMessage.type === "full",
200
- );
201
- if (someEffectIsFullReload) {
202
- reloadHtmlPage();
242
+ };
243
+
244
+ let pendingCallbacks = [];
245
+ let running = false;
246
+ const addToHotQueue = async (callback) => {
247
+ pendingCallbacks.push(callback);
248
+ dequeue();
249
+ };
250
+ const dequeue = async () => {
251
+ if (running) {
203
252
  return;
204
253
  }
205
- reloader.status.goTo("reloading");
206
- const onApplied = (reloadMessage) => {
207
- reloader.changes.remove(reloadMessage);
208
- };
209
- const setReloadMessagePromise = (reloadMessage, promise) => {
210
- promise.then(
211
- () => {
212
- onApplied(reloadMessage);
213
- reloader.currentExecution = null;
214
- },
215
- (e) => {
216
- reloader.status.goTo("failed");
217
- if (typeof window.reportError === "function") {
218
- window.reportError(e);
219
- } else {
220
- console.error(e);
221
- }
222
- console.error(
223
- `[jsenv] Hot reload failed after ${reloadMessage.reason}.
224
- This could be due to syntax errors or importing non-existent modules (see errors in console)`,
225
- );
226
- reloader.currentExecution = null;
227
- },
228
- );
229
- };
230
- reloader.changes.value.forEach((reloadMessage) => {
231
- if (reloadMessage.type === "hot") {
232
- const promise = addToHotQueue(() => {
233
- return applyHotReload(reloadMessage);
234
- });
235
- setReloadMessagePromise(reloadMessage, promise);
236
- } else {
237
- setReloadMessagePromise(reloadMessage, Promise.resolve());
254
+ const callbacks = pendingCallbacks.slice();
255
+ pendingCallbacks = [];
256
+ running = true;
257
+ try {
258
+ await callbacks.reduce(async (previous, callback) => {
259
+ await previous;
260
+ await callback();
261
+ }, Promise.resolve());
262
+ } finally {
263
+ running = false;
264
+ if (pendingCallbacks.length) {
265
+ dequeue();
238
266
  }
239
- });
240
- },
241
- };
242
-
243
- let pendingCallbacks = [];
244
- let running = false;
245
- const addToHotQueue = async (callback) => {
246
- pendingCallbacks.push(callback);
247
- dequeue();
248
- };
249
- const dequeue = async () => {
250
- if (running) {
251
- return;
252
- }
253
- const callbacks = pendingCallbacks.slice();
254
- pendingCallbacks = [];
255
- running = true;
256
- try {
257
- await callbacks.reduce(async (previous, callback) => {
258
- await previous;
259
- await callback();
260
- }, Promise.resolve());
261
- } finally {
262
- running = false;
263
- if (pendingCallbacks.length) {
264
- dequeue();
265
267
  }
266
- }
267
- };
268
+ };
268
269
 
269
- const applyHotReload = async ({ cause, hotInstructions }) => {
270
- await hotInstructions.reduce(
271
- async (previous, { type, boundary, acceptedBy }) => {
272
- await previous;
270
+ const applyHotReload = async ({ cause, hotInstructions }) => {
271
+ for (const instruction of hotInstructions) {
272
+ const { type, boundary, acceptedBy } = instruction;
273
273
 
274
274
  const hot = Date.now();
275
275
  const urlToFetch = new URL(boundary, `${window.location.origin}/`).href;
@@ -277,7 +277,6 @@ const applyHotReload = async ({ cause, hotInstructions }) => {
277
277
  // there is no url hot meta when:
278
278
  // - code was not executed (code splitting with dynamic import)
279
279
  // - import.meta.hot.accept() is not called (happens for HTML and CSS)
280
-
281
280
  if (type === "prune") {
282
281
  if (urlHotMeta) {
283
282
  delete urlHotMetas[urlToFetch];
@@ -290,9 +289,8 @@ const applyHotReload = async ({ cause, hotInstructions }) => {
290
289
  console.groupEnd();
291
290
  }
292
291
  }
293
- return null;
292
+ continue;
294
293
  }
295
-
296
294
  if (acceptedBy === boundary) {
297
295
  console.groupCollapsed(`[jsenv] hot reloading ${boundary} (${cause})`);
298
296
  } else {
@@ -303,7 +301,7 @@ const applyHotReload = async ({ cause, hotInstructions }) => {
303
301
  if (type === "js_module") {
304
302
  if (!urlHotMeta) {
305
303
  // code was not executed, no need to re-execute it
306
- return null;
304
+ continue;
307
305
  }
308
306
  if (urlHotMeta.disposeCallback) {
309
307
  console.log(`call dispose callback`);
@@ -320,18 +318,23 @@ const applyHotReload = async ({ cause, hotInstructions }) => {
320
318
  }
321
319
  console.log(`js module import done`);
322
320
  console.groupEnd();
323
- return namespace;
321
+ continue;
324
322
  }
325
323
  if (type === "html") {
326
- const isRootHtmlFile =
327
- window.location.pathname === "/" &&
328
- new URL(urlToFetch).pathname.slice(1).indexOf("/") === -1;
324
+ let isRootHtmlFile;
325
+ if (window.location.pathname === "/") {
326
+ if (new URL(urlToFetch).pathname.slice(1).indexOf("/") === -1) {
327
+ isRootHtmlFile = true;
328
+ } else if (new URL(urlToFetch).pathname === mainFilePath) {
329
+ isRootHtmlFile = true;
330
+ }
331
+ }
329
332
  if (
330
333
  !isRootHtmlFile &&
331
334
  !compareTwoUrlPaths(urlToFetch, window.location.href)
332
335
  ) {
333
336
  // we are not in that HTML page
334
- return null;
337
+ continue;
335
338
  }
336
339
  const urlToReload = new URL(acceptedBy, `${window.location.origin}/`)
337
340
  .href;
@@ -349,18 +352,18 @@ const applyHotReload = async ({ cause, hotInstructions }) => {
349
352
  });
350
353
  }
351
354
  console.groupEnd();
352
- return null;
355
+ continue;
353
356
  }
354
357
  console.warn(`unknown update type: "${type}"`);
355
- return null;
358
+ }
359
+ };
360
+
361
+ window.__reloader__ = reloader;
362
+ window.__server_events__.listenEvents({
363
+ reload: (reloadServerEvent) => {
364
+ reloader.changes.add(reloadServerEvent.data);
356
365
  },
357
- Promise.resolve(),
358
- );
366
+ });
359
367
  };
360
368
 
361
- window.__reloader__ = reloader;
362
- window.__server_events__.listenEvents({
363
- reload: (reloadServerEvent) => {
364
- reloader.changes.add(reloadServerEvent.data);
365
- },
366
- });
369
+ export { initAutoreload };