@jsenv/core 27.0.0-alpha.85 → 27.0.0-alpha.88

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/core",
3
- "version": "27.0.0-alpha.85",
3
+ "version": "27.0.0-alpha.88",
4
4
  "description": "Tool to develop, test and build js projects",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -65,20 +65,10 @@
65
65
  "@babel/plugin-transform-modules-umd": "7.18.0",
66
66
  "@c88/v8-coverage": "0.1.1",
67
67
  "@financial-times/polyfill-useragent-normaliser": "2.0.1",
68
- "@jsenv/abort": "4.2.2",
69
- "@jsenv/ast": "1.1.0",
68
+ "@jsenv/ast": "1.1.1",
70
69
  "@jsenv/babel-plugins": "1.0.5",
71
- "@jsenv/filesystem": "4.0.9",
72
- "@jsenv/importmap": "1.2.0",
73
- "@jsenv/integrity": "0.0.1",
74
- "@jsenv/log": "2.0.0",
75
- "@jsenv/node-esm-resolution": "0.1.0",
76
- "@jsenv/server": "12.7.0",
77
- "@jsenv/uneval": "1.6.0",
78
- "@jsenv/sourcemap": "1.0.0",
79
- "@jsenv/utils": "2.0.0",
80
- "@jsenv/url-meta": "7.0.0",
81
- "@jsenv/urls": "1.2.5",
70
+ "@jsenv/log": "2.0.1",
71
+ "@jsenv/sourcemap": "1.0.1",
82
72
  "acorn-import-assertions": "1.8.0",
83
73
  "construct-style-sheets-polyfill": "3.1.0",
84
74
  "cuid": "2.1.8",
@@ -91,6 +81,7 @@
91
81
  "pidtree": "0.6.0",
92
82
  "regenerator-runtime": "0.13.9",
93
83
  "rollup": "2.75.6",
84
+ "string-width": "5.1.2",
94
85
  "strip-ansi": "7.0.1",
95
86
  "terser": "5.14.1",
96
87
  "v8-to-istanbul": "9.0.0",
@@ -99,14 +90,24 @@
99
90
  "devDependencies": {
100
91
  "@babel/eslint-parser": "7.18.2",
101
92
  "@babel/plugin-syntax-import-assertions": "7.17.12",
93
+ "@jsenv/abort": "4.2.3",
102
94
  "@jsenv/assert": "2.5.4",
103
95
  "@jsenv/eslint-config": "16.0.9",
104
96
  "@jsenv/file-size-impact": "12.1.13",
97
+ "@jsenv/filesystem": "4.0.10",
105
98
  "@jsenv/https-local": "1.1.0",
99
+ "@jsenv/importmap": "1.2.1",
106
100
  "@jsenv/importmap-node-module": "5.1.3",
101
+ "@jsenv/integrity": "0.0.1",
102
+ "@jsenv/node-esm-resolution": "0.1.0",
107
103
  "@jsenv/package-workspace": "0.2.1",
108
104
  "@jsenv/performance-impact": "2.2.11",
109
105
  "@jsenv/pwa": "5.0.0",
106
+ "@jsenv/server": "12.7.2",
107
+ "@jsenv/uneval": "1.6.0",
108
+ "@jsenv/url-meta": "7.0.0",
109
+ "@jsenv/urls": "1.2.6",
110
+ "@jsenv/utils": "2.0.1",
110
111
  "eslint": "8.17.0",
111
112
  "eslint-plugin-html": "6.2.0",
112
113
  "eslint-plugin-import": "2.26.0",
@@ -116,4 +117,4 @@
116
117
  "prettier": "2.7.1",
117
118
  "redux": "4.1.2"
118
119
  }
119
- }
120
+ }
@@ -28,7 +28,6 @@ import { Abort, raceProcessTeardownEvents } from "@jsenv/abort"
28
28
  import { createLogger, loggerToLevels, createTaskLog } from "@jsenv/log"
29
29
  import { generateSourcemapFileUrl } from "@jsenv/sourcemap"
30
30
  import { parseHtmlString, stringifyHtmlAst } from "@jsenv/ast"
31
- import { createVersionGenerator } from "@jsenv/utils/src/versioning/version_generator.js"
32
31
 
33
32
  import { sortByDependencies } from "../omega/url_graph/sort_by_dependencies.js"
34
33
  import { createUrlGraph } from "../omega/url_graph.js"
@@ -44,6 +43,7 @@ import { isWebWorkerEntryPointReference } from "../omega/web_workers.js"
44
43
  import { GRAPH } from "./graph_utils.js"
45
44
  import { createBuilUrlsGenerator } from "./build_urls_generator.js"
46
45
  import { injectGlobalVersionMapping } from "./inject_global_version_mappings.js"
