@jsenv/core 27.0.0-alpha.59 → 27.0.0-alpha.61

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,8 +1,13 @@
1
1
  {
2
2
  "name": "@jsenv/core",
3
- "version": "27.0.0-alpha.59",
3
+ "version": "27.0.0-alpha.61",
4
4
  "description": "Tool to develop, test and build js projects",
5
5
  "license": "MIT",
6
+ "author": {
7
+ "name": "dmail",
8
+ "email": "dmaillard06@gmail.com",
9
+ "url": "https://twitter.com/damienmaillard"
10
+ },
6
11
  "repository": {
7
12
  "type": "git",
8
13
  "url": "https://github.com/jsenv/jsenv-core"
@@ -33,18 +38,18 @@
33
38
  ],
34
39
  "scripts": {
35
40
  "eslint": "npx eslint . --ext=.js,.mjs,.cjs,.html",
36
- "dev": "node ./script/dev/dev.mjs",
37
- "build": "node ./script/build/build.mjs",
38
- "test": "node ./script/test/test.mjs",
41
+ "dev": "node ./scripts/dev/dev.mjs",
42
+ "build": "node ./scripts/build/build.mjs",
43
+ "test": "node ./scripts/test/test.mjs",
39
44
  "test-packages": "npm run test --workspaces --if-present",
40
- "start_file_server": "node ./script/dev/start_file_server.mjs",
41
- "workspace-versions": "node ./script/publish/workspace_versions.mjs",
42
- "workspace-publish": "node ./script/publish/workspace_publish.mjs",
43
- "performances": "node --expose-gc ./script/performance/generate_performance_report.mjs --log --once",
44
- "file-size": "node ./script/file_size/file_size.mjs --log",
45
+ "start_file_server": "node ./scripts/dev/start_file_server.mjs",
46
+ "workspace-versions": "node ./scripts/publish/workspace_versions.mjs",
47
+ "workspace-publish": "node ./scripts/publish/workspace_publish.mjs",
48
+ "performances": "node --expose-gc ./scripts/performance/generate_performance_report.mjs --log --once",
49
+ "file-size": "node ./scripts/file_size/file_size.mjs --log",
45
50
  "prettier": "prettier --write .",
46
51
  "playwright-install": "npx playwright install-deps && npx playwright install",
47
- "certificate-install": "node ./script/dev/install_certificate_authority.mjs",
52
+ "certificate-install": "node ./scripts/dev/install_certificate_authority.mjs",
48
53
  "test-with-coverage": "npm run test -- --coverage",
49
54
  "prepublishOnly": "npm run build"
50
55
  },
@@ -63,12 +68,12 @@
63
68
  "@jsenv/filesystem": "3.2.2",
64
69
  "@jsenv/importmap": "1.2.0",
65
70
  "@jsenv/integrity": "0.0.1",
66
- "@jsenv/log": "1.5.2",
71
+ "@jsenv/log": "1.6.0",
67
72
  "@jsenv/logger": "4.0.1",
68
73
  "@jsenv/node-esm-resolution": "0.0.6",
69
74
  "@jsenv/server": "12.6.2",
70
75
  "@jsenv/uneval": "1.6.0",
71
- "@jsenv/utils": "1.7.4",
76
+ "@jsenv/utils": "1.7.6",
72
77
  "construct-style-sheets-polyfill": "3.1.0",
73
78
  "cssnano": "5.1.7",
74
79
  "cssnano-preset-default": "5.2.7",
package/readme.md CHANGED
@@ -263,8 +263,8 @@ The presence of a jsenv configuration file is **optional**.
263
263
  /*
264
264
  * This file exports configuration reused by other files such as
265
265
  *
266
- * script/test/test.mjs
267
- * script/build/build.mjs
266
+ * scripts/test/test.mjs
267
+ * scripts/build/build.mjs
268
268
  *
269
269
  * Read more at https://github.com/jsenv/jsenv-core#configuration
270
270
  */
@@ -17,9 +17,9 @@ import {
17
17
  registerDirectoryLifecycle,
18
18
  } from "@jsenv/filesystem"
19
19
  import { Abort, raceProcessTeardownEvents } from "@jsenv/abort"
20
- import { createLogger } from "@jsenv/logger"
20
+ import { createLogger, loggerToLevels } from "@jsenv/logger"
21
21
 
22
- import { createTaskLog } from "@jsenv/utils/logs/task_log.js"
22
+ import { createTaskLog } from "@jsenv/log"
23
23
  import {
24
24
  injectQueryParams,
25
25
  setUrlFilename,
@@ -109,8 +109,9 @@ export const build = async ({
109
109
  cooldownBetweenFileEvents,
110
110
  watch = false,
111
111
 
112
- writeOnFileSystem = true,
113
112
  buildDirectoryClean = true,
113
+ writeOnFileSystem = true,
114
+ writeGeneratedFiles = false,
114
115
  baseUrl = "/",
115
116
  assetManifest = true,
116
117
  assetManifestFileRelativeUrl = "asset-manifest.json",
@@ -140,6 +141,7 @@ export const build = async ({
140
141
  const runBuild = async ({ signal, logLevel }) => {
141
142
  const logger = createLogger({ logLevel })
142
143
  const buildOperation = Abort.startOperation()
144
+ const infoLogsAreDisabled = !loggerToLevels(logger).info
143
145
  buildOperation.addAbortSignal(signal)
144
146
  const entryPointKeys = Object.keys(entryPoints)
145
147
  if (entryPointKeys.length === 1) {
@@ -151,7 +153,9 @@ build ${entryPointKeys.length} entry points`)
151
153
  }
152
154
 
153
155
  const rawGraph = createUrlGraph()
154
- const prebuildTask = createTaskLog(logger, "prebuild")
156
+ const prebuildTask = createTaskLog("prebuild", {
157
+ disabled: infoLogsAreDisabled,
158
+ })
155
159
  let urlCount = 0
156
160
  const rawGraphKitchen = createKitchen({
157
161
  signal,
@@ -161,6 +165,7 @@ build ${entryPointKeys.length} entry points`)
161
165
  scenario: "build",
162
166
  sourcemaps,
163
167
  runtimeCompat,
168
+ writeGeneratedFiles,
164
169
  plugins: [
165
170
  ...plugins,
166
171
  {
@@ -316,7 +321,9 @@ build ${entryPointKeys.length} entry points`)
316
321
  if (urlInfosToBundle.length === 0) {
317
322
  return
318
323
  }
319
- const bundleTask = createTaskLog(logger, `bundle "${type}"`)
324
+ const bundleTask = createTaskLog(`bundle "${type}"`, {
325
+ disabled: infoLogsAreDisabled,
326
+ })
320
327
  try {
321
328
  const bundlerGeneratedUrlInfos =
322
329
  await rawGraphKitchen.pluginController.callAsyncHook(
@@ -378,6 +385,7 @@ build ${entryPointKeys.length} entry points`)
378
385
  sourcemaps,
379
386
  sourcemapsRelativeSources: !versioning,
380
387
  runtimeCompat,
388
+ writeGeneratedFiles,
381
389
  plugins: [
382
390
  jsenvPluginUrlAnalysis(),
383
391
  jsenvPluginAsJsClassic({
@@ -636,7 +644,7 @@ build ${entryPointKeys.length} entry points`)
636
644
  },
637
645
  ],
638
646
  })
639
- const buildTask = createTaskLog(logger, "build")
647
+ const buildTask = createTaskLog("build", { disabled: infoLogsAreDisabled })
640
648
  const postBuildEntryUrls = []
641
649
  try {
642
650
  await loadUrlGraph({
@@ -670,6 +678,7 @@ ${Object.keys(finalGraph.urlInfos).join("\n")}`,
670
678
  await applyUrlVersioning({
671
679
  buildOperation,
672
680
  logger,
681
+ infoLogsAreDisabled,
673
682
  buildDirectoryUrl,
674
683
  rawUrls,
675
684
  buildUrls,
@@ -677,6 +686,7 @@ ${Object.keys(finalGraph.urlInfos).join("\n")}`,
677
686
  postBuildEntryUrls,
678
687
  sourcemaps,
679
688
  runtimeCompat,
689
+ writeGeneratedFiles,
680
690
  rawGraph,
681
691
  finalGraph,
682
692
  finalGraphKitchen,
@@ -802,11 +812,10 @@ ${Object.keys(finalGraph.urlInfos).join("\n")}`,
802
812
  resolveFirstBuild = resolve
803
813
  rejectFirstBuild = reject
804
814
  })
805
- const watchLogger = createLogger({ logLevel: "info" })
806
815
  let buildAbortController
807
816
  let watchFilesTask
808
817
  const startBuild = async () => {
809
- const buildTask = createTaskLog(watchLogger, "build")
818
+ const buildTask = createTaskLog("build")
810
819
  buildAbortController = new AbortController()
811
820
  try {
812
821
  const result = await runBuild({
@@ -815,14 +824,14 @@ ${Object.keys(finalGraph.urlInfos).join("\n")}`,
815
824
  })
816
825
  buildTask.done()
817
826
  resolveFirstBuild(result)
818
- watchFilesTask = createTaskLog(watchLogger, "watch files")
827
+ watchFilesTask = createTaskLog("watch files")
819
828
  } catch (e) {
820
829
  if (Abort.isAbortError(e)) {
821
830
  buildTask.fail(`build aborted`)
822
831
  } else if (e.code === "PARSE_ERROR") {
823
832
  buildTask.fail()
824
- watchLogger.error(e.stack)
825
- watchFilesTask = createTaskLog(watchLogger, "watch files")
833
+ console.error(e.stack)
834
+ watchFilesTask = createTaskLog("watch files")
826
835
  } else {
827
836
  buildTask.fail()
828
837
  rejectFirstBuild(e)
@@ -871,6 +880,7 @@ ${Object.keys(finalGraph.urlInfos).join("\n")}`,
871
880
  const applyUrlVersioning = async ({
872
881
  buildOperation,
873
882
  logger,
883
+ infoLogsAreDisabled,
874
884
  buildDirectoryUrl,
875
885
  rawUrls,
876
886
  buildUrls,
@@ -878,13 +888,16 @@ const applyUrlVersioning = async ({
878
888
  postBuildEntryUrls,
879
889
  sourcemaps,
880
890
  runtimeCompat,
891
+ writeGeneratedFiles,
881
892
  rawGraph,
882
893
  finalGraph,
883
894
  finalGraphKitchen,
884
895
  lineBreakNormalization,
885
896
  versioningMethod,
886
897
  }) => {
887
- const versioningTask = createTaskLog(logger, "inject version in urls")
898
+ const versioningTask = createTaskLog("inject version in urls", {
899
+ disabled: infoLogsAreDisabled,
900
+ })
888
901
  try {
889
902
  const urlsSorted = sortByDependencies(finalGraph.urlInfos)
890
903
  urlsSorted.forEach((url) => {
@@ -980,6 +993,7 @@ const applyUrlVersioning = async ({
980
993
  sourcemaps,
981
994
  sourcemapsRelativeSources: true,
982
995
  runtimeCompat,
996
+ writeGeneratedFiles,
983
997
  plugins: [
984
998
  jsenvPluginUrlAnalysis(),
985
999
  jsenvPluginInline({
@@ -25,10 +25,10 @@ import {
25
25
  assertAndNormalizeDirectoryUrl,
26
26
  registerDirectoryLifecycle,
27
27
  } from "@jsenv/filesystem"
28
- import { createLogger } from "@jsenv/logger"
28
+ import { createLogger, loggerToLevels } from "@jsenv/logger"
29
29
 
30
+ import { createTaskLog } from "@jsenv/log"
30
31
  import { initReloadableProcess } from "@jsenv/utils/process_reload/process_reload.js"
31
- import { createTaskLog } from "@jsenv/utils/logs/task_log.js"
32
32
 
33
33
  export const startBuildServer = async ({
34
34
  signal = new AbortController().signal,
@@ -114,7 +114,9 @@ export const startBuildServer = async ({
114
114
  }
115
115
  signal = reloadableProcess.signal
116
116
 
117
- const startServerTask = createTaskLog(logger, "start build server")
117
+ const startBuildServerTask = createTaskLog("start build server", {
118
+ disabled: !loggerToLevels(logger).info,
119
+ })
118
120
  const server = await startServer({
119
121
  signal,
120
122
  stopOnExit: false,
@@ -174,7 +176,7 @@ export const startBuildServer = async ({
174
176
  )
175
177
  },
176
178
  })
177
- startServerTask.done()
179
+ startBuildServerTask.done()
178
180
  logger.info(``)
179
181
  Object.keys(server.origins).forEach((key) => {
180
182
  logger.info(`- ${server.origins[key]}`)
@@ -2,10 +2,10 @@ import {
2
2
  assertAndNormalizeDirectoryUrl,
3
3
  registerDirectoryLifecycle,
4
4
  } from "@jsenv/filesystem"
5
- import { createLogger } from "@jsenv/logger"
5
+ import { createLogger, loggerToLevels } from "@jsenv/logger"
6
6
 
7
+ import { createTaskLog } from "@jsenv/log"
7
8
  import { initReloadableProcess } from "@jsenv/utils/process_reload/process_reload.js"
8
- import { createTaskLog } from "@jsenv/utils/logs/task_log.js"
9
9
  import { getCorePlugins } from "@jsenv/core/src/plugins/plugins.js"
10
10
  import { createUrlGraph } from "@jsenv/core/src/omega/url_graph.js"
11
11
  import { createKitchen } from "@jsenv/core/src/omega/kitchen.js"
@@ -61,6 +61,7 @@ export const startDevServer = async ({
61
61
  },
62
62
  },
63
63
  toolbar = false,
64
+ writeGeneratedFiles = true,
64
65
  }) => {
65
66
  const logger = createLogger({ logLevel })
66
67
  rootDirectoryUrl = assertAndNormalizeDirectoryUrl(rootDirectoryUrl)
@@ -118,7 +119,9 @@ export const startDevServer = async ({
118
119
  }
119
120
  }
120
121
 
121
- const startServerTask = createTaskLog(logger, "start server")
122
+ const startDevServerTask = createTaskLog("start dev server", {
123
+ disabled: !loggerToLevels(logger).info,
124
+ })
122
125
 
123
126
  const clientFileChangeCallbackList = []
124
127
  const clientFilesPruneCallbackList = []
@@ -154,6 +157,7 @@ export const startDevServer = async ({
154
157
  urlGraph,
155
158
  scenario: "dev",
156
159
  sourcemaps,
160
+ writeGeneratedFiles,
157
161
  plugins: [
158
162
  ...plugins,
159
163
  ...getCorePlugins({
@@ -190,7 +194,7 @@ export const startDevServer = async ({
190
194
  kitchen,
191
195
  scenario: "dev",
192
196
  })
193
- startServerTask.done()
197
+ startDevServerTask.done()
194
198
  logger.info(``)
195
199
  Object.keys(server.origins).forEach((key) => {
196
200
  logger.info(`- ${server.origins[key]}`)
@@ -35,6 +35,7 @@ export const execute = async ({
35
35
  injectedGlobals,
36
36
  transpilation,
37
37
  htmlSupervisor = true,
38
+ writeGeneratedFiles = false,
38
39
 
39
40
  port,
40
41
  protocol,
@@ -74,6 +75,7 @@ export const execute = async ({
74
75
  urlGraph,
75
76
  scenario,
76
77
  sourcemaps,
78
+ writeGeneratedFiles,
77
79
  plugins: [
78
80
  ...plugins,
79
81
  ...getCorePlugins({
@@ -47,7 +47,7 @@ export const createKitchen = ({
47
47
  }[scenario],
48
48
  sourcemapsRelativeSources,
49
49
  runtimeCompat = defaultRuntimeCompat,
50
- writeOnFileSystem = true,
50
+ writeGeneratedFiles,
51
51
  }) => {
52
52
  const pluginController = createPluginController({
53
53
  plugins,
@@ -613,7 +613,7 @@ export const createKitchen = ({
613
613
  outDirectoryUrl = outDirectoryUrl ? String(outDirectoryUrl) : undefined
614
614
 
615
615
  const writeFiles = ({ gotError }) => {
616
- if (!writeOnFileSystem || !outDirectoryUrl) {
616
+ if (!writeGeneratedFiles || !outDirectoryUrl) {
617
617
  return
618
618
  }
619
619
  const { generatedUrl } = urlInfo
@@ -83,7 +83,10 @@ export const createFileService = ({
83
83
  await kitchen.cook({
84
84
  reference: referenceFromGraph || reference,
85
85
  urlInfo,
86
- outDirectoryUrl: `${rootDirectoryUrl}.jsenv/${scenario}/${runtimeName}@${runtimeVersion}/`,
86
+ outDirectoryUrl:
87
+ scenario === "dev"
88
+ ? `${rootDirectoryUrl}.jsenv/${runtimeName}@${runtimeVersion}/`
89
+ : `${rootDirectoryUrl}.jsenv/${scenario}/${runtimeName}@${runtimeVersion}/`,
87
90
  clientRuntimeCompat: {
88
91
  [runtimeName]: runtimeVersion,
89
92
  },
@@ -1,36 +1,32 @@
1
- import { ANSI } from "@jsenv/log"
2
-
3
- import { byteAsFileSize } from "@jsenv/utils/logs/size_log.js"
1
+ import { ANSI, byteAsFileSize, distributePercentages } from "@jsenv/log"
4
2
 
5
3
  export const createUrlGraphSummary = (
6
4
  urlGraph,
7
5
  { title = "graph summary" } = {},
8
6
  ) => {
9
7
  const graphReport = createUrlGraphReport(urlGraph)
10
- const totalLabel = `Total`
11
8
  return `--- ${title} ---
12
9
  ${createRepartitionMessage(graphReport)}
13
- ${ANSI.color(totalLabel, ANSI.GREY)} ${
14
- graphReport.total.count
15
- } (${byteAsFileSize(graphReport.total.size)})
16
10
  --------------------`
17
11
  }
18
12
 
19
13
  const createUrlGraphReport = (urlGraph) => {
20
14
  const { urlInfos } = urlGraph
21
15
  const countGroups = {
16
+ sourcemaps: 0,
22
17
  html: 0,
23
18
  css: 0,
24
19
  js: 0,
20
+ json: 0,
25
21
  other: 0,
26
- sourcemaps: 0,
27
22
  total: 0,
28
23
  }
29
24
  const sizeGroups = {
25
+ sourcemaps: 0,
30
26
  html: 0,
31
27
  css: 0,
32
28
  js: 0,
33
- sourcemaps: 0,
29
+ json: 0,
34
30
  other: 0,
35
31
  total: 0,
36
32
  }
@@ -81,17 +77,63 @@ const createUrlGraphReport = (urlGraph) => {
81
77
  sizeGroups.js += urlContentSize
82
78
  return
83
79
  }
80
+ if (category === "json") {
81
+ countGroups.json++
82
+ sizeGroups.json += urlContentSize
83
+ return
84
+ }
84
85
  countGroups.other++
85
86
  sizeGroups.other += urlContentSize
86
87
  return
87
88
  })
89
+
90
+ const sizesToDistribute = {}
91
+ Object.keys(sizeGroups).forEach((groupName) => {
92
+ if (groupName !== "sourcemaps" && groupName !== "total") {
93
+ sizesToDistribute[groupName] = sizeGroups[groupName]
94
+ }
95
+ })
96
+ const percentageGroups = distributePercentages(sizesToDistribute)
97
+
88
98
  return {
89
- html: { count: countGroups.html, size: sizeGroups.html },
90
- css: { count: countGroups.css, size: sizeGroups.css },
91
- js: { count: countGroups.js, size: sizeGroups.js },
92
- sourcemaps: { count: countGroups.sourcemaps, size: sizeGroups.sourcemaps },
93
- other: { count: countGroups.other, size: sizeGroups.other },
94
- total: { count: countGroups.total, size: sizeGroups.total },
99
+ // sourcemaps are special, there size are ignored
100
+ // so there is no "percentage" associated
101
+ sourcemaps: {
102
+ count: countGroups.sourcemaps,
103
+ size: sizeGroups.sourcemaps,
104
+ percentage: undefined,
105
+ },
106
+
107
+ html: {
108
+ count: countGroups.html,
109
+ size: sizeGroups.html,
110
+ percentage: percentageGroups.html,
111
+ },
112
+ css: {
113
+ count: countGroups.css,
114
+ size: sizeGroups.css,
115
+ percentage: percentageGroups.css,
116
+ },
117
+ js: {
118
+ count: countGroups.js,
119
+ size: sizeGroups.js,
120
+ percentage: percentageGroups.js,
121
+ },
122
+ json: {
123
+ count: countGroups.json,
124
+ size: sizeGroups.json,
125
+ percentage: percentageGroups.json,
126
+ },
127
+ other: {
128
+ count: countGroups.other,
129
+ size: sizeGroups.other,
130
+ percentage: percentageGroups.other,
131
+ },
132
+ total: {
133
+ count: countGroups.total,
134
+ size: sizeGroups.total,
135
+ percentage: 100,
136
+ },
95
137
  }
96
138
  }
97
139
 
@@ -108,32 +150,22 @@ const determineCategory = (urlInfo) => {
108
150
  if (urlInfo.type === "js_module" || urlInfo.type === "js_classic") {
109
151
  return "js"
110
152
  }
153
+ if (urlInfo.type === "json") {
154
+ return "json"
155
+ }
111
156
  return "other"
112
157
  }
113
158
 
114
- const createRepartitionMessage = ({ html, css, js, other }) => {
115
- const parts = []
116
- if (html.count) {
117
- parts.push(
118
- `${ANSI.color(`html:`, ANSI.GREY)} ${html.count} (${byteAsFileSize(
119
- html.size,
120
- )})`,
121
- )
122
- }
123
- if (css.count) {
159
+ const createRepartitionMessage = ({ html, css, js, json, other, total }) => {
160
+ const addPart = (name, { count, size, percentage }) => {
124
161
  parts.push(
125
- `${ANSI.color(`css:`, ANSI.GREY)} ${css.count} (${byteAsFileSize(
126
- css.size,
127
- )})`,
128
- )
129
- }
130
- if (js.count) {
131
- parts.push(
132
- `${ANSI.color(`js:`, ANSI.GREY)} ${js.count} (${byteAsFileSize(
133
- js.size,
134
- )})`,
162
+ `${ANSI.color(`${name}:`, ANSI.GREY)} ${count} (${byteAsFileSize(
163
+ size,
164
+ )} / ${percentage} %)`,
135
165
  )
136
166
  }
167
+
168
+ const parts = []
137
169
  // if (sourcemaps.count) {
138
170
  // parts.push(
139
171
  // `${ANSI.color(`sourcemaps:`, ANSI.GREY)} ${
@@ -141,13 +173,22 @@ const createRepartitionMessage = ({ html, css, js, other }) => {
141
173
  // } (${byteAsFileSize(sourcemaps.size)})`,
142
174
  // )
143
175
  // }
176
+ if (html.count) {
177
+ addPart("html ", html)
178
+ }
179
+ if (css.count) {
180
+ addPart("css ", css)
181
+ }
182
+ if (js.count) {
183
+ addPart("js ", js)
184
+ }
185
+ if (json.count) {
186
+ addPart("json ", json)
187
+ }
144
188
  if (other.count) {
145
- parts.push(
146
- `${ANSI.color(`other:`, ANSI.GREY)} ${other.count} (${byteAsFileSize(
147
- other.size,
148
- )})`,
149
- )
189
+ addPart("other", other)
150
190
  }
191
+ addPart("total", total)
151
192
  return `- ${parts.join(`
152
193
  - `)}`
153
194
  }
@@ -26,13 +26,16 @@ const dequeue = async () => {
26
26
  const callbacks = pendingCallbacks.slice()
27
27
  pendingCallbacks = []
28
28
  running = true
29
- await callbacks.reduce(async (previous, callback) => {
30
- await previous
31
- await callback()
32
- }, Promise.resolve())
33
- running = false
34
- if (pendingCallbacks.length) {
35
- dequeue()
29
+ try {
30
+ await callbacks.reduce(async (previous, callback) => {
31
+ await previous
32
+ await callback()
33
+ }, Promise.resolve())
34
+ } finally {
35
+ running = false
36
+ if (pendingCallbacks.length) {
37
+ dequeue()
38
+ }
36
39
  }
37
40
  }
38
41
 
@@ -113,7 +113,7 @@ export const jsenvPluginDevSSEServer = ({
113
113
  return iterate(firstUrlInfo, trace)
114
114
  }
115
115
  clientFileChangeCallbackList.push(({ url, event }) => {
116
- const urlInfo = urlGraph.urlInfos[url]
116
+ const urlInfo = urlGraph.getUrlInfo(url)
117
117
  // file not part of dependency graph
118
118
  if (!urlInfo) {
119
119
  return
@@ -6,7 +6,7 @@ export const jsenvPluginCacheControl = () => {
6
6
  test: true,
7
7
  },
8
8
  augmentResponse: ({ reference }, context) => {
9
- if (context.scenario === "dev") {
9
+ if (context.scenario === "test") {
10
10
  // During dev, all files are put into browser cache for 1 hour because:
11
11
  // 1: Browser cache is a temporary directory created by playwright
12
12
  // 2: We assume source files won't be modified while tests are running
@@ -103,7 +103,7 @@ export const collectHotDataFromHtmlAst = (htmlAst) => {
103
103
  }
104
104
  iterate(htmlAst, {})
105
105
 
106
- return { hotReferences }
106
+ return hotReferences
107
107
  }
108
108
 
109
109
  const nodeNamesWithHref = ["link", "a", "image", "use"]
@@ -125,7 +125,7 @@ const getNodeContext = (node) => {
125
125
 
126
126
  const htmlNodeCanHotReload = (node) => {
127
127
  if (node.nodeName === "link") {
128
- const { isStylesheet, isRessourceHint } = parseLinkNode(node)
128
+ const { isStylesheet, isRessourceHint, rel } = parseLinkNode(node)
129
129
  if (isStylesheet) {
130
130
  // stylesheets can be hot replaced by default
131
131
  return true
@@ -135,6 +135,9 @@ const htmlNodeCanHotReload = (node) => {
135
135
  // but we won't do anything (if the ressource is deleted we should?)
136
136
  return true
137
137
  }
138
+ if (rel === "icon") {
139
+ return true
140
+ }
138
141
  return false
139
142
  }
140
143
  return [
@@ -25,7 +25,7 @@ export const jsenvPluginImportMetaHot = ({ rootDirectoryUrl }) => {
25
25
  return
26
26
  }
27
27
  const htmlAst = parseHtmlString(htmlUrlInfo.content)
28
- const { hotReferences } = collectHotDataFromHtmlAst(htmlAst)
28
+ const hotReferences = collectHotDataFromHtmlAst(htmlAst)
29
29
  htmlUrlInfo.data.hotDecline = false
30
30
  htmlUrlInfo.data.hotAcceptSelf = false
31
31
  htmlUrlInfo.data.hotAcceptDependencies = hotReferences.map(
@@ -65,6 +65,7 @@ export const executePlan = async (
65
65
  nodeEsmResolution,
66
66
  fileSystemMagicResolution,
67
67
  transpilation,
68
+ writeGeneratedFiles,
68
69
 
69
70
  protocol,
70
71
  privateKey,
@@ -134,7 +135,7 @@ export const executePlan = async (
134
135
  urlGraph,
135
136
  scenario,
136
137
  sourcemaps,
137
- writeOnFileSystem: false,
138
+ writeGeneratedFiles,
138
139
  plugins: [
139
140
  ...plugins,
140
141
  ...getCorePlugins({
@@ -87,6 +87,7 @@ export const executeTestPlan = async ({
87
87
  injectedGlobals,
88
88
  nodeEsmResolution,
89
89
  fileSystemMagicResolution,
90
+ writeGeneratedFiles = false,
90
91
 
91
92
  protocol,
92
93
  privateKey,
@@ -173,6 +174,7 @@ export const executeTestPlan = async ({
173
174
  injectedGlobals,
174
175
  nodeEsmResolution,
175
176
  fileSystemMagicResolution,
177
+ writeGeneratedFiles,
176
178
 
177
179
  protocol,
178
180
  privateKey,
@@ -1,7 +1,4 @@
1
- import { ANSI, UNICODE } from "@jsenv/log"
2
-
3
- import { msAsDuration } from "@jsenv/utils/logs/duration_log.js"
4
- import { byteAsMemoryUsage } from "@jsenv/utils/logs/size_log.js"
1
+ import { ANSI, UNICODE, msAsDuration, byteAsMemoryUsage } from "@jsenv/log"
5
2
 
6
3
  import { EXECUTION_COLORS } from "./execution_colors.js"
7
4