@jsenv/core 23.1.3 → 23.2.2
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/jsenv_browser_system.js +36 -99
- package/dist/jsenv_browser_system.js.map +12 -21
- package/dist/jsenv_compile_proxy.js +18 -82
- package/dist/jsenv_compile_proxy.js.map +11 -21
- package/dist/jsenv_exploring_index.js +127 -274
- package/dist/jsenv_exploring_index.js.map +76 -90
- package/dist/jsenv_exploring_redirector.js +21 -89
- package/dist/jsenv_exploring_redirector.js.map +13 -25
- package/dist/jsenv_toolbar.js +81 -149
- package/dist/jsenv_toolbar.js.map +50 -61
- package/dist/jsenv_toolbar_injector.js +185 -231
- package/dist/jsenv_toolbar_injector.js.map +30 -42
- package/package.json +8 -9
- package/src/abort/abortable.js +172 -0
- package/src/abort/callback_list.js +64 -0
- package/src/abort/callback_race.js +34 -0
- package/src/abort/cleaner.js +22 -0
- package/src/abort/main.js +32 -0
- package/src/abort/process_teardown_events.js +59 -0
- package/src/buildProject.js +132 -123
- package/src/execute.js +108 -107
- package/src/executeTestPlan.js +107 -125
- package/src/importUsingChildProcess.js +2 -1
- package/src/internal/browser-launcher/executeHtmlFile.js +33 -12
- package/src/internal/browser-utils/fetch-browser.js +4 -29
- package/src/internal/browser-utils/fetchUsingXHR.js +5 -7
- package/src/internal/building/buildUsingRollup.js +60 -24
- package/src/internal/building/createJsenvRollupPlugin.js +13 -31
- package/src/internal/building/ressource_builder.js +3 -6
- package/src/internal/building/sourcemap_loader.js +4 -5
- package/src/internal/building/url_fetcher.js +2 -5
- package/src/internal/building/url_loader.js +3 -6
- package/src/internal/compiling/compileFile.js +1 -2
- package/src/internal/compiling/createCompiledFileService.js +8 -9
- package/src/internal/compiling/startCompileServer.js +74 -135
- package/src/internal/executing/coverage/generateCoverageJsonFile.js +20 -3
- package/src/internal/executing/coverage/relativeUrlToEmptyCoverage.js +19 -30
- package/src/internal/executing/coverage/reportToCoverage.js +44 -24
- package/src/internal/executing/coverage/v8CoverageFromNodeV8Directory.js +2 -15
- package/src/internal/executing/createSummaryLog.js +50 -37
- package/src/internal/executing/executeConcurrently.js +89 -47
- package/src/internal/executing/executePlan.js +33 -7
- package/src/internal/executing/executionLogs.js +25 -28
- package/src/internal/executing/execution_colors.js +15 -0
- package/src/internal/executing/generateExecutionSteps.js +3 -2
- package/src/internal/executing/launchAndExecute.js +217 -261
- package/src/internal/exploring/fetchExploringJson.js +3 -4
- package/src/internal/fetchUrl.js +6 -2
- package/src/internal/logs/log_style.js +16 -28
- package/src/internal/logs/msAsDuration.js +1 -1
- package/src/internal/node-launcher/createChildProcessOptions.js +4 -5
- package/src/internal/node-launcher/createControllableNodeProcess.js +117 -229
- package/src/internal/node-launcher/kill_process_tree.js +76 -0
- package/src/internal/node-launcher/nodeControllableFile.mjs +16 -10
- package/src/internal/{promise_track_race.js → promise_race.js} +2 -2
- package/src/internal/runtime/s.js +25 -24
- package/src/internal/toolbar/toolbar.html +157 -61
- package/src/internal/toolbar/toolbar.injector.js +8 -0
- package/src/internal/toolbar/util/animation.js +3 -7
- package/src/internal/toolbar/util/fetching.js +1 -30
- package/src/jsenvServiceWorkerFinalizer.js +1 -2
- package/src/launchBrowser.js +131 -127
- package/src/launchNode.js +29 -17
- package/src/playwright_browser_versions.js +3 -3
- package/src/requireUsingChildProcess.js +2 -1
- package/src/signal/signal.js +65 -0
- package/src/startExploring.js +70 -72
- package/src/internal/executeJsenvAsyncFunction.js +0 -34
- package/src/internal/toolbar/animation/toolbar-movie-icon.svg +0 -15
- package/src/internal/toolbar/compilation/flask.svg +0 -7
- package/src/internal/toolbar/compilation/info.svg +0 -9
- package/src/internal/toolbar/compilation/loupe.svg +0 -11
- package/src/internal/toolbar/compilation/toolbar_compilation.svg +0 -11
- package/src/internal/toolbar/eventsource/toolbar-power-icon.svg +0 -10
- package/src/internal/toolbar/eventsource/toolbar-power-off-icon.svg +0 -10
- package/src/internal/toolbar/responsive/toolbar-dots-icon.svg +0 -10
- package/src/internal/toolbar/settings/toolbar-settings-icon.svg +0 -9
- package/src/internal/toolbar/theme/toolbar-palette-icon.svg +0 -10
- package/src/internal/toolbar/toolbar-cross-icon.svg +0 -10
- package/src/internal/toolbar/toolbar-loading-icon.svg +0 -102
- package/src/internal/toolbar/toolbar-notif-icon.svg +0 -9
- package/src/internal/trackRessources.js +0 -23
|
@@ -1,10 +1,4 @@
|
|
|
1
|
-
/* eslint-disable import/max-dependencies */
|
|
2
1
|
import { readFileSync } from "node:fs"
|
|
3
|
-
import {
|
|
4
|
-
createCancellationToken,
|
|
5
|
-
createCancellationSource,
|
|
6
|
-
composeCancellationToken,
|
|
7
|
-
} from "@jsenv/cancellation"
|
|
8
2
|
import {
|
|
9
3
|
jsenvAccessControlAllowedHeaders,
|
|
10
4
|
startServer,
|
|
@@ -12,6 +6,9 @@ import {
|
|
|
12
6
|
createSSERoom,
|
|
13
7
|
composeServicesWithTiming,
|
|
14
8
|
urlToContentType,
|
|
9
|
+
pluginServerTiming,
|
|
10
|
+
pluginRequestWaitingCheck,
|
|
11
|
+
pluginCORS,
|
|
15
12
|
} from "@jsenv/server"
|
|
16
13
|
import { createLogger, createDetailedMessage } from "@jsenv/logger"
|
|
17
14
|
import {
|
|
@@ -22,12 +19,12 @@ import {
|
|
|
22
19
|
readFile,
|
|
23
20
|
writeFile,
|
|
24
21
|
ensureEmptyDirectory,
|
|
25
|
-
registerFileLifecycle,
|
|
26
22
|
registerDirectoryLifecycle,
|
|
27
23
|
urlIsInsideOf,
|
|
28
24
|
urlToBasename,
|
|
29
25
|
} from "@jsenv/filesystem"
|
|
30
26
|
|
|
27
|
+
import { Abortable } from "@jsenv/core/src/abort/main.js"
|
|
31
28
|
import { isBrowserPartOfSupportedRuntimes } from "@jsenv/core/src/internal/generateGroupMap/runtime_support.js"
|
|
32
29
|
import { loadBabelPluginMapFromFile } from "./load_babel_plugin_map_from_file.js"
|
|
33
30
|
import { extractSyntaxBabelPluginMap } from "./babel_plugins.js"
|
|
@@ -48,7 +45,7 @@ import { urlIsCompilationAsset } from "./compile-directory/compile-asset.js"
|
|
|
48
45
|
import { createTransformHtmlSourceFileService } from "./html_source_file_service.js"
|
|
49
46
|
|
|
50
47
|
export const startCompileServer = async ({
|
|
51
|
-
|
|
48
|
+
signal = new AbortController().signal,
|
|
52
49
|
compileServerLogLevel,
|
|
53
50
|
|
|
54
51
|
projectDirectoryUrl,
|
|
@@ -89,7 +86,7 @@ export const startCompileServer = async ({
|
|
|
89
86
|
compileServerIp = "0.0.0.0",
|
|
90
87
|
compileServerPort = 0,
|
|
91
88
|
keepProcessAlive = false,
|
|
92
|
-
|
|
89
|
+
onStop = () => {},
|
|
93
90
|
|
|
94
91
|
// remaining options
|
|
95
92
|
runtimeSupport,
|
|
@@ -218,15 +215,12 @@ export const startCompileServer = async ({
|
|
|
218
215
|
...babelPluginMap,
|
|
219
216
|
}
|
|
220
217
|
|
|
221
|
-
const
|
|
218
|
+
const compileServerOperation = Abortable.fromSignal(signal)
|
|
222
219
|
|
|
223
220
|
let projectFileRequestedCallback = () => {}
|
|
224
221
|
if (livereloadSSE) {
|
|
225
222
|
const sseSetup = setupServerSentEventsForLivereload({
|
|
226
|
-
|
|
227
|
-
cancellationToken,
|
|
228
|
-
serverStopCancellationSource.token,
|
|
229
|
-
),
|
|
223
|
+
compileServerOperation,
|
|
230
224
|
projectDirectoryUrl,
|
|
231
225
|
jsenvDirectoryRelativeUrl,
|
|
232
226
|
outDirectoryRelativeUrl,
|
|
@@ -236,7 +230,7 @@ export const startCompileServer = async ({
|
|
|
236
230
|
|
|
237
231
|
projectFileRequestedCallback = sseSetup.projectFileRequestedCallback
|
|
238
232
|
const serveSSEForLivereload = createSSEForLivereloadService({
|
|
239
|
-
|
|
233
|
+
compileServerOperation,
|
|
240
234
|
outDirectoryRelativeUrl,
|
|
241
235
|
trackMainAndDependencies: sseSetup.trackMainAndDependencies,
|
|
242
236
|
})
|
|
@@ -283,31 +277,6 @@ export const startCompileServer = async ({
|
|
|
283
277
|
})
|
|
284
278
|
}
|
|
285
279
|
|
|
286
|
-
const sourceFileService = composeServicesWithTiming({
|
|
287
|
-
...(transformHtmlSourceFiles
|
|
288
|
-
? {
|
|
289
|
-
"service:transform html source file":
|
|
290
|
-
createTransformHtmlSourceFileService({
|
|
291
|
-
logger,
|
|
292
|
-
projectDirectoryUrl,
|
|
293
|
-
inlineImportMapIntoHTML,
|
|
294
|
-
jsenvScriptInjection,
|
|
295
|
-
jsenvToolbarInjection,
|
|
296
|
-
}),
|
|
297
|
-
}
|
|
298
|
-
: {}),
|
|
299
|
-
"service:source file": createSourceFileService({
|
|
300
|
-
logger,
|
|
301
|
-
projectDirectoryUrl,
|
|
302
|
-
projectFileRequestedCallback,
|
|
303
|
-
projectFileEtagEnabled,
|
|
304
|
-
transformHtmlSourceFiles,
|
|
305
|
-
inlineImportMapIntoHTML,
|
|
306
|
-
jsenvScriptInjection,
|
|
307
|
-
jsenvToolbarInjection,
|
|
308
|
-
}),
|
|
309
|
-
})
|
|
310
|
-
|
|
311
280
|
const jsenvServices = {
|
|
312
281
|
"service:compilation asset": createCompilationAssetFileService({
|
|
313
282
|
projectDirectoryUrl,
|
|
@@ -327,8 +296,7 @@ export const startCompileServer = async ({
|
|
|
327
296
|
projectDirectoryUrl,
|
|
328
297
|
}),
|
|
329
298
|
"service:compiled file": createCompiledFileService({
|
|
330
|
-
|
|
331
|
-
cancellationToken,
|
|
299
|
+
compileServerOperation,
|
|
332
300
|
logger,
|
|
333
301
|
|
|
334
302
|
projectDirectoryUrl,
|
|
@@ -352,10 +320,38 @@ export const startCompileServer = async ({
|
|
|
352
320
|
sourcemapExcludeSources,
|
|
353
321
|
compileCacheStrategy,
|
|
354
322
|
}),
|
|
323
|
+
...(transformHtmlSourceFiles
|
|
324
|
+
? {
|
|
325
|
+
"service:transform html source file":
|
|
326
|
+
createTransformHtmlSourceFileService({
|
|
327
|
+
logger,
|
|
328
|
+
projectDirectoryUrl,
|
|
329
|
+
inlineImportMapIntoHTML,
|
|
330
|
+
jsenvScriptInjection,
|
|
331
|
+
jsenvToolbarInjection,
|
|
332
|
+
}),
|
|
333
|
+
}
|
|
334
|
+
: {}),
|
|
335
|
+
"service:source file": createSourceFileService({
|
|
336
|
+
logger,
|
|
337
|
+
projectDirectoryUrl,
|
|
338
|
+
projectFileRequestedCallback,
|
|
339
|
+
projectFileEtagEnabled,
|
|
340
|
+
transformHtmlSourceFiles,
|
|
341
|
+
inlineImportMapIntoHTML,
|
|
342
|
+
jsenvScriptInjection,
|
|
343
|
+
jsenvToolbarInjection,
|
|
344
|
+
}),
|
|
355
345
|
}
|
|
356
346
|
|
|
357
347
|
const compileServer = await startServer({
|
|
358
|
-
|
|
348
|
+
signal: compileServerOperation.signal,
|
|
349
|
+
stopOnExit: false,
|
|
350
|
+
stopOnSIGINT: false,
|
|
351
|
+
stopOnInternalError: false,
|
|
352
|
+
sendServerInternalErrorDetails: true,
|
|
353
|
+
keepProcessAlive,
|
|
354
|
+
|
|
359
355
|
logLevel: compileServerLogLevel,
|
|
360
356
|
|
|
361
357
|
protocol: compileServerProtocol,
|
|
@@ -364,44 +360,32 @@ export const startCompileServer = async ({
|
|
|
364
360
|
serverCertificatePrivateKey: compileServerPrivateKey,
|
|
365
361
|
ip: compileServerIp,
|
|
366
362
|
port: compileServerPort,
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
363
|
+
plugins: {
|
|
364
|
+
...pluginCORS({
|
|
365
|
+
accessControlAllowRequestOrigin: true,
|
|
366
|
+
accessControlAllowRequestMethod: true,
|
|
367
|
+
accessControlAllowRequestHeaders: true,
|
|
368
|
+
accessControlAllowedRequestHeaders: [
|
|
369
|
+
...jsenvAccessControlAllowedHeaders,
|
|
370
|
+
"x-jsenv-execution-id",
|
|
371
|
+
],
|
|
372
|
+
accessControlAllowCredentials: true,
|
|
373
|
+
}),
|
|
374
|
+
...pluginServerTiming,
|
|
375
|
+
...pluginRequestWaitingCheck({
|
|
376
|
+
requestWaitingMs: 60 * 1000,
|
|
377
|
+
}),
|
|
378
|
+
},
|
|
371
379
|
requestToResponse: composeServicesWithTiming({
|
|
372
380
|
...customServices,
|
|
373
381
|
...jsenvServices,
|
|
374
382
|
}),
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
...jsenvAccessControlAllowedHeaders,
|
|
380
|
-
"x-jsenv-execution-id",
|
|
381
|
-
],
|
|
382
|
-
accessControlAllowCredentials: true,
|
|
383
|
-
keepProcessAlive,
|
|
383
|
+
onStop: () => {
|
|
384
|
+
onStop()
|
|
385
|
+
compileServerOperation.cleaner.clean()
|
|
386
|
+
},
|
|
384
387
|
})
|
|
385
388
|
|
|
386
|
-
compileServer.stoppedPromise.then(serverStopCancellationSource.cancel)
|
|
387
|
-
|
|
388
|
-
if (stopOnPackageVersionChange) {
|
|
389
|
-
const stopListeningJsenvPackageVersionChange =
|
|
390
|
-
listenJsenvPackageVersionChange({
|
|
391
|
-
projectDirectoryUrl,
|
|
392
|
-
jsenvDirectoryRelativeUrl,
|
|
393
|
-
onJsenvPackageVersionChange: () => {
|
|
394
|
-
compileServer.stop(STOP_REASON_PACKAGE_VERSION_CHANGED)
|
|
395
|
-
},
|
|
396
|
-
})
|
|
397
|
-
compileServer.stoppedPromise.then(
|
|
398
|
-
() => {
|
|
399
|
-
stopListeningJsenvPackageVersionChange()
|
|
400
|
-
},
|
|
401
|
-
() => {},
|
|
402
|
-
)
|
|
403
|
-
}
|
|
404
|
-
|
|
405
389
|
return {
|
|
406
390
|
jsenvDirectoryRelativeUrl,
|
|
407
391
|
outDirectoryRelativeUrl,
|
|
@@ -575,7 +559,7 @@ const compareValueJson = (left, right) => {
|
|
|
575
559
|
*
|
|
576
560
|
*/
|
|
577
561
|
const setupServerSentEventsForLivereload = ({
|
|
578
|
-
|
|
562
|
+
compileServerOperation,
|
|
579
563
|
projectDirectoryUrl,
|
|
580
564
|
jsenvDirectoryRelativeUrl,
|
|
581
565
|
outDirectoryRelativeUrl,
|
|
@@ -621,7 +605,7 @@ const setupServerSentEventsForLivereload = ({
|
|
|
621
605
|
recursive: true,
|
|
622
606
|
},
|
|
623
607
|
)
|
|
624
|
-
|
|
608
|
+
compileServerOperation.cleaner.addCallback(unregisterDirectoryLifecyle)
|
|
625
609
|
|
|
626
610
|
const getDependencySet = (mainRelativeUrl) => {
|
|
627
611
|
if (trackerMap.has(mainRelativeUrl)) {
|
|
@@ -777,11 +761,14 @@ const setupServerSentEventsForLivereload = ({
|
|
|
777
761
|
}
|
|
778
762
|
}
|
|
779
763
|
|
|
780
|
-
return {
|
|
764
|
+
return {
|
|
765
|
+
projectFileRequestedCallback,
|
|
766
|
+
trackMainAndDependencies,
|
|
767
|
+
}
|
|
781
768
|
}
|
|
782
769
|
|
|
783
770
|
const createSSEForLivereloadService = ({
|
|
784
|
-
|
|
771
|
+
compileServerOperation,
|
|
785
772
|
outDirectoryRelativeUrl,
|
|
786
773
|
trackMainAndDependencies,
|
|
787
774
|
}) => {
|
|
@@ -815,17 +802,18 @@ const createSSEForLivereloadService = ({
|
|
|
815
802
|
},
|
|
816
803
|
})
|
|
817
804
|
|
|
818
|
-
const
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
805
|
+
const removeSSECleanupCallback = compileServerOperation.cleaner.addCallback(
|
|
806
|
+
() => {
|
|
807
|
+
removeSSECleanupCallback()
|
|
808
|
+
sseRoom.close()
|
|
809
|
+
stopTracking()
|
|
810
|
+
},
|
|
811
|
+
)
|
|
824
812
|
cache.push({
|
|
825
813
|
mainFileRelativeUrl,
|
|
826
814
|
sseRoom,
|
|
827
815
|
cleanup: () => {
|
|
828
|
-
|
|
816
|
+
removeSSECleanupCallback()
|
|
829
817
|
sseRoom.close()
|
|
830
818
|
stopTracking()
|
|
831
819
|
},
|
|
@@ -1122,51 +1110,6 @@ const createCompileProxyService = ({ projectDirectoryUrl }) => {
|
|
|
1122
1110
|
}
|
|
1123
1111
|
}
|
|
1124
1112
|
|
|
1125
|
-
const listenJsenvPackageVersionChange = ({
|
|
1126
|
-
projectDirectoryUrl,
|
|
1127
|
-
jsenvDirectoryRelativeUrl,
|
|
1128
|
-
onJsenvPackageVersionChange = () => {},
|
|
1129
|
-
}) => {
|
|
1130
|
-
const jsenvCoreDirectoryUrl = resolveUrl(
|
|
1131
|
-
jsenvDirectoryRelativeUrl,
|
|
1132
|
-
projectDirectoryUrl,
|
|
1133
|
-
)
|
|
1134
|
-
const packageFileUrl = resolveUrl("./package.json", jsenvCoreDirectoryUrl)
|
|
1135
|
-
const packageFilePath = urlToFileSystemPath(packageFileUrl)
|
|
1136
|
-
let packageVersion
|
|
1137
|
-
|
|
1138
|
-
try {
|
|
1139
|
-
packageVersion = readPackage(packageFilePath).version
|
|
1140
|
-
} catch (e) {
|
|
1141
|
-
if (e.code === "ENOENT") return () => {}
|
|
1142
|
-
}
|
|
1143
|
-
|
|
1144
|
-
const checkPackageVersion = () => {
|
|
1145
|
-
let packageObject
|
|
1146
|
-
try {
|
|
1147
|
-
packageObject = readPackage(packageFilePath)
|
|
1148
|
-
} catch (e) {
|
|
1149
|
-
// package json deleted ? not a problem
|
|
1150
|
-
// let's wait for it to show back
|
|
1151
|
-
if (e.code === "ENOENT") return
|
|
1152
|
-
// package.json malformed ? not a problem
|
|
1153
|
-
// let's wait for use to fix it or filesystem to finish writing the file
|
|
1154
|
-
if (e.name === "SyntaxError") return
|
|
1155
|
-
throw e
|
|
1156
|
-
}
|
|
1157
|
-
|
|
1158
|
-
if (packageVersion !== packageObject.version) {
|
|
1159
|
-
onJsenvPackageVersionChange()
|
|
1160
|
-
}
|
|
1161
|
-
}
|
|
1162
|
-
|
|
1163
|
-
return registerFileLifecycle(packageFilePath, {
|
|
1164
|
-
added: checkPackageVersion,
|
|
1165
|
-
updated: checkPackageVersion,
|
|
1166
|
-
keepProcessAlive: false,
|
|
1167
|
-
})
|
|
1168
|
-
}
|
|
1169
|
-
|
|
1170
1113
|
const readPackage = (packagePath) => {
|
|
1171
1114
|
const buffer = readFileSync(packagePath)
|
|
1172
1115
|
const string = String(buffer)
|
|
@@ -1174,10 +1117,6 @@ const readPackage = (packagePath) => {
|
|
|
1174
1117
|
return packageObject
|
|
1175
1118
|
}
|
|
1176
1119
|
|
|
1177
|
-
export const STOP_REASON_PACKAGE_VERSION_CHANGED = {
|
|
1178
|
-
toString: () => `package version changed`,
|
|
1179
|
-
}
|
|
1180
|
-
|
|
1181
1120
|
const __filenameReplacement = `import.meta.url.slice('file:///'.length)`
|
|
1182
1121
|
|
|
1183
1122
|
const __dirnameReplacement = `import.meta.url.slice('file:///'.length).replace(/[\\\/\\\\][^\\\/\\\\]*$/, '')`
|
|
@@ -1,5 +1,22 @@
|
|
|
1
|
-
import { writeFile } from "@jsenv/filesystem"
|
|
1
|
+
import { writeFile, urlToFileSystemPath } from "@jsenv/filesystem"
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
import { byteAsFileSize } from "@jsenv/core/src/internal/logs/byteAsFileSize.js"
|
|
4
|
+
|
|
5
|
+
export const generateCoverageJsonFile = async ({
|
|
6
|
+
coverage,
|
|
7
|
+
coverageJsonFileUrl,
|
|
8
|
+
coverageJsonFileLog,
|
|
9
|
+
logger,
|
|
10
|
+
}) => {
|
|
11
|
+
const coverageAsText = JSON.stringify(coverage, null, " ")
|
|
12
|
+
|
|
13
|
+
if (coverageJsonFileLog) {
|
|
14
|
+
logger.info(
|
|
15
|
+
`-> ${urlToFileSystemPath(coverageJsonFileUrl)} (${byteAsFileSize(
|
|
16
|
+
Buffer.byteLength(coverageAsText),
|
|
17
|
+
)})`,
|
|
18
|
+
)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
await writeFile(coverageJsonFileUrl, coverageAsText)
|
|
5
22
|
}
|
|
@@ -1,52 +1,41 @@
|
|
|
1
|
-
import { createOperation } from "@jsenv/cancellation"
|
|
2
1
|
import { resolveUrl, urlToFileSystemPath, readFile } from "@jsenv/filesystem"
|
|
3
2
|
|
|
3
|
+
import { Abortable } from "@jsenv/core/src/abort/main.js"
|
|
4
4
|
import {
|
|
5
5
|
babelPluginsFromBabelPluginMap,
|
|
6
6
|
getMinimalBabelPluginMap,
|
|
7
7
|
} from "@jsenv/core/src/internal/compiling/babel_plugins.js"
|
|
8
|
-
|
|
9
8
|
import { babelPluginInstrument } from "./babel_plugin_instrument.js"
|
|
10
9
|
import { createEmptyCoverage } from "./createEmptyCoverage.js"
|
|
11
10
|
|
|
12
11
|
export const relativeUrlToEmptyCoverage = async (
|
|
13
12
|
relativeUrl,
|
|
14
|
-
{
|
|
13
|
+
{ multipleExecutionsOperation, projectDirectoryUrl, babelPluginMap },
|
|
15
14
|
) => {
|
|
16
15
|
const { transformAsync } = await import("@babel/core")
|
|
17
16
|
|
|
18
17
|
const fileUrl = resolveUrl(relativeUrl, projectDirectoryUrl)
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
start: () => readFile(fileUrl),
|
|
22
|
-
})
|
|
18
|
+
Abortable.throwIfAborted(multipleExecutionsOperation)
|
|
19
|
+
const source = await readFile(fileUrl)
|
|
23
20
|
|
|
24
21
|
try {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
...babelPluginMap,
|
|
31
|
-
"transform-instrument": [
|
|
32
|
-
babelPluginInstrument,
|
|
33
|
-
{ projectDirectoryUrl },
|
|
34
|
-
],
|
|
35
|
-
}
|
|
22
|
+
babelPluginMap = {
|
|
23
|
+
...getMinimalBabelPluginMap(),
|
|
24
|
+
...babelPluginMap,
|
|
25
|
+
"transform-instrument": [babelPluginInstrument, { projectDirectoryUrl }],
|
|
26
|
+
}
|
|
36
27
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
plugins: babelPluginsFromBabelPluginMap(babelPluginMap),
|
|
47
|
-
})
|
|
48
|
-
return { metadata }
|
|
28
|
+
Abortable.throwIfAborted(multipleExecutionsOperation)
|
|
29
|
+
const { metadata } = await transformAsync(source, {
|
|
30
|
+
filename: urlToFileSystemPath(fileUrl),
|
|
31
|
+
filenameRelative: relativeUrl,
|
|
32
|
+
configFile: false,
|
|
33
|
+
babelrc: false,
|
|
34
|
+
ast: true,
|
|
35
|
+
parserOpts: {
|
|
36
|
+
allowAwaitOutsideFunction: true,
|
|
49
37
|
},
|
|
38
|
+
plugins: babelPluginsFromBabelPluginMap(babelPluginMap),
|
|
50
39
|
})
|
|
51
40
|
|
|
52
41
|
const { coverage } = metadata
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { collectFiles } from "@jsenv/filesystem"
|
|
2
|
+
|
|
2
3
|
import { relativeUrlToEmptyCoverage } from "./relativeUrlToEmptyCoverage.js"
|
|
3
4
|
import { istanbulCoverageFromCoverages } from "./istanbulCoverageFromCoverages.js"
|
|
4
5
|
import { normalizeIstanbulCoverage } from "./normalizeIstanbulCoverage.js"
|
|
@@ -6,8 +7,8 @@ import { normalizeIstanbulCoverage } from "./normalizeIstanbulCoverage.js"
|
|
|
6
7
|
export const reportToCoverage = async (
|
|
7
8
|
report,
|
|
8
9
|
{
|
|
10
|
+
multipleExecutionsOperation,
|
|
9
11
|
logger,
|
|
10
|
-
cancellationToken,
|
|
11
12
|
projectDirectoryUrl,
|
|
12
13
|
babelPluginMap,
|
|
13
14
|
coverageConfig,
|
|
@@ -15,50 +16,66 @@ export const reportToCoverage = async (
|
|
|
15
16
|
coverageV8MergeConflictIsExpected,
|
|
16
17
|
},
|
|
17
18
|
) => {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
// here we should forward multipleExecutionsOperation.signal
|
|
20
|
+
// to allow aborting this too
|
|
21
|
+
const istanbulCoverageFromExecution = await executionReportToCoverage(
|
|
22
|
+
report,
|
|
23
|
+
{
|
|
24
|
+
logger,
|
|
25
|
+
projectDirectoryUrl,
|
|
26
|
+
coverageV8MergeConflictIsExpected,
|
|
27
|
+
},
|
|
28
|
+
)
|
|
23
29
|
|
|
24
30
|
if (!coverageIncludeMissing) {
|
|
25
31
|
return istanbulCoverageFromExecution
|
|
26
32
|
}
|
|
27
33
|
|
|
28
34
|
const relativeFileUrlToCoverArray = await listRelativeFileUrlToCover({
|
|
29
|
-
|
|
35
|
+
multipleExecutionsOperation,
|
|
30
36
|
projectDirectoryUrl,
|
|
31
37
|
coverageConfig,
|
|
32
38
|
})
|
|
33
39
|
|
|
34
|
-
const relativeFileUrlMissingCoverageArray =
|
|
35
|
-
(relativeFileUrlToCover) =>
|
|
40
|
+
const relativeFileUrlMissingCoverageArray =
|
|
41
|
+
relativeFileUrlToCoverArray.filter((relativeFileUrlToCover) =>
|
|
36
42
|
Object.keys(istanbulCoverageFromExecution).every((key) => {
|
|
37
43
|
return key !== `./${relativeFileUrlToCover}`
|
|
38
44
|
}),
|
|
39
|
-
|
|
45
|
+
)
|
|
40
46
|
|
|
41
47
|
const istanbulCoverageFromMissedFiles = {}
|
|
48
|
+
// maybe we should prefer reduce over Promise.all here
|
|
49
|
+
// because it creates a LOT of things to do
|
|
42
50
|
await Promise.all(
|
|
43
|
-
relativeFileUrlMissingCoverageArray.map(
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
51
|
+
relativeFileUrlMissingCoverageArray.map(
|
|
52
|
+
async (relativeFileUrlMissingCoverage) => {
|
|
53
|
+
const emptyCoverage = await relativeUrlToEmptyCoverage(
|
|
54
|
+
relativeFileUrlMissingCoverage,
|
|
55
|
+
{
|
|
56
|
+
multipleExecutionsOperation,
|
|
57
|
+
projectDirectoryUrl,
|
|
58
|
+
babelPluginMap,
|
|
59
|
+
},
|
|
60
|
+
)
|
|
61
|
+
istanbulCoverageFromMissedFiles[relativeFileUrlMissingCoverage] =
|
|
62
|
+
emptyCoverage
|
|
63
|
+
return emptyCoverage
|
|
64
|
+
},
|
|
65
|
+
),
|
|
52
66
|
)
|
|
53
67
|
|
|
54
68
|
return {
|
|
55
69
|
...istanbulCoverageFromExecution, // already normalized
|
|
56
|
-
...normalizeIstanbulCoverage(
|
|
70
|
+
...normalizeIstanbulCoverage(
|
|
71
|
+
istanbulCoverageFromMissedFiles,
|
|
72
|
+
projectDirectoryUrl,
|
|
73
|
+
),
|
|
57
74
|
}
|
|
58
75
|
}
|
|
59
76
|
|
|
60
77
|
const listRelativeFileUrlToCover = async ({
|
|
61
|
-
|
|
78
|
+
multipleExecutionsOperation,
|
|
62
79
|
projectDirectoryUrl,
|
|
63
80
|
coverageConfig,
|
|
64
81
|
}) => {
|
|
@@ -67,7 +84,7 @@ const listRelativeFileUrlToCover = async ({
|
|
|
67
84
|
}
|
|
68
85
|
|
|
69
86
|
const matchingFileResultArray = await collectFiles({
|
|
70
|
-
|
|
87
|
+
signal: multipleExecutionsOperation.signal,
|
|
71
88
|
directoryUrl: projectDirectoryUrl,
|
|
72
89
|
structuredMetaMap: structuredMetaMapForCoverage,
|
|
73
90
|
predicate: ({ cover }) => cover,
|
|
@@ -85,7 +102,8 @@ const executionReportToCoverage = async (
|
|
|
85
102
|
Object.keys(report).forEach((file) => {
|
|
86
103
|
const executionResultForFile = report[file]
|
|
87
104
|
Object.keys(executionResultForFile).forEach((executionName) => {
|
|
88
|
-
const executionResultForFileOnRuntime =
|
|
105
|
+
const executionResultForFileOnRuntime =
|
|
106
|
+
executionResultForFile[executionName]
|
|
89
107
|
|
|
90
108
|
const { status, coverage } = executionResultForFileOnRuntime
|
|
91
109
|
if (!coverage) {
|
|
@@ -108,7 +126,9 @@ const executionReportToCoverage = async (
|
|
|
108
126
|
// that were suppose to be coverage but were not.
|
|
109
127
|
|
|
110
128
|
if (status === "completed") {
|
|
111
|
-
logger.warn(
|
|
129
|
+
logger.warn(
|
|
130
|
+
`No execution.coverage from execution named "${executionName}" of ${file}`,
|
|
131
|
+
)
|
|
112
132
|
}
|
|
113
133
|
return
|
|
114
134
|
}
|
|
@@ -26,15 +26,11 @@ export const v8CoverageFromNodeV8Directory = async ({
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
const readV8CoverageReportsFromDirectory = async (coverageDirectory) => {
|
|
29
|
-
const tryReadDirectory = async (
|
|
29
|
+
const tryReadDirectory = async () => {
|
|
30
30
|
const dirContent = await readDirectory(coverageDirectory)
|
|
31
31
|
if (dirContent.length > 0) {
|
|
32
32
|
return dirContent
|
|
33
33
|
}
|
|
34
|
-
if (timeSpentTrying < 800) {
|
|
35
|
-
await new Promise((resolve) => setTimeout(resolve, 100))
|
|
36
|
-
return tryReadDirectory(timeSpentTrying + 100)
|
|
37
|
-
}
|
|
38
34
|
console.warn(`v8 coverage directory is empty at ${coverageDirectory}`)
|
|
39
35
|
return dirContent
|
|
40
36
|
}
|
|
@@ -45,20 +41,11 @@ const readV8CoverageReportsFromDirectory = async (coverageDirectory) => {
|
|
|
45
41
|
await Promise.all(
|
|
46
42
|
dirContent.map(async (dirEntry) => {
|
|
47
43
|
const dirEntryUrl = resolveUrl(dirEntry, coverageDirectoryUrl)
|
|
48
|
-
const tryReadJsonFile = async (
|
|
44
|
+
const tryReadJsonFile = async () => {
|
|
49
45
|
try {
|
|
50
46
|
const fileContent = await readFile(dirEntryUrl, { as: "json" })
|
|
51
47
|
return fileContent
|
|
52
48
|
} catch (e) {
|
|
53
|
-
if (e.name === "SyntaxError") {
|
|
54
|
-
// If there is a syntax error it's likely because Node.js
|
|
55
|
-
// is not done writing the json file content
|
|
56
|
-
// -> let's retry to read file after 100ms
|
|
57
|
-
if (timeSpentTrying < 100) {
|
|
58
|
-
await new Promise((resolve) => setTimeout(resolve, 100))
|
|
59
|
-
return tryReadJsonFile(timeSpentTrying + 100)
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
49
|
console.warn(
|
|
63
50
|
createDetailedMessage(`Error while reading coverage file`, {
|
|
64
51
|
"error stack": e.stack,
|