46
+ import { createVersionGenerator } from "./version_generator.js"
47
47
  import { injectServiceWorkerUrls } from "./inject_service_worker_urls.js"
48
48
  import { resyncRessourceHints } from "./resync_ressource_hints.js"
49
49
 
@@ -166,7 +166,6 @@ build ${entryPointKeys.length} entry points`)
166
166
  const prebuildTask = createTaskLog("prebuild", {
167
167
  disabled: infoLogsAreDisabled,
168
168
  })
169
- let urlCount = 0
170
169
  const prebuildRedirections = new Map()
171
170
  const rawGraphKitchen = createKitchen({
172
171
  signal,
@@ -180,14 +179,6 @@ build ${entryPointKeys.length} entry points`)
180
179
  writeGeneratedFiles,
181
180
  plugins: [
182
181
  ...plugins,
183
- {
184
- name: "jsenv:build_log",
185
- appliesDuring: { build: true },
186
- cooked: () => {
187
- urlCount++
188
- prebuildTask.setRightText(urlCount)
189
- },
190
- },
191
182
  {
192
183
  appliesDuring: "build",
193
184
  fetchUrlContent: (urlInfo, context) => {
@@ -1,7 +1,7 @@
1
1
  import { createMagicSource } from "@jsenv/sourcemap"
2
- import { createVersionGenerator } from "@jsenv/utils/src/versioning/version_generator.js"
3
2
 
4
3
  import { GRAPH } from "./graph_utils.js"
4
+ import { createVersionGenerator } from "./version_generator.js"
5
5
 
6
6
  export const injectServiceWorkerUrls = async ({
7
7
  finalGraph,
@@ -0,0 +1,60 @@
1
+ import { createHash } from "node:crypto"
2
+
3
+ import { CONTENT_TYPE } from "@jsenv/utils/src/content_type/content_type.js"
4
+
5
+ // https://github.com/rollup/rollup/blob/19e50af3099c2f627451a45a84e2fa90d20246d5/src/utils/FileEmitter.ts#L47
6
+ // https://github.com/rollup/rollup/blob/5a5391971d695c808eed0c5d7d2c6ccb594fc689/src/Chunk.ts#L870
7
+ export const createVersionGenerator = () => {
8
+ const hash = createHash("sha256")
9
+
10
+ const augmentWithContent = ({
11
+ content,
12
+ contentType = "application/octet-stream",
13
+ lineBreakNormalization = false,
14
+ }) => {
15
+ hash.update(
16
+ lineBreakNormalization && CONTENT_TYPE.isTextual(contentType)
17
+ ? normalizeLineBreaks(content)
18
+ : content,
19
+ )
20
+ }
21
+
22
+ const augmentWithDependencyVersion = (version) => {
23
+ hash.update(version)
24
+ }
25
+
26
+ return {
27
+ augmentWithContent,
28
+ augmentWithDependencyVersion,
29
+ generate: () => {
30
+ return hash.digest("hex").slice(0, 8)
31
+ },
32
+ }
33
+ }
34
+
35
+ const normalizeLineBreaks = (stringOrBuffer) => {
36
+ if (typeof stringOrBuffer === "string") {
37
+ const stringWithLinuxBreaks = stringOrBuffer.replace(/\r\n/g, "\n")
38
+ return stringWithLinuxBreaks
39
+ }
40
+ return normalizeLineBreaksForBuffer(stringOrBuffer)
41
+ }
42
+
43
+ // https://github.com/nodejs/help/issues/1738#issuecomment-458460503
44
+ const normalizeLineBreaksForBuffer = (buffer) => {
45
+ const int32Array = new Int32Array(buffer, 0, buffer.length)
46
+ const int32ArrayWithLineBreaksNormalized = int32Array.filter(
47
+ (element, index, typedArray) => {
48
+ if (element === 0x0d) {
49
+ if (typedArray[index + 1] === 0x0a) {
50
+ // Windows -> Unix
51
+ return false
52
+ }
53
+ // Mac OS -> Unix
54
+ typedArray[index] = 0x0a
55
+ }
56
+ return true
57
+ },
58
+ )
59
+ return Buffer.from(int32ArrayWithLineBreaksNormalized)
60
+ }
@@ -4,7 +4,7 @@
4
4
  <title>Exploring</title>
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1" />
6
6
  <meta charset="utf-8" />
7
- <link rel="icon" href="virtual:FAVICON_HREF" />
7
+ <link rel="icon" href="ignore:FAVICON_HREF" />
8
8
  <style>
9
9
  button:focus,
10
10
  a:focus,
@@ -36,7 +36,7 @@ export const jsenvPluginExplorer = ({ groups }) => {
36
36
  }))
37
37
  let html = String(readFileSync(new URL(htmlClientFileUrl)))
38
38
  html = html.replace(
39
- "virtual:FAVICON_HREF",
39
+ "ignore:FAVICON_HREF",
40
40
  DATA_URL.stringify({
41
41
  contentType: CONTENT_TYPE.fromUrlExtension(faviconClientFileUrl),
42
42
  base64Flag: true,
@@ -58,6 +58,14 @@ export const jsenvPluginFileUrls = ({
58
58
  urlObject.pathname = pathname.slice(0, -1)
59
59
  }
60
60
  if (foundADirectory && directoryReferenceAllowed) {
61
+ if (
62
+ // ignore new URL second arg
63
+ reference.subtype === "new_url_second_arg" ||
64
+ // ignore root file url
65
+ reference.url === "file:///"
66
+ ) {
67
+ reference.shouldHandle = false
68
+ }
61
69
  reference.data.foundADirectory = true
62
70
  const directoryFacadeUrl = urlObject.href
63
71
  const directoryUrlRaw = preserveSymlinks
@@ -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
  }
@@ -106,7 +106,7 @@ export const jsenvPluginImportmap = () => {
106
106
  onHtmlImportmapParsed(null, htmlUrlInfo.url)
107
107
  return null
108
108
  }
109
- const handleInlineImportmap = async (importmap, textNode) => {
109
+ const handleInlineImportmap = async (importmap, htmlNodeText) => {
110
110
  const { line, column, lineEnd, columnEnd, isOriginal } =
111
111
  getHtmlNodePosition(importmap, {
112
112
  preferOriginal: true,
@@ -127,7 +127,7 @@ export const jsenvPluginImportmap = () => {
127
127
  specifierColumn: column,
128
128
  specifier: inlineImportmapUrl,
129
129
  contentType: "application/importmap+json",
130
- content: textNode.value,
130
+ content: htmlNodeText,
131
131
  })
132
132
  await context.cook(inlineImportmapUrlInfo, {
133
133
  reference: inlineImportmapReference,
@@ -49,8 +49,10 @@ export const getCorePlugins = ({
49
49
  jsenvPluginUrlAnalysis({ rootDirectoryUrl, ...urlAnalysis }),
50
50
  jsenvPluginTranspilation(transpilation),
51
51
  ...(htmlSupervisor ? [jsenvPluginHtmlSupervisor(htmlSupervisor)] : []), // before inline as it turns inline <script> into <script src>
52
+ jsenvPluginImportmap(),
53
+ // before node esm to handle bare specifiers
54
+ // + before node esm to handle importmap before inline content
52
55
  jsenvPluginInline(), // before "file urls" to resolve and load inline urls
53
- jsenvPluginImportmap(), // before node esm to handle bare specifiers before node esm
54
56
  jsenvPluginFileUrls({
55
57
  directoryReferenceAllowed,
56
58
  ...fileSystemMagicResolution,
@@ -6,7 +6,11 @@ import { parseAndTransformCssUrls } from "./css/css_urls.js"
6
6
  import { parseAndTransformJsUrls } from "./js/js_urls.js"
7
7
  import { parseAndTransformWebmanifestUrls } from "./webmanifest/webmanifest_urls.js"
8
8
 
9
- export const jsenvPluginUrlAnalysis = ({ rootDirectoryUrl, include }) => {
9
+ export const jsenvPluginUrlAnalysis = ({
10
+ rootDirectoryUrl,
11
+ include,
12
+ supportedProtocols = ["file:", "data:", "virtual:", "http:", "https:"],
13
+ }) => {
10
14
  let getIncludeInfo = () => undefined
11
15
  if (include) {
12
16
  const associations = URL_META.resolveAssociations(
@@ -23,6 +27,9 @@ export const jsenvPluginUrlAnalysis = ({ rootDirectoryUrl, include }) => {
23
27
  name: "jsenv:url_analysis",
24
28
  appliesDuring: "*",
25
29
  redirectUrl: (reference) => {
30
+ if (reference.shouldHandle !== undefined) {
31
+ return
32
+ }
26
33
  if (
27
34
  reference.specifier[0] === "#" &&
28
35
  // For Html, css and in general "#" refer to a ressource in the page
@@ -43,11 +50,11 @@ export const jsenvPluginUrlAnalysis = ({ rootDirectoryUrl, include }) => {
43
50
  reference.shouldHandle = false
44
51
  return
45
52
  }
46
- if (reference.url.startsWith("data:")) {
47
- reference.shouldHandle = true
48
- return
49
- }
50
- if (reference.url.startsWith("file:")) {
53
+ const { protocol } = new URL(reference.url)
54
+ const protocolIsSupported = supportedProtocols.some(
55
+ (supportedProtocol) => protocol === supportedProtocol,
56
+ )
57
+ if (protocolIsSupported) {
51
58
  reference.shouldHandle = true
52
59
  return
53
60
  }