@jsenv/core 27.0.0-alpha.83 → 27.0.0-alpha.86

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 (62) hide show
  1. package/dist/html/explorer.html +1 -1
  2. package/dist/js/event_source_client.js +3 -3
  3. package/dist/js/s.js +2 -2
  4. package/dist/main.js +503 -417
  5. package/dist/s.js +2 -2
  6. package/dist/s.js.map +2 -1
  7. package/package.json +7 -3
  8. package/src/build/build.js +5 -8
  9. package/src/build/build_urls_generator.js +1 -2
  10. package/src/build/inject_global_version_mappings.js +4 -4
  11. package/src/build/inject_service_worker_urls.js +2 -2
  12. package/src/build/resync_ressource_hints.js +17 -18
  13. package/src/build/start_build_server.js +5 -1
  14. package/src/build/version_generator.js +60 -0
  15. package/src/dev/plugins/explorer/client/explorer.html +1 -1
  16. package/src/dev/plugins/explorer/jsenv_plugin_explorer.js +2 -3
  17. package/src/dev/plugins/toolbar/client/util/fetching.js +1 -1
  18. package/src/dev/plugins/toolbar/jsenv_plugin_toolbar.js +3 -3
  19. package/src/dev/start_dev_server.js +5 -1
  20. package/src/execute/runtimes/browsers/from_playwright.js +2 -2
  21. package/src/execute/runtimes/node/node_process.js +2 -2
  22. package/src/helpers/command/command.js +73 -0
  23. package/src/helpers/worker_reload.js +4 -3
  24. package/src/omega/compat/runtime_compat.js +2 -1
  25. package/src/omega/kitchen.js +4 -1
  26. package/src/omega/server/user_agent.js +2 -1
  27. package/src/omega/url_graph/sort_by_dependencies.js +27 -0
  28. package/src/omega/url_graph/url_info_transformations.js +24 -14
  29. package/src/plugins/autoreload/dev_sse/client/reload.js +6 -3
  30. package/src/plugins/autoreload/dev_sse/jsenv_plugin_dev_sse_client.js +3 -3
  31. package/src/plugins/bundling/css/bundle_css.js +4 -4
  32. package/src/plugins/bundling/js_module/bundle_js_module.js +86 -67
  33. package/src/plugins/commonjs_globals/jsenv_plugin_commonjs_globals.js +2 -2
  34. package/src/plugins/file_urls/jsenv_plugin_file_urls.js +4 -5
  35. package/src/plugins/html_supervisor/jsenv_plugin_html_supervisor.js +62 -74
  36. package/src/plugins/http_urls/jsenv_plugin_http_urls.js +10 -6
  37. package/src/plugins/import_meta_hot/html_hot_dependencies.js +9 -15
  38. package/src/plugins/import_meta_hot/jsenv_plugin_import_meta_hot.js +3 -3
  39. package/src/plugins/import_meta_scenarios/jsenv_plugin_import_meta_scenarios.js +2 -2
  40. package/src/plugins/importmap/jsenv_plugin_importmap.js +25 -27
  41. package/src/plugins/inject_globals/inject_globals.js +4 -4
  42. package/src/plugins/inline/jsenv_plugin_data_urls.js +1 -1
  43. package/src/plugins/inline/jsenv_plugin_html_inline_content.js +41 -43
  44. package/src/plugins/inline/jsenv_plugin_js_inline_content.js +4 -4
  45. package/src/plugins/minification/css/minify_css.js +1 -1
  46. package/src/plugins/transpilation/as_js_classic/client/s.js +2 -2
  47. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic.js +2 -4
  48. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic_html.js +45 -67
  49. package/src/plugins/transpilation/babel/global_this/babel_plugin_global_this_as_jsenv_import.js +2 -3
  50. package/src/plugins/transpilation/babel/helpers/babel_plugin_babel_helpers_as_jsenv_imports.js +3 -4
  51. package/src/plugins/transpilation/babel/jsenv_plugin_babel.js +1 -1
  52. package/src/plugins/transpilation/babel/new_stylesheet/babel_plugin_new_stylesheet_as_jsenv_import.js +2 -3
  53. package/src/plugins/transpilation/babel/regenerator_runtime/babel_plugin_regenerator_runtime_as_jsenv_import.js +2 -3
  54. package/src/plugins/transpilation/css_parcel/jsenv_plugin_css_parcel.js +1 -1
  55. package/src/plugins/transpilation/import_assertions/jsenv_plugin_import_assertions.js +1 -1
  56. package/src/plugins/transpilation/jsenv_plugin_top_level_await.js +2 -1
  57. package/src/plugins/url_analysis/css/css_urls.js +2 -3
  58. package/src/plugins/url_analysis/html/html_urls.js +98 -113
  59. package/src/plugins/url_analysis/js/js_urls.js +3 -2
  60. package/src/plugins/url_analysis/jsenv_plugin_url_analysis.js +10 -6
  61. package/src/test/coverage/empty_coverage_factory.js +1 -1
  62. package/src/test/coverage/file_by_file_coverage.js +1 -2
