@jsenv/core 23.1.4 → 23.3.0
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 +56 -124
- package/dist/jsenv_toolbar_injector.js.map +27 -41
- package/package.json +15 -19
- package/src/buildProject.js +130 -122
- package/src/execute.js +47 -47
- package/src/executeTestPlan.js +107 -125
- package/src/importUsingChildProcess.js +2 -1
- package/src/internal/browser-launcher/executeHtmlFile.js +32 -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 +59 -24
- package/src/internal/building/build_logs.js +7 -6
- package/src/internal/building/createJsenvRollupPlugin.js +10 -33
- 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/building/url_trace.js +3 -4
- package/src/internal/compiling/compileFile.js +1 -2
- package/src/internal/compiling/createCompiledFileService.js +12 -9
- package/src/internal/compiling/startCompileServer.js +85 -133
- package/src/internal/executing/coverage/generateCoverageJsonFile.js +20 -3
- package/src/internal/executing/coverage/relativeUrlToEmptyCoverage.js +18 -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 +48 -37
- package/src/internal/executing/executeConcurrently.js +96 -52
- package/src/internal/executing/executePlan.js +93 -67
- package/src/internal/executing/executionLogs.js +31 -38
- package/src/internal/executing/execution_colors.js +9 -0
- package/src/internal/executing/generateExecutionSteps.js +3 -2
- package/src/internal/executing/launchAndExecute.js +207 -271
- package/src/internal/exploring/fetchExploringJson.js +3 -4
- package/src/internal/fetchUrl.js +6 -2
- package/src/internal/logs/msAsDuration.js +1 -1
- package/src/internal/node-launcher/createChildProcessOptions.js +4 -5
- package/src/internal/node-launcher/createControllableNodeProcess.js +120 -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/util/animation.js +3 -7
- package/src/internal/toolbar/util/fetching.js +1 -30
- package/src/jsenvServiceWorkerFinalizer.js +1 -2
- package/src/launchBrowser.js +146 -139
- package/src/launchNode.js +29 -17
- package/src/playwright_browser_versions.js +3 -3
- package/src/requireUsingChildProcess.js +2 -1
- package/src/startExploring.js +55 -74
- package/src/internal/createCallbackList.js +0 -21
- package/src/internal/executeJsenvAsyncFunction.js +0 -34
- package/src/internal/executing/logUtils.js +0 -30
- package/src/internal/executing/writeLog.js +0 -106
- package/src/internal/executing/writeLog.test-manual.js +0 -62
- package/src/internal/logs/log_style.js +0 -52
- package/src/internal/trackRessources.js +0 -23
|
@@ -1,17 +1,14 @@
|
|
|
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,
|
|
11
|
-
|
|
5
|
+
fetchFileSystem,
|
|
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,17 +19,19 @@ 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"
|
|
26
|
+
import {
|
|
27
|
+
createCallbackList,
|
|
28
|
+
createCallbackListNotifiedOnce,
|
|
29
|
+
} from "@jsenv/abort"
|
|
30
30
|
|
|
31
31
|
import { isBrowserPartOfSupportedRuntimes } from "@jsenv/core/src/internal/generateGroupMap/runtime_support.js"
|
|
32
32
|
import { loadBabelPluginMapFromFile } from "./load_babel_plugin_map_from_file.js"
|
|
33
33
|
import { extractSyntaxBabelPluginMap } from "./babel_plugins.js"
|
|
34
34
|
import { generateGroupMap } from "../generateGroupMap/generateGroupMap.js"
|
|
35
|
-
import { createCallbackList } from "../createCallbackList.js"
|
|
36
35
|
import {
|
|
37
36
|
jsenvCompileProxyFileInfo,
|
|
38
37
|
sourcemapMainFileInfo,
|
|
@@ -48,7 +47,8 @@ import { urlIsCompilationAsset } from "./compile-directory/compile-asset.js"
|
|
|
48
47
|
import { createTransformHtmlSourceFileService } from "./html_source_file_service.js"
|
|
49
48
|
|
|
50
49
|
export const startCompileServer = async ({
|
|
51
|
-
|
|
50
|
+
signal = new AbortController().signal,
|
|
51
|
+
handleSIGINT,
|
|
52
52
|
compileServerLogLevel,
|
|
53
53
|
|
|
54
54
|
projectDirectoryUrl,
|
|
@@ -89,7 +89,7 @@ export const startCompileServer = async ({
|
|
|
89
89
|
compileServerIp = "0.0.0.0",
|
|
90
90
|
compileServerPort = 0,
|
|
91
91
|
keepProcessAlive = false,
|
|
92
|
-
|
|
92
|
+
onStop = () => {},
|
|
93
93
|
|
|
94
94
|
// remaining options
|
|
95
95
|
runtimeSupport,
|
|
@@ -218,15 +218,12 @@ export const startCompileServer = async ({
|
|
|
218
218
|
...babelPluginMap,
|
|
219
219
|
}
|
|
220
220
|
|
|
221
|
-
const
|
|
221
|
+
const serverStopCallbackList = createCallbackListNotifiedOnce()
|
|
222
222
|
|
|
223
223
|
let projectFileRequestedCallback = () => {}
|
|
224
224
|
if (livereloadSSE) {
|
|
225
225
|
const sseSetup = setupServerSentEventsForLivereload({
|
|
226
|
-
|
|
227
|
-
cancellationToken,
|
|
228
|
-
serverStopCancellationSource.token,
|
|
229
|
-
),
|
|
226
|
+
serverStopCallbackList,
|
|
230
227
|
projectDirectoryUrl,
|
|
231
228
|
jsenvDirectoryRelativeUrl,
|
|
232
229
|
outDirectoryRelativeUrl,
|
|
@@ -236,7 +233,7 @@ export const startCompileServer = async ({
|
|
|
236
233
|
|
|
237
234
|
projectFileRequestedCallback = sseSetup.projectFileRequestedCallback
|
|
238
235
|
const serveSSEForLivereload = createSSEForLivereloadService({
|
|
239
|
-
|
|
236
|
+
serverStopCallbackList,
|
|
240
237
|
outDirectoryRelativeUrl,
|
|
241
238
|
trackMainAndDependencies: sseSetup.trackMainAndDependencies,
|
|
242
239
|
})
|
|
@@ -302,7 +299,6 @@ export const startCompileServer = async ({
|
|
|
302
299
|
projectDirectoryUrl,
|
|
303
300
|
}),
|
|
304
301
|
"service:compiled file": createCompiledFileService({
|
|
305
|
-
cancellationToken,
|
|
306
302
|
logger,
|
|
307
303
|
|
|
308
304
|
projectDirectoryUrl,
|
|
@@ -351,7 +347,13 @@ export const startCompileServer = async ({
|
|
|
351
347
|
}
|
|
352
348
|
|
|
353
349
|
const compileServer = await startServer({
|
|
354
|
-
|
|
350
|
+
signal,
|
|
351
|
+
stopOnExit: false,
|
|
352
|
+
stopOnSIGINT: handleSIGINT,
|
|
353
|
+
stopOnInternalError: false,
|
|
354
|
+
sendServerInternalErrorDetails: true,
|
|
355
|
+
keepProcessAlive,
|
|
356
|
+
|
|
355
357
|
logLevel: compileServerLogLevel,
|
|
356
358
|
|
|
357
359
|
protocol: compileServerProtocol,
|
|
@@ -360,44 +362,32 @@ export const startCompileServer = async ({
|
|
|
360
362
|
serverCertificatePrivateKey: compileServerPrivateKey,
|
|
361
363
|
ip: compileServerIp,
|
|
362
364
|
port: compileServerPort,
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
365
|
+
plugins: {
|
|
366
|
+
...pluginCORS({
|
|
367
|
+
accessControlAllowRequestOrigin: true,
|
|
368
|
+
accessControlAllowRequestMethod: true,
|
|
369
|
+
accessControlAllowRequestHeaders: true,
|
|
370
|
+
accessControlAllowedRequestHeaders: [
|
|
371
|
+
...jsenvAccessControlAllowedHeaders,
|
|
372
|
+
"x-jsenv-execution-id",
|
|
373
|
+
],
|
|
374
|
+
accessControlAllowCredentials: true,
|
|
375
|
+
}),
|
|
376
|
+
...pluginServerTiming,
|
|
377
|
+
...pluginRequestWaitingCheck({
|
|
378
|
+
requestWaitingMs: 60 * 1000,
|
|
379
|
+
}),
|
|
380
|
+
},
|
|
367
381
|
requestToResponse: composeServicesWithTiming({
|
|
368
382
|
...customServices,
|
|
369
383
|
...jsenvServices,
|
|
370
384
|
}),
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
...jsenvAccessControlAllowedHeaders,
|
|
376
|
-
"x-jsenv-execution-id",
|
|
377
|
-
],
|
|
378
|
-
accessControlAllowCredentials: true,
|
|
379
|
-
keepProcessAlive,
|
|
385
|
+
onStop: (reason) => {
|
|
386
|
+
onStop()
|
|
387
|
+
serverStopCallbackList.notify(reason)
|
|
388
|
+
},
|
|
380
389
|
})
|
|
381
390
|
|
|
382
|
-
compileServer.stoppedPromise.then(serverStopCancellationSource.cancel)
|
|
383
|
-
|
|
384
|
-
if (stopOnPackageVersionChange) {
|
|
385
|
-
const stopListeningJsenvPackageVersionChange =
|
|
386
|
-
listenJsenvPackageVersionChange({
|
|
387
|
-
projectDirectoryUrl,
|
|
388
|
-
jsenvDirectoryRelativeUrl,
|
|
389
|
-
onJsenvPackageVersionChange: () => {
|
|
390
|
-
compileServer.stop(STOP_REASON_PACKAGE_VERSION_CHANGED)
|
|
391
|
-
},
|
|
392
|
-
})
|
|
393
|
-
compileServer.stoppedPromise.then(
|
|
394
|
-
() => {
|
|
395
|
-
stopListeningJsenvPackageVersionChange()
|
|
396
|
-
},
|
|
397
|
-
() => {},
|
|
398
|
-
)
|
|
399
|
-
}
|
|
400
|
-
|
|
401
391
|
return {
|
|
402
392
|
jsenvDirectoryRelativeUrl,
|
|
403
393
|
outDirectoryRelativeUrl,
|
|
@@ -571,7 +561,7 @@ const compareValueJson = (left, right) => {
|
|
|
571
561
|
*
|
|
572
562
|
*/
|
|
573
563
|
const setupServerSentEventsForLivereload = ({
|
|
574
|
-
|
|
564
|
+
serverStopCallbackList,
|
|
575
565
|
projectDirectoryUrl,
|
|
576
566
|
jsenvDirectoryRelativeUrl,
|
|
577
567
|
outDirectoryRelativeUrl,
|
|
@@ -594,7 +584,7 @@ const setupServerSentEventsForLivereload = ({
|
|
|
594
584
|
return
|
|
595
585
|
}
|
|
596
586
|
|
|
597
|
-
projectFileRequested.notify(relativeUrl, request)
|
|
587
|
+
projectFileRequested.notify({ relativeUrl, request })
|
|
598
588
|
}
|
|
599
589
|
const watchDescription = {
|
|
600
590
|
...livereloadWatchConfig,
|
|
@@ -617,7 +607,7 @@ const setupServerSentEventsForLivereload = ({
|
|
|
617
607
|
recursive: true,
|
|
618
608
|
},
|
|
619
609
|
)
|
|
620
|
-
|
|
610
|
+
serverStopCallbackList.add(unregisterDirectoryLifecyle)
|
|
621
611
|
|
|
622
612
|
const getDependencySet = (mainRelativeUrl) => {
|
|
623
613
|
if (trackerMap.has(mainRelativeUrl)) {
|
|
@@ -630,7 +620,7 @@ const setupServerSentEventsForLivereload = ({
|
|
|
630
620
|
}
|
|
631
621
|
|
|
632
622
|
// each time a file is requested for the first time its dependencySet is computed
|
|
633
|
-
projectFileRequested.
|
|
623
|
+
projectFileRequested.add(({ relativeUrl: mainRelativeUrl }) => {
|
|
634
624
|
// for now no use case of livereloading on node.js
|
|
635
625
|
// and for browsers only html file can be main files
|
|
636
626
|
// this avoid collecting dependencies of non html files that will never be used
|
|
@@ -644,8 +634,8 @@ const setupServerSentEventsForLivereload = ({
|
|
|
644
634
|
dependencySet.add(mainRelativeUrl)
|
|
645
635
|
trackerMap.set(mainRelativeUrl, dependencySet)
|
|
646
636
|
|
|
647
|
-
const
|
|
648
|
-
(relativeUrl, request) => {
|
|
637
|
+
const removeDependencyRequestedCallback = projectFileRequested.add(
|
|
638
|
+
({ relativeUrl, request }) => {
|
|
649
639
|
if (dependencySet.has(relativeUrl)) {
|
|
650
640
|
return
|
|
651
641
|
}
|
|
@@ -668,10 +658,10 @@ const setupServerSentEventsForLivereload = ({
|
|
|
668
658
|
dependencySet.add(relativeUrl)
|
|
669
659
|
},
|
|
670
660
|
)
|
|
671
|
-
const
|
|
661
|
+
const removeMainRemovedCallback = projectFileRemoved.add((relativeUrl) => {
|
|
672
662
|
if (relativeUrl === mainRelativeUrl) {
|
|
673
|
-
|
|
674
|
-
|
|
663
|
+
removeDependencyRequestedCallback()
|
|
664
|
+
removeMainRemovedCallback()
|
|
675
665
|
trackerMap.delete(mainRelativeUrl)
|
|
676
666
|
}
|
|
677
667
|
})
|
|
@@ -683,19 +673,19 @@ const setupServerSentEventsForLivereload = ({
|
|
|
683
673
|
) => {
|
|
684
674
|
livereloadLogger.debug(`track ${mainRelativeUrl} and its dependencies`)
|
|
685
675
|
|
|
686
|
-
const
|
|
676
|
+
const removeModifiedCallback = projectFileModified.add((relativeUrl) => {
|
|
687
677
|
const dependencySet = getDependencySet(mainRelativeUrl)
|
|
688
678
|
if (dependencySet.has(relativeUrl)) {
|
|
689
679
|
modified(relativeUrl)
|
|
690
680
|
}
|
|
691
681
|
})
|
|
692
|
-
const
|
|
682
|
+
const removeRemovedCallback = projectFileRemoved.add((relativeUrl) => {
|
|
693
683
|
const dependencySet = getDependencySet(mainRelativeUrl)
|
|
694
684
|
if (dependencySet.has(relativeUrl)) {
|
|
695
685
|
removed(relativeUrl)
|
|
696
686
|
}
|
|
697
687
|
})
|
|
698
|
-
const
|
|
688
|
+
const removeAddedCallback = projectFileAdded.add((relativeUrl) => {
|
|
699
689
|
const dependencySet = getDependencySet(mainRelativeUrl)
|
|
700
690
|
if (dependencySet.has(relativeUrl)) {
|
|
701
691
|
added(relativeUrl)
|
|
@@ -706,9 +696,9 @@ const setupServerSentEventsForLivereload = ({
|
|
|
706
696
|
livereloadLogger.debug(
|
|
707
697
|
`stop tracking ${mainRelativeUrl} and its dependencies.`,
|
|
708
698
|
)
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
699
|
+
removeModifiedCallback()
|
|
700
|
+
removeRemovedCallback()
|
|
701
|
+
removeAddedCallback()
|
|
712
702
|
}
|
|
713
703
|
}
|
|
714
704
|
|
|
@@ -773,11 +763,14 @@ const setupServerSentEventsForLivereload = ({
|
|
|
773
763
|
}
|
|
774
764
|
}
|
|
775
765
|
|
|
776
|
-
return {
|
|
766
|
+
return {
|
|
767
|
+
projectFileRequestedCallback,
|
|
768
|
+
trackMainAndDependencies,
|
|
769
|
+
}
|
|
777
770
|
}
|
|
778
771
|
|
|
779
772
|
const createSSEForLivereloadService = ({
|
|
780
|
-
|
|
773
|
+
serverStopCallbackList,
|
|
781
774
|
outDirectoryRelativeUrl,
|
|
782
775
|
trackMainAndDependencies,
|
|
783
776
|
}) => {
|
|
@@ -811,9 +804,8 @@ const createSSEForLivereloadService = ({
|
|
|
811
804
|
},
|
|
812
805
|
})
|
|
813
806
|
|
|
814
|
-
const
|
|
815
|
-
|
|
816
|
-
|
|
807
|
+
const removeSSECleanupCallback = serverStopCallbackList.add(() => {
|
|
808
|
+
removeSSECleanupCallback()
|
|
817
809
|
sseRoom.close()
|
|
818
810
|
stopTracking()
|
|
819
811
|
})
|
|
@@ -821,7 +813,7 @@ const createSSEForLivereloadService = ({
|
|
|
821
813
|
mainFileRelativeUrl,
|
|
822
814
|
sseRoom,
|
|
823
815
|
cleanup: () => {
|
|
824
|
-
|
|
816
|
+
removeSSECleanupCallback()
|
|
825
817
|
sseRoom.close()
|
|
826
818
|
stopTracking()
|
|
827
819
|
},
|
|
@@ -865,10 +857,13 @@ const createCompilationAssetFileService = ({ projectDirectoryUrl }) => {
|
|
|
865
857
|
const { origin, ressource } = request
|
|
866
858
|
const requestUrl = `${origin}${ressource}`
|
|
867
859
|
if (urlIsCompilationAsset(requestUrl)) {
|
|
868
|
-
return
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
860
|
+
return fetchFileSystem(
|
|
861
|
+
new URL(request.ressource.slice(1), projectDirectoryUrl),
|
|
862
|
+
{
|
|
863
|
+
headers: request.headers,
|
|
864
|
+
etagEnabled: true,
|
|
865
|
+
},
|
|
866
|
+
)
|
|
872
867
|
}
|
|
873
868
|
return null
|
|
874
869
|
}
|
|
@@ -924,10 +919,13 @@ const createSourceFileService = ({
|
|
|
924
919
|
const relativeUrl = ressource.slice(1)
|
|
925
920
|
projectFileRequestedCallback(relativeUrl, request)
|
|
926
921
|
|
|
927
|
-
const responsePromise =
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
922
|
+
const responsePromise = fetchFileSystem(
|
|
923
|
+
new URL(request.ressource.slice(1), projectDirectoryUrl),
|
|
924
|
+
{
|
|
925
|
+
headers: request.headers,
|
|
926
|
+
etagEnabled: projectFileEtagEnabled,
|
|
927
|
+
},
|
|
928
|
+
)
|
|
931
929
|
|
|
932
930
|
return responsePromise
|
|
933
931
|
}
|
|
@@ -1059,10 +1057,13 @@ const createOutFilesService = async ({
|
|
|
1059
1057
|
if (!isOutRootFile(requestUrl)) {
|
|
1060
1058
|
return null
|
|
1061
1059
|
}
|
|
1062
|
-
return
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1060
|
+
return fetchFileSystem(
|
|
1061
|
+
new URL(request.ressource.slice(1), projectDirectoryUrl),
|
|
1062
|
+
{
|
|
1063
|
+
headers: request.headers,
|
|
1064
|
+
etagEnabled: true,
|
|
1065
|
+
},
|
|
1066
|
+
)
|
|
1066
1067
|
}
|
|
1067
1068
|
}
|
|
1068
1069
|
// serve from memory
|
|
@@ -1118,51 +1119,6 @@ const createCompileProxyService = ({ projectDirectoryUrl }) => {
|
|
|
1118
1119
|
}
|
|
1119
1120
|
}
|
|
1120
1121
|
|
|
1121
|
-
const listenJsenvPackageVersionChange = ({
|
|
1122
|
-
projectDirectoryUrl,
|
|
1123
|
-
jsenvDirectoryRelativeUrl,
|
|
1124
|
-
onJsenvPackageVersionChange = () => {},
|
|
1125
|
-
}) => {
|
|
1126
|
-
const jsenvCoreDirectoryUrl = resolveUrl(
|
|
1127
|
-
jsenvDirectoryRelativeUrl,
|
|
1128
|
-
projectDirectoryUrl,
|
|
1129
|
-
)
|
|
1130
|
-
const packageFileUrl = resolveUrl("./package.json", jsenvCoreDirectoryUrl)
|
|
1131
|
-
const packageFilePath = urlToFileSystemPath(packageFileUrl)
|
|
1132
|
-
let packageVersion
|
|
1133
|
-
|
|
1134
|
-
try {
|
|
1135
|
-
packageVersion = readPackage(packageFilePath).version
|
|
1136
|
-
} catch (e) {
|
|
1137
|
-
if (e.code === "ENOENT") return () => {}
|
|
1138
|
-
}
|
|
1139
|
-
|
|
1140
|
-
const checkPackageVersion = () => {
|
|
1141
|
-
let packageObject
|
|
1142
|
-
try {
|
|
1143
|
-
packageObject = readPackage(packageFilePath)
|
|
1144
|
-
} catch (e) {
|
|
1145
|
-
// package json deleted ? not a problem
|
|
1146
|
-
// let's wait for it to show back
|
|
1147
|
-
if (e.code === "ENOENT") return
|
|
1148
|
-
// package.json malformed ? not a problem
|
|
1149
|
-
// let's wait for use to fix it or filesystem to finish writing the file
|
|
1150
|
-
if (e.name === "SyntaxError") return
|
|
1151
|
-
throw e
|
|
1152
|
-
}
|
|
1153
|
-
|
|
1154
|
-
if (packageVersion !== packageObject.version) {
|
|
1155
|
-
onJsenvPackageVersionChange()
|
|
1156
|
-
}
|
|
1157
|
-
}
|
|
1158
|
-
|
|
1159
|
-
return registerFileLifecycle(packageFilePath, {
|
|
1160
|
-
added: checkPackageVersion,
|
|
1161
|
-
updated: checkPackageVersion,
|
|
1162
|
-
keepProcessAlive: false,
|
|
1163
|
-
})
|
|
1164
|
-
}
|
|
1165
|
-
|
|
1166
1122
|
const readPackage = (packagePath) => {
|
|
1167
1123
|
const buffer = readFileSync(packagePath)
|
|
1168
1124
|
const string = String(buffer)
|
|
@@ -1170,10 +1126,6 @@ const readPackage = (packagePath) => {
|
|
|
1170
1126
|
return packageObject
|
|
1171
1127
|
}
|
|
1172
1128
|
|
|
1173
|
-
export const STOP_REASON_PACKAGE_VERSION_CHANGED = {
|
|
1174
|
-
toString: () => `package version changed`,
|
|
1175
|
-
}
|
|
1176
|
-
|
|
1177
1129
|
const __filenameReplacement = `import.meta.url.slice('file:///'.length)`
|
|
1178
1130
|
|
|
1179
1131
|
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,40 @@
|
|
|
1
|
-
import { createOperation } from "@jsenv/cancellation"
|
|
2
1
|
import { resolveUrl, urlToFileSystemPath, readFile } from "@jsenv/filesystem"
|
|
3
2
|
|
|
4
3
|
import {
|
|
5
4
|
babelPluginsFromBabelPluginMap,
|
|
6
5
|
getMinimalBabelPluginMap,
|
|
7
6
|
} from "@jsenv/core/src/internal/compiling/babel_plugins.js"
|
|
8
|
-
|
|
9
7
|
import { babelPluginInstrument } from "./babel_plugin_instrument.js"
|
|
10
8
|
import { createEmptyCoverage } from "./createEmptyCoverage.js"
|
|
11
9
|
|
|
12
10
|
export const relativeUrlToEmptyCoverage = async (
|
|
13
11
|
relativeUrl,
|
|
14
|
-
{
|
|
12
|
+
{ multipleExecutionsOperation, projectDirectoryUrl, babelPluginMap },
|
|
15
13
|
) => {
|
|
16
14
|
const { transformAsync } = await import("@babel/core")
|
|
17
15
|
|
|
18
16
|
const fileUrl = resolveUrl(relativeUrl, projectDirectoryUrl)
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
start: () => readFile(fileUrl),
|
|
22
|
-
})
|
|
17
|
+
multipleExecutionsOperation.throwIfAborted()
|
|
18
|
+
const source = await readFile(fileUrl)
|
|
23
19
|
|
|
24
20
|
try {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
...babelPluginMap,
|
|
31
|
-
"transform-instrument": [
|
|
32
|
-
babelPluginInstrument,
|
|
33
|
-
{ projectDirectoryUrl },
|
|
34
|
-
],
|
|
35
|
-
}
|
|
21
|
+
babelPluginMap = {
|
|
22
|
+
...getMinimalBabelPluginMap(),
|
|
23
|
+
...babelPluginMap,
|
|
24
|
+
"transform-instrument": [babelPluginInstrument, { projectDirectoryUrl }],
|
|
25
|
+
}
|
|
36
26
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
plugins: babelPluginsFromBabelPluginMap(babelPluginMap),
|
|
47
|
-
})
|
|
48
|
-
return { metadata }
|
|
27
|
+
multipleExecutionsOperation.throwIfAborted()
|
|
28
|
+
const { metadata } = await transformAsync(source, {
|
|
29
|
+
filename: urlToFileSystemPath(fileUrl),
|
|
30
|
+
filenameRelative: relativeUrl,
|
|
31
|
+
configFile: false,
|
|
32
|
+
babelrc: false,
|
|
33
|
+
ast: true,
|
|
34
|
+
parserOpts: {
|
|
35
|
+
allowAwaitOutsideFunction: true,
|
|
49
36
|
},
|
|
37
|
+
plugins: babelPluginsFromBabelPluginMap(babelPluginMap),
|
|
50
38
|
})
|
|
51
39
|
|
|
52
40
|
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,
|