@jsenv/core 27.0.0-alpha.58 → 27.0.0-alpha.60

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.58",
3
+ "version": "27.0.0-alpha.60",
4
4
  "description": "Tool to develop, test and build js projects",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -33,18 +33,18 @@
33
33
  ],
34
34
  "scripts": {
35
35
  "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",
36
+ "dev": "node ./scripts/dev/dev.mjs",
37
+ "build": "node ./scripts/build/build.mjs",
38
+ "test": "node ./scripts/test/test.mjs",
39
39
  "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",
40
+ "start_file_server": "node ./scripts/dev/start_file_server.mjs",
41
+ "workspace-versions": "node ./scripts/publish/workspace_versions.mjs",
42
+ "workspace-publish": "node ./scripts/publish/workspace_publish.mjs",
43
+ "performances": "node --expose-gc ./scripts/performance/generate_performance_report.mjs --log --once",
44
+ "file-size": "node ./scripts/file_size/file_size.mjs --log",
45
45
  "prettier": "prettier --write .",
46
46
  "playwright-install": "npx playwright install-deps && npx playwright install",
47
- "certificate-install": "node ./script/dev/install_certificate_authority.mjs",
47
+ "certificate-install": "node ./scripts/dev/install_certificate_authority.mjs",
48
48
  "test-with-coverage": "npm run test -- --coverage",
49
49
  "prepublishOnly": "npm run build"
50
50
  },
@@ -68,7 +68,7 @@
68
68
  "@jsenv/node-esm-resolution": "0.0.6",
69
69
  "@jsenv/server": "12.6.2",
70
70
  "@jsenv/uneval": "1.6.0",
71
- "@jsenv/utils": "1.7.4",
71
+ "@jsenv/utils": "1.7.5",
72
72
  "construct-style-sheets-polyfill": "3.1.0",
73
73
  "cssnano": "5.1.7",
74
74
  "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
  */
@@ -796,6 +796,12 @@ ${Object.keys(finalGraph.urlInfos).join("\n")}`,
796
796
  return runBuild({ signal: operation.signal, logLevel })
797
797
  }
798
798
 
799
+ let resolveFirstBuild
800
+ let rejectFirstBuild
801
+ const firstBuildPromise = new Promise((resolve, reject) => {
802
+ resolveFirstBuild = resolve
803
+ rejectFirstBuild = reject
804
+ })
799
805
  const watchLogger = createLogger({ logLevel: "info" })
800
806
  let buildAbortController
801
807
  let watchFilesTask
@@ -803,8 +809,12 @@ ${Object.keys(finalGraph.urlInfos).join("\n")}`,
803
809
  const buildTask = createTaskLog(watchLogger, "build")
804
810
  buildAbortController = new AbortController()
805
811
  try {
806
- await runBuild({ signal: buildAbortController.signal, logLevel: "warn" })
812
+ const result = await runBuild({
813
+ signal: buildAbortController.signal,
814
+ logLevel: "warn",
815
+ })
807
816
  buildTask.done()
817
+ resolveFirstBuild(result)
808
818
  watchFilesTask = createTaskLog(watchLogger, "watch files")
809
819
  } catch (e) {
810
820
  if (Abort.isAbortError(e)) {
@@ -815,6 +825,7 @@ ${Object.keys(finalGraph.urlInfos).join("\n")}`,
815
825
  watchFilesTask = createTaskLog(watchLogger, "watch files")
816
826
  } else {
817
827
  buildTask.fail()
828
+ rejectFirstBuild(e)
818
829
  throw e
819
830
  }
820
831
  }
@@ -853,6 +864,7 @@ ${Object.keys(finalGraph.urlInfos).join("\n")}`,
853
864
  operation.addAbortCallback(() => {
854
865
  stopWatchingClientFiles()
855
866
  })
867
+ await firstBuildPromise
856
868
  return stopWatchingClientFiles
857
869
  }
858
870
 
@@ -1,36 +1,35 @@
1
1
  import { ANSI } from "@jsenv/log"
2
2
 
3
3
  import { byteAsFileSize } from "@jsenv/utils/logs/size_log.js"
4
+ import { distributeNumbers } from "@jsenv/utils/logs/number_distribution.js"
4
5
 
5
6
  export const createUrlGraphSummary = (
6
7
  urlGraph,
7
8
  { title = "graph summary" } = {},
8
9
  ) => {
9
10
  const graphReport = createUrlGraphReport(urlGraph)
10
- const totalLabel = `Total`
11
11
  return `--- ${title} ---
12
12
  ${createRepartitionMessage(graphReport)}
13
- ${ANSI.color(totalLabel, ANSI.GREY)} ${
14
- graphReport.total.count
15
- } (${byteAsFileSize(graphReport.total.size)})
16
13
  --------------------`
17
14
  }
18
15
 
19
16
  const createUrlGraphReport = (urlGraph) => {
20
17
  const { urlInfos } = urlGraph
21
18
  const countGroups = {
19
+ sourcemaps: 0,
22
20
  html: 0,
23
21
  css: 0,
24
22
  js: 0,
23
+ json: 0,
25
24
  other: 0,
26
- sourcemaps: 0,
27
25
  total: 0,
28
26
  }
29
27
  const sizeGroups = {
28
+ sourcemaps: 0,
30
29
  html: 0,
31
30
  css: 0,
32
31
  js: 0,
33
- sourcemaps: 0,
32
+ json: 0,
34
33
  other: 0,
35
34
  total: 0,
36
35
  }
@@ -81,17 +80,67 @@ const createUrlGraphReport = (urlGraph) => {
81
80
  sizeGroups.js += urlContentSize
82
81
  return
83
82
  }
83
+ if (category === "json") {
84
+ countGroups.json++
85
+ sizeGroups.json += urlContentSize
86
+ return
87
+ }
84
88
  countGroups.other++
85
89
  sizeGroups.other += urlContentSize
86
90
  return
87
91
  })
