@jsenv/core 24.5.8 → 24.6.1

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": "24.5.8",
3
+ "version": "24.6.1",
4
4
  "description": "Tool to develop, test and build js projects",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -11,7 +11,8 @@
11
11
  "node": ">=14.9.0"
12
12
  },
13
13
  "publishConfig": {
14
- "access": "public"
14
+ "access": "public",
15
+ "registry": "https://registry.npmjs.org"
15
16
  },
16
17
  "type": "module",
17
18
  "exports": {
@@ -135,4 +136,4 @@
135
136
  "redux": "4.1.2",
136
137
  "rollup-plugin-import-assert": "1.1.1"
137
138
  }
138
- }
139
+ }
@@ -159,9 +159,8 @@ export const buildProject = async ({
159
159
  jsenvDirectoryRelativeUrl,
160
160
  jsenvDirectoryClean,
161
161
  // build compiled files are written into a different directory
162
- // than exploring-server. This is because here we compile for rollup
162
+ // than dev-server. This is because here we compile for rollup
163
163
  // that is expecting esmodule format, not systemjs
164
- // + some more differences like import.meta.dev
165
164
  outDirectoryName: "build",
166
165
  importDefaultExtension,
167
166
  moduleOutFormat: "esmodule", // rollup or jsenv rollup plugin will transform into the right format
@@ -32,20 +32,23 @@ export const executeTestPlan = async ({
32
32
  importDefaultExtension,
33
33
 
34
34
  testPlan,
35
- defaultMsAllocatedPerExecution,
36
- cooldownBetweenExecutions,
37
35
 
38
- maxExecutionsInParallel,
36
+ logMemoryHeapUsage = false,
39
37
  completedExecutionLogAbbreviation = false,
40
38
  completedExecutionLogMerging = false,
41
39
  logSummary = true,
42
40
  updateProcessExitCode = true,
41
+
42
+ maxExecutionsInParallel = 1,
43
+ defaultMsAllocatedPerExecution = 30000,
43
44
  // stopAfterExecute: true to ensure runtime is stopped once executed
44
45
  // because we have what we wants: execution is completed and
45
46
  // we have associated coverage and capturedConsole
46
47
  // passsing false means all node process and browsers launched stays opened
47
48
  // (can eventually be used for debug)
48
49
  stopAfterExecute = true,
50
+ cooldownBetweenExecutions = 0,
51
+ gcBetweenExecutions = logMemoryHeapUsage,
49
52
 
50
53
  coverage = process.argv.includes("--cover") ||
51
54
  process.argv.includes("--coverage"),
@@ -148,13 +151,16 @@ export const executeTestPlan = async ({
148
151
  importResolutionMethod,
149
152
  importDefaultExtension,
150
153
 
154
+ logMemoryHeapUsage,
155
+ completedExecutionLogMerging,
156
+ completedExecutionLogAbbreviation,
157
+ logSummary,
158
+
151
159
  defaultMsAllocatedPerExecution,
152
160
  maxExecutionsInParallel,
153
161
  stopAfterExecute,
154
162
  cooldownBetweenExecutions,
155
- completedExecutionLogMerging,
156
- completedExecutionLogAbbreviation,
157
- logSummary,
163
+ gcBetweenExecutions,
158
164
 
159
165
  coverage,
160
166
  coverageConfig,
@@ -52,6 +52,9 @@ export const jsenvTransform = async ({
52
52
  parserOpts: {
53
53
  allowAwaitOutsideFunction: allowTopLevelAwait,
54
54
  },
55
+ generatorOpts: {
56
+ compact: false,
57
+ },
55
58
  }
56
59
 
57
60
  const babelHelperName = filePathToBabelHelperName(inputPath)
@@ -1,16 +1,17 @@
1
1
  import { ANSI } from "@jsenv/log"
2
2
 
3
3
  import { msAsDuration } from "../logs/msAsDuration.js"
4
+ import { formatByte } from "../logs/byte.js"
4
5
  import { EXECUTION_COLORS } from "./execution_colors.js"
5
6
 
6
7
  export const createSummaryLog = (
7
8
  summary,
8
9
  ) => `-------------- summary -----------------
9
- ${createSummaryMessage(summary)}
10
+ ${createAllExecutionsSummary(summary)}
10
11
  total duration: ${msAsDuration(summary.duration)}
11
12
  ----------------------------------------`
12
13
 
13
- const createSummaryMessage = ({
14
+ const createAllExecutionsSummary = ({
14
15
  executionCount,
15
16
  abortedCount,
16
17
  timedoutCount,
@@ -24,7 +25,7 @@ const createSummaryMessage = ({
24
25
 
25
26
  const executionLabel =
26
27
  executionCount === 1 ? `1 execution` : `${executionCount} executions`
27
- return `${executionLabel}: ${createSummaryDetails({
28
+ return `${executionLabel}: ${createStatusSummary({
28
29
  executionCount,
29
30
  abortedCount,
30
31
  timedoutCount,
@@ -34,7 +35,32 @@ const createSummaryMessage = ({
34
35
  })}`
35
36
  }
36
37
 
37
- export const createSummaryDetails = ({
38
+ export const createIntermediateSummary = ({
39
+ executionCount,
40
+ abortedCount,
41
+ timedoutCount,
42
+ erroredCount,
43
+ completedCount,
44
+ cancelledCount,
45
+ memoryHeap,
46
+ }) => {
47
+ let intermediateSummary = createStatusSummary({
48
+ executionCount,
49
+ abortedCount,
50
+ timedoutCount,
51
+ erroredCount,
52
+ completedCount,
53
+ cancelledCount,
54
+ })
55
+
56
+ if (memoryHeap) {
57
+ intermediateSummary += ` / memory heap: ${formatByte(memoryHeap)}`
58
+ }
59
+
60
+ return intermediateSummary
61
+ }
62
+
63
+ const createStatusSummary = ({
38
64
  executionCount,
39
65
  abortedCount,
40
66
  timedoutCount,
@@ -1,4 +1,5 @@
1
1
  import { existsSync } from "node:fs"
2
+ import { memoryUsage } from "node:process"
2
3
  import wrapAnsi from "wrap-ansi"
3
4
  import cuid from "cuid"
4
5
  import { loggerToLevels } from "@jsenv/logger"
@@ -17,6 +18,7 @@ import { launchAndExecute } from "../executing/launchAndExecute.js"
17
18
  import { reportToCoverage } from "./coverage/reportToCoverage.js"
18
19
  import { formatExecuting, formatExecutionResult } from "./executionLogs.js"
19
20
  import { createSummaryLog } from "./createSummaryLog.js"
21
+ import { ensureGlobalGc } from "./gc.js"
20
22
 
21
23
  export const executeConcurrently = async (
22
24
  executionSteps,
@@ -28,16 +30,19 @@ export const executeConcurrently = async (
28
30
 
29
31
  projectDirectoryUrl,
30
32
  compileServer,
31
-
32
33
  babelPluginMap,
33
34
 
34
- defaultMsAllocatedPerExecution = 30000,
35
- cooldownBetweenExecutions = 0,
36
- maxExecutionsInParallel = 1,
37
- stopAfterExecute,
35
+ logSummary,
36
+ logMemoryHeapUsage,
38
37
  completedExecutionLogMerging,
39
38
  completedExecutionLogAbbreviation,
40
39
 
40
+ maxExecutionsInParallel,
41
+ defaultMsAllocatedPerExecution,
42
+ stopAfterExecute,
43
+ cooldownBetweenExecutions,
44
+ gcBetweenExecutions,
45
+
41
46
  coverage,
42
47
  coverageConfig,
43
48
  coverageIncludeMissing,
@@ -48,8 +53,6 @@ export const executeConcurrently = async (
48
53
 
49
54
  beforeExecutionCallback = () => {},
50
55
  afterExecutionCallback = () => {},
51
-
52
- logSummary,
53
56
  },
54
57
  ) => {
55
58
  if (completedExecutionLogMerging && !process.stdout.isTTY) {
@@ -62,12 +65,15 @@ export const executeConcurrently = async (
62
65
  const executionSpinner = executionLogsEnabled && process.stdout.isTTY
63
66
 
64
67
  const startMs = Date.now()
65
-
66
68
  const report = {}
67
69
  const executionCount = executionSteps.length
68
70
 
69
71
  let transformReturnValue = (value) => value
70
72
 
73
+ if (gcBetweenExecutions) {
74
+ ensureGlobalGc()
75
+ }
76
+
71
77
  const coverageTempDirectoryUrl = resolveUrl(
72
78
  coverageTempDirectoryRelativeUrl,
73
79
  projectDirectoryUrl,
@@ -185,6 +191,9 @@ export const executeConcurrently = async (
185
191
  timedoutCount,
186
192
  erroredCount,
187
193
  completedCount,
194
+ ...(logMemoryHeapUsage
195
+ ? { memoryHeap: memoryUsage().heapUsed }
196
+ : {}),
188
197
  }),
189
198
  })
190
199
  }
@@ -249,6 +258,10 @@ export const executeConcurrently = async (
249
258
  completedCount++
250
259
  }
251
260
 
261
+ if (gcBetweenExecutions) {
262
+ global.gc()
263
+ }
264
+
252
265
  if (executionLogsEnabled) {
253
266
  let log = formatExecutionResult(afterExecutionInfo, {
254
267
  completedExecutionLogAbbreviation,
@@ -257,6 +270,7 @@ export const executeConcurrently = async (
257
270
  timedoutCount,
258
271
  erroredCount,
259
272
  completedCount,
273
+ ...(logMemoryHeapUsage ? { memoryHeap: memoryUsage().heapUsed } : {}),
260
274
  })
261
275
  log = `${log}
262
276
 
@@ -24,13 +24,16 @@ export const executePlan = async (
24
24
  importResolutionMethod,
25
25
  importDefaultExtension,
26
26
 
27
+ logSummary,
28
+ logMemoryHeapUsage,
29
+ completedExecutionLogMerging,
30
+ completedExecutionLogAbbreviation,
31
+
27
32
  defaultMsAllocatedPerExecution,
28
33
  maxExecutionsInParallel,
34
+ gcBetweenExecutions,
29
35
  stopAfterExecute,
30
36
  cooldownBetweenExecutions,
31
- completedExecutionLogMerging,
32
- completedExecutionLogAbbreviation,
33
- logSummary,
34
37
 
35
38
  coverage,
36
39
  coverageConfig,
@@ -169,13 +172,16 @@ export const executePlan = async (
169
172
 
170
173
  babelPluginMap: compileServer.babelPluginMap,
171
174
 
175
+ logSummary,
176
+ logMemoryHeapUsage,
177
+ completedExecutionLogMerging,
178
+ completedExecutionLogAbbreviation,
179
+
172
180
  defaultMsAllocatedPerExecution,
173
181
  maxExecutionsInParallel,
174
182
  stopAfterExecute,
183
+ gcBetweenExecutions,
175
184
  cooldownBetweenExecutions,
176
- completedExecutionLogMerging,
177
- completedExecutionLogAbbreviation,
178
- logSummary,
179
185
 
180
186
  coverage,
181
187
  coverageConfig,
@@ -2,11 +2,18 @@ import { ANSI, UNICODE } from "@jsenv/log"
2
2
 
3
3
  import { msAsDuration } from "../logs/msAsDuration.js"
4
4
  import { EXECUTION_COLORS } from "./execution_colors.js"
5
- import { createSummaryDetails } from "./createSummaryLog.js"
5
+ import { createIntermediateSummary } from "./createSummaryLog.js"
6
6
 
7
7
  export const formatExecuting = (
8
8
  { executionIndex },
9
- { executionCount, abortedCount, timedoutCount, erroredCount, completedCount },
9
+ {
10
+ executionCount,
11
+ abortedCount,
12
+ timedoutCount,
13
+ erroredCount,
14
+ completedCount,
15
+ memoryHeap,
16
+ },
10
17
  ) => {
11
18
  const executionNumber = executionIndex + 1
12
19
  const description = ANSI.color(
@@ -16,12 +23,13 @@ export const formatExecuting = (
16
23
  const summary =
17
24
  executionIndex === 0
18
25
  ? ""
19
- : `(${createSummaryDetails({
26
+ : `(${createIntermediateSummary({
20
27
  executionCount: executionIndex,
21
28
  abortedCount,
22
29
  timedoutCount,
23
30
  erroredCount,
24
31
  completedCount,
32
+ memoryHeap,
25
33
  })})`
26
34
 
27
35
  return formatExecution({
@@ -45,6 +53,7 @@ export const formatExecutionResult = (
45
53
  timedoutCount,
46
54
  erroredCount,
47
55
  completedCount,
56
+ memoryHeap,
48
57
  },
49
58
  ) => {
50
59
  const executionNumber = executionIndex + 1
@@ -57,12 +66,13 @@ export const formatExecutionResult = (
57
66
  allocatedMs,
58
67
  })
59
68
 
60
- const summary = `(${createSummaryDetails({
69
+ const summary = `(${createIntermediateSummary({
61
70
  executionCount: executionNumber,
62
71
  abortedCount,
63
72
  timedoutCount,
64
73
  erroredCount,
65
74
  completedCount,
75
+ memoryHeap,
66
76
  })})`
67
77
 
68
78
  if (completedExecutionLogAbbreviation && status === "completed") {
@@ -0,0 +1,9 @@
1
+ import v8 from "node:v8"
2
+ import { runInNewContext } from "node:vm"
3
+
4
+ export const ensureGlobalGc = () => {
5
+ if (!global.gc) {
6
+ v8.setFlagsFromString("--expose_gc")
7
+ global.gc = runInNewContext("gc")
8
+ }
9
+ }
@@ -0,0 +1,10 @@
1
+ import { createRequire } from "module"
2
+
3
+ const require = createRequire(import.meta.url)
4
+
5
+ // https://github.com/visionmedia/bytes.js/
6
+ const bytes = require("bytes")
7
+
8
+ export const formatByte = (metricValue) => {
9
+ return bytes(metricValue, { decimalPlaces: 2, unitSeparator: " " })
10
+ }