@jsenv/core 27.0.0-alpha.74 → 27.0.0-alpha.77

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 (30) hide show
  1. package/dist/js/html_supervisor_setup.js +4 -1
  2. package/dist/main.js +153 -156
  3. package/package.json +5 -6
  4. package/src/build/build.js +6 -11
  5. package/src/build/start_build_server.js +2 -3
  6. package/src/dev/start_dev_server.js +6 -10
  7. package/src/execute/execute.js +1 -4
  8. package/src/execute/runtimes/browsers/from_playwright.js +2 -2
  9. package/src/execute/runtimes/node/child_exec_options.js +1 -1
  10. package/src/execute/runtimes/node/node_process.js +2 -2
  11. package/src/main.js +1 -1
  12. package/src/omega/errors.js +1 -1
  13. package/src/omega/kitchen.js +21 -13
  14. package/src/omega/server/file_service.js +7 -8
  15. package/src/omega/url_graph.js +1 -1
  16. package/src/plugins/bundling/js_module/bundle_js_module.js +2 -2
  17. package/src/plugins/file_urls/jsenv_plugin_file_urls.js +3 -7
  18. package/src/plugins/html_supervisor/client/html_supervisor_setup.js +4 -1
  19. package/src/plugins/inject_globals/inject_globals.js +57 -0
  20. package/src/plugins/inject_globals/jsenv_plugin_inject_globals.js +17 -69
  21. package/src/plugins/inline/jsenv_plugin_data_urls.js +2 -2
  22. package/src/plugins/inline/jsenv_plugin_inline.js +1 -1
  23. package/src/plugins/node_esm_resolution/jsenv_plugin_node_esm_resolution.js +2 -0
  24. package/src/plugins/plugin_controller.js +2 -2
  25. package/src/plugins/plugins.js +0 -3
  26. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic.js +3 -3
  27. package/src/plugins/transpilation/import_assertions/jsenv_plugin_import_assertions.js +12 -12
  28. package/src/test/execute_plan.js +7 -4
  29. package/src/test/execute_test_plan.js +1 -3
  30. package/src/test/execution_steps.js +1 -1
@@ -32,7 +32,10 @@ window.__html_supervisor__ = {
32
32
  lastWindowError = e.error
33
33
  }
34
34
  const cleanup = () => {
35
- document.body.removeChild(script)
35
+ // the execution of the script itself can remove script from the page
36
+ if (script.parentNode) {
37
+ script.parentNode.removeChild(script)
38
+ }
36
39
  window.removeEventListener("error", windowErrorCallback)
37
40
  }
38
41
  window.addEventListener("error", windowErrorCallback)
package/dist/main.js CHANGED
@@ -1,7 +1,6 @@
1
1
  import { parentPort } from "node:worker_threads";
2
2
  import { registerFileLifecycle, readFileSync as readFileSync$1, bufferToEtag, writeFileSync, ensureWindowsDriveLetter, collectFiles, assertAndNormalizeDirectoryUrl, registerDirectoryLifecycle, writeFile, ensureEmptyDirectory, writeDirectory } from "@jsenv/filesystem";
3
- import { createDetailedMessage, createLogger, loggerToLevels } from "@jsenv/logger";
4
- import { createTaskLog, ANSI, msAsDuration, msAsEllapsedTime, byteAsMemoryUsage, UNICODE, createLog, startSpinner, distributePercentages, byteAsFileSize } from "@jsenv/log";
3
+ import { createDetailedMessage, createLogger, createTaskLog, loggerToLevels, ANSI, msAsDuration, msAsEllapsedTime, byteAsMemoryUsage, UNICODE, createLog, startSpinner, distributePercentages, byteAsFileSize } from "@jsenv/log";
5
4
  import { urlToRelativeUrl, generateInlineContentUrl, ensurePathnameTrailingSlash, urlIsInsideOf, urlToFilename, urlToExtension, DATA_URL, injectQueryParams, injectQueryParamsIntoSpecifier, fileSystemPathToUrl, urlToFileSystemPath, isFileSystemPath, normalizeUrl, stringifyUrlSite, setUrlFilename, moveUrl, getCallerPosition, resolveUrl, resolveDirectoryUrl, asUrlWithoutSearch, asUrlUntilPathname, urlToBasename } from "@jsenv/urls";
6
5
  import { initReloadableProcess } from "@jsenv/utils/process_reload/process_reload.js";
7
6
  import { URL_META } from "@jsenv/url-meta";
