@jsenv/core 27.3.0 → 27.3.3
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/dist/controllable_child_process.mjs +1 -0
- package/dist/controllable_worker_thread.mjs +1 -0
- package/dist/js/execute_using_dynamic_import.js +5 -3
- package/dist/main.js +165 -133
- package/package.json +2 -2
- package/src/build/build.js +2 -2
- package/src/build/graph_utils.js +14 -11
- package/src/execute/run.js +27 -28
- package/src/execute/runtimes/browsers/from_playwright.js +90 -92
- package/src/execute/runtimes/node/execute_using_dynamic_import.js +8 -2
- package/src/execute/runtimes/node/node_child_process.js +2 -0
- package/src/execute/runtimes/node/node_worker_thread.js +13 -2
- package/src/omega/url_graph/url_graph_report.js +2 -4
- package/src/omega/url_graph.js +23 -16
- package/src/plugins/autoreload/dev_sse/jsenv_plugin_dev_sse_server.js +1 -2
- package/src/plugins/bundling/js_module/bundle_js_module.js +0 -1
- package/src/plugins/node_esm_resolution/jsenv_plugin_node_esm_resolution.js +1 -2
- package/src/plugins/url_analysis/js/js_urls.js +0 -9
- package/src/test/coverage/report_to_coverage.js +16 -11
- package/src/test/execute_plan.js +3 -2
- package/src/test/execute_test_plan.js +3 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jsenv/core",
|
|
3
|
-
"version": "27.3.
|
|
3
|
+
"version": "27.3.3",
|
|
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": "3.1.0",
|
|
75
75
|
"@jsenv/node-esm-resolution": "0.1.0",
|
|
76
|
-
"@jsenv/server": "12.
|
|
76
|
+
"@jsenv/server": "12.8.0",
|
|
77
77
|
"@jsenv/sourcemap": "1.0.1",
|
|
78
78
|
"@jsenv/uneval": "1.6.0",
|
|
79
79
|
"@jsenv/url-meta": "7.0.0",
|
package/src/build/build.js
CHANGED
|
@@ -738,7 +738,7 @@ build ${entryPointKeys.length} entry points`)
|
|
|
738
738
|
|
|
739
739
|
logger.debug(
|
|
740
740
|
`graph urls pre-versioning:
|
|
741
|
-
${
|
|
741
|
+
${Array.from(finalGraph.urlInfoMap.keys()).join("\n")}`,
|
|
742
742
|
)
|
|
743
743
|
if (versioning) {
|
|
744
744
|
await applyUrlVersioning({
|
|
@@ -973,7 +973,7 @@ const applyUrlVersioning = async ({
|
|
|
973
973
|
disabled: infoLogsAreDisabled,
|
|
974
974
|
})
|
|
975
975
|
try {
|
|
976
|
-
const urlsSorted = sortByDependencies(finalGraph.
|
|
976
|
+
const urlsSorted = sortByDependencies(finalGraph.toObject())
|
|
977
977
|
urlsSorted.forEach((url) => {
|
|
978
978
|
if (url.startsWith("data:")) {
|
|
979
979
|
return
|
package/src/build/graph_utils.js
CHANGED
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
export const GRAPH = {
|
|
2
2
|
map: (graph, callback) => {
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
const array = []
|
|
4
|
+
graph.urlInfoMap.forEach((urlInfo) => {
|
|
5
|
+
array.push(callback(urlInfo))
|
|
5
6
|
})
|
|
7
|
+
return array
|
|
6
8
|
},
|
|
7
9
|
|
|
8
10
|
forEach: (graph, callback) => {
|
|
9
|
-
|
|
10
|
-
callback(graph.urlInfos[url], url)
|
|
11
|
-
})
|
|
11
|
+
graph.urlInfoMap.forEach(callback)
|
|
12
12
|
},
|
|
13
13
|
|
|
14
14
|
filter: (graph, callback) => {
|
|
15
15
|
const urlInfos = []
|
|
16
|
-
|
|
17
|
-
const urlInfo = graph.urlInfos[url]
|
|
16
|
+
graph.urlInfoMap.forEach((urlInfo) => {
|
|
18
17
|
if (callback(urlInfo)) {
|
|
19
18
|
urlInfos.push(urlInfo)
|
|
20
19
|
}
|
|
@@ -23,9 +22,13 @@ export const GRAPH = {
|
|
|
23
22
|
},
|
|
24
23
|
|
|
25
24
|
find: (graph, callback) => {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
let found = null
|
|
26
|
+
for (const urlInfo of graph.urlInfoMap.values()) {
|
|
27
|
+
if (callback(urlInfo)) {
|
|
28
|
+
found = urlInfo
|
|
29
|
+
break
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return found
|
|
30
33
|
},
|
|
31
34
|
}
|
package/src/execute/run.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import cuid from "cuid"
|
|
2
2
|
import { Abort, raceCallbacks } from "@jsenv/abort"
|
|
3
|
-
import {
|
|
3
|
+
import { ensureParentDirectories } from "@jsenv/filesystem"
|
|
4
4
|
|
|
5
5
|
export const run = async ({
|
|
6
6
|
signal = new AbortController().signal,
|
|
@@ -16,7 +16,7 @@ export const run = async ({
|
|
|
16
16
|
runtime,
|
|
17
17
|
runtimeParams,
|
|
18
18
|
}) => {
|
|
19
|
-
|
|
19
|
+
const result = {}
|
|
20
20
|
const callbacks = []
|
|
21
21
|
|
|
22
22
|
const onConsoleRef = { current: () => {} }
|
|
@@ -39,17 +39,13 @@ export const run = async ({
|
|
|
39
39
|
Abort.isAbortError(result.error) &&
|
|
40
40
|
timeoutAbortSource.signal.aborted
|
|
41
41
|
) {
|
|
42
|
-
result =
|
|
43
|
-
status: "timedout",
|
|
44
|
-
}
|
|
42
|
+
result.status = "timedout"
|
|
45
43
|
}
|
|
46
44
|
})
|
|
47
45
|
}
|
|
48
46
|
callbacks.push(() => {
|
|
49
47
|
if (result.status === "errored" && Abort.isAbortError(result.error)) {
|
|
50
|
-
result =
|
|
51
|
-
status: "aborted",
|
|
52
|
-
}
|
|
48
|
+
result.status = "aborted"
|
|
53
49
|
}
|
|
54
50
|
})
|
|
55
51
|
const consoleCalls = []
|
|
@@ -71,6 +67,24 @@ export const run = async ({
|
|
|
71
67
|
})
|
|
72
68
|
}
|
|
73
69
|
|
|
70
|
+
// we do not keep coverage in memory, it can grow very big
|
|
71
|
+
// instead we store it on the filesystem
|
|
72
|
+
// and they can be read later at "coverageFileUrl"
|
|
73
|
+
let coverageFileUrl
|
|
74
|
+
if (coverageEnabled) {
|
|
75
|
+
coverageFileUrl = new URL(
|
|
76
|
+
`./${runtime.name}/${cuid()}.json`,
|
|
77
|
+
coverageTempDirectoryUrl,
|
|
78
|
+
).href
|
|
79
|
+
await ensureParentDirectories(coverageFileUrl)
|
|
80
|
+
if (coverageEnabled) {
|
|
81
|
+
result.coverageFileUrl = coverageFileUrl
|
|
82
|
+
// written within the child_process/worker_thread or during runtime.run()
|
|
83
|
+
// for browsers
|
|
84
|
+
// (because it takes time to serialize and transfer the coverage object)
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
74
88
|
const startMs = Date.now()
|
|
75
89
|
callbacks.push(() => {
|
|
76
90
|
result.duration = Date.now() - startMs
|
|
@@ -94,7 +108,9 @@ export const run = async ({
|
|
|
94
108
|
signal: runOperation.signal,
|
|
95
109
|
logger,
|
|
96
110
|
...runtimeParams,
|
|
111
|
+
collectConsole,
|
|
97
112
|
collectPerformance,
|
|
113
|
+
coverageFileUrl,
|
|
98
114
|
keepRunning,
|
|
99
115
|
stopSignal,
|
|
100
116
|
onConsole: (log) => onConsoleRef.current(log),
|
|
@@ -116,7 +132,7 @@ export const run = async ({
|
|
|
116
132
|
runOperation.throwIfAborted()
|
|
117
133
|
}
|
|
118
134
|
|
|
119
|
-
const { status, namespace, error, performance
|
|
135
|
+
const { status, namespace, error, performance } = winner.data
|
|
120
136
|
result.status = status
|
|
121
137
|
if (status === "errored") {
|
|
122
138
|
result.error = error
|
|
@@ -126,30 +142,13 @@ export const run = async ({
|
|
|
126
142
|
if (collectPerformance) {
|
|
127
143
|
result.performance = performance
|
|
128
144
|
}
|
|
129
|
-
if (coverageEnabled) {
|
|
130
|
-
if (coverage) {
|
|
131
|
-
// we do not keep coverage in memory, it can grow very big
|
|
132
|
-
// instead we store it on the filesystem
|
|
133
|
-
// and they can be read later at "coverageFileUrl"
|
|
134
|
-
const coverageFileUrl = new URL(
|
|
135
|
-
`./${runtime.name}/${cuid()}.json`,
|
|
136
|
-
coverageTempDirectoryUrl,
|
|
137
|
-
)
|
|
138
|
-
writeFileSync(coverageFileUrl, JSON.stringify(coverage, null, " "))
|
|
139
|
-
result.coverageFileUrl = coverageFileUrl.href
|
|
140
|
-
} else {
|
|
141
|
-
// will eventually log a warning in report_to_coverage.js
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
145
|
callbacks.forEach((callback) => {
|
|
145
146
|
callback()
|
|
146
147
|
})
|
|
147
148
|
return result
|
|
148
149
|
} catch (e) {
|
|
149
|
-
result =
|
|
150
|
-
|
|
151
|
-
error: e,
|
|
152
|
-
}
|
|
150
|
+
result.status = "errored"
|
|
151
|
+
result.error = e
|
|
153
152
|
callbacks.forEach((callback) => {
|
|
154
153
|
callback()
|
|
155
154
|
})
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Script } from "node:vm"
|
|
2
|
+
import { writeFileSync } from "node:fs"
|
|
2
3
|
|
|
3
4
|
import { createDetailedMessage } from "@jsenv/log"
|
|
4
5
|
import {
|
|
@@ -41,6 +42,7 @@ export const createRuntimeFromPlaywright = ({
|
|
|
41
42
|
coverageEnabled = false,
|
|
42
43
|
coverageConfig,
|
|
43
44
|
coverageMethodForBrowsers,
|
|
45
|
+
coverageFileUrl,
|
|
44
46
|
|
|
45
47
|
stopAfterAllSignal,
|
|
46
48
|
stopSignal,
|
|
@@ -108,7 +110,8 @@ export const createRuntimeFromPlaywright = ({
|
|
|
108
110
|
}
|
|
109
111
|
}
|
|
110
112
|
|
|
111
|
-
|
|
113
|
+
const result = {}
|
|
114
|
+
const callbacks = []
|
|
112
115
|
if (coverageEnabled) {
|
|
113
116
|
if (
|
|
114
117
|
coveragePlaywrightAPIAvailable &&
|
|
@@ -117,93 +120,86 @@ export const createRuntimeFromPlaywright = ({
|
|
|
117
120
|
await page.coverage.startJSCoverage({
|
|
118
121
|
// reportAnonymousScripts: true,
|
|
119
122
|
})
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
)
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
}
|
|
151
|
-
},
|
|
152
|
-
)
|
|
123
|
+
callbacks.push(async () => {
|
|
124
|
+
const v8CoveragesWithWebUrls = await page.coverage.stopJSCoverage()
|
|
125
|
+
// we convert urls starting with http:// to file:// because we later
|
|
126
|
+
// convert the url to filesystem path in istanbulCoverageFromV8Coverage function
|
|
127
|
+
const v8CoveragesWithFsUrls = v8CoveragesWithWebUrls.map(
|
|
128
|
+
(v8CoveragesWithWebUrl) => {
|
|
129
|
+
const fsUrl = moveUrl({
|
|
130
|
+
url: v8CoveragesWithWebUrl.url,
|
|
131
|
+
from: `${server.origin}/`,
|
|
132
|
+
to: rootDirectoryUrl,
|
|
133
|
+
preferAbsolute: true,
|
|
134
|
+
})
|
|
135
|
+
return {
|
|
136
|
+
...v8CoveragesWithWebUrl,
|
|
137
|
+
url: fsUrl,
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
)
|
|
141
|
+
const coverage = await filterV8Coverage(
|
|
142
|
+
{ result: v8CoveragesWithFsUrls },
|
|
143
|
+
{
|
|
144
|
+
rootDirectoryUrl,
|
|
145
|
+
coverageConfig,
|
|
146
|
+
},
|
|
147
|
+
)
|
|
148
|
+
writeFileSync(
|
|
149
|
+
new URL(coverageFileUrl),
|
|
150
|
+
JSON.stringify(coverage, null, " "),
|
|
151
|
+
)
|
|
152
|
+
})
|
|
153
153
|
} else {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
const
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
154
|
+
callbacks.push(() => {
|
|
155
|
+
const scriptExecutionResults = result.namespace
|
|
156
|
+
if (scriptExecutionResults) {
|
|
157
|
+
const coverage =
|
|
158
|
+
generateCoverageForPage(scriptExecutionResults) || {}
|
|
159
|
+
writeFileSync(
|
|
160
|
+
new URL(coverageFileUrl),
|
|
161
|
+
JSON.stringify(coverage, null, " "),
|
|
162
|
+
)
|
|
163
|
+
}
|
|
164
|
+
})
|
|
164
165
|
}
|
|
165
166
|
} else {
|
|
166
|
-
|
|
167
|
+
callbacks.push(() => {
|
|
167
168
|
const scriptExecutionResults = result.namespace
|
|
168
169
|
if (scriptExecutionResults) {
|
|
169
170
|
Object.keys(scriptExecutionResults).forEach((fileRelativeUrl) => {
|
|
170
171
|
delete scriptExecutionResults[fileRelativeUrl].coverage
|
|
171
172
|
})
|
|
172
173
|
}
|
|
173
|
-
return result
|
|
174
174
|
})
|
|
175
175
|
}
|
|
176
176
|
|
|
177
177
|
if (collectPerformance) {
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
()
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
result.performance = performance
|
|
204
|
-
return result
|
|
205
|
-
},
|
|
206
|
-
)
|
|
178
|
+
callbacks.push(async () => {
|
|
179
|
+
const performance = await page.evaluate(
|
|
180
|
+
/* eslint-disable no-undef */
|
|
181
|
+
/* istanbul ignore next */
|
|
182
|
+
() => {
|
|
183
|
+
const { performance } = window
|
|
184
|
+
if (!performance) {
|
|
185
|
+
return null
|
|
186
|
+
}
|
|
187
|
+
const measures = {}
|
|
188
|
+
const measurePerfEntries = performance.getEntriesByType("measure")
|
|
189
|
+
measurePerfEntries.forEach((measurePerfEntry) => {
|
|
190
|
+
measures[measurePerfEntry.name] = measurePerfEntry.duration
|
|
191
|
+
})
|
|
192
|
+
return {
|
|
193
|
+
timeOrigin: performance.timeOrigin,
|
|
194
|
+
timing: performance.timing.toJSON(),
|
|
195
|
+
navigation: performance.navigation.toJSON(),
|
|
196
|
+
measures,
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
/* eslint-enable no-undef */
|
|
200
|
+
)
|
|
201
|
+
result.performance = performance
|
|
202
|
+
})
|
|
207
203
|
}
|
|
208
204
|
|
|
209
205
|
const fileClientUrl = new URL(fileRelativeUrl, `${server.origin}/`).href
|
|
@@ -290,7 +286,7 @@ export const createRuntimeFromPlaywright = ({
|
|
|
290
286
|
response: async (cb) => {
|
|
291
287
|
try {
|
|
292
288
|
await page.goto(fileClientUrl, { timeout: 0 })
|
|
293
|
-
const
|
|
289
|
+
const returnValue = await page.evaluate(
|
|
294
290
|
/* eslint-disable no-undef */
|
|
295
291
|
/* istanbul ignore next */
|
|
296
292
|
() => {
|
|
@@ -301,9 +297,9 @@ export const createRuntimeFromPlaywright = ({
|
|
|
301
297
|
},
|
|
302
298
|
/* eslint-enable no-undef */
|
|
303
299
|
)
|
|
304
|
-
const { status, scriptExecutionResults } =
|
|
300
|
+
const { status, scriptExecutionResults } = returnValue
|
|
305
301
|
if (status === "errored") {
|
|
306
|
-
const { exceptionSource } =
|
|
302
|
+
const { exceptionSource } = returnValue
|
|
307
303
|
const error = evalException(exceptionSource, {
|
|
308
304
|
rootDirectoryUrl,
|
|
309
305
|
server,
|
|
@@ -353,16 +349,25 @@ export const createRuntimeFromPlaywright = ({
|
|
|
353
349
|
}
|
|
354
350
|
return winner.data
|
|
355
351
|
}
|
|
356
|
-
let result
|
|
357
352
|
|
|
358
353
|
try {
|
|
359
|
-
|
|
360
|
-
result =
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
354
|
+
const { status, error, namespace, performance } = await getResult()
|
|
355
|
+
result.status = status
|
|
356
|
+
if (status === "errored") {
|
|
357
|
+
result.error = error
|
|
358
|
+
} else {
|
|
359
|
+
result.namespace = namespace
|
|
365
360
|
}
|
|
361
|
+
if (collectPerformance) {
|
|
362
|
+
result.performance = performance
|
|
363
|
+
}
|
|
364
|
+
await callbacks.reduce(async (previous, callback) => {
|
|
365
|
+
await previous
|
|
366
|
+
await callback()
|
|
367
|
+
}, Promise.resolve())
|
|
368
|
+
} catch (e) {
|
|
369
|
+
result.status = "errored"
|
|
370
|
+
result.error = e
|
|
366
371
|
}
|
|
367
372
|
if (keepRunning) {
|
|
368
373
|
stopSignal.notify = cleanup
|
|
@@ -478,13 +483,6 @@ const isTargetClosedError = (error) => {
|
|
|
478
483
|
return false
|
|
479
484
|
}
|
|
480
485
|
|
|
481
|
-
const composeTransformer = (previousTransformer, transformer) => {
|
|
482
|
-
return async (value) => {
|
|
483
|
-
const transformedValue = await previousTransformer(value)
|
|
484
|
-
return transformer(transformedValue)
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
|
|
488
486
|
const extractTextFromConsoleMessage = (consoleMessage) => {
|
|
489
487
|
return consoleMessage.text()
|
|
490
488
|
// ensure we use a string so that istanbul won't try
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { writeFileSync } from "node:fs"
|
|
2
|
+
|
|
1
3
|
import { startJsCoverage } from "./profiler_v8_coverage.js"
|
|
2
4
|
import { startObservingPerformances } from "./node_execution_performance.js"
|
|
3
5
|
|
|
@@ -8,8 +10,9 @@ export const executeUsingDynamicImport = async ({
|
|
|
8
10
|
coverageEnabled,
|
|
9
11
|
coverageConfig,
|
|
10
12
|
coverageMethodForNodeJs,
|
|
13
|
+
coverageFileUrl,
|
|
11
14
|
}) => {
|
|
12
|
-
|
|
15
|
+
const result = {}
|
|
13
16
|
const afterImportCallbacks = []
|
|
14
17
|
if (coverageEnabled && coverageMethodForNodeJs === "Profiler") {
|
|
15
18
|
const { filterV8Coverage } = await import(
|
|
@@ -22,7 +25,10 @@ export const executeUsingDynamicImport = async ({
|
|
|
22
25
|
rootDirectoryUrl,
|
|
23
26
|
coverageConfig,
|
|
24
27
|
})
|
|
25
|
-
|
|
28
|
+
writeFileSync(
|
|
29
|
+
new URL(coverageFileUrl),
|
|
30
|
+
JSON.stringify(coverageLight, null, " "),
|
|
31
|
+
)
|
|
26
32
|
})
|
|
27
33
|
}
|
|
28
34
|
if (collectPerformance) {
|
|
@@ -39,6 +39,7 @@ nodeChildProcess.run = async ({
|
|
|
39
39
|
coverageEnabled = false,
|
|
40
40
|
coverageConfig,
|
|
41
41
|
coverageMethodForNodeJs,
|
|
42
|
+
coverageFileUrl,
|
|
42
43
|
collectPerformance,
|
|
43
44
|
|
|
44
45
|
env,
|
|
@@ -199,6 +200,7 @@ nodeChildProcess.run = async ({
|
|
|
199
200
|
coverageEnabled,
|
|
200
201
|
coverageConfig,
|
|
201
202
|
coverageMethodForNodeJs,
|
|
203
|
+
coverageFileUrl,
|
|
202
204
|
exitAfterAction: true,
|
|
203
205
|
},
|
|
204
206
|
},
|
|
@@ -35,10 +35,12 @@ nodeWorkerThread.run = async ({
|
|
|
35
35
|
stopSignal,
|
|
36
36
|
onConsole,
|
|
37
37
|
|
|
38
|
+
collectConsole = false,
|
|
39
|
+
collectPerformance,
|
|
40
|
+
coverageEnabled = false,
|
|
38
41
|
coverageConfig,
|
|
39
42
|
coverageMethodForNodeJs,
|
|
40
|
-
|
|
41
|
-
collectPerformance,
|
|
43
|
+
coverageFileUrl,
|
|
42
44
|
|
|
43
45
|
env,
|
|
44
46
|
debugPort,
|
|
@@ -102,6 +104,14 @@ nodeWorkerThread.run = async ({
|
|
|
102
104
|
})
|
|
103
105
|
|
|
104
106
|
const stop = memoize(async () => {
|
|
107
|
+
// read all stdout before terminating
|
|
108
|
+
// (no need for stderr because it's sync)
|
|
109
|
+
if (collectConsole) {
|
|
110
|
+
while (workerThread.stdout.read() !== null) {}
|
|
111
|
+
await new Promise((resolve) => {
|
|
112
|
+
setTimeout(resolve, 50)
|
|
113
|
+
})
|
|
114
|
+
}
|
|
105
115
|
await workerThread.terminate()
|
|
106
116
|
})
|
|
107
117
|
|
|
@@ -142,6 +152,7 @@ nodeWorkerThread.run = async ({
|
|
|
142
152
|
coverageEnabled,
|
|
143
153
|
coverageConfig,
|
|
144
154
|
coverageMethodForNodeJs,
|
|
155
|
+
coverageFileUrl,
|
|
145
156
|
exitAfterAction: true,
|
|
146
157
|
},
|
|
147
158
|
},
|
|
@@ -11,7 +11,6 @@ ${createRepartitionMessage(graphReport)}
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
const createUrlGraphReport = (urlGraph) => {
|
|
14
|
-
const { urlInfos } = urlGraph
|
|
15
14
|
const countGroups = {
|
|
16
15
|
sourcemaps: 0,
|
|
17
16
|
html: 0,
|
|
@@ -30,11 +29,10 @@ const createUrlGraphReport = (urlGraph) => {
|
|
|
30
29
|
other: 0,
|
|
31
30
|
total: 0,
|
|
32
31
|
}
|
|
33
|
-
|
|
34
|
-
if (url.startsWith("data:")) {
|
|
32
|
+
urlGraph.urlInfoMap.forEach((urlInfo) => {
|
|
33
|
+
if (urlInfo.url.startsWith("data:")) {
|
|
35
34
|
return
|
|
36
35
|
}
|
|
37
|
-
const urlInfo = urlInfos[url]
|
|
38
36
|
// ignore:
|
|
39
37
|
// - inline files: they are already taken into account in the file where they appear
|
|
40
38
|
// - ignored files: we don't know their content
|
package/src/omega/url_graph.js
CHANGED
|
@@ -5,12 +5,12 @@ export const createUrlGraph = ({
|
|
|
5
5
|
clientFileChangeCallbackList,
|
|
6
6
|
clientFilesPruneCallbackList,
|
|
7
7
|
} = {}) => {
|
|
8
|
-
const
|
|
9
|
-
const getUrlInfo = (url) =>
|
|
8
|
+
const urlInfoMap = new Map()
|
|
9
|
+
const getUrlInfo = (url) => urlInfoMap.get(url)
|
|
10
10
|
const deleteUrlInfo = (url) => {
|
|
11
|
-
const urlInfo =
|
|
11
|
+
const urlInfo = urlInfoMap.get(url)
|
|
12
12
|
if (urlInfo) {
|
|
13
|
-
delete
|
|
13
|
+
urlInfoMap.delete(url)
|
|
14
14
|
if (urlInfo.sourcemapReference) {
|
|
15
15
|
deleteUrlInfo(urlInfo.sourcemapReference.url)
|
|
16
16
|
}
|
|
@@ -18,14 +18,14 @@ export const createUrlGraph = ({
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
const reuseOrCreateUrlInfo = (url) => {
|
|
21
|
-
const existingUrlInfo =
|
|
21
|
+
const existingUrlInfo = getUrlInfo(url)
|
|
22
22
|
if (existingUrlInfo) return existingUrlInfo
|
|
23
23
|
const urlInfo = createUrlInfo(url)
|
|
24
|
-
|
|
24
|
+
urlInfoMap.set(url, urlInfo)
|
|
25
25
|
return urlInfo
|
|
26
26
|
}
|
|
27
27
|
const inferReference = (specifier, parentUrl) => {
|
|
28
|
-
const parentUrlInfo =
|
|
28
|
+
const parentUrlInfo = getUrlInfo(parentUrl)
|
|
29
29
|
if (!parentUrlInfo) {
|
|
30
30
|
return null
|
|
31
31
|
}
|
|
@@ -37,13 +37,13 @@ export const createUrlGraph = ({
|
|
|
37
37
|
return firstReferenceOnThatUrl
|
|
38
38
|
}
|
|
39
39
|
const findDependent = (url, predicate) => {
|
|
40
|
-
const urlInfo =
|
|
40
|
+
const urlInfo = getUrlInfo(url)
|
|
41
41
|
if (!urlInfo) {
|
|
42
42
|
return null
|
|
43
43
|
}
|
|
44
44
|
const visitDependents = (urlInfo) => {
|
|
45
45
|
for (const dependentUrl of urlInfo.dependents) {
|
|
46
|
-
const dependent =
|
|
46
|
+
const dependent = getUrlInfo(dependentUrl)
|
|
47
47
|
if (predicate(dependent)) {
|
|
48
48
|
return dependent
|
|
49
49
|
}
|
|
@@ -90,7 +90,7 @@ export const createUrlGraph = ({
|
|
|
90
90
|
const removeDependencies = (urlInfo, urlsToPrune) => {
|
|
91
91
|
urlsToPrune.forEach((urlToPrune) => {
|
|
92
92
|
urlInfo.dependencies.delete(urlToPrune)
|
|
93
|
-
const dependency =
|
|
93
|
+
const dependency = getUrlInfo(urlToPrune)
|
|
94
94
|
if (!dependency) {
|
|
95
95
|
return
|
|
96
96
|
}
|
|
@@ -122,7 +122,7 @@ export const createUrlGraph = ({
|
|
|
122
122
|
|
|
123
123
|
if (clientFileChangeCallbackList) {
|
|
124
124
|
clientFileChangeCallbackList.push(({ url }) => {
|
|
125
|
-
const urlInfo =
|
|
125
|
+
const urlInfo = getUrlInfo(url)
|
|
126
126
|
if (urlInfo) {
|
|
127
127
|
considerModified(urlInfo, Date.now())
|
|
128
128
|
}
|
|
@@ -139,7 +139,7 @@ export const createUrlGraph = ({
|
|
|
139
139
|
urlInfo.modifiedTimestamp = modifiedTimestamp
|
|
140
140
|
urlInfo.contentEtag = undefined
|
|
141
141
|
urlInfo.dependents.forEach((dependentUrl) => {
|
|
142
|
-
const dependentUrlInfo =
|
|
142
|
+
const dependentUrlInfo = getUrlInfo(dependentUrl)
|
|
143
143
|
const { hotAcceptDependencies = [] } = dependentUrlInfo.data
|
|
144
144
|
if (!hotAcceptDependencies.includes(urlInfo.url)) {
|
|
145
145
|
iterate(dependentUrlInfo)
|
|
@@ -164,7 +164,7 @@ export const createUrlGraph = ({
|
|
|
164
164
|
}
|
|
165
165
|
|
|
166
166
|
return {
|
|
167
|
-
|
|
167
|
+
urlInfoMap,
|
|
168
168
|
reuseOrCreateUrlInfo,
|
|
169
169
|
getUrlInfo,
|
|
170
170
|
deleteUrlInfo,
|
|
@@ -174,12 +174,19 @@ export const createUrlGraph = ({
|
|
|
174
174
|
considerModified,
|
|
175
175
|
getRelatedUrlInfos,
|
|
176
176
|
|
|
177
|
+
toObject: () => {
|
|
178
|
+
const data = {}
|
|
179
|
+
urlInfoMap.forEach((urlInfo) => {
|
|
180
|
+
data[urlInfo.url] = urlInfo
|
|
181
|
+
})
|
|
182
|
+
return data
|
|
183
|
+
},
|
|
177
184
|
toJSON: (rootDirectoryUrl) => {
|
|
178
185
|
const data = {}
|
|
179
|
-
|
|
180
|
-
const dependencyUrls = Array.from(
|
|
186
|
+
urlInfoMap.forEach((urlInfo) => {
|
|
187
|
+
const dependencyUrls = Array.from(urlInfo.dependencies)
|
|
181
188
|
if (dependencyUrls.length) {
|
|
182
|
-
const relativeUrl = urlToRelativeUrl(url, rootDirectoryUrl)
|
|
189
|
+
const relativeUrl = urlToRelativeUrl(urlInfo.url, rootDirectoryUrl)
|
|
183
190
|
data[relativeUrl] = dependencyUrls.map((dependencyUrl) =>
|
|
184
191
|
urlToRelativeUrl(dependencyUrl, rootDirectoryUrl),
|
|
185
192
|
)
|
|
@@ -35,7 +35,6 @@ export const jsenvPluginDevSSEServer = ({
|
|
|
35
35
|
})
|
|
36
36
|
}
|
|
37
37
|
const propagateUpdate = (firstUrlInfo) => {
|
|
38
|
-
const urlInfos = urlGraph.urlInfos
|
|
39
38
|
const iterate = (urlInfo, trace) => {
|
|
40
39
|
if (urlInfo.data.hotAcceptSelf) {
|
|
41
40
|
return {
|
|
@@ -56,7 +55,7 @@ export const jsenvPluginDevSSEServer = ({
|
|
|
56
55
|
const { dependents } = urlInfo
|
|
57
56
|
const instructions = []
|
|
58
57
|
for (const dependentUrl of dependents) {
|
|
59
|
-
const dependentUrlInfo =
|
|
58
|
+
const dependentUrlInfo = urlGraph.getUrlInfo(dependentUrl)
|
|
60
59
|
if (dependentUrlInfo.data.hotDecline) {
|
|
61
60
|
return {
|
|
62
61
|
declined: true,
|