@jsenv/core 28.0.0 → 28.1.0

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 (67) hide show
  1. package/dist/controllable_child_process.mjs +1 -2
  2. package/dist/controllable_worker_thread.mjs +1 -2
  3. package/dist/js/autoreload.js +27 -11
  4. package/dist/js/execute_using_dynamic_import.js +804 -1
  5. package/dist/js/script_type_module_supervisor.js +129 -0
  6. package/dist/js/supervisor.js +921 -0
  7. package/dist/js/{wrapper.mjs → ws.js} +0 -0
  8. package/dist/main.js +555 -616
  9. package/package.json +13 -13
  10. package/readme.md +2 -2
  11. package/src/build/build.js +8 -8
  12. package/src/build/inject_global_version_mappings.js +3 -3
  13. package/src/build/{resync_ressource_hints.js → resync_resource_hints.js} +10 -12
  14. package/src/build/start_build_server.js +4 -7
  15. package/src/dev/start_dev_server.js +2 -2
  16. package/src/execute/execute.js +1 -1
  17. package/src/execute/run.js +26 -38
  18. package/src/execute/runtimes/browsers/from_playwright.js +51 -77
  19. package/src/execute/runtimes/node/node_child_process.js +36 -36
  20. package/src/execute/runtimes/node/node_worker_thread.js +36 -36
  21. package/src/omega/kitchen.js +33 -14
  22. package/src/omega/omega_server.js +2 -2
  23. package/src/omega/server/file_service.js +5 -5
  24. package/src/omega/url_graph/url_graph_load.js +4 -4
  25. package/src/omega/url_graph/url_info_transformations.js +8 -1
  26. package/src/omega/url_graph.js +3 -3
  27. package/src/plugins/autoreload/client/reload.js +22 -9
  28. package/src/plugins/autoreload/jsenv_plugin_autoreload_client.js +5 -5
  29. package/src/plugins/autoreload/jsenv_plugin_autoreload_server.js +3 -3
  30. package/src/plugins/autoreload/jsenv_plugin_hmr.js +1 -1
  31. package/src/plugins/explorer/jsenv_plugin_explorer.js +1 -1
  32. package/src/plugins/import_meta_hot/html_hot_dependencies.js +6 -6
  33. package/src/plugins/importmap/jsenv_plugin_importmap.js +5 -3
  34. package/src/plugins/inject_globals/inject_globals.js +3 -3
  35. package/src/plugins/inline/jsenv_plugin_data_urls.js +1 -1
  36. package/src/plugins/inline/jsenv_plugin_html_inline_content.js +10 -5
  37. package/src/plugins/node_esm_resolution/jsenv_plugin_node_esm_resolution.js +2 -13
  38. package/src/plugins/plugin_controller.js +2 -2
  39. package/src/plugins/plugins.js +5 -5
  40. package/src/plugins/server_events/jsenv_plugin_server_events_client_injection.js +4 -4
  41. package/src/plugins/supervisor/client/script_type_module_supervisor.js +108 -0
  42. package/src/plugins/supervisor/client/supervisor.js +921 -0
  43. package/src/plugins/{html_supervisor/jsenv_plugin_html_supervisor.js → supervisor/jsenv_plugin_supervisor.js} +131 -105
  44. package/src/plugins/toolbar/client/execution/toolbar_execution.js +1 -1
  45. package/src/plugins/toolbar/jsenv_plugin_toolbar.js +5 -5
  46. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic.js +9 -7
  47. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic_html.js +8 -7
  48. package/src/plugins/transpilation/babel/jsenv_plugin_babel.js +13 -7
  49. package/src/plugins/transpilation/babel/new_stylesheet/babel_plugin_new_stylesheet_as_jsenv_import.js +6 -4
  50. package/src/plugins/transpilation/jsenv_plugin_transpilation.js +4 -2
  51. package/src/plugins/url_analysis/html/html_urls.js +13 -12
  52. package/src/plugins/url_analysis/jsenv_plugin_url_analysis.js +1 -1
  53. package/src/test/coverage/babel_plugin_instrument.js +1 -35
  54. package/src/test/coverage/empty_coverage_factory.js +1 -1
  55. package/src/test/execute_plan.js +7 -3
  56. package/src/test/execute_test_plan.js +2 -1
  57. package/src/test/logs_file_execution.js +49 -8
  58. package/dist/js/html_supervisor_installer.js +0 -1091
  59. package/dist/js/html_supervisor_setup.js +0 -89
  60. package/dist/js/uneval.js +0 -804
  61. package/src/plugins/html_supervisor/client/error_formatter.js +0 -426
  62. package/src/plugins/html_supervisor/client/error_in_notification.js +0 -21
  63. package/src/plugins/html_supervisor/client/error_overlay.js +0 -191
  64. package/src/plugins/html_supervisor/client/html_supervisor_installer.js +0 -315
  65. package/src/plugins/html_supervisor/client/html_supervisor_setup.js +0 -89
  66. package/src/plugins/html_supervisor/client/perf_browser.js +0 -17
  67. package/src/plugins/html_supervisor/client/uneval_exception.js +0 -8
package/dist/main.js CHANGED
@@ -23,7 +23,7 @@ import v8, { takeCoverage } from "node:v8";
23
23
  import wrapAnsi from "wrap-ansi";
24
24
  import stripAnsi from "strip-ansi";
25
25
  import cuid from "cuid";
26
- import { runInNewContext, Script } from "node:vm";
26
+ import { runInNewContext } from "node:vm";
27
27
  import { fork } from "node:child_process";
28
28
 
29
29
  /*
@@ -94,7 +94,7 @@ const urlToScheme$1 = url => {
94
94
  return scheme;
95
95
  };
96
96
 
97
- const urlToRessource$1 = url => {
97
+ const urlToResource = url => {
98
98
  const scheme = urlToScheme$1(url);
99
99
 
100
100
  if (scheme === "file") {
@@ -115,25 +115,25 @@ const urlToRessource$1 = url => {
115
115
  };
116
116
 
117
117
  const urlToPathname$1 = url => {
118
- const ressource = urlToRessource$1(url);
119
- const pathname = ressourceToPathname$1(ressource);
118
+ const resource = urlToResource(url);
119
+ const pathname = resourceToPathname(resource);
120
120
  return pathname;
121
121
  };
122
122
 
123
- const ressourceToPathname$1 = ressource => {
124
- const searchSeparatorIndex = ressource.indexOf("?");
123
+ const resourceToPathname = resource => {
124
+ const searchSeparatorIndex = resource.indexOf("?");
125
125
 
126
126
  if (searchSeparatorIndex > -1) {
127
- return ressource.slice(0, searchSeparatorIndex);
127
+ return resource.slice(0, searchSeparatorIndex);
128
128
  }
129
129
 
130
- const hashIndex = ressource.indexOf("#");
130
+ const hashIndex = resource.indexOf("#");
131
131
 
132
132
  if (hashIndex > -1) {
133
- return ressource.slice(0, hashIndex);
133
+ return resource.slice(0, hashIndex);
134
134
  }
135
135
 
136
- return ressource;
136
+ return resource;
137
137
  };
138
138
 
139
139
  const urlToFilename$1 = url => {
@@ -616,8 +616,8 @@ const urlToRelativeUrl = (url, baseUrl) => {
616
616
  } = urlObject;
617
617
 
618
618
  if (pathname === "/") {
619
- const baseUrlRessourceWithoutLeadingSlash = baseUrlObject.pathname.slice(1);
620
- return baseUrlRessourceWithoutLeadingSlash;
619
+ const baseUrlResourceWithoutLeadingSlash = baseUrlObject.pathname.slice(1);
620
+ return baseUrlResourceWithoutLeadingSlash;
621
621
  }
622
622
 
623
623
  const basePathname = baseUrlObject.pathname;
@@ -1159,7 +1159,7 @@ const removeNoop = () => {};
1159
1159
  */