@@ -969,7 +968,9 @@ const jsenvPluginNodeEsmResolver = ({
969
968
  fetchUrlContent: urlInfo => {
970
969
  if (urlInfo.url.startsWith("file:///@ignore/")) {
971
970
  return {
972
- content: "export default {}"
971
+ content: "export default {}",
972
+ contentType: "text/javascript",
973
+ type: "js_module"
973
974
  };
974
975
  }
975
976
 
@@ -1232,17 +1233,9 @@ const jsenvPluginFileUrls = ({
1232
1233
 
1233
1234
  const fileBuffer = readFileSync(urlObject);
1234
1235
  const contentType = CONTENT_TYPE.fromUrlExtension(urlInfo.url);
1235
-
1236
- if (CONTENT_TYPE.isTextual(contentType)) {
1237
- return {
1238
- contentType,
1239
- content: String(fileBuffer)
1240
- };
1241
- }
1242
-
1243
1236
  return {
1244
- contentType,
1245
- content: fileBuffer
1237
+ content: CONTENT_TYPE.isTextual(contentType) ? String(fileBuffer) : fileBuffer,
1238
+ contentType
1246
1239
  };
1247
1240
  }
1248
1241
  }];
@@ -1791,12 +1784,12 @@ const jsenvPluginDataUrls = () => {
1791
1784
  } = DATA_URL.parse(urlInfo.url);
1792
1785
  urlInfo.data.base64Flag = base64Flag;
1793
1786
  return {
1794
- contentType,
1795
1787
  content: contentFromUrlData({
1796
1788
  contentType,
1797
1789
  base64Flag,
1798
1790
  urlData
1799
- })
1791
+ }),
1792
+ contentType
1800
1793
  };
1801
1794
  },
1802
1795
  formatUrl: (reference, context) => {
@@ -1819,7 +1812,7 @@ const jsenvPluginDataUrls = () => {
1819
1812
  }
1820
1813
 
1821
1814
  const specifier = DATA_URL.stringify({
1822
- contentType: urlInfo.contentType,
1815
+ contentType: urlInfo.headers["content-type"],
1823
1816
  base64Flag: urlInfo.data.base64Flag,
1824
1817
  data: urlInfo.data.base64Flag ? dataToBase64(urlInfo.content) : String(urlInfo.content)
1825
1818
  });
@@ -1918,10 +1911,10 @@ const jsenvPluginInlineUrls = () => {
1918
1911
  }
1919
1912
 
1920
1913
  return {
1921
- contentType: urlInfo.contentType,
1922
1914
  // we want to fetch the original content otherwise we might re-cook
1923
1915
  // content already cooked
1924
- content: urlInfo.originalContent
1916
+ content: urlInfo.originalContent,
1917
+ contentType: urlInfo.contentType
1925
1918
  };
1926
1919
  }
1927
1920
  };
@@ -2459,78 +2452,6 @@ const babelPluginMetadataImportMetaScenarios = () => {
2459
2452
  };
2460
2453
  };
2461
2454
 
