@jsenv/core 34.2.1 → 34.3.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 (36) hide show
  1. package/dist/html/explorer.html +5 -4
  2. package/dist/importmap_node_loader.mjs +49 -0
  3. package/dist/js/resolveImport.js +504 -0
  4. package/dist/jsenv.js +392 -670
  5. package/dist/no_experimental_warnings.cjs +8 -0
  6. package/package.json +3 -2
  7. package/src/build/build.js +32 -14
  8. package/src/build/version_mappings_injection.js +20 -27
  9. package/src/dev/file_service.js +1 -1
  10. package/src/execute/execute.js +2 -0
  11. package/src/execute/runtimes/node/exec_options.js +15 -2
  12. package/src/execute/runtimes/node/importmap_node_loader.mjs +51 -0
  13. package/src/execute/runtimes/node/importmap_node_loader_file_url.js +4 -0
  14. package/src/execute/runtimes/node/no_experimental_warnings.cjs +12 -0
  15. package/src/execute/runtimes/node/no_experimental_warnings_file_url.js +4 -0
  16. package/src/execute/runtimes/node/node_child_process.js +15 -0
  17. package/src/execute/runtimes/node/node_worker_thread.js +13 -0
  18. package/src/kitchen/kitchen.js +5 -3
  19. package/src/plugins/autoreload/jsenv_plugin_autoreload_client.js +2 -2
  20. package/src/plugins/importmap/jsenv_plugin_importmap.js +6 -2
  21. package/src/plugins/{inline/jsenv_plugin_html_inline_content.js → inline_content_analysis/jsenv_plugin_html_inline_content_analysis.js} +12 -6
  22. package/src/plugins/{inline/jsenv_plugin_inline.js → inline_content_analysis/jsenv_plugin_inline_content_analysis.js} +8 -10
  23. package/src/plugins/{inline/jsenv_plugin_js_inline_content.js → inline_content_analysis/jsenv_plugin_js_inline_content_analysis.js} +4 -2
  24. package/src/plugins/inlining/jsenv_plugin_inlining.js +22 -0
  25. package/src/plugins/{inline/jsenv_plugin_inline_query_param.js → inlining/jsenv_plugin_inlining_as_data_url.js} +16 -9
  26. package/src/plugins/inlining/jsenv_plugin_inlining_into_html.js +149 -0
  27. package/src/plugins/plugins.js +5 -2
  28. package/src/plugins/ribbon/jsenv_plugin_ribbon.js +11 -10
  29. package/src/plugins/server_events/jsenv_plugin_server_events_client_injection.js +2 -2
  30. package/src/plugins/supervisor/html_supervisor_injection.js +23 -25
  31. package/src/plugins/transpilation/import_assertions/jsenv_plugin_import_assertions.js +20 -5
  32. package/src/plugins/transpilation/js_module_fallback/jsenv_plugin_js_module_fallback_inside_html.js +2 -2
  33. package/src/plugins/transpilation/js_module_fallback/jsenv_plugin_js_module_fallback_on_workers.js +3 -3
  34. package/src/plugins/url_analysis/html/html_urls.js +1 -1
  35. /package/src/plugins/{inline → inline_content_analysis}/client/inline_content.js +0 -0
  36. /package/src/plugins/{inline → inline_content_analysis}/jsenv_plugin_data_urls.js +0 -0