1160
1160
  const Abort = {
1161
1161
  isAbortError: error => {
1162
- return error.name === "AbortError";
1162
+ return error && error.name === "AbortError";
1163
1163
  },
1164
1164
  startOperation: () => {
1165
1165
  return createOperation();
@@ -1475,52 +1475,44 @@ const readDirectory = async (url, {
1475
1475
  emfileMaxWait = 1000
1476
1476
  } = {}) => {
1477
1477
  const directoryUrl = assertAndNormalizeDirectoryUrl(url);
1478
- const directoryPath = urlToFileSystemPath(directoryUrl);
1478
+ const directoryUrlObject = new URL(directoryUrl);
1479
1479
  const startMs = Date.now();
1480
1480
  let attemptCount = 0;
1481
1481
 
1482
- const attempt = () => {
1483
- return readdirNaive(directoryPath, {
1484
- handleTooManyFilesOpenedError: async error => {
1482
+ const attempt = async () => {
1483
+ try {
1484
+ const names = await new Promise((resolve, reject) => {
1485
+ readdir(directoryUrlObject, (error, names) => {
1486
+ if (error) {
1487
+ reject(error);
1488
+ } else {
1489
+ resolve(names);
1490
+ }
1491
+ });
1492
+ });
1493
+ return names.map(encodeURIComponent);
1494
+ } catch (e) {
1495
+ // https://nodejs.org/dist/latest-v13.x/docs/api/errors.html#errors_common_system_errors
1496
+ if (e.code === "EMFILE" || e.code === "ENFILE") {
1485
1497
  attemptCount++;
1486
1498
  const nowMs = Date.now();
1487
1499
  const timeSpentWaiting = nowMs - startMs;
1488
1500
 
1489
1501
  if (timeSpentWaiting > emfileMaxWait) {
1490
- throw error;
1502
+ throw e;
1491
1503
  }
1492
1504
 
1493
- return new Promise(resolve => {
1494
- setTimeout(() => {
1495
- resolve(attempt());
1496
- }, attemptCount);
1497
- });
1505
+ await new Promise(resolve => setTimeout(resolve), attemptCount);
1506
+ return await attempt();
1498
1507
  }
1499
- });
1508
+
1509
+ throw e;
1510
+ }
1500
1511
  };
1501
1512
 
1502
1513
  return attempt();
1503
1514
  };
1504
1515
 
1505
- const readdirNaive = (directoryPath, {
1506
- handleTooManyFilesOpenedError = null
1507
- } = {}) => {
1508
- return new Promise((resolve, reject) => {
1509
- readdir(directoryPath, (error, names) => {
1510
- if (error) {
1511
- // https://nodejs.org/dist/latest-v13.x/docs/api/errors.html#errors_common_system_errors
1512
- if (handleTooManyFilesOpenedError && (error.code === "EMFILE" || error.code === "ENFILE")) {
1513
- resolve(handleTooManyFilesOpenedError(error));
1514
- } else {
1515
- reject(error);
1516
- }
1517
- } else {
1518
- resolve(names);
1519
- }
1520
- });
1521
- });
1522
- };
1523
-
1524
1516
  const comparePathnames = (leftPathame, rightPathname) => {
1525
1517
  const leftPartArray = leftPathame.split("/");
1526
1518
  const rightPartArray = rightPathname.split("/");
@@ -2006,10 +1998,10 @@ const ensureWindowsDriveLetter = (url, baseUrl) => {
2006
1998
  return `file:///${driveLetter}:${afterProtocol}`;
2007
1999
  };
2008
2000
 
2009
- const extractDriveLetter = ressource => {
2001
+ const extractDriveLetter = resource => {
2010
2002
  // we still have the windows drive letter
2011
- if (/[a-zA-Z]/.test(ressource[1]) && ressource[2] === ":") {
2012
- return ressource[1];
2003
+ if (/[a-zA-Z]/.test(resource[1]) && resource[2] === ":") {
2004
+ return resource[1];
2013
2005
  }
2014
2006
 
2015
2007
  return null;
@@ -2136,7 +2128,7 @@ const createWatcher = (sourcePath, options) => {
2136
2128
  return watcher;
2137
2129
  };
2138
2130
 
2139
- const trackRessources = () => {
2131
+ const trackResources = () => {
2140
2132
  const callbackArray = [];
2141
2133
 
2142
2134
  const registerCleanupCallback = callback => {
@@ -2244,7 +2236,7 @@ const registerDirectoryLifecycle = (source, {
2244
2236
  return watch;
2245
2237
  };
2246
2238
 
2247
- const tracker = trackRessources();
2239
+ const tracker = trackResources();
2248
2240
  const infoMap = new Map();
2249
2241
 
2250
2242
  const readEntryInfo = url => {
@@ -2380,7 +2372,7 @@ const registerDirectoryLifecycle = (source, {
2380
2372
 
2381
2373
  if (entryInfo.type !== previousInfo.type) {
2382
2374
  // it existed and was replaced by something else
2383
- // we don't handle this as an update. We rather say the ressource
2375
+ // we don't handle this as an update. We rather say the resource
2384
2376
  // is lost and something else is found (call removed() then added())
2385
2377
  handleEntryLost(previousInfo);
2386
2378
  handleEntryFound(entryInfo);
@@ -2591,7 +2583,7 @@ const registerFileLifecycle = (source, {
2591
2583
  }
2592
2584
  }
2593
2585
 
2594
- const tracker = trackRessources();
2586
+ const tracker = trackResources();
2595
2587
 
2596
2588
  const handleFileFound = ({
2597
2589
  existent
@@ -3080,6 +3072,7 @@ const FAILURE_RAW = canUseUnicode ? `✖` : `×`;
3080
3072
  const DEBUG_RAW = canUseUnicode ? `◆` : `♦`;
3081
3073
  const INFO_RAW = canUseUnicode ? `ℹ` : `i`;
3082
3074
  const WARNING_RAW = canUseUnicode ? `⚠` : `‼`;
3075
+ const CIRCLE_CROSS_RAW = canUseUnicode ? `ⓧ` : `(×)`;
3083
3076
  const COMMAND = ANSI.color(COMMAND_RAW, ANSI.GREY); // ANSI_MAGENTA)
3084
3077
 
3085
3078
  const OK = ANSI.color(OK_RAW, ANSI.GREEN);
@@ -3087,6 +3080,7 @@ const FAILURE = ANSI.color(FAILURE_RAW, ANSI.RED);
3087
3080
  const DEBUG = ANSI.color(DEBUG_RAW, ANSI.GREY);
3088
3081
  const INFO = ANSI.color(INFO_RAW, ANSI.BLUE);
3089
3082
  const WARNING = ANSI.color(WARNING_RAW, ANSI.YELLOW);
3083
+ const CIRCLE_CROSS = ANSI.color(CIRCLE_CROSS_RAW, ANSI.RED);
3090
3084
  const UNICODE = {
3091
3085
  COMMAND,
3092
3086
  OK,
@@ -3094,12 +3088,14 @@ const UNICODE = {
3094
3088
  DEBUG,
3095
3089
  INFO,
3096
3090
  WARNING,
3091
+ CIRCLE_CROSS,
3097
3092
  COMMAND_RAW,
3098
3093
  OK_RAW,
3099
3094
  FAILURE_RAW,
3100
3095
  DEBUG_RAW,
3101
3096
  INFO_RAW,
3102
3097
  WARNING_RAW,
3098
+ CIRCLE_CROSS_RAW,
3103
3099
  supported: canUseUnicode
3104
3100
  };
3105
3101
 
@@ -4014,10 +4010,10 @@ const createUrlGraph = ({
4014
4010
  }
4015
4011
 
4016
4012
  references.forEach(reference => {
4017
- if (reference.isRessourceHint) {
4018
- // ressource hint are a special kind of reference.
4013
+ if (reference.isResourceHint) {
4014
+ // resource hint are a special kind of reference.
4019
4015
  // They are a sort of weak reference to an url.
4020
- // We ignore them so that url referenced only by ressource hints
4016
+ // We ignore them so that url referenced only by resource hints
4021
4017
  // have url.dependents.size === 0 and can be considered as not used
4022
4018
  // It means html won't consider url referenced solely
4023
4019
  // by <link> as dependency and it's fine
@@ -4243,7 +4239,7 @@ const parseAndTransformHtmlUrls = async (urlInfo, context) => {
4243
4239
  crossorigin,
4244
4240
  integrity
4245
4241
  } = readFetchMetas(node);
4246
- const isRessourceHint = ["preconnect", "dns-prefetch", "prefetch", "preload", "modulepreload"].includes(subtype);
4242
+ const isResourceHint = ["preconnect", "dns-prefetch", "prefetch", "preload", "modulepreload"].includes(subtype);
4247
4243
  const [reference] = referenceUtils.found({
4248
4244
  type,
4249
4245
  expectedType,
@@ -4252,7 +4248,7 @@ const parseAndTransformHtmlUrls = async (urlInfo, context) => {
4252
4248
  specifier,
4253
4249
  specifierLine: line,
4254
4250
  specifierColumn: column,
4255
- isRessourceHint,
4251
+ isResourceHint,
4256
4252
  crossorigin,
4257
4253
  integrity
4258
4254
  });
@@ -4305,12 +4301,12 @@ const visitHtmlUrls = ({
4305
4301
  attributeName,
4306
4302
  specifier
4307
4303
  }) => {
4308
- const generatedFromInlineContent = getHtmlNodeAttribute(node, "generated-from-inline-content") !== undefined;
4304
+ const isContentCooked = getHtmlNodeAttribute(node, "jsenv-plugin-action") === "content_cooked";
4309
4305
  let position;
4310
4306
 
4311
- if (generatedFromInlineContent) {
4307
+ if (isContentCooked) {
4312
4308
  // when generated from inline content,
4313
- // line, column is not "src" nor "generated-from-src" but "original-position"
4309
+ // line, column is not "src" nor "inlined-from-src" but "original-position"
4314
4310
  position = getHtmlNodePosition(node);
4315
4311
  } else {
4316
4312
  position = getHtmlNodeAttributePosition(node, attributeName);
@@ -4342,9 +4338,9 @@ const visitHtmlUrls = ({
4342
4338
  const value = getHtmlNodeAttribute(node, attributeName);
4343
4339
 
4344
4340
  if (value) {
4345
- const generatedBy = getHtmlNodeAttribute(node, "generated-by");
4341
+ const jsenvPluginOwner = getHtmlNodeAttribute(node, "jsenv-plugin-owner");
4346
4342
 
4347
- if (generatedBy !== undefined) {
4343
+ if (jsenvPluginOwner === "jsenv:importmap") {
4348
4344
  // during build the importmap is inlined
4349
4345
  // and shoud not be considered as a dependency anymore
4350
4346
  return;
@@ -4353,17 +4349,17 @@ const visitHtmlUrls = ({
4353
4349
  addDependency({ ...rest,
4354
4350
  node,
4355
4351
  attributeName,
4356
- specifier: attributeName === "generated-from-src" || attributeName === "generated-from-href" ? new URL(value, url).href : value
4352
+ specifier: attributeName === "inlined-from-src" || attributeName === "inlined-from-href" ? new URL(value, url).href : value
4357
4353
  });
4358
4354
  } else if (attributeName === "src") {
4359
4355
  visitAttributeAsUrlSpecifier({ ...rest,
4360
4356
  node,
4361
- attributeName: "generated-from-src"
4357
+ attributeName: "inlined-from-src"
4362
4358
  });
4363
4359
  } else if (attributeName === "href") {
4364
4360
  visitAttributeAsUrlSpecifier({ ...rest,
4365
4361
  node,
4366
- attributeName: "generated-from-href"
4362
+ attributeName: "inlined-from-href"
4367
4363
  });
4368
4364
  }
4369
4365
  };
@@ -4413,6 +4409,7 @@ const visitHtmlUrls = ({
4413
4409
  if (type === "text") {
4414
4410
  // ignore <script type="whatever" src="./file.js">
4415
4411
  // per HTML spec https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-type
4412
+ // this will be handled by jsenv_plugin_html_inline_content
4416
4413
  return;
4417
4414
  }
4418
4415
 
@@ -4669,7 +4666,7 @@ const jsenvPluginUrlAnalysis = ({
4669
4666
  return;
4670
4667
  }
4671
4668
 
4672
- if (reference.specifier[0] === "#" && // For Html, css and in general "#" refer to a ressource in the page
4669
+ if (reference.specifier[0] === "#" && // For Html, css and in general "#" refer to a resource in the page
4673
4670
  // so that urls must be kept intact
4674
4671
  // However for js import specifiers they have a different meaning and we want
4675
4672
  // to resolve them (https://nodejs.org/api/packages.html#imports for instance)
@@ -5001,7 +4998,8 @@ const jsenvPluginHtmlInlineContent = ({
5001
4998
  });
5002
4999
  setHtmlNodeText(styleNode, inlineStyleUrlInfo.content);
5003
5000
  setHtmlNodeAttributes(styleNode, {
5004
- "generated-by": "jsenv:html_inline_content"
5001
+ "jsenv-plugin-owner": "jsenv:html_inline_content",
5002
+ "jsenv-plugin-action": "content_cooked"
5005
5003
  });
5006
5004
  });
5007
5005
  },
@@ -5015,13 +5013,13 @@ const jsenvPluginHtmlInlineContent = ({
5015
5013
  // - we want to avoid cooking twice a script during build
5016
5014
 
5017
5015
 
5018
- const generatedBy = getHtmlNodeAttribute(scriptNode, "generated-by");
5016
+ const jsenvPluginOwner = getHtmlNodeAttribute(scriptNode, "jsenv-plugin-owner");
5019
5017
 
5020
- if (generatedBy === "jsenv:as_js_classic_html" && !analyzeConvertedScripts) {
5018
+ if (jsenvPluginOwner === "jsenv:as_js_classic_html" && !analyzeConvertedScripts) {
5021
5019
  return;
5022
5020
  }
5023
5021
 
5024
- if (generatedBy === "jsenv:html_supervisor") {
5022
+ if (jsenvPluginOwner === "jsenv:supervisor") {
5025
5023
  return;
5026
5024
  }
5027
5025
 
@@ -5067,7 +5065,8 @@ const jsenvPluginHtmlInlineContent = ({
5067
5065
  });
5068
5066
  setHtmlNodeText(scriptNode, inlineScriptUrlInfo.content);
5069
5067
  setHtmlNodeAttributes(scriptNode, {
5070
- "generated-by": "jsenv:html_inline_content",
5068
+ "jsenv-plugin-owner": "jsenv:html_inline_content",
5069
+ "jsenv-plugin-action": "content_cooked",
5071
5070
  ...(extension ? {
5072
5071
  type: type === "js_module" ? "module" : undefined
5073
5072
  } : {})
@@ -5605,7 +5604,7 @@ const jsenvPluginDataUrls = () => {
5605
5604
  }
5606
5605
 
5607
5606
  const specifier = DATA_URL.stringify({
5608
- contentType: urlInfo.headers["content-type"],
5607
+ contentType: urlInfo.contentType,
5609
5608
  base64Flag: urlInfo.data.base64Flag,
5610
5609
  data: urlInfo.data.base64Flag ? dataToBase64(urlInfo.content) : String(urlInfo.content)
5611
5610
  });
@@ -5825,10 +5824,10 @@ const jsenvPluginAsJsClassicHtml = ({
5825
5824
  const convertedUrls = [];
5826
5825
 
5827
5826
  const getReferenceAsJsClassic = async (reference, {
5828
- // we don't cook ressource hints
5829
- // because they might refer to ressource that will be modified during build
5827
+ // we don't cook resource hints
5828
+ // because they might refer to resource that will be modified during build
5830
5829
  // It also means something else HAVE to reference that url in order to cook it
5831
- // so that the preload is deleted by "resync_ressource_hints.js" otherwise
5830
+ // so that the preload is deleted by "resync_resource_hints.js" otherwise
5832
5831
  cookIt = false
5833
5832
  } = {}) => {
5834
5833
  const newReferenceProps = {
@@ -5943,7 +5942,8 @@ const jsenvPluginAsJsClassicHtml = ({
5943
5942
  setHtmlNodeText(moduleScriptNode, newUrlInfo.content);
5944
5943
  setHtmlNodeAttributes(moduleScriptNode, {
5945
5944
  "type": undefined,
5946
- "generated-by": "jsenv:as_js_classic_html"
5945
+ "jsenv-plugin-owner": "jsenv:as_js_classic_html",
5946
+ "jsenv-plugin-action": "content_cooked"
5947
5947
  });
5948
5948
  });
5949
5949
  }
@@ -6010,10 +6010,9 @@ const jsenvPluginAsJsClassicHtml = ({
6010
6010
  specifier: systemJsClientFileUrl
6011
6011
  });
6012
6012
  injectScriptNodeAsEarlyAsPossible(htmlAst, createHtmlNode({
6013
- "tagName": "script",
6014
- "src": systemJsReference.generatedSpecifier,
6015
- "injected-by": "jsenv:as_js_classic_html"
6016
- }));
6013
+ tagName: "script",
6014
+ src: systemJsReference.generatedSpecifier
6015
+ }), "jsenv:as_js_classic_html");
6017
6016
  }
6018
6017
  }
6019
6018
 
@@ -10409,7 +10408,7 @@ function default_1({
10409
10408
  * and prefer to unique identifier based solely on the specifier basename for instance
10410
10409
  */
10411
10410
  const jsenvPluginAsJsClassic = ({
10412
- systemJsInjection
10411
+ systemJsInjection = true
10413
10412
  }) => {
10414
10413
  const systemJsClientFileUrl = new URL("./js/s.js", import.meta.url).href;
10415
10414
  return [jsenvPluginAsJsClassicConversion({
@@ -10451,7 +10450,7 @@ const jsenvPluginAsJsClassicConversion = ({
10451
10450
  // - import specifier (static/dynamic import + re-export)
10452
10451
  // - url specifier when inside System.register/_context.import()
10453
10452
  // (because it's the transpiled equivalent of static and dynamic imports)
10454
- // And not other references otherwise we could try to transform inline ressources
10453
+ // And not other references otherwise we could try to transform inline resources
10455
10454
  // or specifiers inside new URL()...
10456
10455
  js_import_export: propagateJsClassicSearchParam,
10457
10456
  js_url_specifier: (reference, context) => {
@@ -10468,7 +10467,7 @@ const jsenvPluginAsJsClassicConversion = ({
10468
10467
  context,
10469
10468
  searchParam: "as_js_classic",
10470
10469
  // override the expectedType to "js_module"
10471
- // because when there is ?as_js_classic it means the underlying ressource
10470
+ // because when there is ?as_js_classic it means the underlying resource
10472
10471
  // is a js_module
10473
10472
  expectedType: "js_module"
10474
10473
  });
@@ -10483,7 +10482,7 @@ const jsenvPluginAsJsClassicConversion = ({
10483
10482
  // - the reference contains ?entry_point
10484
10483
  // When js is entry point there can be no HTML to inject systemjs
10485
10484
  // and systemjs must be injected into the js file
10486
- originalUrlInfo.isEntryPoint && // if it's an entry point without dependency (it does not use import)
10485
+ urlInfo.isEntryPoint && // if it's an entry point without dependency (it does not use import)
10487
10486
  // then we can use UMD, otherwise we have to use systemjs
10488
10487
  // because it is imported by systemjs
10489
10488
  !originalUrlInfo.data.usesImport ? "umd" : "system";
@@ -10493,7 +10492,8 @@ const jsenvPluginAsJsClassicConversion = ({
10493
10492
  } = await convertJsModuleToJsClassic({
10494
10493
  systemJsInjection,
10495
10494
  systemJsClientFileUrl,
10496
- urlInfo: originalUrlInfo,
10495
+ urlInfo,
10496
+ originalUrlInfo,
10497
10497
  jsClassicFormat
10498
10498
  });
10499
10499
  urlInfo.data.jsClassicFormat = jsClassicFormat;
@@ -10537,6 +10537,7 @@ const convertJsModuleToJsClassic = async ({
10537
10537
  systemJsInjection,
10538
10538
  systemJsClientFileUrl,
10539
10539
  urlInfo,
10540
+ originalUrlInfo,
10540
10541
  jsClassicFormat
10541
10542
  }) => {
10542
10543
  const {
@@ -10550,9 +10551,9 @@ const convertJsModuleToJsClassic = async ({
10550
10551
  }]] : [[requireBabelPlugin("babel-plugin-transform-async-to-promises"), {
10551
10552
  topLevelAwait: "simple"
10552
10553
  }], babelPluginTransformImportMetaUrl, requireFromJsenv("@babel/plugin-transform-modules-umd")])],
10553
- urlInfo
10554
+ urlInfo: originalUrlInfo
10554
10555
  });
10555
- let sourcemap = urlInfo.sourcemap;
10556
+ let sourcemap = originalUrlInfo.sourcemap;
10556
10557
  sourcemap = await composeTwoSourcemaps(sourcemap, map);
10557
10558
 
10558
10559
  if (systemJsInjection && jsClassicFormat === "system" && urlInfo.isEntryPoint) {
@@ -11397,7 +11398,8 @@ const jsenvPluginImportmap = () => {
11397
11398
  });
11398
11399
  setHtmlNodeText(importmap, inlineImportmapUrlInfo.content);
11399
11400
  setHtmlNodeAttributes(importmap, {
11400
- "generated-by": "jsenv:importmap"
11401
+ "jsenv-plugin-owner": "jsenv:importmap",
11402
+ "jsenv-plugin-action": "content_cooked"
11401
11403
  });
11402
11404
  onHtmlImportmapParsed(JSON.parse(inlineImportmapUrlInfo.content), htmlUrlInfo.url);
11403
11405
  };
@@ -11417,8 +11419,9 @@ const jsenvPluginImportmap = () => {
11417
11419
  setHtmlNodeText(importmap, importmapUrlInfo.content);
11418
11420
  setHtmlNodeAttributes(importmap, {
11419
11421
  "src": undefined,
11420
- "generated-by": "jsenv:importmap",
11421
- "generated-from-src": src
11422
+ "jsenv-plugin-owner": "jsenv:importmap",
11423
+ "jsenv-plugin-action": "inlined",
11424
+ "inlined-from-src": src
11422
11425
  });
11423
11426
  const {
11424
11427
  line,
@@ -11531,26 +11534,26 @@ const getParentUrl = url => {
11531
11534
  if (url.startsWith("file://")) {
11532
11535
  // With node.js new URL('../', 'file:///C:/').href
11533
11536
  // returns "file:///C:/" instead of "file:///"
11534
- const ressource = url.slice("file://".length);
11535
- const slashLastIndex = ressource.lastIndexOf("/");
11537
+ const resource = url.slice("file://".length);
11538
+ const slashLastIndex = resource.lastIndexOf("/");
11536
11539
 
11537
11540
  if (slashLastIndex === -1) {
11538
11541
  return url;
11539
11542
  }
11540
11543
 
11541
- const lastCharIndex = ressource.length - 1;
11544
+ const lastCharIndex = resource.length - 1;
11542
11545
 
11543
11546
  if (slashLastIndex === lastCharIndex) {
11544
- const slashBeforeLastIndex = ressource.lastIndexOf("/", slashLastIndex - 1);
11547
+ const slashBeforeLastIndex = resource.lastIndexOf("/", slashLastIndex - 1);
11545
11548
 
11546
11549
  if (slashBeforeLastIndex === -1) {
11547
11550
  return url;
11548
11551
  }
11549
11552
 
11550
- return `file://${ressource.slice(0, slashBeforeLastIndex + 1)}`;
11553
+ return `file://${resource.slice(0, slashBeforeLastIndex + 1)}`;
11551
11554
  }
11552
11555
 
11553
- return `file://${ressource.slice(0, slashLastIndex + 1)}`;
11556
+ return `file://${resource.slice(0, slashLastIndex + 1)}`;
11554
11557
  }
11555
11558
 
11556
11559
  return new URL(url.endsWith("/") ? "../" : "./", url).href;
@@ -12862,7 +12865,7 @@ const jsenvPluginNodeEsmResolution = ({
12862
12865
  }
12863
12866
  },
12864
12867
  resolveUrl: {
12865
- js_import_export: (reference, context) => {
12868
+ js_import_export: reference => {
12866
12869
  const {
12867
12870
  parentUrl,
12868
12871
  specifier
@@ -12882,16 +12885,7 @@ const jsenvPluginNodeEsmResolution = ({
12882
12885
  // changes
12883
12886
 
12884
12887
  const dependsOnPackageJson = type !== "relative_specifier" && type !== "absolute_specifier" && type !== "node_builtin_specifier";
12885
- const relatedUrlInfos = context.urlGraph.getRelatedUrlInfos(reference.parentUrl);
12886
- relatedUrlInfos.forEach(relatedUrlInfo => {
12887
- if (relatedUrlInfo.dependsOnPackageJson) {
12888
- // the url may depend due to an other reference
12889
- // in that case keep dependsOnPackageJson to true
12890
- return;
12891
- }
12892
-
12893
- relatedUrlInfo.dependsOnPackageJson = dependsOnPackageJson;
12894
- });
12888
+ reference.dependsOnPackageJson = dependsOnPackageJson;
12895
12889
  return url;
12896
12890
  }
12897
12891
  },
@@ -13173,29 +13167,69 @@ const jsenvPluginHttpUrls = () => {
13173
13167
  };
13174
13168
 
13175
13169
  /*
13176
- * Things happening here
13177
- * - html supervisor module injection
13178
- * - scripts are wrapped to be supervised
13170
+ * Jsenv needs to wait for all js execution inside an HTML page before killing the browser.
13171
+ * A naive approach would consider execution done when "load" event is dispatched on window but:
13172
+ *
13173
+ * scenario | covered by window "load"
13174
+ * ------------------------------------------- | -------------------------
13175
+ * js referenced by <script src> | yes
13176
+ * js inlined into <script> | yes
13177
+ * js referenced by <script type="module" src> | partially (not for import and top level await)
13178
+ * js inlined into <script type="module"> | not at all
13179
+ *
13180
+ * This plugin provides a way for jsenv to know when js execution is done
13181
+ * As a side effect this plugin enables ability to hot reload js inlined into <script hot-accept>
13182
+ *
13183
+ * <script src="file.js">
13184
+ * becomes
13185
+ * <script>
13186
+ * window.__supervisor__.superviseScript({ src: 'file.js' })
13187
+ * </script>
13188
+ *
13189
+ * <script>
13190
+ * console.log(42)
13191
+ * </script>
13192
+ * becomes
13193
+ * <script>
13194
+ * window.__supervisor__.superviseScript({ src: 'main.html@L10-L13.js' })
13195
+ * </script>
13196
+ *
13197
+ * <script type="module" src="module.js"></script>
13198
+ * becomes
13199
+ * <script type="module">
13200
+ * import { superviseScriptTypeModule } from 'supervisor'
13201
+ * superviseScriptTypeModule({ src: "module.js" })
13202
+ * </script>
13203
+ *
13204
+ * <script type="module">
13205
+ * console.log(42)
13206
+ * </script>
13207
+ * becomes
13208
+ * <script type="module">
13209
+ * import { superviseScriptTypeModule } from 'supervisor'
13210
+ * superviseScriptTypeModule({ src: 'main.html@L10-L13.js' })
13211
+ * </script>
13179
13212
  */
13180
- const jsenvPluginHtmlSupervisor = ({
13213
+ const jsenvPluginSupervisor = ({
13181
13214
  logs = false,
13182
13215
  measurePerf = false,
13183
13216
  errorOverlay = true,
13184
13217
  openInEditor = true,
13185
13218
  errorBaseUrl
13186
13219
  }) => {
13187
- const htmlSupervisorSetupFileUrl = new URL("./js/html_supervisor_setup.js", import.meta.url).href;
13188
- const htmlSupervisorInstallerFileUrl = new URL("./js/html_supervisor_installer.js", import.meta.url).href;
13220
+ const supervisorFileUrl = new URL("./js/supervisor.js", import.meta.url).href;
13221
+ const scriptTypeModuleSupervisorFileUrl = new URL("./js/script_type_module_supervisor.js", import.meta.url).href;
13189
13222
  return {
13190
- name: "jsenv:html_supervisor",
13223
+ name: "jsenv:supervisor",
13191
13224
  appliesDuring: "dev",
13192
13225
  serve: async (request, context) => {
13193
- if (request.ressource.startsWith("/__get_code_frame__/")) {
13226
+ if (request.pathname.startsWith("/__get_code_frame__/")) {
13194
13227
  const {
13195
13228
  pathname,
13196
13229
  searchParams
13197
13230
  } = new URL(request.url);
13198
- const urlWithLineAndColumn = pathname.slice("/__get_code_frame__/".length);
13231
+ let urlWithLineAndColumn = pathname.slice("/__get_code_frame__/".length);
13232
+ urlWithLineAndColumn = decodeURIComponent(urlWithLineAndColumn);
13199
13233
  const match = urlWithLineAndColumn.match(/:([0-9]+):([0-9]+)$/);
13200
13234
 
13201
13235
  if (!match) {
@@ -13212,7 +13246,10 @@ const jsenvPluginHtmlSupervisor = ({
13212
13246
 
13213
13247
  if (!urlInfo) {
13214
13248
  return {
13215
- status: 404
13249
+ status: 204,
13250
+ headers: {
13251
+ "cache-control": "no-store"
13252
+ }
13216
13253
  };
13217
13254
  }
13218
13255
 
@@ -13222,14 +13259,20 @@ const jsenvPluginHtmlSupervisor = ({
13222
13259
  const sourcemap = urlInfo.sourcemap;
13223
13260
 
13224
13261
  if (sourcemap) {
13225
- const original = await getOriginalPosition({
13262
+ const original = getOriginalPosition({
13226
13263
  sourcemap,
13227
13264
  url: file,
13228
13265
  line,
13229
13266
  column
13230
13267
  });
13231
- line = original.line;
13232
- column = original.column;
13268
+
13269
+ if (original.line !== null) {
13270
+ line = original.line;
13271
+
13272
+ if (original.column !== null) {
13273
+ column = original.column;
13274
+ }
13275
+ }
13233
13276
  }
13234
13277
  }
13235
13278
 
@@ -13242,6 +13285,7 @@ const jsenvPluginHtmlSupervisor = ({
13242
13285
  return {
13243
13286
  status: 200,
13244
13287
  headers: {
13288
+ "cache-control": "no-store",
13245
13289
  "content-type": "text/plain",
13246
13290
  "content-length": Buffer.byteLength(codeFrame)
13247
13291
  },
@@ -13249,8 +13293,9 @@ const jsenvPluginHtmlSupervisor = ({
13249
13293
  };
13250
13294
  }
13251
13295
 
13252
- if (request.ressource.startsWith("/__get_error_cause__/")) {
13253
- const file = request.ressource.slice("/__get_error_cause__/".length);
13296
+ if (request.pathname.startsWith("/__get_error_cause__/")) {
13297
+ let file = request.pathname.slice("/__get_error_cause__/".length);
13298
+ file = decodeURIComponent(file);
13254
13299
 
13255
13300
  if (!file) {
13256
13301
  return {
@@ -13301,7 +13346,7 @@ const jsenvPluginHtmlSupervisor = ({
13301
13346
  return {
13302
13347
  status: 200,
13303
13348
  headers: {
13304
- "cache-control": "no-cache",
13349
+ "cache-control": "no-store",
13305
13350
  "content-type": "application/json",
13306
13351
  "content-length": Buffer.byteLength(body)
13307
13352
  },
@@ -13309,8 +13354,9 @@ const jsenvPluginHtmlSupervisor = ({
13309
13354
  };
13310
13355
  }
13311
13356
 
13312
- if (request.ressource.startsWith("/__open_in_editor__/")) {
13313
- const file = request.ressource.slice("/__open_in_editor__/".length);
13357
+ if (request.pathname.startsWith("/__open_in_editor__/")) {
13358
+ let file = request.pathname.slice("/__open_in_editor__/".length);
13359
+ file = decodeURIComponent(file);
13314
13360
 
13315
13361
  if (!file) {
13316
13362
  return {
@@ -13396,9 +13442,6 @@ const jsenvPluginHtmlSupervisor = ({
13396
13442
  const crossorigin = getHtmlNodeAttribute(node, "crossorigin") !== undefined;
13397
13443
  const defer = getHtmlNodeAttribute(node, "defer") !== undefined;
13398
13444
  const async = getHtmlNodeAttribute(node, "async") !== undefined;
13399
- setHtmlNodeAttributes(node, {
13400
- src: undefined
13401
- });
13402
13445
  scriptsToSupervise.push({
13403
13446
  node,
13404
13447
  type,
@@ -13420,15 +13463,15 @@ const jsenvPluginHtmlSupervisor = ({
13420
13463
  return;
13421
13464
  }
13422
13465
 
13423
- const injectedBy = getHtmlNodeAttribute(node, "injected-by");
13466
+ const jsenvPluginOwner = getHtmlNodeAttribute(node, "jsenv-plugin-owner");
13424
13467
 
13425
- if (injectedBy !== undefined) {
13468
+ if (jsenvPluginOwner !== undefined) {
13426
13469
  return;
13427
13470
  }
13428
13471
 
13429
- const noHtmlSupervisor = getHtmlNodeAttribute(node, "no-html-supervisor");
13472
+ const noSupervisor = getHtmlNodeAttribute(node, "no-supervisor");
13430
13473
 
13431
- if (noHtmlSupervisor !== undefined) {
13474
+ if (noSupervisor !== undefined) {
13432
13475
  return;
13433
13476
  }
13434
13477
 
@@ -13447,36 +13490,33 @@ const jsenvPluginHtmlSupervisor = ({
13447
13490
  }
13448
13491
  }
13449
13492
  });
13450
- const [htmlSupervisorInstallerFileReference] = context.referenceUtils.inject({
13493
+ const [scriptTypeModuleSupervisorFileReference] = context.referenceUtils.inject({
13451
13494
  type: "js_import_export",
13452
13495
  expectedType: "js_module",
13453
- specifier: htmlSupervisorInstallerFileUrl
13496
+ specifier: scriptTypeModuleSupervisorFileUrl
13497
+ });
13498
+ const [supervisorFileReference] = context.referenceUtils.inject({
13499
+ type: "script_src",
13500
+ expectedType: "js_classic",
13501
+ specifier: supervisorFileUrl
13454
13502
  });
13455
13503
  injectScriptNodeAsEarlyAsPossible(htmlAst, createHtmlNode({
13456
- "tagName": "script",
13457
- "type": "module",
13458
- "textContent": `
13459
- import { installHtmlSupervisor } from ${htmlSupervisorInstallerFileReference.generatedSpecifier}
13460
- installHtmlSupervisor(${JSON.stringify({
13504
+ tagName: "script",
13505
+ textContent: `
13506
+ window.__supervisor__.setup(${JSON.stringify({
13461
13507
  rootDirectoryUrl: context.rootDirectoryUrl,
13462
13508
  errorBaseUrl,
13463
13509
  logs,
13464
13510
  measurePerf,
13465
13511
  errorOverlay,
13466
13512
  openInEditor
13467
- }, null, " ")})`,
13468
- "injected-by": "jsenv:html_supervisor"
13469
- }));
13470
- const [htmlSupervisorSetupFileReference] = context.referenceUtils.inject({
13471
- type: "script_src",
13472
- expectedType: "js_classic",
13473
- specifier: htmlSupervisorSetupFileUrl
13474
- });
13513
+ }, null, " ")})
13514
+ `
13515
+ }), "jsenv:supervisor");
13475
13516
  injectScriptNodeAsEarlyAsPossible(htmlAst, createHtmlNode({
13476
- "tagName": "script",
13477
- "src": htmlSupervisorSetupFileReference.generatedSpecifier,
13478
- "injected-by": "jsenv:html_supervisor"
13479
- }));
13517
+ tagName: "script",
13518
+ src: supervisorFileReference.generatedSpecifier
13519
+ }), "jsenv:supervisor");
13480
13520
  scriptsToSupervise.forEach(({
13481
13521
  node,
13482
13522
  isInline,
@@ -13487,25 +13527,39 @@ const jsenvPluginHtmlSupervisor = ({
13487
13527
  integrity,
13488
13528
  crossorigin
13489
13529
  }) => {
13490
- setHtmlNodeText(node, generateCodeToSuperviseScript({
13491
- type,
13530
+ const paramsAsJson = JSON.stringify({
13492
13531
  src,
13493
13532
  isInline,
13494
13533
  defer,
13495
13534
  async,
13496
13535
  integrity,
13497
- crossorigin,
13498
- htmlSupervisorInstallerSpecifier: htmlSupervisorInstallerFileReference.generatedSpecifier
13499
- }));
13500
- setHtmlNodeAttributes(node, {
13501
- "generated-by": "jsenv:html_supervisor",
13502
- ...(src ? {
13503
- "generated-from-src": src
13504
- } : {}),
13505
- ...(isInline ? {
13506
- "generated-from-inline-content": ""
13507
- } : {})
13536
+ crossorigin
13508
13537
  });
13538
+
13539
+ if (type === "js_module") {
13540
+ setHtmlNodeText(node, `
13541
+ import { superviseScriptTypeModule } from ${scriptTypeModuleSupervisorFileReference.generatedSpecifier}
13542
+ superviseScriptTypeModule(${paramsAsJson})
13543
+ `);
13544
+ } else {
13545
+ setHtmlNodeText(node, `
13546
+ window.__supervisor__.superviseScript(${paramsAsJson})
13547
+ `);
13548
+ }
13549
+
13550
+ if (src) {
13551
+ setHtmlNodeAttributes(node, {
13552
+ "jsenv-plugin-owner": "jsenv:supervisor",
13553
+ "jsenv-plugin-action": "inlined",
13554
+ "src": undefined,
13555
+ "inlined-from-src": src
13556
+ });
13557
+ } else {
13558
+ setHtmlNodeAttributes(node, {
13559
+ "jsenv-plugin-owner": "jsenv:supervisor",
13560
+ "jsenv-plugin-action": "content_cooked"
13561
+ });
13562
+ }
13509
13563
  });
13510
13564
  const htmlModified = stringifyHtmlAst(htmlAst);
13511
13565
  return {
@@ -13514,38 +13568,6 @@ const jsenvPluginHtmlSupervisor = ({
13514
13568
  }
13515
13569
  }
13516
13570
  };
13517
- }; // Ideally jsenv should take into account eventual
13518
- // "integrity" and "crossorigin" attribute during supervision
13519
-
13520
- const generateCodeToSuperviseScript = ({
13521
- type,
13522
- src,
13523
- isInline,
13524
- defer,
13525
- async,
13526
- integrity,
13527
- crossorigin,
13528
- htmlSupervisorInstallerSpecifier
13529
- }) => {
13530
- const paramsAsJson = JSON.stringify({
13531
- src,
13532
- isInline,
13533
- defer,
13534
- async,
13535
- integrity,
13536
- crossorigin
13537
- });
13538
-
13539
- if (type === "js_module") {
13540
- return `
13541
- import { superviseScriptTypeModule } from ${htmlSupervisorInstallerSpecifier}
13542
- superviseScriptTypeModule(${paramsAsJson})
13543
- `;
13544
- }
13545
-
13546
- return `
13547
- window.__html_supervisor__.superviseScript(${paramsAsJson})
13548
- `;
13549
13571
  };
13550
13572
 
13551
13573
  /*
@@ -14053,11 +14075,7 @@ export default inlineContent.text`,
14053
14075
  };
14054
14076
 
14055
14077
  const babelPluginInstrument = (api, {
14056
- rootDirectoryUrl,
14057
- useInlineSourceMaps = false,
14058
- coverageConfig = {
14059
- "./**/*": true
14060
- }
14078
+ useInlineSourceMaps = false
14061
14079
  }) => {
14062
14080
  const {
14063
14081
  programVisitor
@@ -14065,17 +14083,6 @@ const babelPluginInstrument = (api, {
14065
14083
  const {
14066
14084
  types
14067
14085
  } = api;
14068
- const associations = URL_META.resolveAssociations({
14069
- cover: coverageConfig
14070
- }, rootDirectoryUrl);
14071
-
14072
- const shouldInstrument = url => {
14073
- return URL_META.applyAssociations({
14074
- url,
14075
- associations
14076
- }).cover;
14077
- };
14078
-
14079
14086
  return {
14080
14087
  name: "transform-instrument",
14081
14088
  visitor: {
@@ -14087,19 +14094,6 @@ const babelPluginInstrument = (api, {
14087
14094
  const {
14088
14095
  opts
14089
14096
  } = file;
14090
-
14091
- if (!opts.sourceFileName) {
14092
- console.warn(`cannot instrument file when "sourceFileName" option is not set`);
14093
- return;
14094
- }
14095
-
14096
- const fileUrl = fileSystemPathToUrl$1(opts.sourceFileName);
14097
-
14098
- if (!shouldInstrument(fileUrl)) {
14099
- return;
14100
- }
14101
-
14102
- this.__dv__ = null;
14103
14097
  let inputSourceMap;
14104
14098
 
14105
14099
  if (useInlineSourceMaps) {
@@ -15078,13 +15072,13 @@ const babelPluginNewStylesheetAsJsenvImport = (babel, {
15078
15072
  return {
15079
15073
  name: "new-stylesheet-as-jsenv-import",
15080
15074
  visitor: {
15081
- Program: (programPath, {
15082
- filename
15083
- }) => {
15084
- const fileUrl = pathToFileURL(filename).href;
15075
+ Program: (programPath, babelState) => {
15076
+ if (babelState.filename) {
15077
+ const fileUrl = pathToFileURL(babelState.filename).href;
15085
15078
 
15086
- if (fileUrl === newStylesheetClientFileUrl) {
15087
- return;
15079
+ if (fileUrl === newStylesheetClientFileUrl) {
15080
+ return;
15081
+ }
15088
15082
  }
15089
15083
 
15090
15084
  let usesNewStylesheet = false;
@@ -15318,10 +15312,17 @@ const jsenvPluginBabel = ({
15318
15312
  const requestHeaders = context.request.headers;
15319
15313
 
15320
15314
  if (requestHeaders["x-coverage-instanbul"]) {
15321
- babelPluginStructure["transform-instrument"] = [babelPluginInstrument, {
15322
- rootDirectoryUrl: context.rootDirectoryUrl,
15323
- coverageConfig: JSON.parse(requestHeaders["x-coverage-instanbul"])
15324
- }];
15315
+ const coverageConfig = JSON.parse(requestHeaders["x-coverage-instanbul"]);
15316
+ const associations = URL_META.resolveAssociations({
15317
+ cover: coverageConfig
15318
+ }, context.rootDirectoryUrl);
15319
+
15320
+ if (URL_META.applyAssociations({
15321
+ url: urlInfo.url,
15322
+ associations
15323
+ }).cover) {
15324
+ babelPluginStructure["transform-instrument"] = [babelPluginInstrument];
15325
+ }
15325
15326
  }
15326
15327
  }
15327
15328
 
@@ -15481,7 +15482,6 @@ const jsenvPluginTranspilation = ({
15481
15482
  importAssertions = true,
15482
15483
  css = true,
15483
15484
  jsModuleAsJsClassic = true,
15484
- systemJsInjection = true,
15485
15485
  topLevelAwait = true,
15486
15486
  babelHelpersAsImport = true,
15487
15487
  getCustomBabelPlugins
@@ -15490,6 +15490,10 @@ const jsenvPluginTranspilation = ({
15490
15490
  importAssertions = {};
15491
15491
  }
15492
15492
 
15493
+ if (jsModuleAsJsClassic === true) {
15494
+ jsModuleAsJsClassic = {};
15495
+ }
15496
+
15493
15497
  return [// import assertions we want it all the time
15494
15498
  ...(importAssertions ? [jsenvPluginImportAssertions(importAssertions)] : []), // babel also so that rollup can bundle babel helpers for instance
15495
15499
  jsenvPluginBabel({
@@ -15500,9 +15504,7 @@ const jsenvPluginTranspilation = ({
15500
15504
  // we want to do it after bundling
15501
15505
  // so the build function will disable jsModuleAsJsClassic during build
15502
15506
  // and enable it manually during postbuild
15503
- ...(jsModuleAsJsClassic ? [jsenvPluginAsJsClassic({
15504
- systemJsInjection
15505
- })] : []), // topLevelAwait must come after js_module_as_js_classic because it's related to the module format
15507
+ ...(jsModuleAsJsClassic ? [jsenvPluginAsJsClassic(jsModuleAsJsClassic)] : []), // topLevelAwait must come after js_module_as_js_classic because it's related to the module format
15506
15508
  // so we want to wait to know the module format before transforming things related to top level await
15507
15509
  ...(topLevelAwait ? [jsenvPluginTopLevelAwait()] : []), ...(css ? [jsenvPluginCssParcel()] : [])];
15508
15510
  };
@@ -16315,7 +16317,7 @@ const collectHotDataFromHtmlAst = htmlAst => {
16315
16317
  });
16316
16318
  visitUrlSpecifierAttribute({
16317
16319
  node,
16318
- attributeName: "generated-from-href",
16320
+ attributeName: "inlined-from-href",
16319
16321
  hotAccepted
16320
16322
  });
16321
16323
  }
@@ -16328,7 +16330,7 @@ const collectHotDataFromHtmlAst = htmlAst => {
16328
16330
  });
16329
16331
  visitUrlSpecifierAttribute({
16330
16332
  node,
16331
- attributeName: "generated-from-src",
16333
+ attributeName: "inlined-from-src",
16332
16334
  hotAccepted
16333
16335
  });
16334
16336
  }
@@ -16397,7 +16399,7 @@ const htmlNodeCanHotReload = node => {
16397
16399
  if (node.nodeName === "link") {
16398
16400
  const {
16399
16401
  isStylesheet,
16400
- isRessourceHint,
16402
+ isResourceHint,
16401
16403
  rel
16402
16404
  } = analyzeLinkNode(node);
16403
16405
 
@@ -16406,9 +16408,9 @@ const htmlNodeCanHotReload = node => {
16406
16408
  return true;
16407
16409
  }
16408
16410
 
16409
- if (isRessourceHint) {
16410
- // for ressource hints html will be notified the underlying ressource has changed
16411
- // but we won't do anything (if the ressource is deleted we should?)
16411
+ if (isResourceHint) {
16412
+ // for resource hints html will be notified the underlying resource has changed
16413
+ // but we won't do anything (if the resource is deleted we should?)
16412
16414
  return true;
16413
16415
  }
16414
16416
 
@@ -16643,10 +16645,7 @@ import.meta.hot = createImportMetaHot(import.meta.url)
16643
16645
  const jsenvPluginHmr = () => {
16644
16646
  return {
16645
16647
  name: "jsenv:hmr",
16646
- appliesDuring: {
16647
- dev: true,
16648
- test: false
16649
- },
16648
+ appliesDuring: "dev",
16650
16649
  redirectUrl: reference => {
16651
16650
  const urlObject = new URL(reference.url);
16652
16651
 
@@ -16689,10 +16688,7 @@ const jsenvPluginAutoreloadClient = () => {
16689
16688
  const autoreloadClientFileUrl = new URL("./js/autoreload.js", import.meta.url).href;
16690
16689
  return {
16691
16690
  name: "jsenv:autoreload_client",
16692
- appliesDuring: {
16693
- dev: true,
16694
- test: false
16695
- },
16691
+ appliesDuring: "dev",
16696
16692
  transformUrlContent: {
16697
16693
  html: (htmlUrlInfo, context) => {
16698
16694
  const htmlAst = parseHtmlString(htmlUrlInfo.content);
@@ -16702,11 +16698,10 @@ const jsenvPluginAutoreloadClient = () => {
16702
16698
  specifier: autoreloadClientFileUrl
16703
16699
  });
16704
16700
  injectScriptNodeAsEarlyAsPossible(htmlAst, createHtmlNode({
16705
- "tagName": "script",
16706
- "type": "module",
16707
- "src": autoreloadClientReference.generatedSpecifier,
16708
- "injected-by": "jsenv:autoreload_client"
16709
- }));
16701
+ tagName: "script",
16702
+ type: "module",
16703
+ src: autoreloadClientReference.generatedSpecifier
16704
+ }), "jsenv:autoreload_client");
16710
16705
  const htmlModified = stringifyHtmlAst(htmlAst);
16711
16706
  return {
16712
16707
  content: htmlModified
@@ -16722,10 +16717,7 @@ const jsenvPluginAutoreloadServer = ({
16722
16717
  }) => {
16723
16718
  return {
16724
16719
  name: "jsenv:autoreload_server",
16725
- appliesDuring: {
16726
- dev: true,
16727
- test: false
16728
- },
16720
+ appliesDuring: "dev",
16729
16721
  serverEvents: {
16730
16722
  reload: ({
16731
16723
  sendServerEvent,
@@ -16887,7 +16879,7 @@ const jsenvPluginAutoreloadServer = ({
16887
16879
  firstUrlInfo
16888
16880
  }) => {
16889
16881
  const mainHotUpdate = propagateUpdate(firstUrlInfo);
16890
- const cause = `following files are no longer referenced: ${prunedUrlInfos.map(prunedUrlInfo => formatUrlForClient(prunedUrlInfo.url))}`; // now check if we can hot update the main ressource
16882
+ const cause = `following files are no longer referenced: ${prunedUrlInfos.map(prunedUrlInfo => formatUrlForClient(prunedUrlInfo.url))}`; // now check if we can hot update the main resource
16891
16883
  // then if we can hot update all dependencies
16892
16884
 
16893
16885
  if (mainHotUpdate.declined) {
@@ -16934,7 +16926,7 @@ const jsenvPluginAutoreloadServer = ({
16934
16926
  rootDirectoryUrl,
16935
16927
  urlGraph
16936
16928
  }) => {
16937
- if (request.ressource === "/__graph__") {
16929
+ if (request.pathname === "/__graph__") {
16938
16930
  const graphJson = JSON.stringify(urlGraph.toJSON(rootDirectoryUrl));
16939
16931
  return {
16940
16932
  status: 200,
@@ -17004,7 +16996,7 @@ const jsenvPluginExplorer = ({
17004
16996
  serve: async (request, {
17005
16997
  rootDirectoryUrl
17006
16998
  }) => {
17007
- if (request.ressource !== "/") {
16999
+ if (request.pathname !== "/") {
17008
17000
  return null;
17009
17001
  }
17010
17002
 
@@ -17057,7 +17049,7 @@ const getCorePlugins = ({
17057
17049
  rootDirectoryUrl,
17058
17050
  runtimeCompat,
17059
17051
  urlAnalysis = {},
17060
- htmlSupervisor,
17052
+ supervisor,
17061
17053
  nodeEsmResolution = true,
17062
17054
  fileSystemMagicResolution,
17063
17055
  directoryReferenceAllowed,
@@ -17069,8 +17061,8 @@ const getCorePlugins = ({
17069
17061
  clientFilesPruneCallbackList,
17070
17062
  explorer
17071
17063
  } = {}) => {
17072
- if (htmlSupervisor === true) {
17073
- htmlSupervisor = {};
17064
+ if (supervisor === true) {
17065
+ supervisor = {};
17074
17066
  }
17075
17067
 
17076
17068
  if (nodeEsmResolution === true) {
@@ -17088,7 +17080,7 @@ const getCorePlugins = ({
17088
17080
  return [jsenvPluginUrlAnalysis({
17089
17081
  rootDirectoryUrl,
17090
17082
  ...urlAnalysis
17091
- }), jsenvPluginTranspilation(transpilation), ...(htmlSupervisor ? [jsenvPluginHtmlSupervisor(htmlSupervisor)] : []), // before inline as it turns inline <script> into <script src>
17083
+ }), jsenvPluginTranspilation(transpilation), ...(supervisor ? [jsenvPluginSupervisor(supervisor)] : []), // before inline as it turns inline <script> into <script src>
17092
17084
  jsenvPluginImportmap(), // before node esm to handle bare specifiers
17093
17085
  // + before node esm to handle importmap before inline content
17094
17086
  jsenvPluginInline(), // before "file urls" to resolve and load inline urls
@@ -17978,7 +17970,7 @@ const nodeStreamToObservable = nodeStream => {
17978
17970
  // safe measure, ensure the readable stream gets
17979
17971
  // used in the next ${readableStreamLifetimeInSeconds} otherwise destroys it
17980
17972
  const timeout = setTimeout(() => {
17981
- process.emitWarning(`Readable stream not used after ${readableStreamLifetimeInSeconds} seconds. It will be destroyed to release ressources`, {
17973
+ process.emitWarning(`Readable stream not used after ${readableStreamLifetimeInSeconds} seconds. It will be destroyed to release resources`, {
17982
17974
  CODE: "READABLE_STREAM_TIMEOUT",
17983
17975
  // url is for http client request
17984
17976
  detail: `path: ${nodeStream.path}, fd: ${nodeStream.fd}, url: ${nodeStream.url}`
@@ -18058,8 +18050,8 @@ const fromNodeRequest = (nodeRequest, {
18058
18050
  signal,
18059
18051
  http2: Boolean(nodeRequest.stream),
18060
18052
  origin: requestOrigin,
18061
- ...getPropertiesFromRessource({
18062
- ressource: nodeRequest.url,
18053
+ ...getPropertiesFromResource({
18054
+ resource: nodeRequest.url,
18063
18055
  baseUrl: requestOrigin
18064
18056
  }),
18065
18057
  method: nodeRequest.method,
@@ -18068,13 +18060,13 @@ const fromNodeRequest = (nodeRequest, {
18068
18060
  });
18069
18061
  };
18070
18062
  const applyRedirectionToRequest = (request, {
18071
- ressource,
18063
+ resource,
18072
18064
  pathname,
18073
18065
  ...rest
18074
18066
  }) => {
18075
18067
  return { ...request,
18076
- ...(ressource ? getPropertiesFromRessource({
18077
- ressource,
18068
+ ...(resource ? getPropertiesFromResource({
18069
+ resource,
18078
18070
  baseUrl: request.url
18079
18071
  }) : pathname ? getPropertiesFromPathname({
18080
18072
  pathname,
@@ -18084,16 +18076,16 @@ const applyRedirectionToRequest = (request, {
18084
18076
  };
18085
18077
  };
18086
18078
 
18087
- const getPropertiesFromRessource = ({
18088
- ressource,
18079
+ const getPropertiesFromResource = ({
18080
+ resource,
18089
18081
  baseUrl
18090
18082
  }) => {
18091
- const urlObject = new URL(ressource, baseUrl);
18083
+ const urlObject = new URL(resource, baseUrl);
18092
18084
  let pathname = urlObject.pathname;
18093
18085
  return {
18094
18086
  url: String(urlObject),
18095
18087
  pathname,
18096
- ressource
18088
+ resource
18097
18089
  };
18098
18090
  };
18099
18091
 
@@ -18101,8 +18093,8 @@ const getPropertiesFromPathname = ({
18101
18093
  pathname,
18102
18094
  baseUrl
18103
18095
  }) => {
18104
- return getPropertiesFromRessource({
18105
- ressource: `${pathname}${new URL(baseUrl).search}`,
18096
+ return getPropertiesFromResource({
18097
+ resource: `${pathname}${new URL(baseUrl).search}`,
18106
18098
  baseUrl
18107
18099
  });
18108
18100
  };
@@ -18130,11 +18122,11 @@ const createPushRequest = (request, {
18130
18122
  const getHeadersInheritedByPushRequest = request => {
18131
18123
  const headersInherited = { ...request.headers
18132
18124
  }; // mtime sent by the client in request headers concerns the main request
18133
- // Time remains valid for request to other ressources so we keep it
18125
+ // Time remains valid for request to other resources so we keep it
18134
18126
  // in child requests
18135
18127
  // delete childHeaders["if-modified-since"]
18136
18128
  // eTag sent by the client in request headers concerns the main request
18137
- // A request made to an other ressource must not inherit the eTag
18129
+ // A request made to an other resource must not inherit the eTag
18138
18130
 
18139
18131
  delete headersInherited["if-none-match"];
18140
18132
  return headersInherited;
@@ -18961,7 +18953,7 @@ const startServer = async ({
18961
18953
  requestWaitingMs
18962
18954
  }) => {
18963
18955
  warn(createDetailedMessage$1(`still no response found for request after ${requestWaitingMs} ms`, {
18964
- "request url": `${request.origin}${request.ressource}`,
18956
+ "request url": request.url,
18965
18957
  "request headers": JSON.stringify(request.headers, null, " ")
18966
18958
  }));
18967
18959
  }
@@ -19385,7 +19377,7 @@ const startServer = async ({
19385
19377
  const onPushStreamError = e => {
19386
19378
  addRequestLog(requestNode, {
19387
19379
  type: "error",
19388
- value: createDetailedMessage$1(`An error occured while pushing a stream to the response for ${request.ressource}`, {
19380
+ value: createDetailedMessage$1(`An error occured while pushing a stream to the response for ${request.resource}`, {
19389
19381
  "error stack": e.stack
19390
19382
  })
19391
19383
  });
@@ -19489,7 +19481,7 @@ const startServer = async ({
19489
19481
 
19490
19482
  addRequestLog(requestNode, {
19491
19483
  type: "info",
19492
- value: request.parent ? `Push ${request.ressource}` : `${request.method} ${request.origin}${request.ressource}`
19484
+ value: request.parent ? `Push ${request.resource}` : `${request.method} ${request.url}`
19493
19485
  });
19494
19486
 
19495
19487
  const warn = value => {
@@ -19809,7 +19801,7 @@ const startServer = async ({
19809
19801
  const websocketClients = new Set();
19810
19802
  const {
19811
19803
  WebSocketServer
19812
- } = await import("./js/wrapper.mjs");
19804
+ } = await import("./js/ws.js");
19813
19805
  let websocketServer = new WebSocketServer({
19814
19806
  noServer: true
19815
19807
  });
@@ -20307,7 +20299,7 @@ const fetchFileSystem = async (filesystemUrl, {
20307
20299
 
20308
20300
  rootDirectoryUrl = rootDirectoryUrlString;
20309
20301
  } // here you might be tempted to add || cacheControl === 'no-cache'
20310
- // but no-cache means ressource can be cache but must be revalidated (yeah naming is strange)
20302
+ // but no-cache means resource can be cache but must be revalidated (yeah naming is strange)
20311
20303
  // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#Cacheability
20312
20304
 
20313
20305
 
@@ -20448,7 +20440,7 @@ const getClientCacheResponse = async ({
20448
20440
  sourceUrl
20449
20441
  }) => {
20450
20442
  // here you might be tempted to add || headers["cache-control"] === "no-cache"
20451
- // but no-cache means ressource can be cache but must be revalidated (yeah naming is strange)
20443
+ // but no-cache means resource can be cache but must be revalidated (yeah naming is strange)
20452
20444
  // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#Cacheability
20453
20445
  if (headers["cache-control"] === "no-store" || // let's disable it on no-cache too
20454
20446
  headers["cache-control"] === "no-cache") {
@@ -21156,8 +21148,8 @@ const flattenAndFilterPlugins = (plugins, {
21156
21148
  }
21157
21149
 
21158
21150
  if (typeof appliesDuring === "string") {
21159
- if (!["dev", "test", "build"].includes(appliesDuring)) {
21160
- throw new Error(`"appliesDuring" must be "dev", "test" or "build", got ${appliesDuring}`);
21151
+ if (!["dev", "build"].includes(appliesDuring)) {
21152
+ throw new Error(`"appliesDuring" must be "dev" or "build", got ${appliesDuring}`);
21161
21153
  }
21162
21154
 
21163
21155
  if (scenarios[appliesDuring]) {
@@ -21366,6 +21358,10 @@ const createUrlInfoTransformer = ({
21366
21358
 
21367
21359
  if (!SOURCEMAP.enabledOnContentType(urlInfo.contentType)) {
21368
21360
  return;
21361
+ }
21362
+
21363
+ if (urlInfo.generatedUrl.startsWith("data:")) {
21364
+ return;
21369
21365
  } // sourcemap is a special kind of reference:
21370
21366
  // It's a reference to a content generated dynamically the content itself.
21371
21367
  // For this reason sourcemap are not added to urlInfo.references
@@ -21472,7 +21468,7 @@ const createUrlInfoTransformer = ({
21472
21468
  await applyIntermediateTransformations(urlInfo, transformations);
21473
21469
  }
21474
21470
 
21475
- if (sourcemapsEnabled && urlInfo.sourcemap) {
21471
+ if (sourcemapsEnabled && urlInfo.sourcemap && !urlInfo.generatedUrl.startsWith("data:")) {
21476
21472
  // during build this function can be called after the file is cooked
21477
21473
  // - to update content and sourcemap after "optimize" hook
21478
21474
  // - to inject versioning into the entry point content
@@ -21849,7 +21845,7 @@ const validateResponseIntegrity = ({
21849
21845
  return true;
21850
21846
  }
21851
21847
 
21852
- const error = new Error(`Integrity validation failed for ressource "${url}". The integrity found for this ressource is "${strongestAlgo}-${actualBase64Value}"`);
21848
+ const error = new Error(`Integrity validation failed for resource "${url}". The integrity found for this resource is "${strongestAlgo}-${actualBase64Value}"`);
21853
21849
  error.code = "EINTEGRITY";
21854
21850
  error.algorithm = strongestAlgo;
21855
21851
  error.found = actualBase64Value;
@@ -21961,7 +21957,8 @@ const createKitchen = ({
21961
21957
  isEntryPoint = false,
21962
21958
  isInline = false,
21963
21959
  injected = false,
21964
- isRessourceHint = false,
21960
+ isResourceHint = false,
21961
+ dependsOnPackageJson,
21965
21962
  content,
21966
21963
  contentType,
21967
21964
  assert,
@@ -21999,8 +21996,9 @@ const createKitchen = ({
21999
21996
  isEntryPoint,
22000
21997
  isInline,
22001
21998
  injected,
22002
- isRessourceHint,
22003
- // for inline ressources the reference contains the content
21999
+ isResourceHint,
22000
+ dependsOnPackageJson,
22001
+ // for inline resources the reference contains the content
22004
22002
  content,
22005
22003
  contentType,
22006
22004
  timing: {},
@@ -22016,9 +22014,9 @@ const createKitchen = ({
22016
22014
  newReference.original = reference.original || reference; // newReference.isEntryPoint = reference.isEntryPoint
22017
22015
  };
22018
22016
 
22019
- const resolveReference = reference => {
22017
+ const resolveReference = (reference, context = kitchenContext) => {
22020
22018
  try {
22021
- let resolvedUrl = pluginController.callHooksUntil("resolveUrl", reference, kitchenContext);
22019
+ let resolvedUrl = pluginController.callHooksUntil("resolveUrl", reference, context);
22022
22020
 
22023
22021
  if (!resolvedUrl) {
22024
22022
  throw new Error(`NO_RESOLVE`);
@@ -22026,7 +22024,7 @@ const createKitchen = ({
22026
22024
 
22027
22025
  resolvedUrl = normalizeUrl(resolvedUrl);
22028
22026
  reference.url = resolvedUrl;
22029
- pluginController.callHooks("redirectUrl", reference, kitchenContext, returnValue => {
22027
+ pluginController.callHooks("redirectUrl", reference, context, returnValue => {
22030
22028
  const normalizedReturnValue = normalizeUrl(returnValue);
22031
22029
 
22032
22030
  if (normalizedReturnValue === reference.url) {
@@ -22047,20 +22045,20 @@ const createKitchen = ({
22047
22045
  }
22048
22046
 
22049
22047
  const urlInfo = urlGraph.reuseOrCreateUrlInfo(reference.url);
22050
- applyReferenceEffectsOnUrlInfo(reference, urlInfo, kitchenContext); // This hook must touch reference.generatedUrl, NOT reference.url
22048
+ applyReferenceEffectsOnUrlInfo(reference, urlInfo, context); // This hook must touch reference.generatedUrl, NOT reference.url
22051
22049
  // And this is because this hook inject query params used to:
22052
22050
  // - bypass browser cache (?v)
22053
22051
  // - convey information (?hmr)
22054
- // But do not represent an other ressource, it is considered as
22055
- // the same ressource under the hood
22052
+ // But do not represent an other resource, it is considered as
22053
+ // the same resource under the hood
22056
22054
 
22057
- pluginController.callHooks("transformUrlSearchParams", reference, kitchenContext, returnValue => {
22055
+ pluginController.callHooks("transformUrlSearchParams", reference, context, returnValue => {
22058
22056
  Object.keys(returnValue).forEach(key => {
22059
22057
  referenceUrlObject.searchParams.set(key, returnValue[key]);
22060
22058
  });
22061
22059
  reference.generatedUrl = normalizeUrl(referenceUrlObject.href);
22062
22060
  });
22063
- const returnValue = pluginController.callHooksUntil("formatUrl", reference, kitchenContext);
22061
+ const returnValue = pluginController.callHooksUntil("formatUrl", reference, context);
22064
22062
  reference.generatedSpecifier = returnValue || reference.generatedUrl;
22065
22063
  reference.generatedSpecifier = urlSpecifierEncoding.encode(reference);
22066
22064
  return urlInfo;
@@ -22257,7 +22255,7 @@ const createKitchen = ({
22257
22255
  ...props
22258
22256
  });
22259
22257
  references.push(reference);
22260
- const referencedUrlInfo = resolveReference(reference);
22258
+ const referencedUrlInfo = resolveReference(reference, context);
22261
22259
  return [reference, referencedUrlInfo];
22262
22260
  };
22263
22261
 
@@ -22332,7 +22330,7 @@ const createKitchen = ({
22332
22330
  });
22333
22331
  references[index] = nextReference;
22334
22332
  mutateReference(previousReference, nextReference);
22335
- const newUrlInfo = resolveReference(nextReference);
22333
+ const newUrlInfo = resolveReference(nextReference, context);
22336
22334
  const currentUrlInfo = context.urlGraph.getUrlInfo(currentReference.url);
22337
22335
 
22338
22336
  if (currentUrlInfo && currentUrlInfo !== newUrlInfo && currentUrlInfo.dependents.size === 0) {
@@ -22528,7 +22526,8 @@ const createKitchen = ({
22528
22526
  reference: originalReference
22529
22527
  });
22530
22528
 
22531
- if (originalUrlInfo.dependents.size === 0) {
22529
+ if (originalUrlInfo.dependents.size === 0 // && context.scenarios.build
22530
+ ) {
22532
22531
  context.urlGraph.deleteUrlInfo(originalUrlInfo.url);
22533
22532
  }
22534
22533
 
@@ -22632,6 +22631,21 @@ const applyReferenceEffectsOnUrlInfo = (reference, urlInfo, context) => {
22632
22631
  urlInfo.originalContent = context.scenarios.build ? urlInfo.originalContent === undefined ? reference.content : urlInfo.originalContent : reference.content;
22633
22632
  urlInfo.content = reference.content;
22634
22633
  }
22634
+
22635
+ const {
22636
+ dependsOnPackageJson
22637
+ } = reference;
22638
+ urlInfo.dependsOnPackageJson = dependsOnPackageJson;
22639
+ const relatedUrlInfos = context.urlGraph.getRelatedUrlInfos(reference.parentUrl);
22640
+ relatedUrlInfos.forEach(relatedUrlInfo => {
22641
+ if (relatedUrlInfo.dependsOnPackageJson) {
22642
+ // the url may depend due to an other reference
22643
+ // in that case keep dependsOnPackageJson to true
22644
+ return;
22645
+ }
22646
+
22647
+ relatedUrlInfo.dependsOnPackageJson = dependsOnPackageJson;
22648
+ });
22635
22649
  };
22636
22650
 
22637
22651
  const adjustUrlSite = (urlInfo, {
@@ -22861,11 +22875,11 @@ const loadUrlGraph = async ({
22861
22875
  references
22862
22876
  } = urlInfo;
22863
22877
  references.forEach(reference => {
22864
- // we don't cook ressource hints
22865
- // because they might refer to ressource that will be modified during build
22878
+ // we don't cook resource hints
22879
+ // because they might refer to resource that will be modified during build
22866
22880
  // It also means something else have to reference that url in order to cook it
22867
- // so that the preload is deleted by "resync_ressource_hints.js" otherwise
22868
- if (reference.isRessourceHint) {
22881
+ // so that the preload is deleted by "resync_resource_hints.js" otherwise
22882
+ if (reference.isResourceHint) {
22869
22883
  return;
22870
22884
  } // we use reference.generatedUrl to mimic what a browser would do:
22871
22885
  // do a fetch to the specifier as found in the file
@@ -23371,12 +23385,11 @@ const injectors = {
23371
23385
  storeOriginalPositions: false
23372
23386
  });
23373
23387
  injectScriptNodeAsEarlyAsPossible(htmlAst, createHtmlNode({
23374
- "tagName": "script",
23375
- "textContent": generateClientCodeForVersionMappings(versionMappings, {
23388
+ tagName: "script",
23389
+ textContent: generateClientCodeForVersionMappings(versionMappings, {
23376
23390
  globalName: "window"
23377
- }),
23378
- "injected-by": "jsenv:versioning"
23379
- }));
23391
+ })
23392
+ }), "jsenv:versioning");
23380
23393
  return {
23381
23394
  content: stringifyHtmlAst(htmlAst)
23382
23395
  };
@@ -23530,23 +23543,23 @@ self.serviceWorkerUrls = ${JSON.stringify(serviceWorkerUrls, null, " ")};
23530
23543
  /*
23531
23544
  * Update <link rel="preload"> and friends after build (once we know everything)
23532
23545
  *
23533
- * - Used to remove ressource hint targeting an url that is no longer used:
23546
+ * - Used to remove resource hint targeting an url that is no longer used:
23534
23547
  * - Happens because of import assertions transpilation (file is inlined into JS)
23535
23548
  */
23536
- const resyncRessourceHints = async ({
23549
+ const resyncResourceHints = async ({
23537
23550
  logger,
23538
23551
  finalGraphKitchen,
23539
23552
  finalGraph,
23540
23553
  rawUrls,
23541
23554
  postBuildRedirections
23542
23555
  }) => {
23543
- const ressourceHintActions = [];
23556
+ const resourceHintActions = [];
23544
23557
  GRAPH.forEach(finalGraph, urlInfo => {
23545
23558
  if (urlInfo.type !== "html") {
23546
23559
  return;
23547
23560
  }
23548
23561
 
23549
- ressourceHintActions.push(async () => {
23562
+ resourceHintActions.push(async () => {
23550
23563
  const htmlAst = parseHtmlString(urlInfo.content, {
23551
23564
  storeOriginalPositions: false
23552
23565
  });
@@ -23558,9 +23571,9 @@ const resyncRessourceHints = async ({
23558
23571
  }
23559
23572
 
23560
23573
  const rel = getHtmlNodeAttribute(linkNode, "rel");
23561
- const isRessourceHint = ["preconnect", "dns-prefetch", "prefetch", "preload", "modulepreload"].includes(rel);
23574
+ const isresourceHint = ["preconnect", "dns-prefetch", "prefetch", "preload", "modulepreload"].includes(rel);
23562
23575
 
23563
- if (!isRessourceHint) {
23576
+ if (!isresourceHint) {
23564
23577
  return;
23565
23578
  }
23566
23579
 
@@ -23574,7 +23587,7 @@ const resyncRessourceHints = async ({
23574
23587
  }
23575
23588
 
23576
23589
  if (!buildUrl) {
23577
- logger.warn(`remove ressource hint because cannot find "${href}"`);
23590
+ logger.warn(`remove resource hint because cannot find "${href}"`);
23578
23591
  actions.push(() => {
23579
23592
  removeHtmlNode(linkNode);
23580
23593
  });
@@ -23585,7 +23598,7 @@ const resyncRessourceHints = async ({
23585
23598
  const urlInfo = finalGraph.getUrlInfo(buildUrl);
23586
23599
 
23587
23600
  if (!urlInfo) {
23588
- logger.warn(`remove ressource hint because cannot find "${buildUrl}" in the graph`);
23601
+ logger.warn(`remove resource hint because cannot find "${buildUrl}" in the graph`);
23589
23602
  actions.push(() => {
23590
23603
  removeHtmlNode(linkNode);
23591
23604
  });
@@ -23593,7 +23606,7 @@ const resyncRessourceHints = async ({
23593
23606
  }
23594
23607
 
23595
23608
  if (urlInfo.dependents.size === 0) {
23596
- logger.info(`remove ressource hint because "${href}" not used anymore`);
23609
+ logger.info(`remove resource hint because "${href}" not used anymore`);
23597
23610
  actions.push(() => {
23598
23611
  removeHtmlNode(linkNode);
23599
23612
  });
@@ -23625,7 +23638,7 @@ const resyncRessourceHints = async ({
23625
23638
  }
23626
23639
  });
23627
23640
  });
23628
- await Promise.all(ressourceHintActions.map(ressourceHintAction => ressourceHintAction()));
23641
+ await Promise.all(resourceHintActions.map(resourceHintAction => resourceHintAction()));
23629
23642
  };
23630
23643
 
23631
23644
  /*
@@ -23906,10 +23919,10 @@ build ${entryPointKeys.length} entry points`);
23906
23919
  addToBundlerIfAny(dependencyUrlInfo);
23907
23920
  });
23908
23921
  rawUrlInfo.references.forEach(reference => {
23909
- if (reference.isRessourceHint && reference.expectedType === "js_module") {
23922
+ if (reference.isResourceHint && reference.expectedType === "js_module") {
23910
23923
  const referencedUrlInfo = rawGraph.getUrlInfo(reference.url);
23911
23924
 
23912
- if (referencedUrlInfo && // something else than the ressource hint is using this url
23925
+ if (referencedUrlInfo && // something else than the resource hint is using this url
23913
23926
  referencedUrlInfo.dependents.size > 0) {
23914
23927
  addToBundlerIfAny(referencedUrlInfo);
23915
23928
  }
@@ -24202,7 +24215,7 @@ build ${entryPointKeys.length} entry points`);
24202
24215
  throw new Error(`urls should be inside build directory at this stage, found "${reference.url}"`);
24203
24216
  }
24204
24217
 
24205
- if (reference.isRessourceHint) {
24218
+ if (reference.isResourceHint) {
24206
24219
  // return the raw url, we will resync at the end
24207
24220
  return rawUrls[reference.url];
24208
24221
  } // remove eventual search params and hash
@@ -24306,7 +24319,7 @@ build ${entryPointKeys.length} entry points`);
24306
24319
  kitchen: finalGraphKitchen,
24307
24320
  outDirectoryUrl: new URL(".jsenv/postbuild/", rootDirectoryUrl),
24308
24321
  writeGeneratedFiles,
24309
- skipRessourceHint: true,
24322
+ skipResourceHint: true,
24310
24323
  startLoading: cookEntryFile => {
24311
24324
  entryUrls.forEach(entryUrl => {
24312
24325
  const [, postBuildEntryUrlInfo] = cookEntryFile({
@@ -24378,7 +24391,7 @@ ${Array.from(finalGraph.urlInfoMap.keys()).join("\n")}`);
24378
24391
  urlInfo.data.buildUrlIsVersioned = useVersionedUrl;
24379
24392
  urlInfo.data.buildUrlSpecifier = buildUrlSpecifier;
24380
24393
  });
24381
- await resyncRessourceHints({
24394
+ await resyncResourceHints({
24382
24395
  logger,
24383
24396
  finalGraphKitchen,
24384
24397
  finalGraph,
@@ -24722,7 +24735,7 @@ const applyUrlVersioning = async ({
24722
24735
  return null;
24723
24736
  }
24724
24737
 
24725
- if (reference.isRessourceHint) {
24738
+ if (reference.isResourceHint) {
24726
24739
  return null;
24727
24740
  } // specifier comes from "normalize" hook done a bit earlier in this file
24728
24741
  // we want to get back their build url to access their infos
@@ -24783,7 +24796,7 @@ const applyUrlVersioning = async ({
24783
24796
  operation: buildOperation,
24784
24797
  urlGraph: finalGraph,
24785
24798
  kitchen: versioningKitchen,
24786
- skipRessourceHint: true,
24799
+ skipResourceHint: true,
24787
24800
  writeGeneratedFiles,
24788
24801
  startLoading: cookEntryFile => {
24789
24802
  postBuildEntryUrls.forEach(postBuildEntryUrl => {
@@ -25033,11 +25046,10 @@ const jsenvPluginServerEventsClientInjection = () => {
25033
25046
  specifier: serverEventsClientFileUrl
25034
25047
  });
25035
25048
  injectScriptNodeAsEarlyAsPossible(htmlAst, createHtmlNode({
25036
- "tagName": "script",
25037
- "type": "module",
25038
- "src": serverEventsClientFileReference.generatedSpecifier,
25039
- "injected-by": "jsenv:server_events"
25040
- }));
25049
+ tagName: "script",
25050
+ type: "module",
25051
+ src: serverEventsClientFileReference.generatedSpecifier
25052
+ }), "jsenv:server_events");
25041
25053
  const htmlModified = stringifyHtmlAst(htmlAst);
25042
25054
  return {
25043
25055
  content: htmlModified
@@ -25083,7 +25095,7 @@ const createFileService = ({
25083
25095
  runtimeCompat,
25084
25096
  plugins,
25085
25097
  urlAnalysis,
25086
- htmlSupervisor,
25098
+ supervisor,
25087
25099
  nodeEsmResolution,
25088
25100
  fileSystemMagicResolution,
25089
25101
  transpilation,
@@ -25197,7 +25209,7 @@ const createFileService = ({
25197
25209
  rootDirectoryUrl,
25198
25210
  runtimeCompat,
25199
25211
  urlAnalysis,
25200
- htmlSupervisor,
25212
+ supervisor,
25201
25213
  nodeEsmResolution,
25202
25214
  fileSystemMagicResolution,
25203
25215
  transpilation,
@@ -25265,7 +25277,7 @@ const createFileService = ({
25265
25277
 
25266
25278
  return async request => {
25267
25279
  // serve file inside ".jsenv" directory
25268
- const requestFileUrl = new URL(request.ressource.slice(1), rootDirectoryUrl).href;
25280
+ const requestFileUrl = new URL(request.resource.slice(1), rootDirectoryUrl).href;
25269
25281
 
25270
25282
  if (urlIsInsideOf(requestFileUrl, jsenvDirectoryUrl)) {
25271
25283
  return fetchFileSystem(requestFileUrl, {
@@ -25289,7 +25301,7 @@ const createFileService = ({
25289
25301
  const parentUrl = inferParentFromRequest(request, rootDirectoryUrl);
25290
25302
 
25291
25303
  if (parentUrl) {
25292
- reference = urlGraph.inferReference(request.ressource, parentUrl);
25304
+ reference = urlGraph.inferReference(request.resource, parentUrl);
25293
25305
  }
25294
25306
 
25295
25307
  if (!reference) {
@@ -25299,7 +25311,7 @@ const createFileService = ({
25299
25311
  },
25300
25312
  parentUrl: parentUrl || rootDirectoryUrl,
25301
25313
  type: "http_request",
25302
- specifier: request.ressource
25314
+ specifier: request.resource
25303
25315
  });
25304
25316
  reference = entryPoint[0];
25305
25317
  }
@@ -25476,7 +25488,7 @@ const startOmegaServer = async ({
25476
25488
  runtimeCompat,
25477
25489
  plugins,
25478
25490
  urlAnalysis,
25479
- htmlSupervisor,
25491
+ supervisor,
25480
25492
  nodeEsmResolution,
25481
25493
  fileSystemMagicResolution,
25482
25494
  transpilation,
@@ -25529,7 +25541,7 @@ const startOmegaServer = async ({
25529
25541
  runtimeCompat,
25530
25542
  plugins,
25531
25543
  urlAnalysis,
25532
- htmlSupervisor,
25544
+ supervisor,
25533
25545
  nodeEsmResolution,
25534
25546
  fileSystemMagicResolution,
25535
25547
  transpilation,
@@ -25637,7 +25649,7 @@ const startDevServer = async ({
25637
25649
  runtimeCompat = defaultRuntimeCompat,
25638
25650
  plugins = [],
25639
25651
  urlAnalysis = {},
25640
- htmlSupervisor = true,
25652
+ supervisor = true,
25641
25653
  nodeEsmResolution,
25642
25654
  fileSystemMagicResolution,
25643
25655
  transpilation,
@@ -25763,7 +25775,7 @@ const startDevServer = async ({
25763
25775
  runtimeCompat,
25764
25776
  plugins,
25765
25777
  urlAnalysis,
25766
- htmlSupervisor,
25778
+ supervisor,
25767
25779
  nodeEsmResolution,
25768
25780
  fileSystemMagicResolution,
25769
25781
  transpilation,
@@ -26158,9 +26170,7 @@ const relativeUrlToEmptyCoverage = async (relativeUrl, {
26158
26170
  const {
26159
26171
  metadata
26160
26172
  } = await applyBabelPlugins({
26161
- babelPlugins: [[babelPluginInstrument, {
26162
- rootDirectoryUrl
26163
- }]],
26173
+ babelPlugins: [babelPluginInstrument],
26164
26174
  urlInfo: {
26165
26175
  originalUrl: fileUrl,
26166
26176
  content
@@ -26395,7 +26405,11 @@ const run = async ({
26395
26405
  runtime,
26396
26406
  runtimeParams
26397
26407
  }) => {
26398
- const result = {};
26408
+ const result = {
26409
+ status: "pending",
26410
+ errors: [],
26411
+ namespace: null
26412
+ };
26399
26413
  const callbacks = [];
26400
26414
  const onConsoleRef = {
26401
26415
  current: () => {}
@@ -26406,25 +26420,14 @@ const run = async ({
26406
26420
  const runtimeLabel = `${runtime.name}/${runtime.version}`;
26407
26421
  const runOperation = Abort.startOperation();
26408
26422
  runOperation.addAbortSignal(signal);
26423
+ let timeoutAbortSource;
26409
26424
 
26410
26425
  if ( // ideally we would rather log than the timeout is ignored
26411
26426
  // when keepRunning is true
26412
26427
  !keepRunning && typeof allocatedMs === "number" && allocatedMs !== Infinity) {
26413
- const timeoutAbortSource = runOperation.timeout(allocatedMs);
26414
- callbacks.push(() => {
26415
- if (result.status === "errored" && Abort.isAbortError(result.error) && timeoutAbortSource.signal.aborted) {
26416
- result.status = "timedout";
26417
- delete result.error;
26418
- }
26419
- });
26428
+ timeoutAbortSource = runOperation.timeout(allocatedMs);
26420
26429
  }
26421
26430
 
26422
- callbacks.push(() => {
26423
- if (result.status === "errored" && Abort.isAbortError(result.error)) {
26424
- result.status = "aborted";
26425
- delete result.error;
26426
- }
26427
- });
26428
26431
  const consoleCalls = [];
26429
26432
 
26430
26433
  onConsoleRef.current = ({
@@ -26448,9 +26451,7 @@ const run = async ({
26448
26451
  };
26449
26452
 
26450
26453
  if (collectConsole) {
26451
- callbacks.push(() => {
26452
- result.consoleCalls = consoleCalls;
26453
- });
26454
+ result.consoleCalls = consoleCalls;
26454
26455
  } // we do not keep coverage in memory, it can grow very big
26455
26456
  // instead we store it on the filesystem
26456
26457
  // and they can be read later at "coverageFileUrl"
@@ -26517,35 +26518,35 @@ const run = async ({
26517
26518
  const {
26518
26519
  status,
26519
26520
  namespace,
26520
- error,
26521
+ errors,
26521
26522
  performance
26522
26523
  } = winner.data;
26523
26524
  result.status = status;
26524
-
26525
- if (status === "errored") {
26526
- result.error = error;
26527
- } else {
26528
- result.namespace = namespace;
26529
- }
26525
+ result.errors.push(...errors);
26526
+ result.namespace = namespace;
26530
26527
 
26531
26528
  if (collectPerformance) {
26532
26529
  result.performance = performance;
26533
26530
  }
26534
-
26535
- callbacks.forEach(callback => {
26536
- callback();
26537
- });
26538
- return result;
26539
26531
  } catch (e) {
26540
- result.status = "errored";
26541
- result.error = e;
26542
- callbacks.forEach(callback => {
26543
- callback();
26544
- });
26545
- return result;
26532
+ if (Abort.isAbortError(e)) {
26533
+ if (timeoutAbortSource && timeoutAbortSource.signal.aborted) {
26534
+ result.status = "timedout";
26535
+ } else {
26536
+ result.status = "aborted";
26537
+ }
26538
+ } else {
26539
+ result.status = "errored";
26540
+ result.errors.push(e);
26541
+ }
26546
26542
  } finally {
26547
26543
  await runOperation.end();
26548
26544
  }
26545
+
26546
+ callbacks.forEach(callback => {
26547
+ callback();
26548
+ });
26549
+ return result;
26549
26550
  };
26550
26551
 
26551
26552
  const pingServer = async url => {
@@ -26694,9 +26695,10 @@ const createExecutionLog = ({
26694
26695
 
26695
26696
  const {
26696
26697
  consoleCalls = [],
26697
- error
26698
+ errors = []
26698
26699
  } = executionResult;
26699
26700
  const consoleOutput = formatConsoleCalls(consoleCalls);
26701
+ const errorsOutput = formatErrors(errors);
26700
26702
  return formatExecution({
26701
26703
  label: `${description}${summary}`,
26702
26704
  details: {
@@ -26706,14 +26708,39 @@ const createExecutionLog = ({
26706
26708
  } : {}),
26707
26709
  ...(logEachDuration ? {
26708
26710
  duration: status === "executing" ? msAsEllapsedTime(Date.now() - startMs) : msAsDuration(endMs - startMs)
26709
- } : {}),
26710
- ...(error ? {
26711
- error: error.stack || error.message || error
26712
26711
  } : {})
26713
26712
  },
26714
- consoleOutput
26713
+ consoleOutput,
26714
+ errorsOutput
26715
26715
  });
26716
26716
  };
26717
+
26718
+ const formatErrors = errors => {
26719
+ if (errors.length === 0) {
26720
+ return "";
26721
+ }
26722
+
26723
+ const formatError = error => error.stack || error.message || error;
26724
+
26725
+ if (errors.length === 1) {
26726
+ return `${ANSI.color(`-------- error --------`, ANSI.RED)}
26727
+ ${formatError(errors[0])}
26728
+ ${ANSI.color(`-------------------------`, ANSI.RED)}`;
26729
+ }
26730
+
26731
+ let output = [];
26732
+ errors.forEach(error => {
26733
+ output.push(prefixFirstAndIndentRemainingLines({
26734
+ prefix: `${UNICODE.CIRCLE_CROSS} `,
26735
+ indentation: " ",
26736
+ text: formatError(error)
26737
+ }));
26738
+ });
26739
+ return `${ANSI.color(`-------- errors (${errors.length}) --------`, ANSI.RED)}
26740
+ ${output.join(`\n`)}
26741
+ ${ANSI.color(`-------------------------`, ANSI.RED)}`;
26742
+ };
26743
+
26717
26744
  const createSummaryLog = summary => `-------------- summary -----------------
26718
26745
  ${createAllExecutionsSummary(summary)}
26719
26746
  total duration: ${msAsDuration(summary.duration)}
@@ -26918,6 +26945,7 @@ const formatConsoleOutput = consoleCalls => {
26918
26945
  const textFormatted = prefixFirstAndIndentRemainingLines({
26919
26946
  prefix: CONSOLE_ICONS[regroupedCall.type],
26920
26947
  text,
26948
+ trimLines: true,
26921
26949
  trimLastLine: index === regroupedCalls.length - 1
26922
26950
  });
26923
26951
  consoleOutput += textFormatted;
@@ -26927,17 +26955,18 @@ const formatConsoleOutput = consoleCalls => {
26927
26955
 
26928
26956
  const prefixFirstAndIndentRemainingLines = ({
26929
26957
  prefix,
26958
+ indentation = " ",
26930
26959
  text,
26960
+ trimLines,
26931
26961
  trimLastLine
26932
26962
  }) => {
26933
26963
  const lines = text.split(/\r?\n/);
26934
26964
  const firstLine = lines.shift();
26935
26965
  let result = `${prefix} ${firstLine}`;
26936
26966
  let i = 0;
26937
- const indentation = ` `;
26938
26967
 
26939
26968
  while (i < lines.length) {
26940
- const line = lines[i].trim();
26969
+ const line = trimLines ? lines[i].trim() : lines[i];
26941
26970
  i++;
26942
26971
  result += line.length ? `\n${indentation}${line}` : trimLastLine && i === lines.length ? "" : `\n`;
26943
26972
  }
@@ -26988,7 +27017,8 @@ const formatConsoleSummary = repartition => {
26988
27017
  const formatExecution = ({
26989
27018
  label,
26990
27019
  details = {},
26991
- consoleOutput
27020
+ consoleOutput,
27021
+ errorsOutput
26992
27022
  }) => {
26993
27023
  let message = ``;
26994
27024
  message += label;
@@ -26998,8 +27028,11 @@ ${key}: ${details[key]}`;
26998
27028
  });
26999
27029
 
27000
27030
  if (consoleOutput) {
27001
- message += `
27002
- ${consoleOutput}`;
27031
+ message += `\n${consoleOutput}`;
27032
+ }
27033
+
27034
+ if (errorsOutput) {
27035
+ message += `\n${errorsOutput}`;
27003
27036
  }
27004
27037
 
27005
27038
  return message;
@@ -27009,6 +27042,7 @@ const executePlan = async (plan, {
27009
27042
  signal,
27010
27043
  handleSIGINT,
27011
27044
  logger,
27045
+ logRefresh,
27012
27046
  logRuntime,
27013
27047
  logEachDuration,
27014
27048
  logSummary,
@@ -27181,7 +27215,7 @@ const executePlan = async (plan, {
27181
27215
 
27182
27216
  const debugLogsEnabled = loggerToLevels(logger).debug;
27183
27217
  const executionLogsEnabled = loggerToLevels(logger).info;
27184
- const executionSpinner = !debugLogsEnabled && executionLogsEnabled && process.stdout.isTTY && // if there is an error during execution npm will mess up the output
27218
+ const executionSpinner = logRefresh && !debugLogsEnabled && executionLogsEnabled && process.stdout.isTTY && // if there is an error during execution npm will mess up the output
27185
27219
  // (happens when npm runs several command in a workspace)
27186
27220
  // so we enable spinner only when !process.exitCode (no error so far)
27187
27221
  process.exitCode !== 1;
@@ -27281,7 +27315,7 @@ const executePlan = async (plan, {
27281
27315
  } else {
27282
27316
  executionResult = {
27283
27317
  status: "errored",
27284
- error: new Error(`No file at ${fileRelativeUrl} for execution "${executionName}"`)
27318
+ errors: [new Error(`No file at ${fileRelativeUrl} for execution "${executionName}"`)]
27285
27319
  };
27286
27320
  }
27287
27321
 
@@ -27527,6 +27561,7 @@ const executeTestPlan = async ({
27527
27561
  signal = new AbortController().signal,
27528
27562
  handleSIGINT = true,
27529
27563
  logLevel = "info",
27564
+ logRefresh = true,
27530
27565
  logRuntime = true,
27531
27566
  logEachDuration = true,
27532
27567
  logSummary = true,
@@ -27617,7 +27652,7 @@ const executeTestPlan = async ({
27617
27652
  signal,
27618
27653
  handleSIGINT,
27619
27654
  logger,
27620
- logLevel,
27655
+ logRefresh,
27621
27656
  logSummary,
27622
27657
  logRuntime,
27623
27658
  logEachDuration,
@@ -27699,54 +27734,6 @@ const executeTestPlan = async ({
27699
27734
  };
27700
27735
  };
27701
27736
 
27702
- const escapeChars = (string, replacements) => {
27703
- const charsToEscape = Object.keys(replacements);
27704
- let result = "";
27705
- let last = 0;
27706
- let i = 0;
27707
-
27708
- while (i < string.length) {
27709
- const char = string[i];
27710
- i++;
27711
-
27712
- if (charsToEscape.includes(char) && !isEscaped(i - 1, string)) {
27713
- if (last === i - 1) {
27714
- result += replacements[char];
27715
- } else {
27716
- result += `${string.slice(last, i - 1)}${replacements[char]}`;
27717
- }
27718
-
27719
- last = i;
27720
- }
27721
- }
27722
-
27723
- if (last !== string.length) {
27724
- result += string.slice(last);
27725
- }
27726
-
27727
- return result;
27728
- };
27729
-
27730
- const escapeRegexpSpecialChars = string => {
27731
- return escapeChars(String(string), {
27732
- "/": "\\/",
27733
- "^": "\\^",
27734
- "\\": "\\\\",
27735
- "[": "\\[",
27736
- "]": "\\]",
27737
- "(": "\\(",
27738
- ")": "\\)",
27739
- "{": "\\{",
27740
- "}": "\\}",
27741
- "?": "\\?",
27742
- "+": "\\+",
27743
- "*": "\\*",
27744
- ".": "\\.",
27745
- "|": "\\|",
27746
- "$": "\\$"
27747
- });
27748
- };
27749
-
27750
27737
  const createRuntimeFromPlaywright = ({
27751
27738
  browserName,
27752
27739
  browserVersion,
@@ -27862,7 +27849,11 @@ const createRuntimeFromPlaywright = ({
27862
27849
  }
27863
27850
  };
27864
27851
 
27865
- const result = {};
27852
+ const result = {
27853
+ status: "pending",
27854
+ namespace: null,
27855
+ errors: []
27856
+ };
27866
27857
  const callbacks = [];
27867
27858
 
27868
27859
  if (coverageEnabled) {
@@ -27984,19 +27975,18 @@ const createRuntimeFromPlaywright = ({
27984
27975
  });
27985
27976
  },
27986
27977
  // https://github.com/GoogleChrome/puppeteer/blob/v1.4.0/docs/api.md#event-pageerror
27987
- pageerror: cb => {
27988
- return registerEvent({
27989
- object: page,
27990
- eventType: "pageerror",
27991
- callback: error => {
27992
- if (ignoreErrorHook(error)) {
27993
- return;
27994
- }
27995
-
27996
- cb(transformErrorHook(error));
27997
- }
27998
- });
27999
- },
27978
+ // pageerror: () => {
27979
+ // return registerEvent({
27980
+ // object: page,
27981
+ // eventType: "pageerror",
27982
+ // callback: (error) => {
27983
+ // if (ignoreErrorHook(error)) {
27984
+ // return
27985
+ // }
27986
+ // result.errors.push(transformErrorHook(error))
27987
+ // },
27988
+ // })
27989
+ // },
28000
27990
  closed: cb => {
28001
27991
  // https://github.com/GoogleChrome/puppeteer/blob/v1.4.0/docs/api.md#event-disconnected
28002
27992
  if (isBrowserDedicatedToExecution) {
@@ -28042,39 +28032,15 @@ const createRuntimeFromPlaywright = ({
28042
28032
 
28043
28033
  /* istanbul ignore next */
28044
28034
  () => {
28045
- if (!window.__html_supervisor__) {
28046
- throw new Error(`window.__html_supervisor__ not found`);
28035
+ if (!window.__supervisor__) {
28036
+ throw new Error(`window.__supervisor__ not found`);
28047
28037
  }
28048
28038
 
28049
- return window.__html_supervisor__.getScriptExecutionResults();
28039
+ return window.__supervisor__.getScriptExecutionResults();
28050
28040
  }
28051
28041
  /* eslint-enable no-undef */
28052
28042
  );
28053
- const {
28054
- status,
28055
- scriptExecutionResults
28056
- } = returnValue;
28057
-
28058
- if (status === "errored") {
28059
- const {
28060
- exceptionSource
28061
- } = returnValue;
28062
- const error = evalException(exceptionSource, {
28063
- rootDirectoryUrl,
28064
- devServerOrigin,
28065
- transformErrorHook
28066
- });
28067
- cb({
28068
- status: "errored",
28069
- error,
28070
- namespace: scriptExecutionResults
28071
- });
28072
- } else {
28073
- cb({
28074
- status: "completed",
28075
- namespace: scriptExecutionResults
28076
- });
28077
- }
28043
+ cb(returnValue);
28078
28044
  } catch (e) {
28079
28045
  reject(e);
28080
28046
  }
@@ -28082,47 +28048,48 @@ const createRuntimeFromPlaywright = ({
28082
28048
  }, resolve);
28083
28049
  });
28084
28050
 
28085
- const getResult = async () => {
28051
+ const writeResult = async () => {
28086
28052
  const winner = await winnerPromise;
28087
28053
 
28088
28054
  if (winner.name === "aborted") {
28089
- return {
28090
- status: "aborted"
28091
- };
28055
+ result.status = "aborted";
28056
+ return;
28092
28057
  }
28093
28058
 
28094
- if (winner.name === "error" || winner.name === "pageerror") {
28095
- const error = winner.data;
28096
- return {
28097
- status: "errored",
28098
- error
28099
- };
28059
+ if (winner.name === "error") {
28060
+ let error = winner.data;
28061
+ result.status = "errored";
28062
+ result.errors.push(error);
28063
+ return;
28100
28064
  }
28101
28065
 
28102
28066
  if (winner.name === "closed") {
28103
- return {
28104
- status: "errored",
28105
- error: isBrowserDedicatedToExecution ? new Error(`browser disconnected during execution`) : new Error(`page closed during execution`)
28106
- };
28107
- }
28067
+ result.status = "errored";
28068
+ result.errors.push(isBrowserDedicatedToExecution ? new Error(`browser disconnected during execution`) : new Error(`page closed during execution`));
28069
+ return;
28070
+ } // winner.name = 'response'
28071
+
28108
28072
 
28109
- return winner.data;
28073
+ const {
28074
+ executionResults
28075
+ } = winner.data;
28076
+ result.status = "completed";
28077
+ result.namespace = executionResults;
28078
+ Object.keys(executionResults).forEach(key => {
28079
+ const executionResult = executionResults[key];
28080
+
28081
+ if (executionResult.status === "errored") {
28082
+ result.status = "errored";
28083
+ result.errors.push({ ...executionResult.exception,
28084
+ stack: executionResult.exception.text
28085
+ });
28086
+ }
28087
+ });
28088
+ return;
28110
28089
  };
28111
28090
 
28112
28091
  try {
28113
- const {
28114
- status,
28115
- error,
28116
- namespace,
28117
- performance
28118
- } = await getResult();
28119
- result.status = status;
28120
-
28121
- if (status === "errored") {
28122
- result.error = error;
28123
- } else {
28124
- result.namespace = namespace;
28125
- }
28092
+ await writeResult();
28126
28093
 
28127
28094
  if (collectPerformance) {
28128
28095
  result.performance = performance;
@@ -28134,7 +28101,7 @@ const createRuntimeFromPlaywright = ({
28134
28101
  }, Promise.resolve());
28135
28102
  } catch (e) {
28136
28103
  result.status = "errored";
28137
- result.error = e;
28104
+ result.errors = [e];
28138
28105
  }
28139
28106
 
28140
28107
  if (keepRunning) {
@@ -28295,25 +28262,6 @@ const registerEvent = ({
28295
28262
  };
28296
28263
  };
28297
28264
 
28298
- const evalException = (exceptionSource, {
28299
- rootDirectoryUrl,
28300
- devServerOrigin,
28301
- transformErrorHook
28302
- }) => {
28303
- const script = new Script(exceptionSource, {
28304
- filename: ""
28305
- });
28306
- const error = script.runInThisContext();
28307
-
28308
- if (error && error instanceof Error) {
28309
- const remoteRootRegexp = new RegExp(escapeRegexpSpecialChars(`${devServerOrigin}/`), "g");
28310
- error.stack = error.stack.replace(remoteRootRegexp, rootDirectoryUrl);
28311
- error.message = error.message.replace(remoteRootRegexp, rootDirectoryUrl);
28312
- }
28313
-
28314
- return transformErrorHook(error);
28315
- };
28316
-
28317
28265
  const chromium = createRuntimeFromPlaywright({
28318
28266
  browserName: "chromium",
28319
28267
  browserVersion: "104.0.5112.48",
@@ -28809,8 +28757,13 @@ nodeChildProcess.run = async ({
28809
28757
  }
28810
28758
  }, resolve);
28811
28759
  });
28760
+ const result = {
28761
+ status: "executing",
28762
+ errors: [],
28763
+ namespace: null
28764
+ };
28812
28765
 
28813
- const getResult = async () => {
28766
+ const writeResult = async () => {
28814
28767
  actionOperation.throwIfAborted();
28815
28768
  await childProcessReadyPromise;
28816
28769
  actionOperation.throwIfAborted();
@@ -28833,18 +28786,16 @@ nodeChildProcess.run = async ({
28833
28786
  const winner = await winnerPromise;
28834
28787
 
28835
28788
  if (winner.name === "aborted") {
28836
- return {
28837
- status: "aborted"
28838
- };
28789
+ result.status = "aborted";
28790
+ return;
28839
28791
  }
28840
28792
 
28841
28793
  if (winner.name === "error") {
28842
28794
  const error = winner.data;
28843
28795
  removeOutputListener();
28844
- return {
28845
- status: "errored",
28846
- error
28847
- };
28796
+ result.status = "errored";
28797
+ result.errors.push(error);
28798
+ return;
28848
28799
  }
28849
28800
 
28850
28801
  if (winner.name === "exit") {
@@ -28854,25 +28805,22 @@ nodeChildProcess.run = async ({
28854
28805
  await cleanup("process exit");
28855
28806
 
28856
28807
  if (code === 12) {
28857
- return {
28858
- status: "errored",
28859
- error: new Error(`node process exited with 12 (the forked child process wanted to use a non-available port for debug)`)
28860
- };
28808
+ result.status = "errored";
28809
+ result.errors.push(new Error(`node process exited with 12 (the forked child process wanted to use a non-available port for debug)`));
28810
+ return;
28861
28811
  }
28862
28812
 
28863
28813
  if (code === null || code === 0 || code === EXIT_CODES.SIGINT || code === EXIT_CODES.SIGTERM || code === EXIT_CODES.SIGABORT) {
28864
- return {
28865
- status: "errored",
28866
- error: new Error(`node process exited during execution`)
28867
- };
28814
+ result.status = "errored";
28815
+ result.errors.push(new Error(`node process exited during execution`));
28816
+ return;
28868
28817
  } // process.exit(1) in child process or process.exitCode = 1 + process.exit()
28869
28818
  // means there was an error even if we don't know exactly what.
28870
28819
 
28871
28820
 
28872
- return {
28873
- status: "errored",
28874
- error: new Error(`node process exited with code ${code} during execution`)
28875
- };
28821
+ result.status = "errored";
28822
+ result.errors.push(new Error(`node process exited with code ${code} during execution`));
28823
+ return;
28876
28824
  }
28877
28825
 
28878
28826
  const {
@@ -28881,27 +28829,27 @@ nodeChildProcess.run = async ({
28881
28829
  } = winner.data;
28882
28830
 
28883
28831
  if (status === "action-failed") {
28884
- return {
28885
- status: "errored",
28886
- error: value
28887
- };
28832
+ result.status = "errored";
28833
+ result.errors.push(value);
28834
+ return;
28888
28835
  }
28889
28836
 
28890
- return {
28891
- status: "completed",
28892
- ...value
28893
- };
28837
+ const {
28838
+ namespace,
28839
+ performance,
28840
+ coverage
28841
+ } = value;
28842
+ result.status = "completed";
28843
+ result.namespace = namespace;
28844
+ result.performance = performance;
28845
+ result.coverage = coverage;
28894
28846
  };
28895
28847
 
28896
- let result;
28897
-
28898
28848
  try {
28899
- result = await getResult();
28849
+ await writeResult();
28900
28850
  } catch (e) {
28901
- result = {
28902
- status: "errored",
28903
- error: e
28904
- };
28851
+ result.status = "errored";
28852
+ result.errors.push(e);
28905
28853
  }
28906
28854
 
28907
28855
  if (keepRunning) {
@@ -29108,8 +29056,13 @@ nodeWorkerThread.run = async ({
29108
29056
  }
29109
29057
  }, resolve);
29110
29058
  });
29059
+ const result = {
29060
+ status: "executing",
29061
+ errors: [],
29062
+ namespace: null
29063
+ };
29111
29064
 
29112
- const getResult = async () => {
29065
+ const writeResult = async () => {
29113
29066
  actionOperation.throwIfAborted();
29114
29067
  await workerThreadReadyPromise;
29115
29068
  actionOperation.throwIfAborted();
@@ -29132,18 +29085,16 @@ nodeWorkerThread.run = async ({
29132
29085
  const winner = await winnerPromise;
29133
29086
 
29134
29087
  if (winner.name === "aborted") {
29135
- return {
29136
- status: "aborted"
29137
- };
29088
+ result.status = "aborted";
29089
+ return;
29138
29090
  }
29139
29091
 
29140
29092
  if (winner.name === "error") {
29141
29093
  const error = winner.data;
29142
29094
  removeOutputListener();
29143
- return {
29144
- status: "errored",
29145
- error
29146
- };
29095
+ result.status = "errored";
29096
+ result.errors.push(error);
29097
+ return;
29147
29098
  }
29148
29099
 
29149
29100
  if (winner.name === "exit") {
@@ -29153,25 +29104,21 @@ nodeWorkerThread.run = async ({
29153
29104
  await cleanup("process exit");
29154
29105
 
29155
29106
  if (code === 12) {
29156
- return {
29157
- status: "errored",
29158
- error: new Error(`node process exited with 12 (the forked child process wanted to use a non-available port for debug)`)
29159
- };
29107
+ result.status = "errored";
29108
+ result.errors.push(new Error(`node process exited with 12 (the forked child process wanted to use a non-available port for debug)`));
29109
+ return;
29160
29110
  }
29161
29111
 
29162
29112
  if (code === null || code === 0 || code === EXIT_CODES.SIGINT || code === EXIT_CODES.SIGTERM || code === EXIT_CODES.SIGABORT) {
29163
- return {
29164
- status: "errored",
29165
- error: new Error(`node worker thread exited during execution`)
29166
- };
29113
+ result.status = "errored";
29114
+ result.errors.push(new Error(`node worker thread exited during execution`));
29115
+ return;
29167
29116
  } // process.exit(1) in child process or process.exitCode = 1 + process.exit()
29168
29117
  // means there was an error even if we don't know exactly what.
29169
29118
 
29170
29119
 
29171
- return {
29172
- status: "errored",
29173
- error: new Error(`node worker thread exited with code ${code} during execution`)
29174
- };
29120
+ result.status = "errored";
29121
+ result.errors.push(new Error(`node worker thread exited with code ${code} during execution`));
29175
29122
  }
29176
29123
 
29177
29124
  const {
@@ -29180,10 +29127,9 @@ nodeWorkerThread.run = async ({
29180
29127
  } = winner.data;
29181
29128
 
29182
29129
  if (status === "action-failed") {
29183
- return {
29184
- status: "errored",
29185
- error: value
29186
- };
29130
+ result.status = "errored";
29131
+ result.errors.push(value);
29132
+ return;
29187
29133
  }
29188
29134
 
29189
29135
  const {
@@ -29191,23 +29137,17 @@ nodeWorkerThread.run = async ({
29191
29137
  performance,
29192
29138
  coverage
29193
29139
  } = value;
29194
- return {
29195
- status: "completed",
29196
- namespace,
29197
- performance,
29198
- coverage
29199
- };
29140
+ result.status = "completed";
29141
+ result.namespace = namespace;
29142
+ result.performance = performance;
29143
+ result.coverage = coverage;
29200
29144
  };
29201
29145
 
29202
- let result;
29203
-
29204
29146
  try {
29205
- result = await getResult();
29147
+ await writeResult();
29206
29148
  } catch (e) {
29207
- result = {
29208
- status: "errored",
29209
- error: e
29210
- };
29149
+ result.status = "errored";
29150
+ result.errors.push(e);
29211
29151
  }
29212
29152
 
29213
29153
  if (keepRunning) {
@@ -29486,15 +29426,15 @@ const createBuildFilesService = ({
29486
29426
  buildIndexPath
29487
29427
  }) => {
29488
29428
  return request => {
29489
- const urlIsVersioned = new URL(request.ressource, request.origin).searchParams.has("v");
29429
+ const urlIsVersioned = new URL(request.url).searchParams.has("v");
29490
29430
 
29491
- if (buildIndexPath && request.ressource === "/") {
29431
+ if (buildIndexPath && request.resource === "/") {
29492
29432
  request = { ...request,
29493
- ressource: `/${buildIndexPath}`
29433
+ resource: `/${buildIndexPath}`
29494
29434
  };
29495
29435
  }
29496
29436
 
29497
- return fetchFileSystem(new URL(request.ressource.slice(1), buildDirectoryUrl), {
29437
+ return fetchFileSystem(new URL(request.resource.slice(1), buildDirectoryUrl), {
29498
29438
  headers: request.headers,
29499
29439
  cacheControl: urlIsVersioned ? `private,max-age=${SECONDS_IN_30_DAYS},immutable` : "private,max-age=0,must-revalidate",
29500
29440
  etagEnabled: true,
@@ -29594,7 +29534,7 @@ const execute = async ({
29594
29534
  */
29595
29535
 
29596
29536
 
29597
- throw result.error;
29537
+ throw result.errors[result.errors.length - 1];
29598
29538
  }
29599
29539
 
29600
29540
  return result;
@@ -29627,10 +29567,9 @@ const globalInjectorOnHtml = async (urlInfo, globals) => {
29627
29567
  isWebWorker: false
29628
29568
  });
29629
29569
  injectScriptNodeAsEarlyAsPossible(htmlAst, createHtmlNode({
29630
- "tagName": "script",
29631
- "textContent": clientCode,
29632
- "injected-by": "jsenv:inject_globals"
29633
- }));
29570
+ tagName: "script",
29571
+ textContent: clientCode
29572
+ }), "jsenv:inject_globals");
29634
29573
  return stringifyHtmlAst(htmlAst);
29635
29574
  };
29636
29575