@jsenv/core 27.0.0-alpha.22 → 27.0.0-alpha.23
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 +3 -4
- package/src/dev/start_dev_server.js +2 -0
- package/src/execute/execute.js +8 -1
- package/src/execute/run.js +2 -2
- package/src/execute/runtimes/browsers/from_playwright.js +34 -1
- package/src/execute/runtimes/node/controllable_file.mjs +26 -10
- package/src/execute/runtimes/node/node_execution_performance.js +67 -0
- package/src/execute/runtimes/node/node_process.js +2 -5
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jsenv/core",
|
|
3
|
-
"version": "27.0.0-alpha.
|
|
3
|
+
"version": "27.0.0-alpha.23",
|
|
4
4
|
"description": "Tool to develop, test and build js projects",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -11,8 +11,7 @@
|
|
|
11
11
|
"node": ">=16.13.0"
|
|
12
12
|
},
|
|
13
13
|
"publishConfig": {
|
|
14
|
-
"access": "public"
|
|
15
|
-
"registry": "https://registry.npmjs.org"
|
|
14
|
+
"access": "public"
|
|
16
15
|
},
|
|
17
16
|
"type": "module",
|
|
18
17
|
"imports": {},
|
|
@@ -111,4 +110,4 @@
|
|
|
111
110
|
"redux": "4.1.2",
|
|
112
111
|
"rollup": "2.70.1"
|
|
113
112
|
}
|
|
114
|
-
}
|
|
113
|
+
}
|
|
@@ -32,6 +32,7 @@ export const startDevServer = async ({
|
|
|
32
32
|
injectedGlobals,
|
|
33
33
|
nodeEsmResolution,
|
|
34
34
|
fileSystemMagicResolution,
|
|
35
|
+
transpilation,
|
|
35
36
|
autoreload = true,
|
|
36
37
|
explorerGroups = {
|
|
37
38
|
source: {
|
|
@@ -95,6 +96,7 @@ export const startDevServer = async ({
|
|
|
95
96
|
injectedGlobals,
|
|
96
97
|
nodeEsmResolution,
|
|
97
98
|
fileSystemMagicResolution,
|
|
99
|
+
transpilation,
|
|
98
100
|
autoreload,
|
|
99
101
|
}),
|
|
100
102
|
jsenvPluginExplorer({
|
package/src/execute/execute.js
CHANGED
|
@@ -23,6 +23,7 @@ export const execute = async ({
|
|
|
23
23
|
collectConsole,
|
|
24
24
|
collectCoverage,
|
|
25
25
|
coverageTempDirectoryUrl,
|
|
26
|
+
collectPerformance = false,
|
|
26
27
|
runtime,
|
|
27
28
|
runtimeParams,
|
|
28
29
|
|
|
@@ -33,6 +34,7 @@ export const execute = async ({
|
|
|
33
34
|
fileSystemMagicResolution,
|
|
34
35
|
injectedGlobals,
|
|
35
36
|
transpilation,
|
|
37
|
+
htmlSupervisor = true,
|
|
36
38
|
|
|
37
39
|
port,
|
|
38
40
|
protocol,
|
|
@@ -75,10 +77,14 @@ export const execute = async ({
|
|
|
75
77
|
plugins: [
|
|
76
78
|
...plugins,
|
|
77
79
|
...getCorePlugins({
|
|
80
|
+
rootDirectoryUrl,
|
|
81
|
+
urlGraph,
|
|
78
82
|
scenario,
|
|
83
|
+
|
|
84
|
+
htmlSupervisor,
|
|
85
|
+
injectedGlobals,
|
|
79
86
|
nodeEsmResolution,
|
|
80
87
|
fileSystemMagicResolution,
|
|
81
|
-
injectedGlobals,
|
|
82
88
|
transpilation,
|
|
83
89
|
}),
|
|
84
90
|
],
|
|
@@ -120,6 +126,7 @@ export const execute = async ({
|
|
|
120
126
|
collectConsole,
|
|
121
127
|
collectCoverage,
|
|
122
128
|
coverageTempDirectoryUrl,
|
|
129
|
+
collectPerformance,
|
|
123
130
|
runtime,
|
|
124
131
|
runtimeParams,
|
|
125
132
|
})
|
package/src/execute/run.js
CHANGED
|
@@ -11,8 +11,7 @@ export const run = async ({
|
|
|
11
11
|
collectConsole = false,
|
|
12
12
|
collectCoverage = false,
|
|
13
13
|
coverageTempDirectoryUrl,
|
|
14
|
-
|
|
15
|
-
// collectPerformance = false,
|
|
14
|
+
collectPerformance = false,
|
|
16
15
|
|
|
17
16
|
runtime,
|
|
18
17
|
runtimeParams,
|
|
@@ -117,6 +116,7 @@ export const run = async ({
|
|
|
117
116
|
signal: runOperation.signal,
|
|
118
117
|
logger,
|
|
119
118
|
...runtimeParams,
|
|
119
|
+
collectPerformance,
|
|
120
120
|
keepRunning,
|
|
121
121
|
stopSignal,
|
|
122
122
|
onConsole: (log) => onConsoleRef.current(log),
|
|
@@ -35,7 +35,7 @@ export const createRuntimeFromPlaywright = ({
|
|
|
35
35
|
server,
|
|
36
36
|
|
|
37
37
|
// measurePerformance,
|
|
38
|
-
|
|
38
|
+
collectPerformance,
|
|
39
39
|
collectCoverage = false,
|
|
40
40
|
coverageForceIstanbul,
|
|
41
41
|
urlShouldBeCovered,
|
|
@@ -167,6 +167,39 @@ export const createRuntimeFromPlaywright = ({
|
|
|
167
167
|
return result
|
|
168
168
|
})
|
|
169
169
|
}
|
|
170
|
+
|
|
171
|
+
if (collectPerformance) {
|
|
172
|
+
resultTransformer = composeTransformer(
|
|
173
|
+
resultTransformer,
|
|
174
|
+
async (result) => {
|
|
175
|
+
const performance = await page.evaluate(
|
|
176
|
+
/* eslint-disable no-undef */
|
|
177
|
+
/* istanbul ignore next */
|
|
178
|
+
() => {
|
|
179
|
+
const { performance } = window
|
|
180
|
+
if (!performance) {
|
|
181
|
+
return null
|
|
182
|
+
}
|
|
183
|
+
const measures = {}
|
|
184
|
+
const measurePerfEntries = performance.getEntriesByType("measure")
|
|
185
|
+
measurePerfEntries.forEach((measurePerfEntry) => {
|
|
186
|
+
measures[measurePerfEntry.name] = measurePerfEntry.duration
|
|
187
|
+
})
|
|
188
|
+
return {
|
|
189
|
+
timeOrigin: performance.timeOrigin,
|
|
190
|
+
timing: performance.timing.toJSON(),
|
|
191
|
+
navigation: performance.navigation.toJSON(),
|
|
192
|
+
measures,
|
|
193
|
+
}
|
|
194
|
+
/* eslint-enable no-undef */
|
|
195
|
+
},
|
|
196
|
+
)
|
|
197
|
+
result.performance = performance
|
|
198
|
+
return result
|
|
199
|
+
},
|
|
200
|
+
)
|
|
201
|
+
}
|
|
202
|
+
|
|
170
203
|
const fileClientUrl = new URL(fileRelativeUrl, `${server.origin}/`).href
|
|
171
204
|
|
|
172
205
|
// https://github.com/GoogleChrome/puppeteer/blob/v1.4.0/docs/api.md#event-console
|
|
@@ -1,17 +1,33 @@
|
|
|
1
1
|
import v8 from "node:v8"
|
|
2
2
|
import { uneval } from "@jsenv/uneval"
|
|
3
|
+
import { startObservingPerformances } from "./node_execution_performance.js"
|
|
3
4
|
|
|
4
5
|
const ACTIONS_AVAILABLE = {
|
|
5
|
-
"execute-using-dynamic-import": async ({ fileUrl }) => {
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
6
|
+
"execute-using-dynamic-import": async ({ fileUrl, collectPerformance }) => {
|
|
7
|
+
const getNamespace = async () => {
|
|
8
|
+
const namespace = await import(fileUrl)
|
|
9
|
+
const namespaceResolved = {}
|
|
10
|
+
await Promise.all([
|
|
11
|
+
...Object.keys(namespace).map(async (key) => {
|
|
12
|
+
const value = await namespace[key]
|
|
13
|
+
namespaceResolved[key] = value
|
|
14
|
+
}),
|
|
15
|
+
])
|
|
16
|
+
return namespaceResolved
|
|
17
|
+
}
|
|
18
|
+
if (collectPerformance) {
|
|
19
|
+
const getPerformance = startObservingPerformances()
|
|
20
|
+
const namespace = await getNamespace()
|
|
21
|
+
const performance = await getPerformance()
|
|
22
|
+
return {
|
|
23
|
+
namespace,
|
|
24
|
+
performance,
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
const namespace = await getNamespace()
|
|
28
|
+
return {
|
|
29
|
+
namespace,
|
|
30
|
+
}
|
|
15
31
|
},
|
|
16
32
|
"execute-using-require": async ({ fileUrl }) => {
|
|
17
33
|
const { createRequire } = await import("module")
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { PerformanceObserver, performance } from "node:perf_hooks"
|
|
2
|
+
|
|
3
|
+
export const startObservingPerformances = () => {
|
|
4
|
+
const measureEntries = []
|
|
5
|
+
// https://nodejs.org/dist/latest-v16.x/docs/api/perf_hooks.html
|
|
6
|
+
const perfObserver = new PerformanceObserver(
|
|
7
|
+
(
|
|
8
|
+
// https://nodejs.org/dist/latest-v16.x/docs/api/perf_hooks.html#perf_hooks_class_performanceobserverentrylist
|
|
9
|
+
list,
|
|
10
|
+
) => {
|
|
11
|
+
const perfMeasureEntries = list.getEntriesByType("measure")
|
|
12
|
+
measureEntries.push(...perfMeasureEntries)
|
|
13
|
+
},
|
|
14
|
+
)
|
|
15
|
+
perfObserver.observe({
|
|
16
|
+
entryTypes: ["measure"],
|
|
17
|
+
})
|
|
18
|
+
return async () => {
|
|
19
|
+
// wait for node to call the performance observer
|
|
20
|
+
await new Promise((resolve) => {
|
|
21
|
+
setTimeout(resolve)
|
|
22
|
+
})
|
|
23
|
+
performance.clearMarks()
|
|
24
|
+
perfObserver.disconnect()
|
|
25
|
+
return {
|
|
26
|
+
...readNodePerformance(),
|
|
27
|
+
measures: measuresFromMeasureEntries(measureEntries),
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const readNodePerformance = () => {
|
|
33
|
+
const nodePerformance = {
|
|
34
|
+
nodeTiming: asPlainObject(performance.nodeTiming),
|
|
35
|
+
timeOrigin: performance.timeOrigin,
|
|
36
|
+
eventLoopUtilization: performance.eventLoopUtilization(),
|
|
37
|
+
}
|
|
38
|
+
return nodePerformance
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// remove getters that cannot be stringified
|
|
42
|
+
const asPlainObject = (objectWithGetters) => {
|
|
43
|
+
const objectWithoutGetters = {}
|
|
44
|
+
Object.keys(objectWithGetters).forEach((key) => {
|
|
45
|
+
objectWithoutGetters[key] = objectWithGetters[key]
|
|
46
|
+
})
|
|
47
|
+
return objectWithoutGetters
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const measuresFromMeasureEntries = (measureEntries) => {
|
|
51
|
+
const measures = {}
|
|
52
|
+
// Sort to ensure measures order is predictable
|
|
53
|
+
// It seems to be already predictable on Node 16+ but
|
|
54
|
+
// it's not the case on Node 14.
|
|
55
|
+
measureEntries.sort((a, b) => {
|
|
56
|
+
return a.startTime - b.startTime
|
|
57
|
+
})
|
|
58
|
+
measureEntries.forEach(
|
|
59
|
+
(
|
|
60
|
+
// https://nodejs.org/dist/latest-v16.x/docs/api/perf_hooks.html#perf_hooks_class_performanceentry
|
|
61
|
+
perfMeasureEntry,
|
|
62
|
+
) => {
|
|
63
|
+
measures[perfMeasureEntry.name] = perfMeasureEntry.duration
|
|
64
|
+
},
|
|
65
|
+
)
|
|
66
|
+
return measures
|
|
67
|
+
}
|
|
@@ -35,10 +35,9 @@ nodeProcess.run = async ({
|
|
|
35
35
|
stopSignal,
|
|
36
36
|
onConsole,
|
|
37
37
|
|
|
38
|
-
measurePerformance,
|
|
39
|
-
collectPerformance,
|
|
40
38
|
collectCoverage = false,
|
|
41
39
|
coverageForceIstanbul,
|
|
40
|
+
collectPerformance,
|
|
42
41
|
|
|
43
42
|
debugPort,
|
|
44
43
|
debugMode,
|
|
@@ -191,9 +190,7 @@ nodeProcess.run = async ({
|
|
|
191
190
|
actionType: "execute-using-dynamic-import",
|
|
192
191
|
actionParams: {
|
|
193
192
|
fileUrl: new URL(fileRelativeUrl, rootDirectoryUrl).href,
|
|
194
|
-
measurePerformance,
|
|
195
193
|
collectPerformance,
|
|
196
|
-
collectCoverage,
|
|
197
194
|
},
|
|
198
195
|
})
|
|
199
196
|
const winner = await winnerPromise
|
|
@@ -246,7 +243,7 @@ nodeProcess.run = async ({
|
|
|
246
243
|
}
|
|
247
244
|
return {
|
|
248
245
|
status: "completed",
|
|
249
|
-
|
|
246
|
+
...value,
|
|
250
247
|
}
|
|
251
248
|
}
|
|
252
249
|
|