2462
- const jsenvPluginInjectGlobals = (globals = {}) => {
2463
- if (Object.keys(globals).length === 0) {
2464
- return [];
2465
- }
2466
-
2467
- return {
2468
- name: "jsenv:inject_globals",
2469
- appliesDuring: "*",
2470
- transformUrlContent: {
2471
- html: injectGlobals,
2472
- js_classic: injectGlobals,
2473
- js_module: injectGlobals
2474
- }
2475
- };
2476
- };
2477
- const injectGlobals = (urlInfo, globals) => {
2478
- if (urlInfo.type === "html") {
2479
- return globalInjectorOnHtmlEntryPoint(urlInfo, globals);
2480
- }
2481
-
2482
- if (urlInfo.type === "js_classic" || urlInfo.type === "js_module") {
2483
- return globalsInjectorOnJsEntryPoints(urlInfo, globals);
2484
- }
2485
-
2486
- throw new Error(`cannot inject globals into "${urlInfo.type}"`);
2487
- };
2488
-
2489
- const globalInjectorOnHtmlEntryPoint = async (urlInfo, globals) => {
2490
- if (!urlInfo.data.isEntryPoint) {
2491
- return null;
2492
- } // ideally we would inject an importmap but browser support is too low
2493
- // (even worse for worker/service worker)
2494
- // so for now we inject code into entry points
2495
-
2496
-
2497
- const htmlAst = parseHtmlString(urlInfo.content, {
2498
- storeOriginalPositions: false
2499
- });
2500
- const clientCode = generateClientCodeForGlobals({
2501
- globals,
2502
- isWebWorker: false
2503
- });
2504
- injectScriptAsEarlyAsPossible(htmlAst, createHtmlNode({
2505
- "tagName": "script",
2506
- "textContent": clientCode,
2507
- "injected-by": "jsenv:inject_globals"
2508
- }));
2509
- return stringifyHtmlAst(htmlAst);
2510
- };
2511
-
2512
- const globalsInjectorOnJsEntryPoints = async (urlInfo, globals) => {
2513
- if (!urlInfo.data.isEntryPoint && !urlInfo.data.isWebWorkerEntryPoint) {
2514
- return null;
2515
- }
2516
-
2517
- const clientCode = generateClientCodeForGlobals({
2518
- globals,
2519
- isWebWorker: isWebWorkerUrlInfo(urlInfo)
2520
- });
2521
- const magicSource = createMagicSource(urlInfo.content);
2522
- magicSource.prepend(clientCode);
2523
- return magicSource.toContentAndSourcemap();
2524
- };
2525
-
2526
- const generateClientCodeForGlobals = ({
2527
- isWebWorker = false,
2528
- globals
2529
- }) => {
2530
- const globalName = isWebWorker ? "self" : "window";
2531
- return `Object.assign(${globalName}, ${JSON.stringify(globals, null, " ")});`;
2532
- };
2533
-
2534
2455
  const jsenvPluginCssParcel = () => {
2535
2456
  return {
2536
2457
  name: "jsenv:css_parcel",
@@ -2643,14 +2564,14 @@ const jsenvPluginAsModules = () => {
2643
2564
 
2644
2565
  const jsonText = JSON.stringify(originalUrlInfo.content.trim());
2645
2566
  return {
2646
- originalUrl: originalUrlInfo.originalUrl,
2647
- originalContent: originalUrlInfo.originalContent,
2648
- type: "js_module",
2649
- contentType: "text/javascript",
2650
2567
  // here we could `export default ${jsonText}`:
2651
2568
  // but js engine are optimized to recognize JSON.parse
2652
2569
  // and use a faster parsing strategy
2653
- content: `export default JSON.parse(${jsonText})`
2570
+ content: `export default JSON.parse(${jsonText})`,
2571
+ contentType: "text/javascript",
2572
+ type: "js_module",
2573
+ originalUrl: originalUrlInfo.originalUrl,
2574
+ originalContent: originalUrlInfo.originalContent
2654
2575
  };
2655
2576
  }
2656
2577
  };
@@ -2676,16 +2597,16 @@ const jsenvPluginAsModules = () => {
2676
2597
  canUseTemplateString: true
2677
2598
  });
2678
2599
  return {
2679
- originalUrl: originalUrlInfo.originalUrl,
2680
- originalContent: originalUrlInfo.originalContent,
2681
- type: "js_module",
2682
- contentType: "text/javascript",
2683
2600
  content: `import { InlineContent } from ${JSON.stringify(inlineContentClientFileUrl)}
2684
2601
 
2685
2602
  const inlineContent = new InlineContent(${cssText}, { type: "text/css" })
2686
2603
  const stylesheet = new CSSStyleSheet()
2687
2604
  stylesheet.replaceSync(inlineContent.text)
2688
- export default stylesheet`
2605
+ export default stylesheet`,
2606
+ contentType: "text/javascript",
2607
+ type: "js_module",
2608
+ originalUrl: originalUrlInfo.originalUrl,
2609
+ originalContent: originalUrlInfo.originalContent
2689
2610
  };
2690
2611
  }
2691
2612
  };
@@ -2711,14 +2632,14 @@ const jsenvPluginAsModules = () => {
2711
2632
  canUseTemplateString: true
2712
2633
  });
2713
2634
  return {
2714
- originalUrl: originalUrlInfo.originalUrl,
2715
- originalContent: originalUrlInfo.originalContent,
2716
- type: "js_module",
2717
- contentType: "text/javascript",
2718
2635
  content: `import { InlineContent } from ${JSON.stringify(inlineContentClientFileUrl)}
2719
2636
 
2720
2637
  const inlineContent = new InlineContent(${textPlain}, { type: "text/plain" })
2721
- export default inlineContent.text`
2638
+ export default inlineContent.text`,
2639
+ contentType: "text/javascript",
2640
+ type: "js_module",
2641
+ originalUrl: originalUrlInfo.originalUrl,
2642
+ originalContent: originalUrlInfo.originalContent
2722
2643
  };
