@jsenv/core 27.0.3 → 27.2.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.
Files changed (37) hide show
  1. package/dist/controllable_child_process.mjs +139 -0
  2. package/dist/controllable_worker_thread.mjs +103 -0
  3. package/dist/js/execute_using_dynamic_import.js +169 -0
  4. package/dist/js/v8_coverage.js +539 -0
  5. package/dist/main.js +683 -818
  6. package/package.json +9 -8
  7. package/src/build/build.js +9 -12
  8. package/src/build/build_urls_generator.js +1 -1
  9. package/src/build/inject_global_version_mappings.js +3 -2
  10. package/src/build/inject_service_worker_urls.js +1 -2
  11. package/src/execute/run.js +50 -68
  12. package/src/execute/runtimes/browsers/chromium.js +1 -1
  13. package/src/execute/runtimes/browsers/firefox.js +1 -1
  14. package/src/execute/runtimes/browsers/from_playwright.js +13 -8
  15. package/src/execute/runtimes/browsers/webkit.js +1 -1
  16. package/src/execute/runtimes/node/{controllable_file.mjs → controllable_child_process.mjs} +18 -50
  17. package/src/execute/runtimes/node/controllable_worker_thread.mjs +103 -0
  18. package/src/execute/runtimes/node/execute_using_dynamic_import.js +49 -0
  19. package/src/execute/runtimes/node/exit_codes.js +9 -0
  20. package/src/execute/runtimes/node/{node_process.js → node_child_process.js} +56 -50
  21. package/src/execute/runtimes/node/node_worker_thread.js +268 -25
  22. package/src/execute/runtimes/node/profiler_v8_coverage.js +56 -0
  23. package/src/main.js +3 -1
  24. package/src/omega/kitchen.js +19 -6
  25. package/src/omega/server/file_service.js +2 -2
  26. package/src/omega/url_graph/url_graph_load.js +0 -1
  27. package/src/omega/url_graph.js +1 -0
  28. package/src/plugins/bundling/js_module/bundle_js_module.js +2 -5
  29. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic.js +18 -15
  30. package/src/plugins/url_resolution/jsenv_plugin_url_resolution.js +2 -1
  31. package/src/test/coverage/report_to_coverage.js +16 -19
  32. package/src/test/coverage/v8_coverage.js +26 -0
  33. package/src/test/coverage/{v8_coverage_from_directory.js → v8_coverage_node_directory.js} +22 -26
  34. package/src/test/execute_plan.js +98 -91
  35. package/src/test/execute_test_plan.js +19 -13
  36. package/src/test/logs_file_execution.js +90 -13
  37. package/dist/js/controllable_file.mjs +0 -227
package/dist/main.js CHANGED
@@ -13,17 +13,17 @@ import { performance } from "node:perf_hooks";
13
13
  import { extname, dirname, basename } from "node:path";
14
14
  import { pathToFileURL, fileURLToPath } from "node:url";
15
15
  import crypto, { createHash } from "node:crypto";
16
+ import { U as URL_META, f as filterV8Coverage } from "./js/v8_coverage.js";
16
17
  import { parseHtmlString, stringifyHtmlAst, visitHtmlNodes, getHtmlNodeAttribute, setHtmlNodeAttributes, parseSrcSet, getHtmlNodePosition, getHtmlNodeAttributePosition, applyPostCss, postCssPluginUrlVisitor, parseJsUrls, findHtmlNode, getHtmlNodeText, removeHtmlNode, setHtmlNodeText, analyzeScriptNode, applyBabelPlugins, injectScriptNodeAsEarlyAsPossible, createHtmlNode, removeHtmlNodeText, transpileWithParcel, injectJsImport, minifyWithParcel, analyzeLinkNode } from "@jsenv/ast";
17
18
  import { createMagicSource, composeTwoSourcemaps, sourcemapConverter, SOURCEMAP, generateSourcemapFileUrl, generateSourcemapDataUrl } from "@jsenv/sourcemap";
18
19
  import { createRequire } from "node:module";
19
20
  import babelParser from "@babel/parser";
21
+ import v8, { takeCoverage } from "node:v8";
20
22
  import wrapAnsi from "wrap-ansi";
21
23
  import stripAnsi from "strip-ansi";
22
24
  import cuid from "cuid";
23
- import v8 from "node:v8";
24
25
  import { runInNewContext, Script } from "node:vm";
25
26
  import { fork } from "node:child_process";
26
- import { u as uneval } from "./js/uneval.js";
27
27
 
28
28
  const LOG_LEVEL_OFF = "off";
29
29
  const LOG_LEVEL_DEBUG = "debug";
@@ -332,23 +332,27 @@ const canUseUnicode = isUnicodeSupported();
332
332
  const COMMAND_RAW = canUseUnicode ? `❯` : `>`;
333
333
  const OK_RAW = canUseUnicode ? `✔` : `√`;
334
334
  const FAILURE_RAW = canUseUnicode ? `✖` : `×`;
335
+ const DEBUG_RAW = canUseUnicode ? `◆` : `♦`;
335
336
  const INFO_RAW = canUseUnicode ? `ℹ` : `i`;
336
337
  const WARNING_RAW = canUseUnicode ? `⚠` : `‼`;
337
338
  const COMMAND = ANSI.color(COMMAND_RAW, ANSI.GREY); // ANSI_MAGENTA)
338
339
 
339
340
  const OK = ANSI.color(OK_RAW, ANSI.GREEN);
340
341
  const FAILURE = ANSI.color(FAILURE_RAW, ANSI.RED);
342
+ const DEBUG = ANSI.color(DEBUG_RAW, ANSI.GREY);
341
343
  const INFO = ANSI.color(INFO_RAW, ANSI.BLUE);
342
344
  const WARNING = ANSI.color(WARNING_RAW, ANSI.YELLOW);
343
345
  const UNICODE = {
344
346
  COMMAND,
345
347
  OK,
346
348
  FAILURE,
349
+ DEBUG,
347
350
  INFO,
348
351
  WARNING,
349
352
  COMMAND_RAW,
350
353
  OK_RAW,
351
354
  FAILURE_RAW,
355
+ DEBUG_RAW,
352
356
  INFO_RAW,
353
357
  WARNING_RAW,
354
358
  supported: canUseUnicode
@@ -5738,515 +5742,6 @@ const createEventHistory = limit => {
5738
5742
  };
5739
5743
  };
5740
5744
 
