@jsenv/core 27.0.0-alpha.85 → 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.
@@ -2,7 +2,7 @@
2
2
  <title>Exploring</title>
3
3
  <meta name="viewport" content="width=device-width, initial-scale=1">
4
4
  <meta charset="utf-8">
5
- <link rel="icon" href="virtual:FAVICON_HREF">
5
+ <link rel="icon" href="ignore:FAVICON_HREF">
6
6
  <style>button:focus, a:focus, input:focus, [data-contains-hidden-input] input:focus + * {
7
7
  outline-offset: -2px;
8
8
  outline-style: none;
package/dist/main.js CHANGED
@@ -29,7 +29,7 @@ import { memoize } from "@jsenv/utils/src/memoize/memoize.js";
29
29
  import { escapeRegexpSpecialChars } from "@jsenv/utils/src/string/escape_regexp_special_chars.js";
30
30
  import { fork } from "node:child_process";
31
31
  import { uneval } from "@jsenv/uneval";
32
- import { createVersionGenerator } from "@jsenv/utils/src/versioning/version_generator.js";
32
+ import { createHash } from "node:crypto";
33
33
 
34
34
  const createReloadableWorker = (workerFileUrl, options = {}) => {
35
35
  const workerFilePath = fileURLToPath(workerFileUrl);
@@ -520,7 +520,8 @@ const parseAndTransformWebmanifestUrls = async (urlInfo, context) => {
520
520
 
521
521
  const jsenvPluginUrlAnalysis = ({
522
522
  rootDirectoryUrl,
523
- include
523
+ include,
524
+ supportedProtocols = ["file:", "data:", "virtual:", "http:", "https:"]
524
525
  }) => {
525
526
  let getIncludeInfo = () => undefined;
526
527
 
@@ -565,12 +566,12 @@ const jsenvPluginUrlAnalysis = ({
565
566
  return;
566
567
  }
567
568
 
568
- if (reference.url.startsWith("data:")) {
569
- reference.shouldHandle = true;
570
- return;
571
- }
569
+ const {
570
+ protocol
571
+ } = new URL(reference.url);
572
+ const protocolIsSupported = supportedProtocols.some(supportedProtocol => protocol === supportedProtocol);
572
573
 
573
- if (reference.url.startsWith("file:")) {
574
+ if (protocolIsSupported) {
574
575
  reference.shouldHandle = true;
575
576
  return;
576
577
  }
@@ -1251,13 +1252,14 @@ const resolveSymlink = fileUrl => {
1251
1252
  const jsenvPluginHttpUrls = () => {
1252
1253
  return {
1253
1254
  name: "jsenv:http_urls",
1254
- appliesDuring: "*" // fetchUrlContent: (urlInfo) => {
1255
- // if (urlInfo.url.startsWith("http") || urlInfo.url.startsWith("https")) {
1256
- // return { shouldHandle: false }
1257
- // }
1258
- // return null
1259
- // },
1255
+ appliesDuring: "*",
1256
+ redirectUrl: reference => {
1257
+ if (reference.url.startsWith("http:") || reference.url.startsWith("https:")) {
1258
+ reference.shouldHandle = false;
1259
+ } // TODO: according to some pattern matching jsenv could be allowed
1260
+ // to fetch and transform http urls
1260
1261
 
1262
+ }
1261
1263
  };
1262
1264
  };
1263
1265
 
@@ -8392,7 +8394,7 @@ const jsenvPluginExplorer = ({
8392
8394
  meta
8393
8395
  }));
8394
8396
  let html = String(readFileSync(new URL(htmlClientFileUrl)));
8395
- html = html.replace("virtual:FAVICON_HREF", DATA_URL.stringify({
8397
+ html = html.replace("ignore:FAVICON_HREF", DATA_URL.stringify({
8396
8398
  contentType: CONTENT_TYPE.fromUrlExtension(faviconClientFileUrl),
8397
8399
  base64Flag: true,
8398
8400
  data: readFileSync(new URL(faviconClientFileUrl)).toString("base64")
@@ -12377,6 +12379,60 @@ ${globalName}.__v__ = function (specifier) {
12377
12379
  `;
12378
12380
  };
12379
12381
 
12382
+ // https://github.com/rollup/rollup/blob/5a5391971d695c808eed0c5d7d2c6ccb594fc689/src/Chunk.ts#L870
12383
+
12384
+ const createVersionGenerator = () => {
12385
+ const hash = createHash("sha256");
12386
+
12387
+ const augmentWithContent = ({
12388
+ content,
12389
+ contentType = "application/octet-stream",
12390
+ lineBreakNormalization = false
12391
+ }) => {
12392
+ hash.update(lineBreakNormalization && CONTENT_TYPE.isTextual(contentType) ? normalizeLineBreaks(content) : content);
12393
+ };
12394
+
12395
+ const augmentWithDependencyVersion = version => {
12396
+ hash.update(version);
12397
+ };
12398
+
12399
+ return {
12400
+ augmentWithContent,
12401
+ augmentWithDependencyVersion,
12402
+ generate: () => {
12403
+ return hash.digest("hex").slice(0, 8);
12404
+ }
12405
+ };
12406
+ };
12407
+
12408
+ const normalizeLineBreaks = stringOrBuffer => {
12409
+ if (typeof stringOrBuffer === "string") {
12410
+ const stringWithLinuxBreaks = stringOrBuffer.replace(/\r\n/g, "\n");
12411
+ return stringWithLinuxBreaks;
12412
+ }
12413
+
12414
+ return normalizeLineBreaksForBuffer(stringOrBuffer);
12415
+ }; // https://github.com/nodejs/help/issues/1738#issuecomment-458460503
12416
+
12417
+
12418
+ const normalizeLineBreaksForBuffer = buffer => {
12419
+ const int32Array = new Int32Array(buffer, 0, buffer.length);
12420
+ const int32ArrayWithLineBreaksNormalized = int32Array.filter((element, index, typedArray) => {
12421
+ if (element === 0x0d) {
12422
+ if (typedArray[index + 1] === 0x0a) {
12423
+ // Windows -> Unix
12424
+ return false;
12425
+ } // Mac OS -> Unix
12426
+
12427
+
12428
+ typedArray[index] = 0x0a;
12429
+ }
12430
+
12431
+ return true;
12432
+ });
12433
+ return Buffer.from(int32ArrayWithLineBreaksNormalized);
12434
+ };
12435
+
12380
12436
  const injectServiceWorkerUrls = async ({
12381
12437
  finalGraph,
12382
12438
  finalGraphKitchen,
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.86",
4
4
  "description": "Tool to develop, test and build js projects",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -73,7 +73,7 @@
73
73
  "@jsenv/integrity": "0.0.1",
74
74
  "@jsenv/log": "2.0.0",
75
75
  "@jsenv/node-esm-resolution": "0.1.0",
76
- "@jsenv/server": "12.7.0",
76
+ "@jsenv/server": "12.7.1",
77
77
  "@jsenv/uneval": "1.6.0",
78
78
  "@jsenv/sourcemap": "1.0.0",
79
79
  "@jsenv/utils": "2.0.0",
@@ -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
 
@@ -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,
@@ -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
  }
@@ -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(
@@ -43,11 +47,11 @@ export const jsenvPluginUrlAnalysis = ({ rootDirectoryUrl, include }) => {
43
47
  reference.shouldHandle = false
44
48
  return
45
49
  }
46
- if (reference.url.startsWith("data:")) {
47
- reference.shouldHandle = true
48
- return
49
- }
50
- if (reference.url.startsWith("file:")) {
50
+ const { protocol } = new URL(reference.url)
51
+ const protocolIsSupported = supportedProtocols.some(
52
+ (supportedProtocol) => protocol === supportedProtocol,
53
+ )
54
+ if (protocolIsSupported) {
51
55
  reference.shouldHandle = true
52
56
  return
53
57
  }