2723
2644
  }
2724
2645
  };
@@ -3202,11 +3123,11 @@ const jsenvPluginAsJsClassicConversion = ({
3202
3123
  });
3203
3124
  urlInfo.data.jsClassicFormat = jsClassicFormat;
3204
3125
  return {
3126
+ content,
3127
+ contentType: "text/javascript",
3128
+ type: "js_classic",
3205
3129
  originalUrl: originalUrlInfo.originalUrl,
3206
3130
  originalContent: originalUrlInfo.originalContent,
3207
- type: "js_classic",
3208
- contentType: "text/javascript",
3209
- content,
3210
3131
  sourcemap
3211
3132
  };
3212
3133
  }
@@ -6027,7 +5948,6 @@ const getCorePlugins = ({
6027
5948
  nodeEsmResolution,
6028
5949
  fileSystemMagicResolution,
6029
5950
  directoryReferenceAllowed,
6030
- injectedGlobals,
6031
5951
  transpilation = true,
6032
5952
  minification = false,
6033
5953
  bundling = false,
@@ -6057,7 +5977,7 @@ const getCorePlugins = ({
6057
5977
  rootDirectoryUrl,
6058
5978
  runtimeCompat,
6059
5979
  ...nodeEsmResolution
6060
- }), jsenvPluginUrlResolution(), jsenvPluginUrlVersion(), jsenvPluginInjectGlobals(injectedGlobals), jsenvPluginCommonJsGlobals(), jsenvPluginImportMetaScenarios(), jsenvPluginNodeRuntime({
5980
+ }), jsenvPluginUrlResolution(), jsenvPluginUrlVersion(), jsenvPluginCommonJsGlobals(), jsenvPluginImportMetaScenarios(), jsenvPluginNodeRuntime({
6061
5981
  runtimeCompat
6062
5982
  }), jsenvPluginBundling(bundling), jsenvPluginMinification(minification), jsenvPluginImportMetaHot(), ...(clientAutoreload ? [jsenvPluginAutoreload({
6063
5983
  rootDirectoryUrl,
@@ -6368,7 +6288,7 @@ const createUrlInfo = url => {
6368
6288
  sourcemap: null,
6369
6289
  sourcemapReference: null,
6370
6290
  timing: {},
6371
- responseHeaders: {}
6291
+ headers: {}
6372
6292
  };
6373
6293
  };
6374
6294
 
@@ -6666,14 +6586,15 @@ const returnValueAssertions = [{
6666
6586
  if (typeof valueReturned === "object") {
6667
6587
  const {
6668
6588
  shouldHandle,
6669
- content
6589
+ content,
6590
+ body
6670
6591
  } = valueReturned;
6671
6592
 
6672
6593
  if (shouldHandle === false) {
6673
6594
  return undefined;
6674
6595
  }
6675
6596
 
6676
- if (typeof content !== "string" && !Buffer.isBuffer(content)) {
6597
+ if (typeof content !== "string" && !Buffer.isBuffer(content) && !body) {
6677
6598
  throw new Error(`Unexpected "content" returned by plugin: it must be a string or a buffer; got ${content}`);
6678
6599
  }
6679
6600
 
@@ -7297,17 +7218,35 @@ const createKitchen = ({
7297
7218
  return;
7298
7219
  }
7299
7220
 
7300
- const {
7221
+ let {
7222
+ content,
7223
+ contentType,
7301
7224
  data,
7302
7225
  type,
7303
7226
  subtype,
7304
- contentType = "application/octet-stream",
7305
7227
  originalUrl,
7306
7228
  originalContent,
7307
- content,
7308
7229
  sourcemap,
7309
- filename
7230
+ filename,
7231
+ status = 200,
7232
+ headers = {},
7233
+ body
7310
7234
  } = fetchUrlContentReturnValue;
7235
+
7236
+ if (status !== 200) {
7237
+ throw new Error(`unexpected status, ${status}`);
7238
+ }
7239
+
7240
+ if (content === undefined) {
7241
+ content = body;
7242
+ }
7243
+
7244
+ if (contentType === undefined) {
7245
+ contentType = headers["content-type"] || "application/octet-stream";
7246
+ }
7247
+
7248
+ urlInfo.contentType = contentType;
7249
+ urlInfo.headers = headers;
7311
7250
  urlInfo.type = type || reference.expectedType || inferUrlInfoType({
7312
7251
  url: urlInfo.url,
7313
7252
  contentType
@@ -7316,8 +7255,7 @@ const createKitchen = ({
7316
7255
  url: urlInfo.url,
7317
7256
  type: urlInfo.type,
7318
7257
  subtype: urlInfo.subtype
7319
- });
7320
- urlInfo.contentType = contentType; // during build urls info are reused and load returns originalUrl/originalContent
7258
+ }); // during build urls info are reused and load returns originalUrl/originalContent
7321
7259
 
7322
7260
  urlInfo.originalUrl = originalUrl || urlInfo.originalUrl;
7323
7261
  urlInfo.originalContent = originalContent === undefined ? content : originalContent;
@@ -7372,9 +7310,7 @@ const createKitchen = ({
7372
7310
  } = dishContext;
7373
7311
 
7374
7312
  context.cook = (urlInfo, nestedDishContext) => {
7375
- return cookDuringCook(urlInfo, {
7376
- outDirectoryUrl: dishContext.outDirectoryUrl,
7377
- clientRuntimeCompat: dishContext.clientRuntimeCompat,
7313
+ return cookDuringCook(urlInfo, { ...dishContext,
7378
7314
  ...nestedDishContext
7379
7315
  });
7380
7316
  };
@@ -8042,7 +7978,7 @@ const createFileService = ({
8042
7978
  status: 304,
8043
7979
  headers: {
8044
7980
  "cache-control": `private,max-age=0,must-revalidate`,
8045
- ...urlInfo.responseHeaders
7981
+ ...urlInfo.headers
8046
7982
  }
8047
7983
  };
8048
7984
  }
@@ -8057,7 +7993,6 @@ const createFileService = ({
8057
7993
  urlInfo.type = null;
8058
7994
  urlInfo.subtype = null;
8059
7995
  urlInfo.timing = {};
8060
- urlInfo.responseHeaders = {};
8061
7996
  }
8062
7997
 
8063
7998
  const {
@@ -8073,10 +8008,7 @@ const createFileService = ({
8073
8008
  outDirectoryUrl: scenario === "dev" ? `${rootDirectoryUrl}.jsenv/${runtimeName}@${runtimeVersion}/` : `${rootDirectoryUrl}.jsenv/${scenario}/${runtimeName}@${runtimeVersion}/`
8074
8009
  });
8075
8010
  let {
8076
- response,
8077
- contentType,
8078
- content,
8079
- contentEtag
8011
+ response
8080
8012
  } = urlInfo;
8081
8013
 
8082
8014
  if (response) {
@@ -8087,13 +8019,13 @@ const createFileService = ({
8087
8019
  url: reference.url,
8088
8020
  status: 200,
8089
8021
  headers: {
8090
- "content-type": contentType,
8091
- "content-length": Buffer.byteLength(content),
8022
+ "content-length": Buffer.byteLength(urlInfo.content),
8092
8023
  "cache-control": `private,max-age=0,must-revalidate`,
8093
- "eTag": contentEtag,
8094
- ...urlInfo.responseHeaders
8024
+ "eTag": urlInfo.contentEtag,
8025
+ ...urlInfo.headers,
8026
+ "content-type": urlInfo.contentType
8095
8027
  },
8096
- body: content,
8028
+ body: urlInfo.content,
8097
8029
  timing: urlInfo.timing
8098
8030
  };
8099
8031
  kitchen.pluginController.callHooks("augmentResponse", {
@@ -8396,11 +8328,10 @@ const startDevServer = async ({
8396
8328
  // (because node cluster won't work)
8397
8329
  devServerAutoreload = typeof process.send !== "function" && !parentPort && !process.env.VSCODE_INSPECTOR_OPTIONS,
8398
8330
  clientFiles = {
8399
- "./**": true,
8400
- "./**/.*/": false,
8331
+ "./src/": true,
8332
+ "./src/**/.*/": false,
8401
8333
  // any folder starting with a dot is ignored (includes .git,.jsenv for instance)
8402
- "./**/dist/": false,
8403
- "./**/node_modules/": false
8334
+ "./src/**/node_modules/": false
8404
8335
  },
8405
8336
  cooldownBetweenFileEvents,
8406
8337
  clientAutoreload = true,
@@ -8417,8 +8348,7 @@ const startDevServer = async ({
8417
8348
  },
8418
8349
  plugins = [],
8419
8350
  urlAnalysis = {},
8420
- htmlSupervisor = true,
8421
- injectedGlobals,
8351
+ htmlSupervisor = false,
8422
8352
  nodeEsmResolution,
8423
8353
  fileSystemMagicResolution,
8424
8354
  transpilation,
@@ -8577,7 +8507,6 @@ const startDevServer = async ({
8577
8507
  runtimeCompat,
8578
8508
  urlAnalysis,
8579
8509
  htmlSupervisor,
8580
- injectedGlobals,
8581
8510
  nodeEsmResolution,
8582
8511
  fileSystemMagicResolution,
8583
8512
  transpilation,
@@ -9135,7 +9064,6 @@ const executePlan = async (plan, {
9135
9064
  scenario,
9136
9065
  sourcemaps,
9137
9066
  plugins,
9138
- injectedGlobals,
9139
9067
  nodeEsmResolution,
9140
9068
  fileSystemMagicResolution,
9141
9069
  transpilation,
@@ -9220,7 +9148,6 @@ const executePlan = async (plan, {
9220
9148
  htmlSupervisor: true,
9221
9149
  nodeEsmResolution,
9222
9150
  fileSystemMagicResolution,
9223
- injectedGlobals,
9224
9151
  transpilation: { ...transpilation,
9225
9152
  getCustomBabelPlugins: ({
9226
9153
  clientRuntimeCompat
@@ -9738,7 +9665,6 @@ const executeTestPlan = async ({
9738
9665
  coverageSkipFull = false,
9739
9666
  sourcemaps = "inline",
9740
9667
  plugins = [],
9741
- injectedGlobals,
9742
9668
  nodeEsmResolution,
9743
9669
  fileSystemMagicResolution,
9744
9670
  writeGeneratedFiles = false,
@@ -9819,7 +9745,6 @@ const executeTestPlan = async ({
9819
9745
  scenario: "test",
9820
9746
  sourcemaps,
9821
9747
  plugins,
9822
- injectedGlobals,
9823
9748
  nodeEsmResolution,
9824
9749
  fileSystemMagicResolution,
9825
9750
  writeGeneratedFiles,
@@ -11899,7 +11824,6 @@ const build = async ({
11899
11824
  nodeEsmResolution,
11900
11825
  fileSystemMagicResolution,
11901
11826
  directoryReferenceAllowed,
11902
- injectedGlobals,
11903
11827
  transpilation = {},
11904
11828
  bundling = true,
11905
11829
  minification = true,
@@ -11908,11 +11832,10 @@ const build = async ({
11908
11832
  // "filename", "search_param"
11909
11833
  lineBreakNormalization = process.platform === "win32",
11910
11834
  clientFiles = {
11911
- "./**": true,
11912
- "./**/.*/": false,
11835
+ "./src/": true,
11836
+ "./src/**/.*/": false,
11913
11837
  // any folder starting with a dot is ignored (includes .git,.jsenv for instance)
11914
- "./dist/": false,
11915
- "./**/node_modules/": false
11838
+ "./src/**/node_modules/": false
11916
11839
  },
11917
11840
  cooldownBetweenFileEvents,
11918
11841
  watch = false,
@@ -12012,7 +11935,6 @@ build ${entryPointKeys.length} entry points`);
12012
11935
  nodeEsmResolution,
12013
11936
  fileSystemMagicResolution,
12014
11937
  directoryReferenceAllowed,
12015
- injectedGlobals,
12016
11938
  transpilation: { ...transpilation,
12017
11939
  babelHelpersAsImport: !useExplicitJsClassicConversion,
12018
11940
  jsModuleAsJsClassic: false
@@ -12985,10 +12907,10 @@ const applyUrlVersioning = async ({
12985
12907
  const rawUrlInfo = rawGraph.getUrlInfo(rawUrls[versionedUrlInfo.url]);
12986
12908
  const finalUrlInfo = finalGraph.getUrlInfo(versionedUrlInfo.url);
12987
12909
  return {
12988
- originalContent: rawUrlInfo ? rawUrlInfo.originalContent : undefined,
12989
- sourcemap: finalUrlInfo ? finalUrlInfo.sourcemap : undefined,
12910
+ content: versionedUrlInfo.content,
12990
12911
  contentType: versionedUrlInfo.contentType,
12991
- content: versionedUrlInfo.content
12912
+ originalContent: rawUrlInfo ? rawUrlInfo.originalContent : undefined,
12913
+ sourcemap: finalUrlInfo ? finalUrlInfo.sourcemap : undefined
12992
12914
  };
12993
12915
  }
12994
12916
 
@@ -13307,7 +13229,6 @@ const execute = async ({
13307
13229
  plugins = [],
13308
13230
  nodeEsmResolution,
13309
13231
  fileSystemMagicResolution,
13310
- injectedGlobals,
13311
13232
  transpilation,
13312
13233
  htmlSupervisor = true,
13313
13234
  writeGeneratedFiles = false,
@@ -13361,7 +13282,6 @@ const execute = async ({
13361
13282
  scenario,
13362
13283
  runtimeCompat,
13363
13284
  htmlSupervisor,
13364
- injectedGlobals,
13365
13285
  nodeEsmResolution,
13366
13286
  fileSystemMagicResolution,
13367
13287
  transpilation
@@ -13436,4 +13356,81 @@ const execute = async ({
13436
13356
  }
13437
13357
  };
13438
13358
 
13439
- export { build, chromium, chromiumIsolatedTab, defaultCoverageConfig, execute, executeTestPlan, firefox, firefoxIsolatedTab, injectGlobals, nodeProcess, startBuildServer, startDevServer, webkit, webkitIsolatedTab };
13359
+ const injectGlobals = (urlInfo, globals) => {
13360
+ if (urlInfo.type === "html") {
13361
+ return globalInjectorOnHtml(urlInfo, globals);
13362
+ }
13363
+
13364
+ if (urlInfo.type === "js_classic" || urlInfo.type === "js_module") {
13365
+ return globalsInjectorOnJs(urlInfo, globals);
13366
+ }
13367
+
13368
+ throw new Error(`cannot inject globals into "${urlInfo.type}"`);
13369
+ };
13370
+
13371
+ const globalInjectorOnHtml = async (urlInfo, globals) => {
13372
+ // ideally we would inject an importmap but browser support is too low
13373
+ // (even worse for worker/service worker)
13374
+ // so for now we inject code into entry points
13375
+ const htmlAst = parseHtmlString(urlInfo.content, {
13376
+ storeOriginalPositions: false
13377
+ });
13378
+ const clientCode = generateClientCodeForGlobals({
13379
+ globals,
13380
+ isWebWorker: false
13381
+ });
13382
+ injectScriptAsEarlyAsPossible(htmlAst, createHtmlNode({
13383
+ "tagName": "script",
13384
+ "textContent": clientCode,
13385
+ "injected-by": "jsenv:inject_globals"
13386
+ }));
13387
+ return stringifyHtmlAst(htmlAst);
13388
+ };
13389
+
13390
+ const globalsInjectorOnJs = async (urlInfo, globals) => {
13391
+ const clientCode = generateClientCodeForGlobals({
13392
+ globals,
13393
+ isWebWorker: urlInfo.subtype === "worker" || urlInfo.subtype === "service_worker" || urlInfo.subtype === "shared_worker"
13394
+ });
13395
+ const magicSource = createMagicSource(urlInfo.content);
13396
+ magicSource.prepend(clientCode);
13397
+ return magicSource.toContentAndSourcemap();
13398
+ };
13399
+
13400
+ const generateClientCodeForGlobals = ({
13401
+ isWebWorker = false,
13402
+ globals
13403
+ }) => {
13404
+ const globalName = isWebWorker ? "self" : "window";
13405
+ return `Object.assign(${globalName}, ${JSON.stringify(globals, null, " ")});`;
13406
+ };
13407
+
13408
+ const jsenvPluginInjectGlobals = urlAssociations => {
13409
+ return {
13410
+ name: "jsenv:inject_globals",
13411
+ appliesDuring: "*",
13412
+ transformUrlContent: async urlInfo => {
13413
+ const url = Object.keys(urlAssociations).find(url => {
13414
+ return url === urlInfo.url;
13415
+ });
13416
+
13417
+ if (!url) {
13418
+ return null;
13419
+ }
13420
+
13421
+ let globals = urlAssociations[url];
13422
+
13423
+ if (typeof globals === "function") {
13424
+ globals = await globals();
13425
+ }
13426
+
13427
+ if (Object.keys(globals).length === 0) {
13428
+ return null;
13429
+ }
13430
+
13431
+ return injectGlobals(urlInfo, globals);
13432
+ }
13433
+ };
13434
+ };
13435
+
13436
+ export { build, chromium, chromiumIsolatedTab, defaultCoverageConfig, execute, executeTestPlan, firefox, firefoxIsolatedTab, jsenvPluginInjectGlobals, nodeProcess, startBuildServer, startDevServer, webkit, webkitIsolatedTab };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/core",
3
- "version": "27.0.0-alpha.74",
3
+ "version": "27.0.0-alpha.77",
4
4
  "description": "Tool to develop, test and build js projects",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -68,17 +68,16 @@
68
68
  "@financial-times/polyfill-useragent-normaliser": "2.0.1",
69
69
  "@jsenv/abort": "4.1.2",
70
70
  "@jsenv/babel-plugins": "1.0.3",
71
- "@jsenv/filesystem": "4.0.4",
71
+ "@jsenv/filesystem": "4.0.7",
72
72
  "@jsenv/importmap": "1.2.0",
73
73
  "@jsenv/integrity": "0.0.1",
74
- "@jsenv/log": "1.6.3",
75
- "@jsenv/logger": "4.1.1",
74
+ "@jsenv/log": "2.0.0",
76
75
  "@jsenv/node-esm-resolution": "0.0.10",
77
76
  "@jsenv/server": "12.6.3",
78
77
  "@jsenv/uneval": "1.6.0",
79
- "@jsenv/utils": "1.8.7",
78
+ "@jsenv/utils": "1.8.10",
80
79
  "@jsenv/url-meta": "7.0.0",
81
- "@jsenv/urls": "1.2.1",
80
+ "@jsenv/urls": "1.2.4",
82
81
  "construct-style-sheets-polyfill": "3.1.0",
83
82
  "cssnano": "5.1.7",
84
83
  "cssnano-preset-default": "5.2.7",
@@ -25,9 +25,7 @@ import {
25
25
  registerDirectoryLifecycle,
26
26
  } from "@jsenv/filesystem"
27
27
  import { Abort, raceProcessTeardownEvents } from "@jsenv/abort"
28
- import { createLogger, loggerToLevels } from "@jsenv/logger"
29
-
30
- import { createTaskLog } from "@jsenv/log"
28
+ import { createLogger, loggerToLevels, createTaskLog } from "@jsenv/log"
31
29
  import { createVersionGenerator } from "@jsenv/utils/versioning/version_generator.js"
32
30
  import { generateSourcemapUrl } from "@jsenv/utils/sourcemap/sourcemap_utils.js"
33
31
  import {
@@ -109,7 +107,6 @@ export const build = async ({
109
107
  nodeEsmResolution,
110
108
  fileSystemMagicResolution,
111
109
  directoryReferenceAllowed,
112
- injectedGlobals,
113
110
  transpilation = {},
114
111
  bundling = true,
115
112
  minification = true,
@@ -118,10 +115,9 @@ export const build = async ({
118
115
  lineBreakNormalization = process.platform === "win32",
119
116
 
120
117
  clientFiles = {
121
- "./**": true,
122
- "./**/.*/": false, // any folder starting with a dot is ignored (includes .git,.jsenv for instance)
123
- "./dist/": false,
124
- "./**/node_modules/": false,
118
+ "./src/": true,
119
+ "./src/**/.*/": false, // any folder starting with a dot is ignored (includes .git,.jsenv for instance)
120
+ "./src/**/node_modules/": false,
125
121
  },
126
122
  cooldownBetweenFileEvents,
127
123
  watch = false,
@@ -224,7 +220,6 @@ build ${entryPointKeys.length} entry points`)
224
220
  nodeEsmResolution,
225
221
  fileSystemMagicResolution,
226
222
  directoryReferenceAllowed,
227
- injectedGlobals,
228
223
  transpilation: {
229
224
  ...transpilation,
230
225
  babelHelpersAsImport: !useExplicitJsClassicConversion,
@@ -1187,12 +1182,12 @@ const applyUrlVersioning = async ({
1187
1182
  )
1188
1183
  const finalUrlInfo = finalGraph.getUrlInfo(versionedUrlInfo.url)
1189
1184
  return {
1185
+ content: versionedUrlInfo.content,
1186
+ contentType: versionedUrlInfo.contentType,
1190
1187
  originalContent: rawUrlInfo
1191
1188
  ? rawUrlInfo.originalContent
1192
1189
  : undefined,
1193
1190
  sourcemap: finalUrlInfo ? finalUrlInfo.sourcemap : undefined,
1194
- contentType: versionedUrlInfo.contentType,
1195
- content: versionedUrlInfo.content,
1196
1191
  }
1197
1192
  }
1198
1193
  return versionedUrlInfo