@@ -34,12 +34,13 @@ export const createReloadableWorker = (workerFileUrl, options = {}) => {
34
34
  worker.once("error", (error) => {
35
35
  console.error(error)
36
36
  })
37
- worker.once("exit", () => {
38
- worker = null
39
- })
40
37
  await new Promise((resolve) => {
41
38
  worker.once("online", resolve)
42
39
  })
40
+ worker.once("exit", () => {
41
+ worker = null
42
+ })
43
+ return worker
43
44
  }
44
45
 
45
46
  const reload = async () => {
@@ -1,4 +1,5 @@
1
- import { findHighestVersion } from "@jsenv/utils/semantic_versioning/highest_version.js"
1
+ import { findHighestVersion } from "@jsenv/utils/src/semantic_versioning/highest_version.js"
2
+
2
3
  import { featureCompats } from "./features_compats.js"
3
4
 
4
5
  export const RUNTIME_COMPAT = {
@@ -8,7 +8,8 @@ import {
8
8
  } from "@jsenv/urls"
9
9
  import { writeFileSync, ensureWindowsDriveLetter } from "@jsenv/filesystem"
10
10
  import { createDetailedMessage } from "@jsenv/log"
11
- import { CONTENT_TYPE } from "@jsenv/utils/content_type/content_type.js"
11
+ import { CONTENT_TYPE } from "@jsenv/utils/src/content_type/content_type.js"
12
+
12
13
  import { createPluginController } from "../plugins/plugin_controller.js"
13
14
  import { urlSpecifierEncoding } from "./url_specifier_encoding.js"
14
15
  import { createUrlInfoTransformer } from "./url_graph/url_info_transformations.js"
@@ -711,6 +712,8 @@ const memoizeCook = (cook) => {
711
712
  const applyReferenceEffectsOnUrlInfo = (reference, urlInfo, context) => {
712
713
  if (reference.shouldHandle) {
713
714
  urlInfo.shouldHandle = true
715
+ } else {
716
+ urlInfo.shouldHandle = false
714
717
  }
715
718
  urlInfo.originalUrl = urlInfo.originalUrl || reference.url
716
719
 
@@ -1,4 +1,5 @@
1
- import { memoizeByFirstArgument } from "@jsenv/utils/memoize/memoize_by_first_argument.js"
1
+ import { memoizeByFirstArgument } from "@jsenv/utils/src/memoize/memoize_by_first_argument.js"
2
+
2
3
  import { requireFromJsenv } from "@jsenv/core/src/require_from_jsenv.js"
3
4
 
4
5
  export const parseUserAgentHeader = memoizeByFirstArgument((userAgent) => {
@@ -0,0 +1,27 @@
1
+ export const sortByDependencies = (nodes) => {
2
+ const visited = []
3
+ const sorted = []
4
+ const circular = []
5
+ const visit = (url) => {
6
+ const isSorted = sorted.includes(url)
7
+ if (isSorted) {
8
+ return
9
+ }
10
+ const isVisited = visited.includes(url)
11
+ if (isVisited) {
12
+ circular.push(url)
13
+ sorted.push(url)
14
+ } else {
15
+ visited.push(url)
16
+ nodes[url].dependencies.forEach((dependencyUrl) => {
17
+ visit(dependencyUrl, url)
18
+ })
19
+ sorted.push(url)
20
+ }
21
+ }
22
+ Object.keys(nodes).forEach((url) => {
23
+ visit(url)
24
+ })
25
+ sorted.circular = circular
26
+ return sorted
27
+ }
@@ -1,12 +1,12 @@
1
+ import { pathToFileURL } from "node:url"
1
2
  import { bufferToEtag } from "@jsenv/filesystem"
2
- import { urlToRelativeUrl } from "@jsenv/urls"
3
-
4
- import { composeTwoSourcemaps } from "@jsenv/utils/sourcemap/sourcemap_composition_v3.js"
3
+ import { urlToRelativeUrl, isFileSystemPath } from "@jsenv/urls"
5
4
  import {
5
+ composeTwoSourcemaps,
6
6
  SOURCEMAP,
7
- sourcemapToBase64Url,
8
- generateSourcemapUrl,
9
- } from "@jsenv/utils/sourcemap/sourcemap_utils.js"
7
+ generateSourcemapFileUrl,
8
+ generateSourcemapDataUrl,
9
+ } from "@jsenv/sourcemap"
10
10
 
11
11
  export const createUrlInfoTransformer = ({
12
12
  logger,
@@ -23,18 +23,25 @@ export const createUrlInfoTransformer = ({
23
23
  sourcemaps === "programmatic"
24
24
 
25
25
  const normalizeSourcemap = (urlInfo, sourcemap) => {
26
+ let { sources } = sourcemap
27
+ if (sources) {
28
+ sources = sources.map((source) => {
29
+ if (source && isFileSystemPath(source)) {
30
+ return String(pathToFileURL(source))
31
+ }
32
+ return source
33
+ })
34
+ }
26
35
  const wantSourcesContent =
27
36
  // for inline content (<script> insdide html)
28
37
  // chrome won't be able to fetch the file as it does not exists
29
38
  // so sourcemap must contain sources
30
39
  sourcemapsSourcesContent ||
31
40
  urlInfo.isInline ||
32
- (sourcemap.sources &&
33
- sourcemap.sources.some(
34
- (source) => !source || !source.startsWith("file:"),
35
- ))
36
- if (sourcemap.sources && sourcemap.sources.length > 1) {
37
- sourcemap.sources = sourcemap.sources.map(
41
+ (sources &&
42
+ sources.some((source) => !source || !source.startsWith("file:")))
43
+ if (sources && sources.length > 1) {
44
+ sourcemap.sources = sources.map(
38
45
  (source) => new URL(source, urlInfo.originalUrl).href,
39
46
  )
40
47
  if (!wantSourcesContent) {
@@ -65,7 +72,9 @@ export const createUrlInfoTransformer = ({
65
72
  // when jsenv is done cooking the file
66
73
  // during build it's urlInfo.url to be inside the build
67
74
  // but otherwise it's generatedUrl to be inside .jsenv/ directory
68
- urlInfo.sourcemapGeneratedUrl = generateSourcemapUrl(urlInfo.generatedUrl)
75
+ urlInfo.sourcemapGeneratedUrl = generateSourcemapFileUrl(
76
+ urlInfo.generatedUrl,
77
+ )
69
78
  const [sourcemapReference, sourcemapUrlInfo] = injectSourcemapPlaceholder({
70
79
  urlInfo,
71
80
  specifier: urlInfo.sourcemapGeneratedUrl,
@@ -154,7 +163,8 @@ export const createUrlInfoTransformer = ({
154
163
  }
155
164
  sourcemapUrlInfo.content = JSON.stringify(sourcemap, null, " ")
156
165
  if (sourcemaps === "inline") {
157
- sourcemapReference.generatedSpecifier = sourcemapToBase64Url(sourcemap)
166
+ sourcemapReference.generatedSpecifier =
167
+ generateSourcemapDataUrl(sourcemap)
158
168
  }
159
169
  if (sourcemaps === "file" || sourcemaps === "inline") {
160
170
  urlInfo.content = SOURCEMAP.writeComment({
@@ -1,4 +1,7 @@
1
- import { htmlAttributeSrcSet } from "@jsenv/utils/html_ast/html_attribute_src_set.js"
1
+ import {
2
+ parseSrcSet,
3
+ stringifySrcSet,
4
+ } from "@jsenv/ast/src/html/html_src_set.js"
2
5
 
3
6
  import { injectQuery, compareTwoUrlPaths } from "./url_helpers.js"
4
7
 
@@ -57,7 +60,7 @@ export const reloadDOMNodesUsingUrl = (urlToReload) => {
57
60
  visitNodeAttributeAsUrl(img, "src")
58
61
  const srcset = img.srcset
59
62
  if (srcset) {
60
- const srcCandidates = htmlAttributeSrcSet.parse(srcset)
63
+ const srcCandidates = parseSrcSet(srcset)
61
64
  srcCandidates.forEach((srcCandidate) => {
62
65
  const url = new URL(srcCandidate.specifier, `${window.location.href}`)
63
66
  if (shouldReloadUrl(url)) {
@@ -65,7 +68,7 @@ export const reloadDOMNodesUsingUrl = (urlToReload) => {
65
68
  }
66
69
  })
67
70
  mutations.push(() => {
68
- img.srcset = htmlAttributeSrcSet.stringify(srcCandidates)
71
+ img.srcset = stringifySrcSet(srcCandidates)
69
72
  })
70
73
  }
71
74
  })
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  parseHtmlString,
3
3
  stringifyHtmlAst,
4
- injectScriptAsEarlyAsPossible,
4
+ injectScriptNodeAsEarlyAsPossible,
5
5
  createHtmlNode,
6
- } from "@jsenv/utils/html_ast/html_ast.js"
6
+ } from "@jsenv/ast"
7
7
 
8
8
  export const jsenvPluginDevSSEClient = () => {
9
9
  const eventSourceClientFileUrl = new URL(
@@ -22,7 +22,7 @@ export const jsenvPluginDevSSEClient = () => {
22
22
  expectedType: "js_module",
23
23
  specifier: eventSourceClientFileUrl,
24
24
  })
25
- injectScriptAsEarlyAsPossible(
25
+ injectScriptNodeAsEarlyAsPossible(
26
26
  htmlAst,
27
27
  createHtmlNode({
28
28
  "tagName": "script",
@@ -6,10 +6,10 @@
6
6
  * It can be quite challenging, see "bundle_sourcemap.js"
7
7
  */
8
8
 
9
- import { applyPostCss } from "@jsenv/utils/css_ast/apply_post_css.js"
10
- import { postCssPluginUrlVisitor } from "@jsenv/utils/css_ast/postcss_plugin_url_visitor.js"
11
- import { createMagicSource } from "@jsenv/utils/sourcemap/magic_source.js"
12
- import { sortByDependencies } from "@jsenv/utils/graph/sort_by_dependencies.js"
9
+ import { createMagicSource } from "@jsenv/sourcemap"
10
+ import { applyPostCss, postCssPluginUrlVisitor } from "@jsenv/ast"
11
+
12
+ import { sortByDependencies } from "@jsenv/core/src/omega/url_graph/sort_by_dependencies.js"
13
13
 
14
14
  // Do not use until https://github.com/parcel-bundler/parcel-css/issues/181
15
15
  export const bundleCss = async ({ cssUrlInfos, context }) => {
@@ -4,8 +4,8 @@ import { URL_META } from "@jsenv/url-meta"
4
4
  import { isFileSystemPath } from "@jsenv/urls"
5
5
  import { createDetailedMessage } from "@jsenv/log"
6
6
  import { babelHelperNameFromUrl } from "@jsenv/babel-plugins"
7
- import { applyRollupPlugins } from "@jsenv/utils/js_ast/apply_rollup_plugins.js"
8
- import { sourcemapConverter } from "@jsenv/utils/sourcemap/sourcemap_converter.js"
7
+ import { sourcemapConverter } from "@jsenv/sourcemap"
8
+
9
9
  import { fileUrlConverter } from "@jsenv/core/src/omega/file_url_converter.js"
10
10
 
11
11
  const globalThisClientFileUrl = new URL(
@@ -53,71 +53,6 @@ export const bundleJsModule = async ({
53
53
  return jsModuleBundleUrlInfos
54
54
  }
55
55
 
56
- export const buildWithRollup = async ({
57
- signal,
58
- logger,
59
- rootDirectoryUrl,
60
- buildDirectoryUrl,
61
- urlGraph,
62
- jsModuleUrlInfos,
63
-
64
- runtimeCompat,
65
- sourcemaps,
66
-
67
- include,
68
- babelHelpersChunk,
69
- }) => {
70
- const resultRef = { current: null }
71
- try {
72
- await applyRollupPlugins({
73
- rollupPlugins: [
74
- rollupPluginJsenv({
75
- signal,
76
- logger,
77
- rootDirectoryUrl,
78
- buildDirectoryUrl,
79
- urlGraph,
80
- jsModuleUrlInfos,
81
-
82
- runtimeCompat,
83
- sourcemaps,
84
- include,
85
- babelHelpersChunk,
86
- resultRef,
87
- }),
88
- ],
89
- inputOptions: {
90
- input: [],
91
- onwarn: (warning) => {
92
- if (warning.code === "CIRCULAR_DEPENDENCY") {
93
- return
94
- }
95
- if (
96
- warning.code === "THIS_IS_UNDEFINED" &&
97
- pathToFileURL(warning.id).href === globalThisClientFileUrl
98
- ) {
99
- return
100
- }
101
- if (warning.code === "EVAL") {
102
- // ideally we should disable only for jsenv files
103
- return
104
- }
105
- logger.warn(String(warning))
106
- },
107
- },
108
- })
109
- return resultRef.current
110
- } catch (e) {
111
- if (e.code === "MISSING_EXPORT") {
112
- const detailedMessage = createDetailedMessage(e.message, {
113
- frame: e.frame,
114
- })
115
- throw new Error(detailedMessage, { cause: e })
116
- }
117
- throw e
118
- }
119
- }
120
-
121
56
  const rollupPluginJsenv = ({
122
57
  // logger,
123
58
  rootDirectoryUrl,
@@ -311,6 +246,90 @@ const rollupPluginJsenv = ({
311
246
  }
312
247
  }
313
248
 
249
+ const buildWithRollup = async ({
250
+ signal,
251
+ logger,
252
+ rootDirectoryUrl,
253
+ buildDirectoryUrl,
254
+ urlGraph,
255
+ jsModuleUrlInfos,
256
+
257
+ runtimeCompat,
258
+ sourcemaps,
259
+
260
+ include,
261
+ babelHelpersChunk,
262
+ }) => {
263
+ const resultRef = { current: null }
264
+ try {
265
+ await applyRollupPlugins({
266
+ rollupPlugins: [
267
+ rollupPluginJsenv({
268
+ signal,
269
+ logger,
270
+ rootDirectoryUrl,
271
+ buildDirectoryUrl,
272
+ urlGraph,
273
+ jsModuleUrlInfos,
274
+
275
+ runtimeCompat,
276
+ sourcemaps,
277
+ include,
278
+ babelHelpersChunk,
279
+ resultRef,
280
+ }),
281
+ ],
282
+ inputOptions: {
283
+ input: [],
284
+ onwarn: (warning) => {
285
+ if (warning.code === "CIRCULAR_DEPENDENCY") {
286
+ return
287
+ }
288
+ if (
289
+ warning.code === "THIS_IS_UNDEFINED" &&
290
+ pathToFileURL(warning.id).href === globalThisClientFileUrl
291
+ ) {
292
+ return
293
+ }
294
+ if (warning.code === "EVAL") {
295
+ // ideally we should disable only for jsenv files
296
+ return
297
+ }
298
+ logger.warn(String(warning))
299
+ },
300
+ },
301
+ })
302
+ return resultRef.current
303
+ } catch (e) {
304
+ if (e.code === "MISSING_EXPORT") {
305
+ const detailedMessage = createDetailedMessage(e.message, {
306
+ frame: e.frame,
307
+ })
308
+ throw new Error(detailedMessage, { cause: e })
309
+ }
310
+ throw e
311
+ }
312
+ }
313
+
314
+ const applyRollupPlugins = async ({
315
+ rollupPlugins,
316
+ inputOptions = {},
317
+ outputOptions = {},
318
+ }) => {
319
+ const { rollup } = await import("rollup")
320
+ const { importAssertions } = await import("acorn-import-assertions")
321
+ const rollupReturnValue = await rollup({
322
+ ...inputOptions,
323
+ plugins: rollupPlugins,
324
+ acornInjectPlugins: [
325
+ importAssertions,
326
+ ...(inputOptions.acornInjectPlugins || []),
327
+ ],
328
+ })
329
+ const rollupOutputArray = await rollupReturnValue.generate(outputOptions)
330
+ return rollupOutputArray
331
+ }
332
+
314
333
  const willBeInsideJsDirectory = ({
315
334
  chunkInfo,
316
335
  fileUrlConverter,
@@ -7,8 +7,8 @@
7
7
  * - global
8
8
  */
9
9
 
10
- import { applyBabelPlugins } from "@jsenv/utils/js_ast/apply_babel_plugins.js"
11
- import { createMagicSource } from "@jsenv/utils/sourcemap/magic_source.js"
10
+ import { createMagicSource } from "@jsenv/sourcemap"
11
+ import { applyBabelPlugins } from "@jsenv/ast"
12
12
 
13
13
  export const jsenvPluginCommonJsGlobals = () => {
14
14
  const transformCommonJsGlobals = async (urlInfo, { scenario }) => {
@@ -6,17 +6,16 @@ import {
6
6
  urlToFilename,
7
7
  ensurePathnameTrailingSlash,
8
8
  } from "@jsenv/urls"
9
-
10
9
  import {
11
10
  applyFileSystemMagicResolution,
12
11
  getExtensionsToTry,
13
12
  } from "@jsenv/node-esm-resolution"
14
- import { CONTENT_TYPE } from "@jsenv/utils/content_type/content_type.js"
13
+ import { CONTENT_TYPE } from "@jsenv/utils/src/content_type/content_type.js"
15
14
 
16
15
  export const jsenvPluginFileUrls = ({
17
16
  magicExtensions = ["inherit", ".js"],
18
17
  magicDirectoryIndex = true,
19
- preservesSymlink = true,
18
+ preserveSymlinks = false,
20
19
  directoryReferenceAllowed = false,
21
20
  }) => {
22
21
  return [
@@ -61,7 +60,7 @@ export const jsenvPluginFileUrls = ({
61
60
  if (foundADirectory && directoryReferenceAllowed) {
62
61
  reference.data.foundADirectory = true
63
62
  const directoryFacadeUrl = urlObject.href
64
- const directoryUrlRaw = preservesSymlink
63
+ const directoryUrlRaw = preserveSymlinks
65
64
  ? directoryFacadeUrl
66
65
  : resolveSymlink(directoryFacadeUrl)
67
66
  const directoryUrl = `${directoryUrlRaw}${search}${hash}`
@@ -82,7 +81,7 @@ export const jsenvPluginFileUrls = ({
82
81
  }
83
82
  reference.data.foundADirectory = filesystemResolution.isDirectory
84
83
  const fileFacadeUrl = filesystemResolution.url
85
- const fileUrlRaw = preservesSymlink
84
+ const fileUrlRaw = preserveSymlinks
86
85
  ? fileFacadeUrl
87
86
  : resolveSymlink(fileFacadeUrl)
88
87
  const fileUrl = `${fileUrlRaw}${search}${hash}`
@@ -7,17 +7,17 @@
7
7
  import {
8
8
  parseHtmlString,
9
9
  stringifyHtmlAst,
10
- visitHtmlAst,
11
- getHtmlNodeAttributeByName,
12
- removeHtmlNodeAttributeByName,
13
- parseScriptNode,
14
- injectScriptAsEarlyAsPossible,
10
+ visitHtmlNodes,
11
+ getHtmlNodeAttribute,
12
+ setHtmlNodeAttributes,
13
+ analyzeScriptNode,
14
+ injectScriptNodeAsEarlyAsPossible,
15
15
  createHtmlNode,
16
- htmlNodePosition,
17
- getHtmlNodeTextNode,
16
+ getHtmlNodePosition,
17
+ getHtmlNodeText,
18
18
  removeHtmlNodeText,
19
- setHtmlNodeGeneratedText,
20
- } from "@jsenv/utils/html_ast/html_ast.js"
19
+ setHtmlNodeText,
20
+ } from "@jsenv/ast"
21
21
  import { generateInlineContentUrl } from "@jsenv/urls"
22
22
 
23
23
  export const jsenvPluginHtmlSupervisor = ({
@@ -45,10 +45,10 @@ export const jsenvPluginHtmlSupervisor = ({
45
45
  const htmlAst = parseHtmlString(content)
46
46
  const scriptsToSupervise = []
47
47
 
48
- const handleInlineScript = (node, textNode) => {
49
- const scriptCategory = parseScriptNode(node)
48
+ const handleInlineScript = (node, htmlNodeText) => {
49
+ const scriptCategory = analyzeScriptNode(node)
50
50
  const { line, column, lineEnd, columnEnd, isOriginal } =
51
- htmlNodePosition.readNodePosition(node, {
51
+ getHtmlNodePosition(node, {
52
52
  preferOriginal: true,
53
53
  })
54
54
  let inlineScriptUrl = generateInlineContentUrl({
@@ -69,7 +69,7 @@ export const jsenvPluginHtmlSupervisor = ({
69
69
  specifierColumn: column,
70
70
  specifier: inlineScriptUrl,
71
71
  contentType: "text/javascript",
72
- content: textNode.value,
72
+ content: htmlNodeText,
73
73
  })
74
74
  removeHtmlNodeText(node)
75
75
  scriptsToSupervise.push({
@@ -79,76 +79,61 @@ export const jsenvPluginHtmlSupervisor = ({
79
79
  src: inlineScriptReference.generatedSpecifier,
80
80
  })
81
81
  }
82
- const handleScriptWithSrc = (node, srcAttribute) => {
83
- const scriptCategory = parseScriptNode(node)
84
- const integrityAttribute = getHtmlNodeAttributeByName(
85
- node,
86
- "integrity",
87
- )
88
- const integrity = integrityAttribute
89
- ? integrityAttribute.value
90
- : undefined
91
- const crossoriginAttribute = getHtmlNodeAttributeByName(
92
- node,
93
- "crossorigin",
94
- )
95
- const crossorigin = crossoriginAttribute
96
- ? crossoriginAttribute.value
97
- : undefined
98
- const deferAttribute = getHtmlNodeAttributeByName(node, "crossorigin")
99
- const defer = deferAttribute ? deferAttribute.value : undefined
100
- const asyncAttribute = getHtmlNodeAttributeByName(node, "crossorigin")
101
- const async = asyncAttribute ? asyncAttribute.value : undefined
102
- removeHtmlNodeAttributeByName(node, "src")
82
+ const handleScriptWithSrc = (node, src) => {
83
+ const scriptCategory = analyzeScriptNode(node)
84
+ const integrity = getHtmlNodeAttribute(node, "integrity")
85
+ const crossorigin =
86
+ getHtmlNodeAttribute(node, "crossorigin") !== undefined
87
+ const defer = getHtmlNodeAttribute(node, "defer") !== undefined
88
+ const async = getHtmlNodeAttribute(node, "async") !== undefined
89
+ setHtmlNodeAttributes(node, {
90
+ src: undefined,
91
+ })
103
92
  scriptsToSupervise.push({
104
93
  node,
105
94
  type: scriptCategory,
106
- src: srcAttribute.value,
95
+ src,
107
96
  defer,
108
97
  async,
109
98
  integrity,
110
99
  crossorigin,
111
100
  })
112
101
  }
113
- visitHtmlAst(htmlAst, (node) => {
114
- if (node.nodeName !== "script") {
115
- return
116
- }
117
- const scriptCategory = parseScriptNode(node)
118
- if (scriptCategory !== "classic" && scriptCategory !== "module") {
119
- return
120
- }
121
- const injectedByAttribute = getHtmlNodeAttributeByName(
122
- node,
123
- "injected-by",
124
- )
125
- if (injectedByAttribute) {
126
- return
127
- }
128
- const noHtmlSupervisor = getHtmlNodeAttributeByName(
129
- node,
130
- "no-html-supervisor",
131
- )
132
- if (noHtmlSupervisor) {
133
- return
134
- }
135
- const textNode = getHtmlNodeTextNode(node)
136
- if (textNode) {
137
- handleInlineScript(node, textNode)
138
- return
139
- }
140
- const srcAttribute = getHtmlNodeAttributeByName(node, "src")
141
- if (srcAttribute) {
142
- handleScriptWithSrc(node, srcAttribute)
143
- return
144
- }
102
+ visitHtmlNodes(htmlAst, {
103
+ script: (node) => {
104
+ const scriptCategory = analyzeScriptNode(node)
105
+ if (scriptCategory !== "classic" && scriptCategory !== "module") {
106
+ return
107
+ }
108
+ const injectedBy = getHtmlNodeAttribute(node, "injected-by")
109
+ if (injectedBy !== undefined) {
110
+ return
111
+ }
112
+ const noHtmlSupervisor = getHtmlNodeAttribute(
113
+ node,
114
+ "no-html-supervisor",
115
+ )
116
+ if (noHtmlSupervisor !== undefined) {
117
+ return
118
+ }
119
+ const htmlNodeText = getHtmlNodeText(node)
120
+ if (htmlNodeText) {
121
+ handleInlineScript(node, htmlNodeText)
122
+ return
123
+ }
124
+ const src = getHtmlNodeAttribute(node, "src")
125
+ if (src) {
126
+ handleScriptWithSrc(node, src)
127
+ return
128
+ }
129
+ },
145
130
  })
146
131
  const [htmlSupervisorInstallerFileReference] = referenceUtils.inject({
147
132
  type: "js_import_export",
148
133
  expectedType: "js_module",
149
134
  specifier: htmlSupervisorInstallerFileUrl,
150
135
  })
151
- injectScriptAsEarlyAsPossible(
136
+ injectScriptNodeAsEarlyAsPossible(
152
137
  htmlAst,
153
138
  createHtmlNode({
154
139
  "tagName": "script",
@@ -173,7 +158,7 @@ export const jsenvPluginHtmlSupervisor = ({
173
158
  expectedType: "js_classic",
174
159
  specifier: htmlSupervisorSetupFileUrl,
175
160
  })
176
- injectScriptAsEarlyAsPossible(
161
+ injectScriptNodeAsEarlyAsPossible(
177
162
  htmlAst,
178
163
  createHtmlNode({
179
164
  "tagName": "script",
@@ -192,8 +177,9 @@ export const jsenvPluginHtmlSupervisor = ({
192
177
  integrity,
193
178
  crossorigin,
194
179
  }) => {
195
- setHtmlNodeGeneratedText(node, {
196
- generatedText: generateCodeToSuperviseScript({
180
+ setHtmlNodeText(
181
+ node,
182
+ generateCodeToSuperviseScript({
197
183
  type,
198
184
  src,
199
185
  isInline,
@@ -204,9 +190,11 @@ export const jsenvPluginHtmlSupervisor = ({
204
190
  htmlSupervisorInstallerSpecifier:
205
191
  htmlSupervisorInstallerFileReference.generatedSpecifier,
206
192
  }),
207
- generatedBy: "jsenv:html_supervisor",
208
- generatedFromSrc: src,
209
- generatedFromInlineContent: isInline,
193
+ )
194
+ setHtmlNodeAttributes(node, {
195
+ "generated-by": "jsenv:html_supervisor",
196
+ ...(src ? { "generated-from-src": src } : {}),
197
+ ...(isInline ? { "generated-from-inline-content": "" } : {}),
210
198
  })
211
199
  },
212
200
  )
@@ -2,11 +2,15 @@ export const jsenvPluginHttpUrls = () => {
2
2
  return {
3
3
  name: "jsenv:http_urls",
4
4
  appliesDuring: "*",
5
- // fetchUrlContent: (urlInfo) => {
6
- // if (urlInfo.url.startsWith("http") || urlInfo.url.startsWith("https")) {
7
- // return { shouldHandle: false }
8
- // }
9
- // return null
10
- // },
5
+ redirectUrl: (reference) => {
6
+ if (
7
+ reference.url.startsWith("http:") ||
8
+ reference.url.startsWith("https:")
9
+ ) {
10
+ reference.shouldHandle = false
11
+ }
12
+ // TODO: according to some pattern matching jsenv could be allowed
13
+ // to fetch and transform http urls
14
+ },
11
15
  }
12
16
  }