5741
- const assertUrlLike = (value, name = "url") => {
5742
- if (typeof value !== "string") {
5743
- throw new TypeError(`${name} must be a url string, got ${value}`);
5744
- }
5745
-
5746
- if (isWindowsPathnameSpecifier(value)) {
5747
- throw new TypeError(`${name} must be a url but looks like a windows pathname, got ${value}`);
5748
- }
5749
-
5750
- if (!hasScheme$1(value)) {
5751
- throw new TypeError(`${name} must be a url and no scheme found, got ${value}`);
5752
- }
5753
- };
5754
- const isPlainObject = value => {
5755
- if (value === null) {
5756
- return false;
5757
- }
5758
-
5759
- if (typeof value === "object") {
5760
- if (Array.isArray(value)) {
5761
- return false;
5762
- }
5763
-
5764
- return true;
5765
- }
5766
-
5767
- return false;
5768
- };
5769
-
5770
- const isWindowsPathnameSpecifier = specifier => {
5771
- const firstChar = specifier[0];
5772
- if (!/[a-zA-Z]/.test(firstChar)) return false;
5773
- const secondChar = specifier[1];
5774
- if (secondChar !== ":") return false;
5775
- const thirdChar = specifier[2];
5776
- return thirdChar === "/" || thirdChar === "\\";
5777
- };
5778
-
5779
- const hasScheme$1 = specifier => /^[a-zA-Z]+:/.test(specifier);
5780
-
5781
- const resolveAssociations = (associations, baseUrl) => {
5782
- assertUrlLike(baseUrl, "baseUrl");
5783
- const associationsResolved = {};
5784
- Object.keys(associations).forEach(key => {
5785
- const valueMap = associations[key];
5786
- const valueMapResolved = {};
5787
- Object.keys(valueMap).forEach(pattern => {
5788
- const value = valueMap[pattern];
5789
- const patternResolved = normalizeUrlPattern(pattern, baseUrl);
5790
- valueMapResolved[patternResolved] = value;
5791
- });
5792
- associationsResolved[key] = valueMapResolved;
5793
- });
5794
- return associationsResolved;
5795
- };
5796
-
5797
- const normalizeUrlPattern = (urlPattern, baseUrl) => {
5798
- // starts with a scheme
5799
- if (/^[a-zA-Z]{2,}:/.test(urlPattern)) {
5800
- return urlPattern;
5801
- }
5802
-
5803
- return String(new URL(urlPattern, baseUrl));
5804
- };
5805
-
5806
- const asFlatAssociations = associations => {
5807
- if (!isPlainObject(associations)) {
5808
- throw new TypeError(`associations must be a plain object, got ${associations}`);
5809
- }
5810
-
5811
- const flatAssociations = {};
5812
- Object.keys(associations).forEach(key => {
5813
- const valueMap = associations[key];
5814
-
5815
- if (!isPlainObject(valueMap)) {
5816
- throw new TypeError(`all associations value must be objects, found "${key}": ${valueMap}`);
5817
- }
5818
-
5819
- Object.keys(valueMap).forEach(pattern => {
5820
- const value = valueMap[pattern];
5821
- const previousValue = flatAssociations[pattern];
5822
- flatAssociations[pattern] = previousValue ? { ...previousValue,
5823
- [key]: value
5824
- } : {
5825
- [key]: value
5826
- };
5827
- });
5828
- });
5829
- return flatAssociations;
5830
- };
5831
-
5832
- /*
5833
- * Link to things doing pattern matching:
5834
- * https://git-scm.com/docs/gitignore
5835
- * https://github.com/kaelzhang/node-ignore
5836
- */
5837
- /** @module jsenv_url_meta **/
5838
-
5839
- /**
5840
- * An object representing the result of applying a pattern to an url
5841
- * @typedef {Object} MatchResult
5842
- * @property {boolean} matched Indicates if url matched pattern
5843
- * @property {number} patternIndex Index where pattern stopped matching url, otherwise pattern.length
5844
- * @property {number} urlIndex Index where url stopped matching pattern, otherwise url.length
5845
- * @property {Array} matchGroups Array of strings captured during pattern matching
5846
- */
5847
-
5848
- /**
5849
- * Apply a pattern to an url
5850
- * @param {Object} applyPatternMatchingParams
5851
- * @param {string} applyPatternMatchingParams.pattern "*", "**" and trailing slash have special meaning
5852
- * @param {string} applyPatternMatchingParams.url a string representing an url
5853
- * @return {MatchResult}
5854
- */
5855
-
5856
- const applyPatternMatching = ({
5857
- url,
5858
- pattern
5859
- }) => {
5860
- assertUrlLike(pattern, "pattern");
5861
- assertUrlLike(url, "url");
5862
- const {
5863
- matched,
5864
- patternIndex,
5865
- index,
5866
- groups
5867
- } = applyMatching(pattern, url);
5868
- const matchGroups = [];
5869
- let groupIndex = 0;
5870
- groups.forEach(group => {
5871
- if (group.name) {
5872
- matchGroups[group.name] = group.string;
5873
- } else {
5874
- matchGroups[groupIndex] = group.string;
5875
- groupIndex++;
5876
- }
5877
- });
5878
- return {
5879
- matched,
5880
- patternIndex,
5881
- urlIndex: index,
5882
- matchGroups
5883
- };
5884
- };
5885
-
5886
- const applyMatching = (pattern, string) => {
5887
- const groups = [];
5888
- let patternIndex = 0;
5889
- let index = 0;
5890
- let remainingPattern = pattern;
5891
- let remainingString = string;
5892
- let restoreIndexes = true;
5893
-
5894
- const consumePattern = count => {
5895
- const subpattern = remainingPattern.slice(0, count);
5896
- remainingPattern = remainingPattern.slice(count);
5897
- patternIndex += count;
5898
- return subpattern;
5899
- };
5900
-
5901
- const consumeString = count => {
5902
- const substring = remainingString.slice(0, count);
5903
- remainingString = remainingString.slice(count);
5904
- index += count;
5905
- return substring;
5906
- };
5907
-
5908
- const consumeRemainingString = () => {
5909
- return consumeString(remainingString.length);
5910
- };
5911
-
5912
- let matched;
5913
-
5914
- const iterate = () => {
5915
- const patternIndexBefore = patternIndex;
5916
- const indexBefore = index;
5917
- matched = matchOne();
5918
-
5919
- if (matched === undefined) {
5920
- consumePattern(1);
5921
- consumeString(1);
5922
- iterate();
5923
- return;
5924
- }
5925
-
5926
- if (matched === false && restoreIndexes) {
5927
- patternIndex = patternIndexBefore;
5928
- index = indexBefore;
5929
- }
5930
- };
5931
-
5932
- const matchOne = () => {
5933
- // pattern consumed and string consumed
5934
- if (remainingPattern === "" && remainingString === "") {
5935
- return true; // string fully matched pattern
5936
- } // pattern consumed, string not consumed
5937
-
5938
-
5939
- if (remainingPattern === "" && remainingString !== "") {
5940
- return false; // fails because string longer than expected
5941
- } // -- from this point pattern is not consumed --
5942
- // string consumed, pattern not consumed
5943
-
5944
-
5945
- if (remainingString === "") {
5946
- if (remainingPattern === "**") {
5947
- // trailing "**" is optional
5948
- consumePattern(2);
5949
- return true;
5950
- }
5951
-
5952
- if (remainingPattern === "*") {
5953
- groups.push({
5954
- string: ""
5955
- });
5956
- }
5957
-
5958
- return false; // fail because string shorter than expected
5959
- } // -- from this point pattern and string are not consumed --
5960
- // fast path trailing slash
5961
-
5962
-
5963
- if (remainingPattern === "/") {
5964
- if (remainingString[0] === "/") {
5965
- // trailing slash match remaining
5966
- consumePattern(1);
5967
- groups.push({
5968
- string: consumeRemainingString()
5969
- });
5970
- return true;
5971
- }
5972
-
5973
- return false;
5974
- } // fast path trailing '**'
5975
-
5976
-
5977
- if (remainingPattern === "**") {
5978
- consumePattern(2);
5979
- consumeRemainingString();
5980
- return true;
5981
- } // pattern leading **
5982
-
5983
-
5984
- if (remainingPattern.slice(0, 2) === "**") {
5985
- consumePattern(2); // consumes "**"
5986
-
5987
- if (remainingPattern[0] === "/") {
5988
- consumePattern(1); // consumes "/"
5989
- } // pattern ending with ** always match remaining string
5990
-
5991
-
5992
- if (remainingPattern === "") {
5993
- consumeRemainingString();
5994
- return true;
5995
- }
5996
-
5997
- const skipResult = skipUntilMatch({
5998
- pattern: remainingPattern,
5999
- string: remainingString,
6000
- canSkipSlash: true
6001
- });
6002
- groups.push(...skipResult.groups);
6003
- consumePattern(skipResult.patternIndex);
6004
- consumeRemainingString();
6005
- restoreIndexes = false;
6006
- return skipResult.matched;
6007
- }
6008
-
6009
- if (remainingPattern[0] === "*") {
6010
- consumePattern(1); // consumes "*"
6011
-
6012
- if (remainingPattern === "") {
6013
- // matches everything except '/'
6014
- const slashIndex = remainingString.indexOf("/");
6015
-
6016
- if (slashIndex === -1) {
6017
- groups.push({
6018
- string: consumeRemainingString()
6019
- });
6020
- return true;
6021
- }
6022
-
6023
- groups.push({
6024
- string: consumeString(slashIndex)
6025
- });
6026
- return false;
6027
- } // the next char must not the one expected by remainingPattern[0]
6028
- // because * is greedy and expect to skip at least one char
6029
-
6030
-
6031
- if (remainingPattern[0] === remainingString[0]) {
6032
- groups.push({
6033
- string: ""
6034
- });
6035
- patternIndex = patternIndex - 1;
6036
- return false;
6037
- }
6038
-
6039
- const skipResult = skipUntilMatch({
6040
- pattern: remainingPattern,
6041
- string: remainingString,
6042
- canSkipSlash: false
6043
- });
6044
- groups.push(skipResult.group, ...skipResult.groups);
6045
- consumePattern(skipResult.patternIndex);
6046
- consumeString(skipResult.index);
6047
- restoreIndexes = false;
6048
- return skipResult.matched;
6049
- }
6050
-
6051
- if (remainingPattern[0] !== remainingString[0]) {
6052
- return false;
6053
- }
6054
-
6055
- return undefined;
6056
- };
6057
-
6058
- iterate();
6059
- return {
6060
- matched,
6061
- patternIndex,
6062
- index,
6063
- groups
6064
- };
6065
- };
6066
-
6067
- const skipUntilMatch = ({
6068
- pattern,
6069
- string,
6070
- canSkipSlash
6071
- }) => {
6072
- let index = 0;
6073
- let remainingString = string;
6074
- let longestMatchRange = null;
6075
-
6076
- const tryToMatch = () => {
6077
- const matchAttempt = applyMatching(pattern, remainingString);
6078
-
6079
- if (matchAttempt.matched) {
6080
- return {
6081
- matched: true,
6082
- patternIndex: matchAttempt.patternIndex,
6083
- index: index + matchAttempt.index,
6084
- groups: matchAttempt.groups,
6085
- group: {
6086
- string: remainingString === "" ? string : string.slice(0, -remainingString.length)
6087
- }
6088
- };
6089
- }
6090
-
6091
- const matchAttemptIndex = matchAttempt.index;
6092
- const matchRange = {
6093
- patternIndex: matchAttempt.patternIndex,
6094
- index,
6095
- length: matchAttemptIndex,
6096
- groups: matchAttempt.groups
6097
- };
6098
-
6099
- if (!longestMatchRange || longestMatchRange.length < matchRange.length) {
6100
- longestMatchRange = matchRange;
6101
- }
6102
-
6103
- const nextIndex = matchAttemptIndex + 1;
6104
- const canSkip = nextIndex < remainingString.length && (canSkipSlash || remainingString[0] !== "/");
6105
-
6106
- if (canSkip) {
6107
- // search against the next unattempted string
6108
- index += nextIndex;
6109
- remainingString = remainingString.slice(nextIndex);
6110
- return tryToMatch();
6111
- }
6112
-
6113
- return {
6114
- matched: false,
6115
- patternIndex: longestMatchRange.patternIndex,
6116
- index: longestMatchRange.index + longestMatchRange.length,
6117
- groups: longestMatchRange.groups,
6118
- group: {
6119
- string: string.slice(0, longestMatchRange.index)
6120
- }
6121
- };
6122
- };
6123
-
6124
- return tryToMatch();
6125
- };
6126
-
6127
- const applyAssociations = ({
6128
- url,
6129
- associations
6130
- }) => {
6131
- assertUrlLike(url);
6132
- const flatAssociations = asFlatAssociations(associations);
6133
- return Object.keys(flatAssociations).reduce((previousValue, pattern) => {
6134
- const {
6135
- matched
6136
- } = applyPatternMatching({
6137
- pattern,
6138
- url
6139
- });
6140
-
6141
- if (matched) {
6142
- const value = flatAssociations[pattern];
6143
-
6144
- if (isPlainObject(previousValue) && isPlainObject(value)) {
6145
- return { ...previousValue,
6146
- ...value
6147
- };
6148
- }
6149
-
6150
- return value;
6151
- }
6152
-
6153
- return previousValue;
6154
- }, {});
6155
- };
6156
-
6157
- const applyAliases = ({
6158
- url,
6159
- aliases
6160
- }) => {
6161
- let aliasFullMatchResult;
6162
- const aliasMatchingKey = Object.keys(aliases).find(key => {
6163
- const aliasMatchResult = applyPatternMatching({
6164
- pattern: key,
6165
- url
6166
- });
6167
-
6168
- if (aliasMatchResult.matched) {
6169
- aliasFullMatchResult = aliasMatchResult;
6170
- return true;
6171
- }
6172
-
6173
- return false;
6174
- });
6175
-
6176
- if (!aliasMatchingKey) {
6177
- return url;
6178
- }
6179
-
6180
- const {
6181
- matchGroups
6182
- } = aliasFullMatchResult;
6183
- const alias = aliases[aliasMatchingKey];
6184
- const parts = alias.split("*");
6185
- const newUrl = parts.reduce((previous, value, index) => {
6186
- return `${previous}${value}${index === parts.length - 1 ? "" : matchGroups[index]}`;
6187
- }, "");
6188
- return newUrl;
6189
- };
6190
-
6191
- const urlChildMayMatch = ({
6192
- url,
6193
- associations,
6194
- predicate
6195
- }) => {
6196
- assertUrlLike(url, "url"); // the function was meants to be used on url ending with '/'
6197
-
6198
- if (!url.endsWith("/")) {
6199
- throw new Error(`url should end with /, got ${url}`);
6200
- }
6201
-
6202
- if (typeof predicate !== "function") {
6203
- throw new TypeError(`predicate must be a function, got ${predicate}`);
6204
- }
6205
-
6206
- const flatAssociations = asFlatAssociations(associations); // for full match we must create an object to allow pattern to override previous ones
6207
-
6208
- let fullMatchMeta = {};
6209
- let someFullMatch = false; // for partial match, any meta satisfying predicate will be valid because
6210
- // we don't know for sure if pattern will still match for a file inside pathname
6211
-
6212
- const partialMatchMetaArray = [];
6213
- Object.keys(flatAssociations).forEach(pattern => {
6214
- const value = flatAssociations[pattern];
6215
- const matchResult = applyPatternMatching({
6216
- pattern,
6217
- url
6218
- });
6219
-
6220
- if (matchResult.matched) {
6221
- someFullMatch = true;
6222
-
6223
- if (isPlainObject(fullMatchMeta) && isPlainObject(value)) {
6224
- fullMatchMeta = { ...fullMatchMeta,
6225
- ...value
6226
- };
6227
- } else {
6228
- fullMatchMeta = value;
6229
- }
6230
- } else if (someFullMatch === false && matchResult.urlIndex >= url.length) {
6231
- partialMatchMetaArray.push(value);
6232
- }
6233
- });
6234
-
6235
- if (someFullMatch) {
6236
- return Boolean(predicate(fullMatchMeta));
6237
- }
6238
-
6239
- return partialMatchMetaArray.some(partialMatchMeta => predicate(partialMatchMeta));
6240
- };
6241
-
6242
- const URL_META = {
6243
- resolveAssociations,
6244
- applyAssociations,
6245
- urlChildMayMatch,
6246
- applyPatternMatching,
6247
- applyAliases
6248
- };
6249
-
6250
5745
  const pluginRequestWaitingCheck = ({
6251
5746
  requestWaitingMs = 20000,
6252
5747
  requestWaitingCallback = ({
@@ -10067,7 +9562,10 @@ const jsenvPluginUrlResolution = () => {
10067
9562
  name: "jsenv:url_resolution",
10068
9563
  appliesDuring: "*",
10069
9564
  resolveUrl: {
9565
+ "http_request": urlResolver,
9566
+ // during dev
10070
9567
  "entry_point": urlResolver,
9568
+ // during build
10071
9569
  "link_href": urlResolver,
10072
9570
  "script_src": urlResolver,
10073
9571
  "a_href": urlResolver,
@@ -18022,16 +17520,16 @@ const jsenvPluginAsJsClassicConversion = ({
18022
17520
  return null;
18023
17521
  }
18024
17522
 
18025
- const isJsEntryPoint = // in general html files are entry points
18026
- // but during build js can be sepcified as an entry point
18027
- // (meaning there is no html file where we can inject systemjs)
18028
- // in that case we need to inject systemjs in the js file
18029
- originalUrlInfo.data.isEntryPoint || // In thoose case we need to inject systemjs the worker js file
18030
- originalUrlInfo.data.isWebWorkerEntryPoint; // if it's an entry point without dependency (it does not use import)
17523
+ const jsClassicFormat = // in general html file are entry points, but js can be entry point when:
17524
+ // - passed in entryPoints to build
17525
+ // - is used by web worker
17526
+ // - the reference contains ?entry_point
17527
+ // When js is entry point there can be no HTML to inject systemjs
17528
+ // and systemjs must be injected into the js file
17529
+ originalUrlInfo.isEntryPoint && // if it's an entry point without dependency (it does not use import)
18031
17530
  // then we can use UMD, otherwise we have to use systemjs
18032
17531
  // because it is imported by systemjs
18033
-
18034
- const jsClassicFormat = isJsEntryPoint && !originalUrlInfo.data.usesImport ? "umd" : "system";
17532
+ !originalUrlInfo.data.usesImport ? "umd" : "system";
18035
17533
  const {
18036
17534
  content,
18037
17535
  sourcemap
@@ -18039,7 +17537,6 @@ const jsenvPluginAsJsClassicConversion = ({
18039
17537
  systemJsInjection,
18040
17538
  systemJsClientFileUrl,
18041
17539
  urlInfo: originalUrlInfo,
18042
- isJsEntryPoint,
18043
17540
  jsClassicFormat
18044
17541
  });
18045
17542
  urlInfo.data.jsClassicFormat = jsClassicFormat;
@@ -18083,7 +17580,6 @@ const convertJsModuleToJsClassic = async ({
18083
17580
  systemJsInjection,
18084
17581
  systemJsClientFileUrl,
18085
17582
  urlInfo,
18086
- isJsEntryPoint,
18087
17583
  jsClassicFormat
18088
17584
  }) => {
18089
17585
  const {
@@ -18102,7 +17598,7 @@ const convertJsModuleToJsClassic = async ({
18102
17598
  let sourcemap = urlInfo.sourcemap;
18103
17599
  sourcemap = await composeTwoSourcemaps(sourcemap, map);
18104
17600
 
18105
- if (systemJsInjection && jsClassicFormat === "system" && isJsEntryPoint) {
17601
+ if (systemJsInjection && jsClassicFormat === "system" && urlInfo.isEntryPoint) {
18106
17602
  const magicSource = createMagicSource(code);
18107
17603
  const systemjsCode = readFileSync(systemJsClientFileUrl, {
18108
17604
  as: "string"
@@ -19796,7 +19292,7 @@ const rollupPluginJsenv = ({
19796
19292
  jsModuleUrlInfos.forEach(jsModuleUrlInfo => {
19797
19293
  const id = jsModuleUrlInfo.url;
19798
19294
 
19799
- if (jsModuleUrlInfo.data.isEntryPoint) {
19295
+ if (jsModuleUrlInfo.isEntryPoint) {
19800
19296
  emitChunk({
19801
19297
  id
19802
19298
  });
@@ -20079,7 +19575,7 @@ const willBeInsideJsDirectory = ({
20079
19575
  return true;
20080
19576
  }
20081
19577
 
20082
- if (!jsModuleUrlInfo.data.isEntryPoint && !jsModuleUrlInfo.data.isWebWorkerEntryPoint) {
19578
+ if (!jsModuleUrlInfo.isEntryPoint) {
20083
19579
  // not an entry point, jsenv will put it inside js/ directory
20084
19580
  return true;
20085
19581
  }
@@ -21439,6 +20935,7 @@ const createUrlInfo = url => {
21439
20935
  originalUrl: undefined,
21440
20936
  generatedUrl: null,
21441
20937
  filename: "",
20938
+ isEntryPoint: false,
21442
20939
  isInline: false,
21443
20940
  inlineUrlSite: null,
21444
20941
  shouldHandle: undefined,
@@ -22370,6 +21867,7 @@ const createKitchen = ({
22370
21867
  baseUrl,
22371
21868
  isOriginalPosition,
22372
21869
  shouldHandle,
21870
+ isEntryPoint = false,
22373
21871
  isInline = false,
22374
21872
  injected = false,
22375
21873
  isRessourceHint = false,
@@ -22407,6 +21905,7 @@ const createKitchen = ({
22407
21905
  baseUrl,
22408
21906
  isOriginalPosition,
22409
21907
  shouldHandle,
21908
+ isEntryPoint,
22410
21909
  isInline,
22411
21910
  injected,
22412
21911
  isRessourceHint,
@@ -22423,7 +21922,7 @@ const createKitchen = ({
22423
21922
  const mutateReference = (reference, newReference) => {
22424
21923
  reference.next = newReference;
22425
21924
  newReference.prev = reference;
22426
- newReference.original = reference.original || reference;
21925
+ newReference.original = reference.original || reference; // newReference.isEntryPoint = reference.isEntryPoint
22427
21926
  };
22428
21927
 
22429
21928
  const resolveReference = reference => {
@@ -22448,11 +21947,16 @@ const createKitchen = ({
22448
21947
  reference.url = normalizedReturnValue;
22449
21948
  mutateReference(previousReference, reference);
22450
21949
  });
22451
- const urlInfo = urlGraph.reuseOrCreateUrlInfo(reference.url);
22452
- applyReferenceEffectsOnUrlInfo(reference, urlInfo, kitchenContext);
22453
21950
  const referenceUrlObject = new URL(reference.url);
22454
21951
  reference.searchParams = referenceUrlObject.searchParams;
22455
- reference.generatedUrl = reference.url; // This hook must touch reference.generatedUrl, NOT reference.url
21952
+ reference.generatedUrl = reference.url;
21953
+
21954
+ if (reference.searchParams.has("entry_point")) {
21955
+ reference.isEntryPoint = true;
21956
+ }
21957
+
21958
+ const urlInfo = urlGraph.reuseOrCreateUrlInfo(reference.url);
21959
+ applyReferenceEffectsOnUrlInfo(reference, urlInfo, kitchenContext); // This hook must touch reference.generatedUrl, NOT reference.url
22456
21960
  // And this is because this hook inject query params used to:
22457
21961
  // - bypass browser cache (?v)
22458
21962
  // - convey information (?hmr)
@@ -22553,7 +22057,8 @@ const createKitchen = ({
22553
22057
  filename,
22554
22058
  status = 200,
22555
22059
  headers = {},
22556
- body
22060
+ body,
22061
+ isEntryPoint
22557
22062
  } = fetchUrlContentReturnValue;
22558
22063
 
22559
22064
  if (status !== 200) {
@@ -22589,6 +22094,10 @@ const createKitchen = ({
22589
22094
  Object.assign(urlInfo.data, data);
22590
22095
  }
22591
22096
 
22097
+ if (typeof isEntryPoint === "boolean") {
22098
+ urlInfo.isEntryPoint = isEntryPoint;
22099
+ }
22100
+
22592
22101
  if (filename) {
22593
22102
  urlInfo.filename = filename;
22594
22103
  }
@@ -22891,6 +22400,7 @@ const createKitchen = ({
22891
22400
 
22892
22401
  const prepareEntryPoint = params => {
22893
22402
  const entryReference = createReference(params);
22403
+ entryReference.isEntryPoint = true;
22894
22404
  const entryUrlInfo = resolveReference(entryReference);
22895
22405
  return [entryReference, entryUrlInfo];
22896
22406
  };
@@ -22998,6 +22508,11 @@ const applyReferenceEffectsOnUrlInfo = (reference, urlInfo, context) => {
22998
22508
  }
22999
22509
 
23000
22510
  urlInfo.originalUrl = urlInfo.originalUrl || reference.url;
22511
+
22512
+ if (reference.isEntryPoint || isWebWorkerEntryPointReference(reference)) {
22513
+ urlInfo.isEntryPoint = true;
22514
+ }
22515
+
23001
22516
  Object.assign(urlInfo.data, reference.data);
23002
22517
  Object.assign(urlInfo.timing, reference.timing);
23003
22518
 
@@ -23022,10 +22537,6 @@ const applyReferenceEffectsOnUrlInfo = (reference, urlInfo, context) => {
23022
22537
  urlInfo.originalContent = context === "build" ? urlInfo.originalContent === undefined ? reference.content : urlInfo.originalContent : reference.content;
23023
22538
  urlInfo.content = reference.content;
23024
22539
  }
23025
-
23026
- if (isWebWorkerEntryPointReference(reference)) {
23027
- urlInfo.data.isWebWorkerEntryPoint = true;
23028
- }
23029
22540
  };
23030
22541
 
23031
22542
  const adjustUrlSite = (urlInfo, {
@@ -23308,10 +22819,10 @@ const createFileService = ({
23308
22819
  }
23309
22820
 
23310
22821
  if (!reference) {
23311
- const entryPoint = kitchen.prepareEntryPoint({
22822
+ const entryPoint = kitchen.injectReference({
23312
22823
  trace: parentUrl || rootDirectoryUrl,
23313
22824
  parentUrl: parentUrl || rootDirectoryUrl,
23314
- type: "entry_point",
22825
+ type: "http_request",
23315
22826
  specifier: request.ressource
23316
22827
  });
23317
22828
  reference = entryPoint[0];
@@ -24064,23 +23575,31 @@ const babelPluginInstrument = (api, {
24064
23575
  };
24065
23576
  };
24066
23577
 
24067
- const visitNodeV8Directory = async ({
23578
+ const readNodeV8CoverageDirectory = async ({
24068
23579
  logger,
24069
23580
  signal,
24070
- NODE_V8_COVERAGE,
24071
23581
  onV8Coverage,
24072
23582
  maxMsWaitingForNodeToWriteCoverageFile = 2000
24073
23583
  }) => {
23584
+ const NODE_V8_COVERAGE = process.env.NODE_V8_COVERAGE;
24074
23585
  const operation = Abort.startOperation();
24075
23586
  operation.addAbortSignal(signal);
23587
+ let timeSpentTrying = 0;
24076
23588
 
24077
23589
  const tryReadDirectory = async () => {
24078
- const dirContent = await readDirectory(NODE_V8_COVERAGE);
23590
+ const dirContent = readdirSync(NODE_V8_COVERAGE);
24079
23591
 
24080
23592
  if (dirContent.length > 0) {
24081
23593
  return dirContent;
24082
23594
  }
24083
23595
 
23596
+ if (timeSpentTrying < maxMsWaitingForNodeToWriteCoverageFile) {
23597
+ await new Promise(resolve => setTimeout(resolve, 200));
23598
+ timeSpentTrying += 200;
23599
+ logger.debug("retry to read coverage directory");
23600
+ return tryReadDirectory();
23601
+ }
23602
+
24084
23603
  logger.warn(`v8 coverage directory is empty at ${NODE_V8_COVERAGE}`);
24085
23604
  return dirContent;
24086
23605
  };
@@ -24092,17 +23611,16 @@ const visitNodeV8Directory = async ({
24092
23611
  await dirContent.reduce(async (previous, dirEntry) => {
24093
23612
  operation.throwIfAborted();
24094
23613
  await previous;
24095
- const dirEntryUrl = resolveUrl$1(dirEntry, coverageDirectoryUrl);
23614
+ const dirEntryUrl = new URL(dirEntry, coverageDirectoryUrl);
24096
23615
 
24097
- const tryReadJsonFile = async (timeSpentTrying = 0) => {
24098
- const fileContent = await readFile(dirEntryUrl, {
24099
- as: "string"
24100
- });
23616
+ const tryReadJsonFile = async () => {
23617
+ const fileContent = String(readFileSync$1(dirEntryUrl));
24101
23618
 
24102
23619
  if (fileContent === "") {
24103
- if (timeSpentTrying < 400) {
23620
+ if (timeSpentTrying < maxMsWaitingForNodeToWriteCoverageFile) {
24104
23621
  await new Promise(resolve => setTimeout(resolve, 200));
24105
- return tryReadJsonFile(timeSpentTrying + 200);
23622
+ timeSpentTrying += 200;
23623
+ return tryReadJsonFile();
24106
23624
  }
24107
23625
 
24108
23626
  console.warn(`Coverage JSON file is empty at ${dirEntryUrl}`);
@@ -24115,7 +23633,8 @@ const visitNodeV8Directory = async ({
24115
23633
  } catch (e) {
24116
23634
  if (timeSpentTrying < maxMsWaitingForNodeToWriteCoverageFile) {
24117
23635
  await new Promise(resolve => setTimeout(resolve, 200));
24118
- return tryReadJsonFile(timeSpentTrying + 200);
23636
+ timeSpentTrying += 200;
23637
+ return tryReadJsonFile();
24119
23638
  }
24120
23639
 
24121
23640
  console.warn(createDetailedMessage$1(`Error while reading coverage file`, {
@@ -24129,21 +23648,13 @@ const visitNodeV8Directory = async ({
24129
23648
  const fileContent = await tryReadJsonFile();
24130
23649
 
24131
23650
  if (fileContent) {
24132
- onV8Coverage(fileContent);
23651
+ await onV8Coverage(fileContent);
24133
23652
  }
24134
23653
  }, Promise.resolve());
24135
23654
  } finally {
24136
23655
  await operation.end();
24137
23656
  }
24138
23657
  };
24139
- const filterV8Coverage = (v8Coverage, {
24140
- urlShouldBeCovered
24141
- }) => {
24142
- const v8CoverageFiltered = { ...v8Coverage,
24143
- result: v8Coverage.result.filter(fileReport => urlShouldBeCovered(fileReport.url))
24144
- };
24145
- return v8CoverageFiltered;
24146
- };
24147
23658
 
24148
23659
  const composeTwoV8Coverages = (firstV8Coverage, secondV8Coverage) => {
24149
23660
  if (secondV8Coverage.result.length === 0) {
@@ -24444,8 +23955,7 @@ const reportToCoverage = async (report, {
24444
23955
  rootDirectoryUrl,
24445
23956
  coverageConfig,
24446
23957
  coverageIncludeMissing,
24447
- urlShouldBeCovered,
24448
- coverageForceIstanbul,
23958
+ coverageMethodForNodeJs,
24449
23959
  coverageV8ConflictWarning
24450
23960
  }) => {
24451
23961
  // collect v8 and istanbul coverage from executions
@@ -24474,20 +23984,20 @@ const reportToCoverage = async (report, {
24474
23984
  // in any scenario we are fine because
24475
23985
  // coverDescription will generate empty coverage for files
24476
23986
  // that were suppose to be coverage but were not.
24477
- if (executionResult.status === "completed" && executionResult.runtimeName !== "node" && !process.env.NODE_V8_COVERAGE) {
24478
- logger.warn(`No execution.coverageFileUrl from execution named "${executionName}" of ${file}`);
23987
+ if (executionResult.status === "completed" && executionResult.type === "node" && coverageMethodForNodeJs !== "NODE_V8_COVERAGE") {
23988
+ logger.warn(`No "coverageFileUrl" from execution named "${executionName}" of ${file}`);
24479
23989
  }
24480
23990
  }
24481
23991
  });
24482
23992
 
24483
- if (!coverageForceIstanbul && process.env.NODE_V8_COVERAGE) {
24484
- await visitNodeV8Directory({
23993
+ if (coverageMethodForNodeJs === "NODE_V8_COVERAGE") {
23994
+ await readNodeV8CoverageDirectory({
24485
23995
  logger,
24486
23996
  signal,
24487
- NODE_V8_COVERAGE: process.env.NODE_V8_COVERAGE,
24488
- onV8Coverage: nodeV8Coverage => {
24489
- const nodeV8CoverageLight = filterV8Coverage(nodeV8Coverage, {
24490
- urlShouldBeCovered
23997
+ onV8Coverage: async nodeV8Coverage => {
23998
+ const nodeV8CoverageLight = await filterV8Coverage(nodeV8Coverage, {
23999
+ rootDirectoryUrl,
24000
+ coverageConfig
24491
24001
  });
24492
24002
  v8Coverage = v8Coverage ? composeTwoV8Coverages(v8Coverage, nodeV8CoverageLight) : nodeV8CoverageLight;
24493
24003
  }
@@ -24566,9 +24076,7 @@ const getCoverageFromReport = async ({
24566
24076
  return;
24567
24077
  }
24568
24078
 
24569
- const executionCoverage = await readFile(coverageFileUrl, {
24570
- as: "json"
24571
- });
24079
+ const executionCoverage = JSON.parse(String(readFileSync$1(new URL(coverageFileUrl))));
24572
24080
 
24573
24081
  if (isV8Coverage(executionCoverage)) {
24574
24082
  v8Coverage = v8Coverage ? composeTwoV8Coverages(v8Coverage, executionCoverage) : executionCoverage;
@@ -24595,21 +24103,20 @@ const run = async ({
24595
24103
  keepRunning = false,
24596
24104
  mirrorConsole = false,
24597
24105
  collectConsole = false,
24598
- collectCoverage = false,
24106
+ coverageEnabled = false,
24599
24107
  coverageTempDirectoryUrl,
24600
24108
  collectPerformance = false,
24601
24109
  runtime,
24602
24110
  runtimeParams
24603
24111
  }) => {
24112
+ let result = {};
24113
+ const callbacks = [];
24604
24114
  const onConsoleRef = {
24605
24115
  current: () => {}
24606
24116
  };
24607
24117
  const stopSignal = {
24608
24118
  notify: () => {}
24609
24119
  };
24610
-
24611
- let resultTransformer = result => result;
24612
-
24613
24120
  const runtimeLabel = `${runtime.name}/${runtime.version}`;
24614
24121
  const runOperation = Abort.startOperation();
24615
24122
  runOperation.addAbortSignal(signal);
@@ -24618,21 +24125,21 @@ const run = async ({
24618
24125
  // when keepRunning is true
24619
24126
  !keepRunning && typeof allocatedMs === "number" && allocatedMs !== Infinity) {
24620
24127
  const timeoutAbortSource = runOperation.timeout(allocatedMs);
24621
- resultTransformer = composeTransformer$1(resultTransformer, result => {
24128
+ callbacks.push(() => {
24622
24129
  if (result.status === "errored" && Abort.isAbortError(result.error) && timeoutAbortSource.signal.aborted) {
24623
- return createTimedoutResult();
24130
+ result = {
24131
+ status: "timedout"
24132
+ };
24624
24133
  }
24625
-
24626
- return result;
24627
24134
  });
24628
24135
  }
24629
24136
 
24630
- resultTransformer = composeTransformer$1(resultTransformer, result => {
24137
+ callbacks.push(() => {
24631
24138
  if (result.status === "errored" && Abort.isAbortError(result.error)) {
24632
- return createAbortedResult();
24139
+ result = {
24140
+ status: "aborted"
24141
+ };
24633
24142
  }
24634
-
24635
- return result;
24636
24143
  });
24637
24144
  const consoleCalls = [];
24638
24145
 
@@ -24657,44 +24164,14 @@ const run = async ({
24657
24164
  };
24658
24165
 
24659
24166
  if (collectConsole) {
24660
- resultTransformer = composeTransformer$1(resultTransformer, result => {
24167
+ callbacks.push(() => {
24661
24168
  result.consoleCalls = consoleCalls;
24662
- return result;
24663
- });
24664
- }
24665
-
24666
- if (collectCoverage) {
24667
- resultTransformer = composeTransformer$1(resultTransformer, async result => {
24668
- // we do not keep coverage in memory, it can grow very big
24669
- // instead we store it on the filesystem
24670
- // and they can be read later at "coverageFileUrl"
24671
- const {
24672
- coverage
24673
- } = result;
24674
-
24675
- if (coverage) {
24676
- const coverageFileUrl = resolveUrl$1(`./${runtime.name}/${cuid()}`, coverageTempDirectoryUrl);
24677
- await writeFile(coverageFileUrl, JSON.stringify(coverage, null, " "));
24678
- result.coverageFileUrl = coverageFileUrl;
24679
- delete result.coverage;
24680
- }
24681
-
24682
- return result;
24683
- });
24684
- } else {
24685
- resultTransformer = composeTransformer$1(resultTransformer, result => {
24686
- // as collectCoverage is disabled
24687
- // executionResult.coverage is undefined or {}
24688
- // we delete it just to have a cleaner object
24689
- delete result.coverage;
24690
- return result;
24691
24169
  });
24692
24170
  }
24693
24171
 
24694
24172
  const startMs = Date.now();
24695
- resultTransformer = composeTransformer$1(resultTransformer, result => {
24173
+ callbacks.push(() => {
24696
24174
  result.duration = Date.now() - startMs;
24697
- return result;
24698
24175
  });
24699
24176
 
24700
24177
  try {
@@ -24710,7 +24187,7 @@ const run = async ({
24710
24187
  },
24711
24188
  runned: async cb => {
24712
24189
  try {
24713
- const result = await runtime.run({
24190
+ const runResult = await runtime.run({
24714
24191
  signal: runOperation.signal,
24715
24192
  logger,
24716
24193
  ...runtimeParams,
@@ -24719,7 +24196,7 @@ const run = async ({
24719
24196
  stopSignal,
24720
24197
  onConsole: log => onConsoleRef.current(log)
24721
24198
  });
24722
- cb(result);
24199
+ cb(runResult);
24723
24200
  } catch (e) {
24724
24201
  cb({
24725
24202
  status: "errored",
@@ -24735,40 +24212,55 @@ const run = async ({
24735
24212
  runOperation.throwIfAborted();
24736
24213
  }
24737
24214
 
24738
- let result = winner.data;
24739
- result = await resultTransformer(result);
24215
+ const {
24216
+ status,
24217
+ namespace,
24218
+ error,
24219
+ performance,
24220
+ coverage
24221
+ } = winner.data;
24222
+ result.status = status;
24223
+
24224
+ if (status === "errored") {
24225
+ result.error = error;
24226
+ } else {
24227
+ result.namespace = namespace;
24228
+ }
24229
+
24230
+ if (collectPerformance) {
24231
+ result.performance = performance;
24232
+ }
24233
+
24234
+ if (coverageEnabled) {
24235
+ if (coverage) {
24236
+ // we do not keep coverage in memory, it can grow very big
24237
+ // instead we store it on the filesystem
24238
+ // and they can be read later at "coverageFileUrl"
24239
+ const coverageFileUrl = new URL(`./${runtime.name}/${cuid()}.json`, coverageTempDirectoryUrl);
24240
+ writeFileSync(coverageFileUrl, JSON.stringify(coverage, null, " "));
24241
+ result.coverageFileUrl = coverageFileUrl.href;
24242
+ } else {// will eventually log a warning in report_to_coverage.js
24243
+ }
24244
+ }
24245
+
24246
+ callbacks.forEach(callback => {
24247
+ callback();
24248
+ });
24740
24249
  return result;
24741
24250
  } catch (e) {
24742
- let result = {
24251
+ result = {
24743
24252
  status: "errored",
24744
24253
  error: e
24745
24254
  };
24746
- result = await resultTransformer(result);
24255
+ callbacks.forEach(callback => {
24256
+ callback();
24257
+ });
24747
24258
  return result;
24748
24259
  } finally {
24749
24260
  await runOperation.end();
24750
24261
  }
24751
24262
  };
24752
24263
 
24753
- const composeTransformer$1 = (previousTransformer, transformer) => {
24754
- return async value => {
24755
- const transformedValue = await previousTransformer(value);
24756
- return transformer(transformedValue);
24757
- };
24758
- };
24759
-
24760
- const createAbortedResult = () => {
24761
- return {
24762
- status: "aborted"
24763
- };
24764
- };
24765
-
24766
- const createTimedoutResult = () => {
24767
- return {
24768
- status: "timedout"
24769
- };
24770
- };
24771
-
24772
24264
  const ensureGlobalGc = () => {
24773
24265
  if (!global.gc) {
24774
24266
  v8.setFlagsFromString("--expose_gc");
@@ -24853,6 +24345,8 @@ const createExecutionLog = ({
24853
24345
  }, {
24854
24346
  completedExecutionLogAbbreviation,
24855
24347
  counters,
24348
+ logRuntime,
24349
+ logEachDuration,
24856
24350
  timeEllapsed,
24857
24351
  memoryHeap
24858
24352
  }) => {
@@ -24885,8 +24379,12 @@ const createExecutionLog = ({
24885
24379
  label: `${description}${summary}`,
24886
24380
  details: {
24887
24381
  file: fileRelativeUrl,
24888
- runtime: `${runtimeName}/${runtimeVersion}`,
24889
- duration: status === "executing" ? msAsEllapsedTime(Date.now() - startMs) : msAsDuration(endMs - startMs),
24382
+ ...(logRuntime ? {
24383
+ runtime: `${runtimeName}/${runtimeVersion}`
24384
+ } : {}),
24385
+ ...(logEachDuration ? {
24386
+ duration: status === "executing" ? msAsEllapsedTime(Date.now() - startMs) : msAsDuration(endMs - startMs)
24387
+ } : {}),
24890
24388
  ...(error ? {
24891
24389
  error: error.stack || error.message || error
24892
24390
  } : {})
@@ -25040,22 +24538,93 @@ const descriptionFormatters = {
25040
24538
  };
25041
24539
 
25042
24540
  const formatConsoleCalls = consoleCalls => {
25043
- const consoleOutput = consoleCalls.reduce((previous, {
25044
- text
25045
- }) => {
25046
- return `${previous}${text}`;
25047
- }, "");
25048
- const consoleOutputTrimmed = consoleOutput.trim();
25049
-
25050
- if (consoleOutputTrimmed === "") {
24541
+ if (consoleCalls.length === 0) {
25051
24542
  return "";
25052
24543
  }
25053
24544
 
25054
- return `${ANSI.color(`-------- console output --------`, ANSI.GREY)}
25055
- ${consoleOutputTrimmed}
24545
+ const repartition = {
24546
+ debug: 0,
24547
+ info: 0,
24548
+ warning: 0,
24549
+ error: 0,
24550
+ log: 0
24551
+ };
24552
+ let consoleOutput = ``;
24553
+ consoleCalls.forEach(consoleCall => {
24554
+ repartition[consoleCall.type]++;
24555
+ const text = consoleCall.text;
24556
+ const textFormatted = prefixFirstAndIndentRemainingLines({
24557
+ prefix: CONSOLE_ICONS[consoleCall.type],
24558
+ text,
24559
+ trimLastLine: consoleCall === consoleCalls[consoleCalls.length - 1]
24560
+ });
24561
+ consoleOutput += textFormatted;
24562
+ });
24563
+ return `${ANSI.color(`-------- ${formatConsoleSummary(repartition)} --------`, ANSI.GREY)}
24564
+ ${consoleOutput}
25056
24565
  ${ANSI.color(`-------------------------`, ANSI.GREY)}`;
25057
24566
  };
25058
24567
 
24568
+ const CONSOLE_ICONS = {
24569
+ debug: UNICODE.DEBUG,
24570
+ info: UNICODE.INFO,
24571
+ warning: UNICODE.WARNING,
24572
+ error: UNICODE.FAILURE,
24573
+ log: " "
24574
+ };
24575
+
24576
+ const formatConsoleSummary = repartition => {
24577
+ const {
24578
+ debug,
24579
+ info,
24580
+ warning,
24581
+ error
24582
+ } = repartition;
24583
+ const parts = [];
24584
+
24585
+ if (error) {
24586
+ parts.push(`${CONSOLE_ICONS.error} ${error}`);
24587
+ }
24588
+
24589
+ if (warning) {
24590
+ parts.push(`${CONSOLE_ICONS.warning} ${warning}`);
24591
+ }
24592
+
24593
+ if (info) {
24594
+ parts.push(`${CONSOLE_ICONS.info} ${info}`);
24595
+ }
24596
+
24597
+ if (debug) {
24598
+ parts.push(`${CONSOLE_ICONS.debug} ${debug}`);
24599
+ }
24600
+
24601
+ if (parts.length === 0) {
24602
+ return `console`;
24603
+ }
24604
+
24605
+ return `console (${parts.join(" ")})`;
24606
+ };
24607
+
24608
+ const prefixFirstAndIndentRemainingLines = ({
24609
+ prefix,
24610
+ text,
24611
+ trimLastLine
24612
+ }) => {
24613
+ const lines = text.split(/\r?\n/);
24614
+ const firstLine = lines.shift();
24615
+ let result = `${prefix} ${firstLine}`;
24616
+ let i = 0;
24617
+ const indentation = ` `;
24618
+
24619
+ while (i < lines.length) {
24620
+ const line = lines[i].trim();
24621
+ i++;
24622
+ result += line.length ? `\n${indentation}${line}` : trimLastLine && i === lines.length ? "" : `\n`;
24623
+ }
24624
+
24625
+ return result;
24626
+ };
24627
+
25059
24628
  const formatExecution = ({
25060
24629
  label,
25061
24630
  details = {},
@@ -25080,6 +24649,8 @@ const executePlan = async (plan, {
25080
24649
  signal,
25081
24650
  handleSIGINT,
25082
24651
  logger,
24652
+ logRuntime,
24653
+ logEachDuration,
25083
24654
  logSummary,
25084
24655
  logTimeUsage,
25085
24656
  logMemoryHeapUsage,
@@ -25093,10 +24664,11 @@ const executePlan = async (plan, {
25093
24664
  failFast,
25094
24665
  gcBetweenExecutions,
25095
24666
  cooldownBetweenExecutions,
25096
- coverage,
24667
+ coverageEnabled,
25097
24668
  coverageConfig,
25098
24669
  coverageIncludeMissing,
25099
- coverageForceIstanbul,
24670
+ coverageMethodForBrowsers,
24671
+ coverageMethodForNodeJs,
25100
24672
  coverageV8ConflictWarning,
25101
24673
  coverageTempDirectoryRelativeUrl,
25102
24674
  scenario,
@@ -25114,10 +24686,14 @@ const executePlan = async (plan, {
25114
24686
  beforeExecutionCallback = () => {},
25115
24687
  afterExecutionCallback = () => {}
25116
24688
  } = {}) => {
24689
+ const executePlanReturnValue = {};
24690
+ const report = {};
24691
+ const callbacks = [];
25117
24692
  const stopAfterAllSignal = {
25118
24693
  notify: () => {}
25119
24694
  };
25120
24695
  let someNeedsServer = false;
24696
+ let someNodeRuntime = false;
25121
24697
  const runtimes = {};
25122
24698
  Object.keys(plan).forEach(filePattern => {
25123
24699
  const filePlan = plan[filePattern];
@@ -25133,6 +24709,10 @@ const executePlan = async (plan, {
25133
24709
  if (runtime.needsServer) {
25134
24710
  someNeedsServer = true;
25135
24711
  }
24712
+
24713
+ if (runtime.type === "node") {
24714
+ someNodeRuntime = true;
24715
+ }
25136
24716
  }
25137
24717
  });
25138
24718
  });
@@ -25160,10 +24740,67 @@ const executePlan = async (plan, {
25160
24740
  }
25161
24741
 
25162
24742
  try {
24743
+ const coverageTempDirectoryUrl = new URL(coverageTempDirectoryRelativeUrl, rootDirectoryUrl).href;
24744
+
24745
+ if (someNodeRuntime && coverageEnabled && coverageMethodForNodeJs === "NODE_V8_COVERAGE") {
24746
+ if (process.env.NODE_V8_COVERAGE) {
24747
+ // when runned multiple times, we don't want to keep previous files in this directory
24748
+ await ensureEmptyDirectory(process.env.NODE_V8_COVERAGE);
24749
+ } else {
24750
+ coverageMethodForNodeJs = "Profiler";
24751
+ logger.warn(createDetailedMessage$1(`process.env.NODE_V8_COVERAGE is required to generate coverage for Node.js subprocesses`, {
24752
+ "suggestion": `Preprend NODE_V8_COVERAGE=.coverage/node to the command executing this process`,
24753
+ "suggestion 2": `use coverageMethodForNodeJs: "Profiler". But it means coverage for child_process and worker_thread cannot be collected`
24754
+ }));
24755
+ }
24756
+ }
24757
+
24758
+ if (gcBetweenExecutions) {
24759
+ ensureGlobalGc();
24760
+ }
24761
+
24762
+ if (coverageEnabled) {
24763
+ // when runned multiple times, we don't want to keep previous files in this directory
24764
+ await ensureEmptyDirectory(coverageTempDirectoryUrl);
24765
+ callbacks.push(async () => {
24766
+ if (multipleExecutionsOperation.signal.aborted) {
24767
+ // don't try to do the coverage stuff
24768
+ return;
24769
+ }
24770
+
24771
+ try {
24772
+ if (coverageMethodForNodeJs === "NODE_V8_COVERAGE") {
24773
+ takeCoverage(); // conceptually we don't need coverage anymore so it would be
24774
+ // good to call v8.stopCoverage()
24775
+ // but it logs a strange message about "result is not an object"
24776
+ }
24777
+
24778
+ const planCoverage = await reportToCoverage(report, {
24779
+ signal: multipleExecutionsOperation.signal,
24780
+ logger,
24781
+ rootDirectoryUrl,
24782
+ coverageConfig,
24783
+ coverageIncludeMissing,
24784
+ coverageMethodForBrowsers,
24785
+ coverageV8ConflictWarning
24786
+ });
24787
+ executePlanReturnValue.planCoverage = planCoverage;
24788
+ } catch (e) {
24789
+ if (Abort.isAbortError(e)) {
24790
+ return;
24791
+ }
24792
+
24793
+ throw e;
24794
+ }
24795
+ });
24796
+ }
24797
+
25163
24798
  let runtimeParams = {
25164
24799
  rootDirectoryUrl,
25165
- collectCoverage: coverage,
25166
- coverageForceIstanbul,
24800
+ coverageEnabled,
24801
+ coverageConfig,
24802
+ coverageMethodForBrowsers,
24803
+ coverageMethodForNodeJs,
25167
24804
  stopAfterAllSignal
25168
24805
  };
25169
24806
 
@@ -25190,7 +24827,7 @@ const executePlan = async (plan, {
25190
24827
  getCustomBabelPlugins: ({
25191
24828
  clientRuntimeCompat
25192
24829
  }) => {
25193
- if (coverage && Object.keys(clientRuntimeCompat)[0] !== "chrome") {
24830
+ if (coverageEnabled && Object.keys(clientRuntimeCompat)[0] !== "chrome") {
25194
24831
  return {
25195
24832
  "transform-instrument": [babelPluginInstrument, {
25196
24833
  rootDirectoryUrl,
@@ -25246,79 +24883,7 @@ const executePlan = async (plan, {
25246
24883
  // so we enable spinner only when !process.exitCode (no error so far)
25247
24884
  process.exitCode !== 1;
25248
24885
  const startMs = Date.now();
25249
- const report = {};
25250
24886
  let rawOutput = "";
25251
-
25252
- let transformReturnValue = value => value;
25253
-
25254
- if (gcBetweenExecutions) {
25255
- ensureGlobalGc();
25256
- }
25257
-
25258
- const coverageTempDirectoryUrl = new URL(coverageTempDirectoryRelativeUrl, rootDirectoryUrl).href;
25259
-
25260
- if (coverage) {
25261
- const associations = URL_META.resolveAssociations({
25262
- cover: coverageConfig
25263
- }, rootDirectoryUrl);
25264
-
25265
- const urlShouldBeCovered = url => {
25266
- const {
25267
- cover
25268
- } = URL_META.applyAssociations({
25269
- url: new URL(url, rootDirectoryUrl).href,
25270
- associations
25271
- });
25272
- return cover;
25273
- };
25274
-
25275
- runtimeParams.urlShouldBeCovered = urlShouldBeCovered; // in case runned multiple times, we don't want to keep writing lot of files in this directory
25276
-
25277
- if (!process.env.NODE_V8_COVERAGE) {
25278
- await ensureEmptyDirectory(coverageTempDirectoryUrl);
25279
- }
25280
-
25281
- if (runtimes.node) {
25282
- // v8 coverage is written in a directoy and auto propagate to subprocesses
25283
- // through process.env.NODE_V8_COVERAGE.
25284
- if (!coverageForceIstanbul && !process.env.NODE_V8_COVERAGE) {
25285
- const v8CoverageDirectory = new URL(`./node_v8/${cuid()}`, coverageTempDirectoryUrl).href;
25286
- await writeDirectory(v8CoverageDirectory, {
25287
- allowUseless: true
25288
- });
25289
- process.env.NODE_V8_COVERAGE = urlToFileSystemPath(v8CoverageDirectory);
25290
- }
25291
- }
25292
-
25293
- transformReturnValue = async value => {
25294
- if (multipleExecutionsOperation.signal.aborted) {
25295
- // don't try to do the coverage stuff
25296
- return value;
25297
- }
25298
-
25299
- try {
25300
- value.coverage = await reportToCoverage(value.report, {
25301
- signal: multipleExecutionsOperation.signal,
25302
- logger,
25303
- rootDirectoryUrl,
25304
- coverageConfig,
25305
- coverageIncludeMissing,
25306
- coverageForceIstanbul,
25307
- urlShouldBeCovered,
25308
- coverageV8ConflictWarning
25309
- });
25310
- } catch (e) {
25311
- if (Abort.isAbortError(e)) {
25312
- return value;
25313
- }
25314
-
25315
- throw e;
25316
- }
25317
-
25318
- return value;
25319
- };
25320
- }
25321
-
25322
24887
  logger.info("");
25323
24888
  let executionLog = createLog({
25324
24889
  newLine: ""
@@ -25343,6 +24908,7 @@ const executePlan = async (plan, {
25343
24908
  fileRelativeUrl,
25344
24909
  runtime
25345
24910
  } = paramsFromStep;
24911
+ const runtimeType = runtime.type;
25346
24912
  const runtimeName = runtime.name;
25347
24913
  const runtimeVersion = runtime.version;
25348
24914
  const executionParams = {
@@ -25358,6 +24924,7 @@ const executePlan = async (plan, {
25358
24924
  };
25359
24925
  const beforeExecutionInfo = {
25360
24926
  fileRelativeUrl,
24927
+ runtimeType,
25361
24928
  runtimeName,
25362
24929
  runtimeVersion,
25363
24930
  executionIndex,
@@ -25375,6 +24942,8 @@ const executePlan = async (plan, {
25375
24942
  render: () => {
25376
24943
  return createExecutionLog(beforeExecutionInfo, {
25377
24944
  counters,
24945
+ logRuntime,
24946
+ logEachDuration,
25378
24947
  ...(logTimeUsage ? {
25379
24948
  timeEllapsed: Date.now() - startMs
25380
24949
  } : {}),
@@ -25399,7 +24968,7 @@ const executePlan = async (plan, {
25399
24968
  mirrorConsole: false,
25400
24969
  // file are executed in parallel, log would be a mess to read
25401
24970
  collectConsole: executionParams.collectConsole,
25402
- collectCoverage: coverage,
24971
+ coverageEnabled,
25403
24972
  coverageTempDirectoryUrl,
25404
24973
  runtime: executionParams.runtime,
25405
24974
  runtimeParams: { ...runtimeParams,
@@ -25448,6 +25017,8 @@ const executePlan = async (plan, {
25448
25017
  let log = createExecutionLog(afterExecutionInfo, {
25449
25018
  completedExecutionLogAbbreviation,
25450
25019
  counters,
25020
+ logRuntime,
25021
+ logEachDuration,
25451
25022
  ...(logTimeUsage ? {
25452
25023
  timeEllapsed: Date.now() - startMs
25453
25024
  } : {}),
@@ -25515,16 +25086,14 @@ const executePlan = async (plan, {
25515
25086
  logger.info(`-> ${urlToFileSystemPath(logFileUrl)}`);
25516
25087
  }
25517
25088
 
25518
- const result = await transformReturnValue({
25519
- summary,
25520
- report
25521
- });
25522
- return {
25523
- aborted: multipleExecutionsOperation.signal.aborted,
25524
- planSummary: result.summary,
25525
- planReport: result.report,
25526
- planCoverage: result.coverage
25527
- };
25089
+ executePlanReturnValue.aborted = multipleExecutionsOperation.signal.aborted;
25090
+ executePlanReturnValue.planSummary = summary;
25091
+ executePlanReturnValue.planReport = report;
25092
+ await callbacks.reduce(async (previous, callback) => {
25093
+ await previous;
25094
+ await callback();
25095
+ }, Promise.resolve());
25096
+ return executePlanReturnValue;
25528
25097
  } finally {
25529
25098
  await multipleExecutionsOperation.end();
25530
25099
  }
@@ -25645,7 +25214,7 @@ const executeInParallel = async ({
25645
25214
  * @param {boolean} [testPlanParameters.failFast=false] Fails immediatly when a test execution fails
25646
25215
  * @param {number} [testPlanParameters.cooldownBetweenExecutions=0] Millisecond to wait between each execution
25647
25216
  * @param {boolean} [testPlanParameters.logMemoryHeapUsage=false] Add memory heap usage during logs
25648
- * @param {boolean} [testPlanParameters.coverage=false] Controls if coverage is collected during files executions
25217
+ * @param {boolean} [testPlanParameters.coverageEnabled=false] Controls if coverage is collected during files executions
25649
25218
  * @param {boolean} [testPlanParameters.coverageV8ConflictWarning=true] Warn when coverage from 2 executions cannot be merged
25650
25219
  * @return {Object} An object containing the result of all file executions
25651
25220
  */
@@ -25654,6 +25223,8 @@ const executeTestPlan = async ({
25654
25223
  signal = new AbortController().signal,
25655
25224
  handleSIGINT = true,
25656
25225
  logLevel = "info",
25226
+ logRuntime = true,
25227
+ logEachDuration = true,
25657
25228
  logSummary = true,
25658
25229
  logTimeUsage = false,
25659
25230
  logMemoryHeapUsage = false,
@@ -25674,22 +25245,25 @@ const executeTestPlan = async ({
25674
25245
  keepRunning = false,
25675
25246
  cooldownBetweenExecutions = 0,
25676
25247
  gcBetweenExecutions = logMemoryHeapUsage,
25677
- coverage = process.argv.includes("--cover") || process.argv.includes("--coverage"),
25678
- coverageTempDirectoryRelativeUrl = "./.coverage/tmp/",
25248
+ coverageEnabled = process.argv.includes("--cover") || process.argv.includes("--coverage"),
25679
25249
  coverageConfig = {
25680
25250
  "./src/": true
25681
25251
  },
25682
25252
  coverageIncludeMissing = true,
25683
25253
  coverageAndExecutionAllowed = false,
25684
- coverageForceIstanbul = false,
25254
+ coverageMethodForNodeJs = "NODE_V8_COVERAGE",
25255
+ // "Profiler" also accepted
25256
+ coverageMethodForBrowsers = "playwright_api",
25257
+ // "istanbul" also accepted
25685
25258
  coverageV8ConflictWarning = true,
25686
- coverageReportTextLog = true,
25687
- coverageReportJsonFile = process.env.CI ? null : "./.coverage/coverage.json",
25688
- coverageReportHtmlDirectory = process.env.CI ? "./.coverage/" : null,
25259
+ coverageTempDirectoryRelativeUrl = "./.coverage/tmp/",
25689
25260
  // skip empty means empty files won't appear in the coverage reports (json and html)
25690
25261
  coverageReportSkipEmpty = false,
25691
25262
  // skip full means file with 100% coverage won't appear in coverage reports (json and html)
25692
25263
  coverageReportSkipFull = false,
25264
+ coverageReportTextLog = true,
25265
+ coverageReportJsonFile = process.env.CI ? null : "./.coverage/coverage.json",
25266
+ coverageReportHtmlDirectory = process.env.CI ? "./.coverage/" : null,
25693
25267
  sourcemaps = "inline",
25694
25268
  plugins = [],
25695
25269
  nodeEsmResolution,
@@ -25710,7 +25284,7 @@ const executeTestPlan = async ({
25710
25284
  throw new Error(`testPlan must be an object, got ${testPlan}`);
25711
25285
  }
25712
25286
 
25713
- if (coverage) {
25287
+ if (coverageEnabled) {
25714
25288
  if (typeof coverageConfig !== "object") {
25715
25289
  throw new TypeError(`coverageConfig must be an object, got ${coverageConfig}`);
25716
25290
  }
@@ -25751,6 +25325,8 @@ const executeTestPlan = async ({
25751
25325
  logger,
25752
25326
  logLevel,
25753
25327
  logSummary,
25328
+ logRuntime,
25329
+ logEachDuration,
25754
25330
  logTimeUsage,
25755
25331
  logMemoryHeapUsage,
25756
25332
  logFileRelativeUrl,
@@ -25763,10 +25339,11 @@ const executeTestPlan = async ({
25763
25339
  keepRunning,
25764
25340
  cooldownBetweenExecutions,
25765
25341
  gcBetweenExecutions,
25766
- coverage,
25342
+ coverageEnabled,
25767
25343
  coverageConfig,
25768
25344
  coverageIncludeMissing,
25769
- coverageForceIstanbul,
25345
+ coverageMethodForBrowsers,
25346
+ coverageMethodForNodeJs,
25770
25347
  coverageV8ConflictWarning,
25771
25348
  coverageTempDirectoryRelativeUrl,
25772
25349
  scenario: "test",
@@ -25793,7 +25370,7 @@ const executeTestPlan = async ({
25793
25370
  // and in case coverage json file gets written in the same directory
25794
25371
  // it must be done before
25795
25372
 
25796
- if (coverage && coverageReportHtmlDirectory) {
25373
+ if (coverageEnabled && coverageReportHtmlDirectory) {
25797
25374
  const coverageHtmlDirectoryUrl = resolveDirectoryUrl(coverageReportHtmlDirectory, rootDirectoryUrl);
25798
25375
 
25799
25376
  if (!urlIsInsideOf(coverageHtmlDirectoryUrl, rootDirectoryUrl)) {
@@ -25811,7 +25388,7 @@ const executeTestPlan = async ({
25811
25388
  }));
25812
25389
  }
25813
25390
 
25814
- if (coverage && coverageReportJsonFile) {
25391
+ if (coverageEnabled && coverageReportJsonFile) {
25815
25392
  const coverageJsonFileUrl = new URL(coverageReportJsonFile, rootDirectoryUrl).href;
25816
25393
  promises.push(generateCoverageJsonFile({
25817
25394
  coverage: result.planCoverage,
@@ -25820,7 +25397,7 @@ const executeTestPlan = async ({
25820
25397
  }));
25821
25398
  }
25822
25399
 
25823
- if (coverage && coverageReportTextLog) {
25400
+ if (coverageEnabled && coverageReportTextLog) {
25824
25401
  promises.push(generateCoverageTextLog(result.planCoverage, {
25825
25402
  coverageReportSkipEmpty,
25826
25403
  coverageReportSkipFull
@@ -25895,6 +25472,7 @@ const createRuntimeFromPlaywright = ({
25895
25472
  isolatedTab = false
25896
25473
  }) => {
25897
25474
  const runtime = {
25475
+ type: "browser",
25898
25476
  name: browserName,
25899
25477
  version: browserVersion,
25900
25478
  needsServer: true
@@ -25909,9 +25487,9 @@ const createRuntimeFromPlaywright = ({
25909
25487
  server,
25910
25488
  // measurePerformance,
25911
25489
  collectPerformance,
25912
- collectCoverage = false,
25913
- coverageForceIstanbul,
25914
- urlShouldBeCovered,
25490
+ coverageEnabled = false,
25491
+ coverageConfig,
25492
+ coverageMethodForBrowsers,
25915
25493
  stopAfterAllSignal,
25916
25494
  stopSignal,
25917
25495
  keepRunning,
@@ -25996,8 +25574,8 @@ const createRuntimeFromPlaywright = ({
25996
25574
 
25997
25575
  let resultTransformer = result => result;
25998
25576
 
25999
- if (collectCoverage) {
26000
- if (coveragePlaywrightAPIAvailable && !coverageForceIstanbul) {
25577
+ if (coverageEnabled) {
25578
+ if (coveragePlaywrightAPIAvailable && coverageMethodForBrowsers === "playwright_api") {
26001
25579
  await page.coverage.startJSCoverage({// reportAnonymousScripts: true,
26002
25580
  });
26003
25581
  resultTransformer = composeTransformer(resultTransformer, async result => {
@@ -26015,10 +25593,11 @@ const createRuntimeFromPlaywright = ({
26015
25593
  url: fsUrl
26016
25594
  };
26017
25595
  });
26018
- const coverage = filterV8Coverage({
25596
+ const coverage = await filterV8Coverage({
26019
25597
  result: v8CoveragesWithFsUrls
26020
25598
  }, {
26021
- urlShouldBeCovered
25599
+ rootDirectoryUrl,
25600
+ coverageConfig
26022
25601
  });
26023
25602
  return { ...result,
26024
25603
  coverage
@@ -26443,20 +26022,23 @@ const evalException = (exceptionSource, {
26443
26022
 
26444
26023
  const chromium = createRuntimeFromPlaywright({
26445
26024
  browserName: "chromium",
26446
- browserVersion: "97.0.4666.0",
26025
+ browserVersion: "104.0.5112.20",
26026
+ // to update, check https://github.com/microsoft/playwright/releases
26447
26027
  coveragePlaywrightAPIAvailable: true
26448
26028
  });
26449
26029
  const chromiumIsolatedTab = chromium.isolatedTab;
26450
26030
 
26451
26031
  const firefox = createRuntimeFromPlaywright({
26452
26032
  browserName: "firefox",
26453
- browserVersion: "93.0"
26033
+ browserVersion: "100.0.2" // to update, check https://github.com/microsoft/playwright/releases
26034
+
26454
26035
  });
26455
26036
  const firefoxIsolatedTab = firefox.isolatedTab;
26456
26037
 
26457
26038
  const webkit = createRuntimeFromPlaywright({
26458
26039
  browserName: "webkit",
26459
26040
  browserVersion: "15.4",
26041
+ // to update, check https://github.com/microsoft/playwright/releases
26460
26042
  ignoreErrorHook: error => {
26461
26043
  // we catch error during execution but safari throw unhandled rejection
26462
26044
  // in a non-deterministic way.
@@ -26755,13 +26337,24 @@ const killProcessTree = async (processId, {
26755
26337
  await check();
26756
26338
  };
26757
26339
 
26758
- const NODE_CONTROLLABLE_FILE_URL = new URL("./js/controllable_file.mjs", import.meta.url).href;
26759
- const nodeProcess = {
26760
- name: "node",
26340
+ // https://nodejs.org/api/process.html#process_signal_events
26341
+ const SIGINT_SIGNAL_NUMBER = 2;
26342
+ const SIGABORT_SIGNAL_NUMBER = 6;
26343
+ const SIGTERM_SIGNAL_NUMBER = 15;
26344
+ const EXIT_CODES = {
26345
+ SIGINT: 128 + SIGINT_SIGNAL_NUMBER,
26346
+ SIGABORT: 128 + SIGABORT_SIGNAL_NUMBER,
26347
+ SIGTERM: 128 + SIGTERM_SIGNAL_NUMBER
26348
+ };
26349
+
26350
+ const CONTROLLABLE_CHILD_PROCESS_URL = new URL("./controllable_child_process.mjs", import.meta.url).href;
26351
+ const nodeChildProcess = {
26352
+ type: "node",
26353
+ name: "node_child_process",
26761
26354
  version: process.version.slice(1)
26762
26355
  };
26763
26356
 
26764
- nodeProcess.run = async ({
26357
+ nodeChildProcess.run = async ({
26765
26358
  signal = new AbortController().signal,
26766
26359
  logger,
26767
26360
  logProcessCommand = false,
@@ -26771,13 +26364,14 @@ nodeProcess.run = async ({
26771
26364
  gracefulStopAllocatedMs = 4000,
26772
26365
  stopSignal,
26773
26366
  onConsole,
26774
- collectCoverage = false,
26775
- coverageForceIstanbul,
26367
+ coverageEnabled = false,
26368
+ coverageConfig,
26369
+ coverageMethodForNodeJs,
26776
26370
  collectPerformance,
26371
+ env,
26777
26372
  debugPort,
26778
26373
  debugMode,
26779
26374
  debugModeInheritBreak,
26780
- env,
26781
26375
  inheritProcessEnv = true,
26782
26376
  commandLineOptions = [],
26783
26377
  stdin = "pipe",
@@ -26789,13 +26383,10 @@ nodeProcess.run = async ({
26789
26383
  }
26790
26384
 
26791
26385
  env = { ...env,
26792
- COVERAGE_ENABLED: collectCoverage,
26793
26386
  JSENV: true
26794
26387
  };
26795
26388
 
26796
- if (coverageForceIstanbul) {
26797
- // if we want to force istanbul, we will set process.env.NODE_V8_COVERAGE = ''
26798
- // into the child_process
26389
+ if (coverageMethodForNodeJs !== "NODE_V8_COVERAGE") {
26799
26390
  env.NODE_V8_COVERAGE = "";
26800
26391
  }
26801
26392
 
@@ -26820,8 +26411,8 @@ nodeProcess.run = async ({
26820
26411
  const envForChildProcess = { ...(inheritProcessEnv ? process.env : {}),
26821
26412
  ...env
26822
26413
  };
26823
- logger[logProcessCommand ? "info" : "debug"](`${process.argv[0]} ${execArgv.join(" ")} ${urlToFileSystemPath(NODE_CONTROLLABLE_FILE_URL)}`);
26824
- const childProcess = fork(urlToFileSystemPath(NODE_CONTROLLABLE_FILE_URL), {
26414
+ logger[logProcessCommand ? "info" : "debug"](`${process.argv[0]} ${execArgv.join(" ")} ${fileURLToPath(CONTROLLABLE_CHILD_PROCESS_URL)}`);
26415
+ const childProcess = fork(fileURLToPath(CONTROLLABLE_CHILD_PROCESS_URL), {
26825
26416
  execArgv,
26826
26417
  // silent: true
26827
26418
  stdio: ["pipe", "pipe", "pipe", "ipc"],
@@ -26845,9 +26436,9 @@ nodeProcess.run = async ({
26845
26436
  }
26846
26437
 
26847
26438
  const childProcessReadyPromise = new Promise(resolve => {
26848
- onceProcessMessage(childProcess, "ready", resolve);
26439
+ onceChildProcessMessage(childProcess, "ready", resolve);
26849
26440
  });
26850
- const removeOutputListener = installProcessOutputListener(childProcess, ({
26441
+ const removeOutputListener = installChildProcessOutputListener(childProcess, ({
26851
26442
  type,
26852
26443
  text
26853
26444
  }) => {
@@ -26908,10 +26499,10 @@ nodeProcess.run = async ({
26908
26499
  // },
26909
26500
  // https://nodejs.org/api/child_process.html#child_process_event_error
26910
26501
  error: cb => {
26911
- return onceProcessEvent(childProcess, "error", cb);
26502
+ return onceChildProcessEvent(childProcess, "error", cb);
26912
26503
  },
26913
26504
  exit: cb => {
26914
- return onceProcessEvent(childProcess, "exit", (code, signal) => {
26505
+ return onceChildProcessEvent(childProcess, "exit", (code, signal) => {
26915
26506
  cb({
26916
26507
  code,
26917
26508
  signal
@@ -26919,7 +26510,7 @@ nodeProcess.run = async ({
26919
26510
  });
26920
26511
  },
26921
26512
  response: cb => {
26922
- onceProcessMessage(childProcess, "action-result", cb);
26513
+ return onceChildProcessMessage(childProcess, "action-result", cb);
26923
26514
  }
26924
26515
  }, resolve);
26925
26516
  });
@@ -26928,11 +26519,19 @@ nodeProcess.run = async ({
26928
26519
  actionOperation.throwIfAborted();
26929
26520
  await childProcessReadyPromise;
26930
26521
  actionOperation.throwIfAborted();
26931
- await sendToProcess(childProcess, "action", {
26932
- actionType: "execute-using-dynamic-import",
26933
- actionParams: {
26934
- fileUrl: new URL(fileRelativeUrl, rootDirectoryUrl).href,
26935
- collectPerformance
26522
+ await sendToChildProcess(childProcess, {
26523
+ type: "action",
26524
+ data: {
26525
+ actionType: "execute-using-dynamic-import",
26526
+ actionParams: {
26527
+ rootDirectoryUrl,
26528
+ fileUrl: new URL(fileRelativeUrl, rootDirectoryUrl).href,
26529
+ collectPerformance,
26530
+ coverageEnabled,
26531
+ coverageConfig,
26532
+ coverageMethodForNodeJs,
26533
+ exitAfterAction: true
26534
+ }
26936
26535
  }
26937
26536
  });
26938
26537
  const winner = await winnerPromise;
@@ -26965,7 +26564,7 @@ nodeProcess.run = async ({
26965
26564
  };
26966
26565
  }
26967
26566
 
26968
- if (code === null || code === 0 || code === SIGINT_EXIT_CODE || code === SIGTERM_EXIT_CODE || code === SIGABORT_EXIT_CODE) {
26567
+ if (code === null || code === 0 || code === EXIT_CODES.SIGINT || code === EXIT_CODES.SIGTERM || code === EXIT_CODES.SIGABORT) {
26969
26568
  return {
26970
26569
  status: "errored",
26971
26570
  error: new Error(`node process exited during execution`)
@@ -27019,31 +26618,25 @@ nodeProcess.run = async ({
27019
26618
 
27020
26619
  await actionOperation.end();
27021
26620
  return result;
27022
- }; // https://nodejs.org/api/process.html#process_signal_events
27023
-
27024
-
27025
- const SIGINT_SIGNAL_NUMBER = 2;
27026
- const SIGABORT_SIGNAL_NUMBER = 6;
27027
- const SIGTERM_SIGNAL_NUMBER = 15;
27028
- const SIGINT_EXIT_CODE = 128 + SIGINT_SIGNAL_NUMBER;
27029
- const SIGABORT_EXIT_CODE = 128 + SIGABORT_SIGNAL_NUMBER;
27030
- const SIGTERM_EXIT_CODE = 128 + SIGTERM_SIGNAL_NUMBER; // http://man7.org/linux/man-pages/man7/signal.7.html
26621
+ }; // http://man7.org/linux/man-pages/man7/signal.7.html
27031
26622
  // https:// github.com/nodejs/node/blob/1d9511127c419ec116b3ddf5fc7a59e8f0f1c1e4/lib/internal/child_process.js#L472
27032
26623
 
26624
+
27033
26625
  const GRACEFUL_STOP_SIGNAL = "SIGTERM";
27034
26626
  const STOP_SIGNAL = "SIGKILL"; // it would be more correct if GRACEFUL_STOP_FAILED_SIGNAL was SIGHUP instead of SIGKILL.
27035
26627
  // but I'm not sure and it changes nothing so just use SIGKILL
27036
26628
 
27037
26629
  const GRACEFUL_STOP_FAILED_SIGNAL = "SIGKILL";
27038
26630
 
27039
- const sendToProcess = async (childProcess, type, data) => {
27040
- const source = uneval(data, {
27041
- functionAllowed: true
27042
- });
26631
+ const sendToChildProcess = async (childProcess, {
26632
+ type,
26633
+ data
26634
+ }) => {
27043
26635
  return new Promise((resolve, reject) => {
27044
26636
  childProcess.send({
26637
+ jsenv: true,
27045
26638
  type,
27046
- data: source
26639
+ data
27047
26640
  }, error => {
27048
26641
  if (error) {
27049
26642
  reject(error);
@@ -27054,7 +26647,7 @@ const sendToProcess = async (childProcess, type, data) => {
27054
26647
  });
27055
26648
  };
27056
26649
 
27057
- const installProcessOutputListener = (childProcess, callback) => {
26650
+ const installChildProcessOutputListener = (childProcess, callback) => {
27058
26651
  // beware that we may receive ansi output here, should not be a problem but keep that in mind
27059
26652
  const stdoutDataCallback = chunk => {
27060
26653
  callback({
@@ -27079,9 +26672,9 @@ const installProcessOutputListener = (childProcess, callback) => {
27079
26672
  };
27080
26673
  };
27081
26674
 
27082
- const onceProcessMessage = (childProcess, type, callback) => {
26675
+ const onceChildProcessMessage = (childProcess, type, callback) => {
27083
26676
  const onmessage = message => {
27084
- if (message.type === type) {
26677
+ if (message && message.jsenv && message.type === type) {
27085
26678
  childProcess.removeListener("message", onmessage); // eslint-disable-next-line no-eval
27086
26679
 
27087
26680
  callback(message.data ? eval(`(${message.data})`) : "");
@@ -27094,13 +26687,290 @@ const onceProcessMessage = (childProcess, type, callback) => {
27094
26687
  };
27095
26688
  };
27096
26689
 
27097
- const onceProcessEvent = (childProcess, type, callback) => {
26690
+ const onceChildProcessEvent = (childProcess, type, callback) => {
27098
26691
  childProcess.once(type, callback);
27099
26692
  return () => {
27100
26693
  childProcess.removeListener(type, callback);
27101
26694
  };
27102
26695
  };
27103
26696
 
26697
+ // https://github.com/avajs/ava/blob/576f534b345259055c95fa0c2b33bef10847a2af/lib/fork.js#L23
26698
+ const CONTROLLABLE_WORKER_THREAD_URL = new URL("./controllable_worker_thread.mjs", import.meta.url).href;
26699
+ const nodeWorkerThread = {
26700
+ type: "node",
26701
+ name: "node_worker_thread",
26702
+ version: process.version.slice(1)
26703
+ };
26704
+
26705
+ nodeWorkerThread.run = async ({
26706
+ signal = new AbortController().signal,
26707
+ // logger,
26708
+ rootDirectoryUrl,
26709
+ fileRelativeUrl,
26710
+ keepRunning,
26711
+ stopSignal,
26712
+ onConsole,
26713
+ coverageConfig,
26714
+ coverageMethodForNodeJs,
26715
+ coverageEnabled = false,
26716
+ collectPerformance,
26717
+ env,
26718
+ debugPort,
26719
+ debugMode,
26720
+ debugModeInheritBreak,
26721
+ inheritProcessEnv = true,
26722
+ commandLineOptions = []
26723
+ }) => {
26724
+ if (env !== undefined && typeof env !== "object") {
26725
+ throw new TypeError(`env must be an object, got ${env}`);
26726
+ }
26727
+
26728
+ env = { ...env,
26729
+ JSENV: true
26730
+ };
26731
+
26732
+ if (coverageMethodForNodeJs !== "NODE_V8_COVERAGE") {
26733
+ env.NODE_V8_COVERAGE = "";
26734
+ }
26735
+
26736
+ const workerThreadExecOptions = await createChildExecOptions({
26737
+ signal,
26738
+ debugPort,
26739
+ debugMode,
26740
+ debugModeInheritBreak
26741
+ });
26742
+ const execArgvForWorkerThread = ExecOptions.toExecArgv({ ...workerThreadExecOptions,
26743
+ ...ExecOptions.fromExecArgv(commandLineOptions)
26744
+ });
26745
+ const envForWorkerThread = { ...(inheritProcessEnv ? process.env : {}),
26746
+ ...env
26747
+ };
26748
+ const cleanupCallbackList = createCallbackListNotifiedOnce();
26749
+
26750
+ const cleanup = async reason => {
26751
+ await cleanupCallbackList.notify({
26752
+ reason
26753
+ });
26754
+ };
26755
+
26756
+ const actionOperation = Abort.startOperation();
26757
+ actionOperation.addAbortSignal(signal); // https://nodejs.org/api/worker_threads.html#new-workerfilename-options
26758
+
26759
+ const workerThread = new Worker(fileURLToPath(CONTROLLABLE_WORKER_THREAD_URL), {
26760
+ env: envForWorkerThread,
26761
+ execArgv: execArgvForWorkerThread,
26762
+ // workerData: { options },
26763
+ // trackUnmanagedFds: true,
26764
+ stdin: true,
26765
+ stdout: true,
26766
+ stderr: true
26767
+ });
26768
+ const removeOutputListener = installWorkerThreadOutputListener(workerThread, ({
26769
+ type,
26770
+ text
26771
+ }) => {
26772
+ onConsole({
26773
+ type,
26774
+ text
26775
+ });
26776
+ });
26777
+ const workerThreadReadyPromise = new Promise(resolve => {
26778
+ onceWorkerThreadMessage(workerThread, "ready", resolve);
26779
+ });
26780
+ const stop = memoize(async () => {
26781
+ await workerThreadReadyPromise;
26782
+ await workerThread.terminate();
26783
+ });
26784
+ const winnerPromise = new Promise(resolve => {
26785
+ raceCallbacks({
26786
+ aborted: cb => {
26787
+ return actionOperation.addAbortCallback(cb);
26788
+ },
26789
+ error: cb => {
26790
+ return onceWorkerThreadEvent(workerThread, "error", cb);
26791
+ },
26792
+ exit: cb => {
26793
+ return onceWorkerThreadEvent(workerThread, "exit", (code, signal) => {
26794
+ cb({
26795
+ code,
26796
+ signal
26797
+ });
26798
+ });
26799
+ },
26800
+ response: cb => {
26801
+ return onceWorkerThreadMessage(workerThread, "action-result", cb);
26802
+ }
26803
+ }, resolve);
26804
+ });
26805
+
26806
+ const getResult = async () => {
26807
+ actionOperation.throwIfAborted();
26808
+ await workerThreadReadyPromise;
26809
+ actionOperation.throwIfAborted();
26810
+ await sendToWorkerThread(workerThread, {
26811
+ type: "action",
26812
+ data: {
26813
+ actionType: "execute-using-dynamic-import",
26814
+ actionParams: {
26815
+ rootDirectoryUrl,
26816
+ fileUrl: new URL(fileRelativeUrl, rootDirectoryUrl).href,
26817
+ collectPerformance,
26818
+ coverageEnabled,
26819
+ coverageConfig,
26820
+ coverageMethodForNodeJs,
26821
+ exitAfterAction: true
26822
+ }
26823
+ }
26824
+ });
26825
+ const winner = await winnerPromise;
26826
+
26827
+ if (winner.name === "aborted") {
26828
+ return {
26829
+ status: "aborted"
26830
+ };
26831
+ }
26832
+
26833
+ if (winner.name === "error") {
26834
+ const error = winner.data;
26835
+ removeOutputListener();
26836
+ return {
26837
+ status: "errored",
26838
+ error
26839
+ };
26840
+ }
26841
+
26842
+ if (winner.name === "exit") {
26843
+ const {
26844
+ code
26845
+ } = winner.data;
26846
+ await cleanup("process exit");
26847
+
26848
+ if (code === 12) {
26849
+ return {
26850
+ status: "errored",
26851
+ error: new Error(`node process exited with 12 (the forked child process wanted to use a non-available port for debug)`)
26852
+ };
26853
+ }
26854
+
26855
+ if (code === null || code === 0 || code === EXIT_CODES.SIGINT || code === EXIT_CODES.SIGTERM || code === EXIT_CODES.SIGABORT) {
26856
+ return {
26857
+ status: "errored",
26858
+ error: new Error(`node worker thread exited during execution`)
26859
+ };
26860
+ } // process.exit(1) in child process or process.exitCode = 1 + process.exit()
26861
+ // means there was an error even if we don't know exactly what.
26862
+
26863
+
26864
+ return {
26865
+ status: "errored",
26866
+ error: new Error(`node worker thread exited with code ${code} during execution`)
26867
+ };
26868
+ }
26869
+
26870
+ const {
26871
+ status,
26872
+ value
26873
+ } = winner.data;
26874
+
26875
+ if (status === "action-failed") {
26876
+ return {
26877
+ status: "errored",
26878
+ error: value
26879
+ };
26880
+ }
26881
+
26882
+ const {
26883
+ namespace,
26884
+ performance,
26885
+ coverage
26886
+ } = value;
26887
+ return {
26888
+ status: "completed",
26889
+ namespace,
26890
+ performance,
26891
+ coverage
26892
+ };
26893
+ };
26894
+
26895
+ let result;
26896
+
26897
+ try {
26898
+ result = await getResult();
26899
+ } catch (e) {
26900
+ result = {
26901
+ status: "errored",
26902
+ error: e
26903
+ };
26904
+ }
26905
+
26906
+ if (keepRunning) {
26907
+ stopSignal.notify = stop;
26908
+ } else {
26909
+ await stop();
26910
+ }
26911
+
26912
+ await actionOperation.end();
26913
+ return result;
26914
+ };
26915
+
26916
+ const installWorkerThreadOutputListener = (workerThread, callback) => {
26917
+ // beware that we may receive ansi output here, should not be a problem but keep that in mind
26918
+ const stdoutDataCallback = chunk => {
26919
+ callback({
26920
+ type: "log",
26921
+ text: String(chunk)
26922
+ });
26923
+ };
26924
+
26925
+ workerThread.stdout.on("data", stdoutDataCallback);
26926
+
26927
+ const stdErrorDataCallback = chunk => {
26928
+ callback({
26929
+ type: "error",
26930
+ text: String(chunk)
26931
+ });
26932
+ };
26933
+
26934
+ workerThread.stderr.on("data", stdErrorDataCallback);
26935
+ return () => {
26936
+ workerThread.stdout.removeListener("data", stdoutDataCallback);
26937
+ workerThread.stderr.removeListener("data", stdoutDataCallback);
26938
+ };
26939
+ };
26940
+
26941
+ const sendToWorkerThread = (worker, {
26942
+ type,
26943
+ data
26944
+ }) => {
26945
+ worker.postMessage({
26946
+ jsenv: true,
26947
+ type,
26948
+ data
26949
+ });
26950
+ };
26951
+
26952
+ const onceWorkerThreadMessage = (workerThread, type, callback) => {
26953
+ const onmessage = message => {
26954
+ if (message && message.jsenv && message.type === type) {
26955
+ workerThread.removeListener("message", onmessage); // eslint-disable-next-line no-eval
26956
+
26957
+ callback(message.data ? eval(`(${message.data})`) : undefined);
26958
+ }
26959
+ };
26960
+
26961
+ workerThread.on("message", onmessage);
26962
+ return () => {
26963
+ workerThread.removeListener("message", onmessage);
26964
+ };
26965
+ };
26966
+
26967
+ const onceWorkerThreadEvent = (worker, type, callback) => {
26968
+ worker.once(type, callback);
26969
+ return () => {
26970
+ worker.removeListener(type, callback);
26971
+ };
26972
+ };
26973
+
27104
26974
  const loadUrlGraph = async ({
27105
26975
  operation,
27106
26976
  urlGraph,
@@ -27170,7 +27040,6 @@ const loadUrlGraph = async ({
27170
27040
  type,
27171
27041
  specifier
27172
27042
  });
27173
- entryUrlInfo.data.isEntryPoint = true;
27174
27043
  cook(entryUrlInfo, {
27175
27044
  reference: entryReference
27176
27045
  });
@@ -27544,7 +27413,7 @@ const determineDirectoryPath = ({
27544
27413
  return parentDirectoryPath;
27545
27414
  }
27546
27415
 
27547
- if (urlInfo.data.isEntryPoint || urlInfo.data.isWebWorkerEntryPoint) {
27416
+ if (urlInfo.isEntryPoint) {
27548
27417
  return "";
27549
27418
  }
27550
27419
 
@@ -27578,7 +27447,7 @@ const injectGlobalVersionMapping = async ({
27578
27447
  versionMappings
27579
27448
  }) => {
27580
27449
  await Promise.all(GRAPH.map(finalGraph, async urlInfo => {
27581
- if (urlInfo.data.isEntryPoint || urlInfo.data.isWebWorkerEntryPoint) {
27450
+ if (urlInfo.isEntryPoint) {
27582
27451
  await injectVersionMappings({
27583
27452
  urlInfo,
27584
27453
  kitchen: finalGraphKitchen,
@@ -27614,7 +27483,7 @@ const jsInjector = (urlInfo, {
27614
27483
  }) => {
27615
27484
  const magicSource = createMagicSource(urlInfo.content);
27616
27485
  magicSource.prepend(generateClientCodeForVersionMappings(versionMappings, {
27617
- globalName: urlInfo.data.isWebWorkerEntryPoint ? "self" : "window"
27486
+ globalName: isWebWorkerUrlInfo(urlInfo) ? "self" : "window"
27618
27487
  }));
27619
27488
  return magicSource.toContentAndSourcemap();
27620
27489
  };
@@ -27720,7 +27589,7 @@ const injectServiceWorkerUrls = async ({
27720
27589
  lineBreakNormalization
27721
27590
  }) => {
27722
27591
  const serviceWorkerEntryUrlInfos = GRAPH.filter(finalGraph, finalUrlInfo => {
27723
- return finalUrlInfo.subtype === "service_worker" && finalUrlInfo.data.isWebWorkerEntryPoint;
27592
+ return finalUrlInfo.subtype === "service_worker" && finalUrlInfo.isEntryPoint;
27724
27593
  });
27725
27594
 
27726
27595
  if (serviceWorkerEntryUrlInfos.length === 0) {
@@ -28136,7 +28005,7 @@ build ${entryPointKeys.length} entry points`);
28136
28005
  };
28137
28006
 
28138
28007
  GRAPH.forEach(rawGraph, rawUrlInfo => {
28139
- if (rawUrlInfo.data.isEntryPoint) {
28008
+ if (rawUrlInfo.isEntryPoint) {
28140
28009
  addToBundlerIfAny(rawUrlInfo);
28141
28010
 
28142
28011
  if (rawUrlInfo.type === "html") {
@@ -28214,6 +28083,7 @@ build ${entryPointKeys.length} entry points`);
28214
28083
  const bundleUrlInfo = {
28215
28084
  type,
28216
28085
  subtype: rawUrlInfo ? rawUrlInfo.subtype : undefined,
28086
+ isEntryPoint: rawUrlInfo ? rawUrlInfo.isEntryPoint : undefined,
28217
28087
  filename: rawUrlInfo ? rawUrlInfo.filename : undefined,
28218
28088
  originalUrl: rawUrlInfo ? rawUrlInfo.originalUrl : undefined,
28219
28089
  originalContent: rawUrlInfo ? rawUrlInfo.originalContent : undefined,
@@ -28351,9 +28221,8 @@ build ${entryPointKeys.length} entry points`);
28351
28221
 
28352
28222
  const buildUrl = buildUrlsGenerator.generate(rawUrl, {
28353
28223
  urlInfo: {
28354
- data: { ...reference.data,
28355
- isWebWorkerEntryPoint: isWebWorkerEntryPointReference(reference)
28356
- },
28224
+ data: reference.data,
28225
+ isEntryPoint: reference.isEntryPoint || isWebWorkerEntryPointReference(reference),
28357
28226
  type: reference.expectedType,
28358
28227
  subtype: reference.expectedSubtype,
28359
28228
  filename: reference.filename
@@ -28645,7 +28514,7 @@ ${Object.keys(finalGraph.urlInfos).join("\n")}`);
28645
28514
  // nothing uses this url anymore
28646
28515
  // - versioning update inline content
28647
28516
  // - file converted for import assertion of js_classic conversion
28648
- if (!urlInfo.data.isEntryPoint && urlInfo.type !== "sourcemap" && urlInfo.dependents.size === 0) {
28517
+ if (!urlInfo.isEntryPoint && urlInfo.type !== "sourcemap" && urlInfo.dependents.size === 0) {
28649
28518
  cleanupActions.push(() => {
28650
28519
  finalGraph.deleteUrlInfo(urlInfo.url);
28651
28520
  });
@@ -28867,7 +28736,7 @@ const applyUrlVersioning = async ({
28867
28736
  return;
28868
28737
  }
28869
28738
 
28870
- if (!urlInfo.data.isEntryPoint && urlInfo.dependents.size === 0) {
28739
+ if (!urlInfo.isEntryPoint && urlInfo.dependents.size === 0) {
28871
28740
  return;
28872
28741
  }
28873
28742
 
@@ -29113,7 +28982,7 @@ const assertEntryPoints = ({
29113
28982
  };
29114
28983
 
29115
28984
  const canUseVersionedUrl = urlInfo => {
29116
- if (urlInfo.data.isEntryPoint) {
28985
+ if (urlInfo.isEntryPoint) {
29117
28986
  return false;
29118
28987
  }
29119
28988
 
@@ -29121,10 +28990,6 @@ const canUseVersionedUrl = urlInfo => {
29121
28990
  return false;
29122
28991
  }
29123
28992
 
29124
- if (urlInfo.subtype === "service_worker") {
29125
- return !urlInfo.data.isWebWorkerEntryPoint;
29126
- }
29127
-
29128
28993
  return true;
29129
28994
  };
29130
28995
 
@@ -29586,4 +29451,4 @@ const jsenvPluginInjectGlobals = urlAssociations => {
29586
29451
  };
29587
29452
  };
29588
29453
 
29589
- export { build, chromium, chromiumIsolatedTab, execute, executeTestPlan, firefox, firefoxIsolatedTab, jsenvPluginInjectGlobals, nodeProcess, startBuildServer, startDevServer, webkit, webkitIsolatedTab };
29454
+ export { build, chromium, chromiumIsolatedTab, execute, executeTestPlan, firefox, firefoxIsolatedTab, jsenvPluginInjectGlobals, nodeChildProcess, nodeWorkerThread, startBuildServer, startDevServer, webkit, webkitIsolatedTab };