92
+
93
+ const sizesToDistribute = {}
94
+ Object.keys(sizeGroups).forEach((groupName) => {
95
+ if (groupName !== "sourcemaps" && groupName !== "total") {
96
+ sizesToDistribute[groupName] = sizeGroups[groupName]
97
+ }
98
+ })
99
+ const ratios = distributeNumbers(sizesToDistribute)
100
+ const percentageGroups = {}
101
+ Object.keys(ratios).forEach((groupName) => {
102
+ percentageGroups[groupName] = parseFloat(ratios[groupName]) * 100
103
+ })
104
+
88
105
  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 },
106
+ // sourcemaps are special, there size are ignored
107
+ // so there is no "percentage" associated
108
+ sourcemaps: {
109
+ count: countGroups.sourcemaps,
110
+ size: sizeGroups.sourcemaps,
111
+ percentage: undefined,
112
+ },
113
+
114
+ html: {
115
+ count: countGroups.html,
116
+ size: sizeGroups.html,
117
+ percentage: percentageGroups.html,
118
+ },
119
+ css: {
120
+ count: countGroups.css,
121
+ size: sizeGroups.css,
122
+ percentage: percentageGroups.css,
123
+ },
124
+ js: {
125
+ count: countGroups.js,
126
+ size: sizeGroups.js,
127
+ percentage: percentageGroups.js,
128
+ },
129
+ json: {
130
+ count: countGroups.json,
131
+ size: sizeGroups.json,
132
+ percentage: percentageGroups.json,
133
+ },
134
+ other: {
135
+ count: countGroups.other,
136
+ size: sizeGroups.other,
137
+ percentage: percentageGroups.other,
138
+ },
139
+ total: {
140
+ count: countGroups.total,
141
+ size: sizeGroups.total,
142
+ percentage: 100,
143
+ },
95
144
  }
96
145
  }
97
146
 
@@ -108,32 +157,22 @@ const determineCategory = (urlInfo) => {
108
157
  if (urlInfo.type === "js_module" || urlInfo.type === "js_classic") {
109
158
  return "js"
110
159
  }
160
+ if (urlInfo.type === "json") {
161
+ return "json"
162
+ }
111
163
  return "other"
112
164
  }
113
165
 
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) {
166
+ const createRepartitionMessage = ({ html, css, js, json, other, total }) => {
167
+ const addPart = (name, { count, size, percentage }) => {
124
168
  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
- )})`,
169
+ `${ANSI.color(`${name}:`, ANSI.GREY)} ${count} (${byteAsFileSize(
170
+ size,
171
+ )} / ${percentage} %)`,
135
172
  )
136
173
  }
174
+
175
+ const parts = []
137
176
  // if (sourcemaps.count) {
138
177
  // parts.push(
139
178
  // `${ANSI.color(`sourcemaps:`, ANSI.GREY)} ${
@@ -141,13 +180,22 @@ const createRepartitionMessage = ({ html, css, js, other }) => {
141
180
  // } (${byteAsFileSize(sourcemaps.size)})`,
142
181
  // )
143
182
  // }
183
+ if (html.count) {
184
+ addPart("html ", html)
185
+ }
186
+ if (css.count) {
187
+ addPart("css ", css)
188
+ }
189
+ if (js.count) {
190
+ addPart("js ", js)
191
+ }
192
+ if (json.count) {
193
+ addPart("json ", json)
194
+ }
144
195
  if (other.count) {
145
- parts.push(
146
- `${ANSI.color(`other:`, ANSI.GREY)} ${other.count} (${byteAsFileSize(
147
- other.size,
148
- )})`,
149
- )
196
+ addPart("other", other)
150
197
  }
198
+ addPart("total", total)
151
199
  return `- ${parts.join(`
152
200
  - `)}`
153
201
  }