@@ -0,0 +1,8 @@
1
+ // see https://github.com/nodejs/node/issues/47478
2
+ const originalEmit = process.emit;
3
+ process.emit = (event, error) => {
4
+ if (event === "warning" && error.name === "ExperimentalWarning" && error.message.includes("--experimental-loader")) {
5
+ return false;
6
+ }
7
+ return originalEmit.call(process, event, error);
8
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/core",
3
- "version": "34.2.1",
3
+ "version": "34.3.0",
4
4
  "description": "Tool to develop, test and build js projects",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -43,6 +43,7 @@
43
43
  "eslint": "npx eslint . --ext=.js,.mjs,.cjs,.html",
44
44
  "dev": "node --conditions=development ./scripts/dev/dev.mjs",
45
45
  "test": "node --conditions=development ./scripts/test/test.mjs",
46
+ "test:no_snapshot_assertion": "npm run test -- --no-snapshot-assertion",
46
47
  "test:dev_errors_snapshots": "node --conditions=development ./tests/dev_server/errors/generate_snapshot_files.mjs",
47
48
  "test:workspace": "npm run test --workspaces --if-present -- --workspace",
48
49
  "build": "node --conditions=development ./scripts/build/build.mjs",
@@ -65,7 +66,7 @@
65
66
  "@c88/v8-coverage": "0.1.1",
66
67
  "@financial-times/polyfill-useragent-normaliser": "1.10.2",
67
68
  "@jsenv/abort": "4.2.4",
68
- "@jsenv/ast": "3.0.5",
69
+ "@jsenv/ast": "3.0.6",
69
70
  "@jsenv/babel-plugins": "1.1.5",
70
71
  "@jsenv/filesystem": "4.2.3",
71
72
  "@jsenv/importmap": "1.2.1",
@@ -65,7 +65,8 @@ import {
65
65
  isWebWorkerUrlInfo,
66
66
  } from "../kitchen/web_workers.js"
67
67
  import { jsenvPluginUrlAnalysis } from "../plugins/url_analysis/jsenv_plugin_url_analysis.js"
68
- import { jsenvPluginInline } from "../plugins/inline/jsenv_plugin_inline.js"
68
+ import { jsenvPluginInlining } from "../plugins/inlining/jsenv_plugin_inlining.js"
69
+ import { jsenvPluginInlineContentAnalysis } from "../plugins/inline_content_analysis/jsenv_plugin_inline_content_analysis.js"
69
70
  import { jsenvPluginJsModuleFallback } from "../plugins/transpilation/js_module_fallback/jsenv_plugin_js_module_fallback.js"
70
71
  import { getCorePlugins } from "../plugins/plugins.js"
71
72
  import { jsenvPluginLineBreakNormalization } from "./jsenv_plugin_line_break_normalization.js"
@@ -112,7 +113,7 @@ export const defaultRuntimeCompat = {
112
113
  * Controls if url in build file contents are versioned
113
114
  * @param {('search_param'|'filename')} [buildParameters.versioningMethod="search_param"]
114
115
  * Controls how url are versioned
115
- * @param {boolean|string} [buildParameters.sourcemaps=false]
116
+ * @param {('none'|'inline'|'file'|'programmatic'} [buildParameters.sourcemaps="none"]
116
117
  * Generate sourcemaps in the build directory
117
118
  * @return {Object} buildReturnValue
118
119
  * @return {Object} buildReturnValue.buildFileContents
@@ -134,7 +135,7 @@ export const build = async ({
134
135
  runtimeCompat = defaultRuntimeCompat,
135
136
  base = runtimeCompat.node ? "./" : "/",
136
137
  plugins = [],
137
- sourcemaps = false,
138
+ sourcemaps = "none",
138
139
  sourcemapsSourcesContent,
139
140
  urlAnalysis = {},
140
141
  urlResolution,
@@ -347,6 +348,7 @@ build ${entryPointKeys.length} entry points`)
347
348
  babelHelpersAsImport: !explicitJsModuleFallback,
348
349
  jsModuleFallbackOnJsClassic: false,
349
350
  },
351
+ inlining: false,
350
352
  scenarioPlaceholders,
351
353
  }),
352
354
  ],
@@ -396,9 +398,10 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
396
398
  jsenvPluginJsModuleFallback({
397
399
  systemJsInjection: true,
398
400
  }),
399
- jsenvPluginInline({
401
+ jsenvPluginInlineContentAnalysis({
400
402
  fetchInlineUrls: false,
401
403
  }),
404
+ jsenvPluginInlining(),
402
405
  {
403
406
  name: "jsenv:build",
404
407
  appliesDuring: "build",
@@ -442,16 +445,28 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
442
445
  return reference.url
443
446
  }
444
447
  if (reference.isInline) {
448
+ const parentUrlInfo = finalGraph.getUrlInfo(reference.parentUrl)
449
+ const parentRawUrl = parentUrlInfo.originalUrl
445
450
  const rawUrlInfo = GRAPH.find(rawGraph, (rawUrlInfo) => {
446
- if (!rawUrlInfo.isInline) {
447
- return false
451
+ const { inlineUrlSite } = rawUrlInfo
452
+ // not inline
453
+ if (!inlineUrlSite) return false
454
+ if (
455
+ inlineUrlSite.url === parentRawUrl &&
456
+ inlineUrlSite.line === reference.specifierLine &&
457
+ inlineUrlSite.column === reference.specifierColumn
458
+ ) {
459
+ return true
448
460
  }
449
461
  if (rawUrlInfo.content === reference.content) {
450
462
  return true
451
463
  }
452
- return rawUrlInfo.originalContent === reference.content
464
+ if (rawUrlInfo.originalContent === reference.content) {
465
+ return true
466
+ }
467
+ return false
453
468
  })
454
- const parentUrlInfo = finalGraph.getUrlInfo(reference.parentUrl)
469
+
455
470
  if (!rawUrlInfo) {
456
471
  // generated during final graph
457
472
  // (happens for JSON.parse injected for import assertions for instance)
@@ -640,6 +655,13 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
640
655
  return rawUrlInfo
641
656
  }
642
657
  if (reference.isInline) {
658
+ if (reference.prev && !reference.prev.isInline) {
659
+ const urlBeforeRedirect = findKey(
660
+ finalRedirections,
661
+ reference.prev.url,
662
+ )
663
+ return fromBundleOrRawGraph(urlBeforeRedirect)
664
+ }
643
665
  return fromBundleOrRawGraph(reference.url)
644
666
  }
645
667
  // reference updated during "postbuild":
@@ -1162,7 +1184,7 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
1162
1184
  ...contextSharedDuringBuild,
1163
1185
  plugins: [
1164
1186
  urlAnalysisPlugin,
1165
- jsenvPluginInline({
1187
+ jsenvPluginInlineContentAnalysis({
1166
1188
  fetchInlineUrls: false,
1167
1189
  analyzeConvertedScripts: true, // to be able to version their urls
1168
1190
  allowEscapeForVersioning: true,
@@ -1485,11 +1507,7 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
1485
1507
  type: getHtmlNodeAttribute(hintNode, "type"),
1486
1508
  crossorigin: getHtmlNodeAttribute(hintNode, "crossorigin"),
1487
1509
  })
1488
- insertHtmlNodeAfter(
1489
- nodeToInsert,
1490
- hintNode.parentNode,
1491
- hintNode,
1492
- )
1510
+ insertHtmlNodeAfter(nodeToInsert, hintNode)
1493
1511
  })
1494
1512
  }
1495
1513
  })
@@ -3,7 +3,7 @@
3
3
  import { createMagicSource } from "@jsenv/sourcemap"
4
4
  import {
5
5
  parseHtmlString,
6
- injectScriptNodeAsEarlyAsPossible,
6
+ injectHtmlNodeAsEarlyAsPossible,
7
7
  createHtmlNode,
8
8
  stringifyHtmlAst,
9
9
  } from "@jsenv/ast"
@@ -32,7 +32,7 @@ const injectors = {
32
32
  const htmlAst = parseHtmlString(urlInfo.content, {
33
33
  storeOriginalPositions: false,
34
34
  })
35
- injectScriptNodeAsEarlyAsPossible(
35
+ injectHtmlNodeAsEarlyAsPossible(
36
36
  htmlAst,
37
37
  createHtmlNode({
38
38
  tagName: "script",
@@ -52,12 +52,11 @@ const injectors = {
52
52
  }
53
53
  const jsInjector = (urlInfo, { versionMappings, minification }) => {
54
54
  const magicSource = createMagicSource(urlInfo.content)
55
- magicSource.prepend(
56
- generateClientCodeForVersionMappings(versionMappings, {
57
- globalName: isWebWorkerUrlInfo(urlInfo) ? "self" : "window",
58
- minification,
59
- }),
60
- )
55
+ const code = generateClientCodeForVersionMappings(versionMappings, {
56
+ globalName: isWebWorkerUrlInfo(urlInfo) ? "self" : "window",
57
+ minification,
58
+ })
59
+ magicSource.prepend(`${code}\n\n`)
61
60
  return magicSource.toContentAndSourcemap()
62
61
  }
63
62
  const generateClientCodeForVersionMappings = (
@@ -69,14 +68,12 @@ const generateClientCodeForVersionMappings = (
69
68
  versionMappings,
70
69
  )}; ${globalName}.__v__ = function (s) { return m[s] || s }; })();`
71
70
  }
72
- return `
73
- ;(function() {
71
+ return `;(function() {
74
72
  var __versionMappings__ = ${JSON.stringify(versionMappings, null, " ")};
75
73
  ${globalName}.__v__ = function (specifier) {
76
74
  return __versionMappings__[specifier] || specifier
77
75
  };
78
- })();
79
- `
76
+ })();`
80
77
  }
81
78
 
82
79
  export const injectVersionMappingsAsImportmap = async ({
@@ -90,21 +87,17 @@ export const injectVersionMappingsAsImportmap = async ({
90
87
  // jsenv_plugin_importmap.js is removing importmap during build
91
88
  // it means at this point we know HTML has no importmap in it
92
89
  // we can safely inject one
93
- const importmapNode = createHtmlNode({
94
- tagName: "script",
95
- type: "importmap",
96
- textContent: kitchen.kitchenContext.minification
97
- ? JSON.stringify({ imports: versionMappings })
98
- : `
99
- {
100
- "imports": {${JSON.stringify(versionMappings, null, " ").slice(
101
- 1,
102
- -1,
103
- )} }
104
- }
105
- `,
106
- })
107
- injectScriptNodeAsEarlyAsPossible(htmlAst, importmapNode, "jsenv:versioning")
90
+ injectHtmlNodeAsEarlyAsPossible(
91
+ htmlAst,
92
+ createHtmlNode({
93
+ tagName: "script",
94
+ type: "importmap",
95
+ textContent: kitchen.kitchenContext.minification
96
+ ? JSON.stringify({ imports: versionMappings })
97
+ : JSON.stringify({ imports: versionMappings }, null, " "),
98
+ }),
99
+ "jsenv:versioning",
100
+ )
108
101
  kitchen.urlInfoTransformer.applyFinalTransformations(urlInfo, {
109
102
  content: stringifyHtmlAst(htmlAst),
110
103
  })
@@ -370,7 +370,7 @@ export const createFileService = ({
370
370
  if (code === "PARSE_ERROR") {
371
371
  // when possible let browser re-throw the syntax error
372
372
  // it's not possible to do that when url info content is not available
373
- // (happens for as_js_classic for instance)
373
+ // (happens for js_module_fallback for instance)
374
374
  if (urlInfo.content !== undefined) {
375
375
  return {
376
376
  url: reference.url,
@@ -23,6 +23,7 @@ export const execute = async ({
23
23
  logLevel,
24
24
  rootDirectoryUrl,
25
25
  webServer,
26
+ importMap,
26
27
 
27
28
  fileRelativeUrl,
28
29
  allocatedMs,
@@ -65,6 +66,7 @@ export const execute = async ({
65
66
  rootDirectoryUrl,
66
67
  webServer,
67
68
  fileRelativeUrl,
69
+ importMap,
68
70
  ...runtimeParams,
69
71
  }
70
72
 
@@ -5,7 +5,14 @@ export const ExecOptions = {
5
5
  while (i < execArgv.length) {
6
6
  const execArg = execArgv[i]
7
7
  const option = execOptionFromExecArg(execArg)
8
- execOptions[option.name] = option.value
8
+ const existing = execOptions[option.name]
9
+ if (existing) {
10
+ execOptions[option.name] = Array.isArray(existing)
11
+ ? [...existing, option.value]
12
+ : [existing, option.value]
13
+ } else {
14
+ execOptions[option.name] = option.value
15
+ }
9
16
  i++
10
17
  }
11
18
  return execOptions
@@ -21,7 +28,13 @@ export const ExecOptions = {
21
28
  execArgv.push(optionName)
22
29
  return
23
30
  }
24
- execArgv.push(`${optionName}=${optionValue}`)
31
+ if (Array.isArray(optionValue)) {
32
+ optionValue.forEach((subValue) => {
33
+ execArgv.push(`${optionName}=${subValue}`)
34
+ })
35
+ } else {
36
+ execArgv.push(`${optionName}=${optionValue}`)
37
+ }
25
38
  })
26
39
  return execArgv
27
40
  },
@@ -0,0 +1,51 @@
1
+ import { readFileSync } from "node:fs"
2
+ import { pathToFileURL } from "node:url"
3
+ import { normalizeImportMap, resolveImport } from "@jsenv/importmap"
4
+
5
+ let importMap
6
+
7
+ const cwdUrl = `${String(pathToFileURL(process.cwd()))}/`
8
+
9
+ if (process.env.IMPORT_MAP) {
10
+ importMap = JSON.parse(process.env.IMPORT_MAP)
11
+ } else if (process.env.IMPORT_MAP_PATH) {
12
+ const importmapFileUrl = pathToFileURL(process.env.IMPORT_MAP_PATH)
13
+ const importmapFileContentAsString = readFileSync(importmapFileUrl, "utf8")
14
+ importMap = JSON.parse(importmapFileContentAsString)
15
+ } else {
16
+ const importmapFileUrl = new URL("./import_map.json", cwdUrl)
17
+ const importmapFileContentAsString = readFileSync(importmapFileUrl, "utf8")
18
+ importMap = JSON.parse(importmapFileContentAsString)
19
+ }
20
+
21
+ const importMapBaseUrl = process.env.IMPORT_MAP_BASE_URL || cwdUrl
22
+ importMap = normalizeImportMap(importMap, importMapBaseUrl)
23
+
24
+ export const resolve = (specifier, context, nextResolve) => {
25
+ try {
26
+ let mapped
27
+ const importer = context.parentURL ? String(context.parentURL) : undefined
28
+ const resolved = resolveImport({
29
+ specifier,
30
+ importer,
31
+ importMap,
32
+ defaultExtension: ".js",
33
+ onImportMapping: () => {
34
+ mapped = true
35
+ },
36
+ })
37
+ if (mapped) {
38
+ return {
39
+ shortCircuit: true,
40
+ url: resolved,
41
+ }
42
+ }
43
+ } catch (e) {
44
+ if (e.message.includes("bare specifier")) {
45
+ return nextResolve(specifier, context)
46
+ }
47
+ console.error(e)
48
+ return nextResolve(specifier, context)
49
+ }
50
+ return nextResolve(specifier, context)
51
+ }
@@ -0,0 +1,4 @@
1
+ export const IMPORTMAP_NODE_LOADER_FILE_URL = new URL(
2
+ "./importmap_node_loader.mjs?entry_point",
3
+ import.meta.url,
4
+ ).href
@@ -0,0 +1,12 @@
1
+ // see https://github.com/nodejs/node/issues/47478
2
+ const originalEmit = process.emit
3
+ process.emit = (event, error) => {
4
+ if (
5
+ event === "warning" &&
6
+ error.name === "ExperimentalWarning" &&
7
+ error.message.includes("--experimental-loader")
8
+ ) {
9
+ return false
10
+ }
11
+ return originalEmit.call(process, event, error)
12
+ }
@@ -0,0 +1,4 @@
1
+ export const NO_EXPERIMENTAL_WARNING_FILE_URL = new URL(
2
+ "./no_experimental_warnings.cjs?entry_point",
3
+ import.meta.url,
4
+ ).href
@@ -12,6 +12,8 @@ import { createChildExecOptions } from "./child_exec_options.js"
12
12
  import { ExecOptions } from "./exec_options.js"
13
13
  import { killProcessTree } from "./kill_process_tree.js"
14
14
  import { EXIT_CODES } from "./exit_codes.js"
15
+ import { IMPORTMAP_NODE_LOADER_FILE_URL } from "./importmap_node_loader_file_url.js"
16
+ import { NO_EXPERIMENTAL_WARNING_FILE_URL } from "./no_experimental_warnings_file_url.js"
15
17
 
16
18
  const CONTROLLABLE_CHILD_PROCESS_URL = new URL(
17
19
  "./controllable_child_process.mjs?entry_point",
@@ -30,6 +32,7 @@ nodeChildProcess.run = async ({
30
32
  logProcessCommand = false,
31
33
  rootDirectoryUrl,
32
34
  fileRelativeUrl,
35
+ importMap,
33
36
 
34
37
  keepRunning,
35
38
  gracefulStopAllocatedMs = 4000,
@@ -67,6 +70,17 @@ nodeChildProcess.run = async ({
67
70
  ...commandLineOptions,
68
71
  ]
69
72
 
73
+ if (importMap) {
74
+ env.IMPORT_MAP = JSON.stringify(importMap)
75
+ env.IMPORT_MAP_BASE_URL = rootDirectoryUrl
76
+ commandLineOptions.push(
77
+ `--experimental-loader=${fileURLToPath(IMPORTMAP_NODE_LOADER_FILE_URL)}`,
78
+ )
79
+ commandLineOptions.push(
80
+ `--require=${fileURLToPath(NO_EXPERIMENTAL_WARNING_FILE_URL)}`,
81
+ )
82
+ }
83
+
70
84
  const cleanupCallbackList = createCallbackListNotifiedOnce()
71
85
  const cleanup = async (reason) => {
72
86
  await cleanupCallbackList.notify({ reason })
@@ -96,6 +110,7 @@ nodeChildProcess.run = async ({
96
110
  // silent: true
97
111
  stdio: ["pipe", "pipe", "pipe", "ipc"],
98
112
  env: envForChildProcess,
113
+ cwd: new URL(rootDirectoryUrl),
99
114
  })
100
115
  logger.debug(
101
116
  createDetailedMessage(`child process forked (pid ${childProcess.pid})`, {
@@ -13,6 +13,8 @@ import { memoize } from "@jsenv/utils/src/memoize/memoize.js"
13
13
  import { createChildExecOptions } from "./child_exec_options.js"
14
14
  import { ExecOptions } from "./exec_options.js"
15
15
  import { EXIT_CODES } from "./exit_codes.js"
16
+ import { IMPORTMAP_NODE_LOADER_FILE_URL } from "./importmap_node_loader_file_url.js"
17
+ import { NO_EXPERIMENTAL_WARNING_FILE_URL } from "./no_experimental_warnings_file_url.js"
16
18
 
17
19
  const CONTROLLABLE_WORKER_THREAD_URL = new URL(
18
20
  "./controllable_worker_thread.mjs?entry_point",
@@ -30,6 +32,7 @@ nodeWorkerThread.run = async ({
30
32
  // logger,
31
33
  rootDirectoryUrl,
32
34
  fileRelativeUrl,
35
+ importMap,
33
36
 
34
37
  keepRunning,
35
38
  stopSignal,
@@ -59,6 +62,16 @@ nodeWorkerThread.run = async ({
59
62
  if (coverageMethodForNodeJs !== "NODE_V8_COVERAGE") {
60
63
  env.NODE_V8_COVERAGE = ""
61
64
  }
65
+ if (importMap) {
66
+ env.IMPORT_MAP = JSON.stringify(importMap)
67
+ env.IMPORT_MAP_BASE_URL = rootDirectoryUrl
68
+ commandLineOptions.push(
69
+ `--experimental-loader=${fileURLToPath(IMPORTMAP_NODE_LOADER_FILE_URL)}`,
70
+ )
71
+ commandLineOptions.push(
72
+ `--require=${fileURLToPath(NO_EXPERIMENTAL_WARNING_FILE_URL)}`,
73
+ )
74
+ }
62
75
 
63
76
  const workerThreadExecOptions = await createChildExecOptions({
64
77
  signal,
@@ -720,6 +720,7 @@ ${ANSI.color(normalizedReturnValue, ANSI.YELLOW)}
720
720
 
721
721
  const getWithoutSearchParam = ({
722
722
  urlInfo,
723
+ reference,
723
724
  context,
724
725
  searchParam,
725
726
  expectedType,
@@ -730,17 +731,18 @@ ${ANSI.color(normalizedReturnValue, ANSI.YELLOW)}
730
731
  return [null, null]
731
732
  }
732
733
  searchParams.delete(searchParam)
733
- const originalRef = context.reference.original || context.reference
734
+ const originalRef =
735
+ reference || context.reference.original || context.reference
734
736
  const referenceWithoutSearchParam = {
735
737
  ...originalRef,
736
738
  original: originalRef,
737
739
  searchParams,
738
740
  data: { ...originalRef.data },
739
741
  expectedType,
740
- specifier: context.reference.specifier
742
+ specifier: originalRef.specifier
741
743
  .replace(`?${searchParam}`, "")
742
744
  .replace(`&${searchParam}`, ""),
743
- url: urlObject.href,
745
+ url: normalizeUrl(urlObject.href),
744
746
  generatedSpecifier: null,
745
747
  generatedUrl: null,
746
748
  filename: null,
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  parseHtmlString,
3
3
  stringifyHtmlAst,
4
- injectScriptNodeAsEarlyAsPossible,
4
+ injectHtmlNodeAsEarlyAsPossible,
5
5
  createHtmlNode,
6
6
  } from "@jsenv/ast"
7
7
 
@@ -23,7 +23,7 @@ export const jsenvPluginAutoreloadClient = () => {
23
23
  expectedType: "js_module",
24
24
  specifier: autoreloadClientFileUrl,
25
25
  })
26
- injectScriptNodeAsEarlyAsPossible(
26
+ injectHtmlNodeAsEarlyAsPossible(
27
27
  htmlAst,
28
28
  createHtmlNode({
29
29
  tagName: "script",
@@ -132,7 +132,9 @@ export const jsenvPluginImportmap = () => {
132
132
  await context.cook(inlineImportmapUrlInfo, {
133
133
  reference: inlineImportmapReference,
134
134
  })
135
- setHtmlNodeText(importmap, inlineImportmapUrlInfo.content)
135
+ setHtmlNodeText(importmap, inlineImportmapUrlInfo.content, {
136
+ indentation: "auto",
137
+ })
136
138
  setHtmlNodeAttributes(importmap, {
137
139
  "jsenv-cooked-by": "jsenv:importmap",
138
140
  })
@@ -160,7 +162,9 @@ export const jsenvPluginImportmap = () => {
160
162
  JSON.parse(importmapUrlInfo.content),
161
163
  htmlUrlInfo.url,
162
164
  )
163
- setHtmlNodeText(importmap, importmapUrlInfo.content)
165
+ setHtmlNodeText(importmap, importmapUrlInfo.content, {
166
+ indentation: "auto",
167
+ })
164
168
  setHtmlNodeAttributes(importmap, {
165
169
  "src": undefined,
166
170
  "jsenv-inlined-by": "jsenv:importmap",
@@ -19,7 +19,9 @@ import {
19
19
  } from "@jsenv/ast"
20
20
  import { CONTENT_TYPE } from "@jsenv/utils/src/content_type/content_type.js"
21
21
 
22
- export const jsenvPluginHtmlInlineContent = ({ analyzeConvertedScripts }) => {
22
+ export const jsenvPluginHtmlInlineContentAnalysis = ({
23
+ analyzeConvertedScripts,
24
+ }) => {
23
25
  const cookInlineContent = async ({
24
26
  context,
25
27
  inlineContentUrlInfo,
@@ -48,7 +50,7 @@ ${e.traceMessage}`)
48
50
  }
49
51
 
50
52
  return {
51
- name: "jsenv:html_inline_content",
53
+ name: "jsenv:html_inline_content_analysis",
52
54
  appliesDuring: "*",
53
55
  transformUrlContent: {
54
56
  html: async (urlInfo, context) => {
@@ -99,9 +101,11 @@ ${e.traceMessage}`)
99
101
  })
100
102
  })
101
103
  mutations.push(() => {
102
- setHtmlNodeText(styleNode, inlineStyleUrlInfo.content)
104
+ setHtmlNodeText(styleNode, inlineStyleUrlInfo.content, {
105
+ indentation: false, // indentation would decrease strack trace precision
106
+ })
103
107
  setHtmlNodeAttributes(styleNode, {
104
- "jsenv-cooked-by": "jsenv:html_inline_content",
108
+ "jsenv-cooked-by": "jsenv:html_inline_content_analysis",
105
109
  })
106
110
  })
107
111
  },
@@ -163,7 +167,7 @@ ${e.traceMessage}`)
163
167
  })
164
168
  mutations.push(() => {
165
169
  const attributes = {
166
- "jsenv-cooked-by": "jsenv:html_inline_content",
170
+ "jsenv-cooked-by": "jsenv:html_inline_content_analysis",
167
171
  // 1. <script type="jsx"> becomes <script>
168
172
  // 2. <script type="module/jsx"> becomes <script type="module">
169
173
  ...(extension
@@ -176,7 +180,9 @@ ${e.traceMessage}`)
176
180
  ...attributes,
177
181
  })
178
182
  } else {
179
- setHtmlNodeText(scriptNode, inlineScriptUrlInfo.content)
183
+ setHtmlNodeText(scriptNode, inlineScriptUrlInfo.content, {
184
+ indentation: false, // indentation would decrease stack trace precision
185
+ })
180
186
  setHtmlNodeAttributes(scriptNode, {
181
187
  ...attributes,
182
188
  })
@@ -1,25 +1,23 @@
1
- import { jsenvPluginHtmlInlineContent } from "./jsenv_plugin_html_inline_content.js"
2
- import { jsenvPluginJsInlineContent } from "./jsenv_plugin_js_inline_content.js"
1
+ import { jsenvPluginHtmlInlineContentAnalysis } from "./jsenv_plugin_html_inline_content_analysis.js"
2
+ import { jsenvPluginJsInlineContentAnalysis } from "./jsenv_plugin_js_inline_content_analysis.js"
3
3
  import { jsenvPluginDataUrls } from "./jsenv_plugin_data_urls.js"
4
- import { jsenvPluginInlineQueryParam } from "./jsenv_plugin_inline_query_param.js"
5
4
 
6
- export const jsenvPluginInline = ({
5
+ export const jsenvPluginInlineContentAnalysis = ({
7
6
  fetchInlineUrls = true,
8
7
  analyzeConvertedScripts = false,
9
8
  allowEscapeForVersioning = false,
10
9
  } = {}) => {
11
10
  return [
12
- ...(fetchInlineUrls ? [jsenvPluginInlineUrls()] : []),
13
- jsenvPluginHtmlInlineContent({ analyzeConvertedScripts }),
14
- jsenvPluginJsInlineContent({ allowEscapeForVersioning }),
11
+ ...(fetchInlineUrls ? [jsenvPluginInlineContentFetcher()] : []),
12
+ jsenvPluginHtmlInlineContentAnalysis({ analyzeConvertedScripts }),
13
+ jsenvPluginJsInlineContentAnalysis({ allowEscapeForVersioning }),
15
14
  jsenvPluginDataUrls(),
16
- jsenvPluginInlineQueryParam(),
17
15
  ]
18
16
  }
19
17
 
20
- const jsenvPluginInlineUrls = () => {
18
+ const jsenvPluginInlineContentFetcher = () => {
21
19
  return {
22
- name: "jsenv:inline_urls",
20
+ name: "jsenv:inline_content_fetcher",
23
21
  appliesDuring: "*",
24
22
  fetchUrlContent: (urlInfo) => {
25
23
  if (!urlInfo.isInline) {
@@ -4,7 +4,9 @@ import { applyBabelPlugins } from "@jsenv/ast"
4
4
  import { CONTENT_TYPE } from "@jsenv/utils/src/content_type/content_type.js"
5
5
  import { JS_QUOTES } from "@jsenv/utils/src/string/js_quotes.js"
6
6
 
7
- export const jsenvPluginJsInlineContent = ({ allowEscapeForVersioning }) => {
7
+ export const jsenvPluginJsInlineContentAnalysis = ({
8
+ allowEscapeForVersioning,
9
+ }) => {
8
10
  const parseAndTransformInlineContentCalls = async (urlInfo, context) => {
9
11
  const inlineContentInfos = await parseJsInlineContentInfos({
10
12
  js: urlInfo.content,
@@ -63,7 +65,7 @@ export const jsenvPluginJsInlineContent = ({ allowEscapeForVersioning }) => {
63
65
  }
64
66
 
65
67
  return {
66
- name: "jsenv:js_inline_content",
68
+ name: "jsenv:js_inline_content_analysis",
67
69
  appliesDuring: "*",
68
70
  transformUrlContent: {
69
71
  js_classic: parseAndTransformInlineContentCalls,
@@ -0,0 +1,22 @@
1
+ import { jsenvPluginInliningAsDataUrl } from "./jsenv_plugin_inlining_as_data_url.js"
2
+ import { jsenvPluginInliningIntoHtml } from "./jsenv_plugin_inlining_into_html.js"
3
+
4
+ export const jsenvPluginInlining = () => {
5
+ return [
6
+ {
7
+ name: "jsenv:inlining",
8
+ appliesDuring: "*",
9
+ redirectUrl: (reference) => {
10
+ const { searchParams } = reference
11
+ if (searchParams.has("inline")) {
12
+ const urlObject = new URL(reference.url)
13
+ urlObject.searchParams.delete("inline")
14
+ return urlObject.href
15
+ }
16
+ return null
17
+ },
18
+ },
19
+ jsenvPluginInliningAsDataUrl(),
20
+ jsenvPluginInliningIntoHtml(),
21
+ ]
22
+ }