@jsenv/core 27.0.0-alpha.92 → 27.0.0-alpha.93
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/main.js +88 -58
- package/package.json +9 -9
- package/src/build/build.js +7 -6
- package/src/build/start_build_server.js +35 -15
- package/src/dev/start_dev_server.js +14 -11
- package/src/execute/run.js +7 -1
- package/src/execute/runtimes/browsers/from_playwright.js +1 -1
- package/src/helpers/worker_reload.js +4 -4
- package/src/main.js +1 -4
- package/src/omega/compat/features_compats.js +5 -3
- package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic_html.js +2 -1
- package/src/test/execute_test_plan.js +6 -9
package/dist/main.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { workerData, Worker, parentPort } from "node:worker_threads";
|
|
1
2
|
import http from "node:http";
|
|
2
3
|
import cluster from "node:cluster";
|
|
3
4
|
import process$1, { memoryUsage } from "node:process";
|
|
@@ -12,7 +13,6 @@ import { performance } from "node:perf_hooks";
|
|
|
12
13
|
import { extname, dirname, basename } from "node:path";
|
|
13
14
|
import { pathToFileURL, fileURLToPath } from "node:url";
|
|
14
15
|
import crypto, { createHash } from "node:crypto";
|
|
15
|
-
import { workerData, Worker } from "node:worker_threads";
|
|
16
16
|
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
17
|
import { createMagicSource, composeTwoSourcemaps, sourcemapConverter, SOURCEMAP, generateSourcemapFileUrl, generateSourcemapDataUrl } from "@jsenv/sourcemap";
|
|
18
18
|
import { createRequire } from "node:module";
|
|
@@ -562,8 +562,8 @@ const parseMs = ms => {
|
|
|
562
562
|
};
|
|
563
563
|
};
|
|
564
564
|
|
|
565
|
-
const byteAsFileSize =
|
|
566
|
-
return formatBytes(
|
|
565
|
+
const byteAsFileSize = numberOfBytes => {
|
|
566
|
+
return formatBytes(numberOfBytes);
|
|
567
567
|
};
|
|
568
568
|
const byteAsMemoryUsage = metricValue => {
|
|
569
569
|
return formatBytes(metricValue, {
|
|
@@ -581,13 +581,14 @@ const formatBytes = (number, {
|
|
|
581
581
|
const exponent = Math.min(Math.floor(Math.log10(number) / 3), BYTE_UNITS.length - 1);
|
|
582
582
|
const unitNumber = number / Math.pow(1000, exponent);
|
|
583
583
|
const unitName = BYTE_UNITS[exponent];
|
|
584
|
-
const
|
|
584
|
+
const maxDecimals = unitNumber < 100 ? 1 : 0;
|
|
585
585
|
const unitNumberRounded = setRoundedPrecision(unitNumber, {
|
|
586
|
-
decimals
|
|
586
|
+
decimals: maxDecimals,
|
|
587
|
+
decimalsWhenSmall: 1
|
|
587
588
|
});
|
|
588
589
|
|
|
589
590
|
if (fixedDecimals) {
|
|
590
|
-
return `${unitNumberRounded.toFixed(
|
|
591
|
+
return `${unitNumberRounded.toFixed(maxDecimals)} ${unitName}`;
|
|
591
592
|
}
|
|
592
593
|
|
|
593
594
|
return `${unitNumberRounded} ${unitName}`;
|
|
@@ -8559,12 +8560,12 @@ const createReloadableWorker = (workerFileUrl, options = {}) => {
|
|
|
8559
8560
|
worker.once("error", error => {
|
|
8560
8561
|
console.error(error);
|
|
8561
8562
|
});
|
|
8562
|
-
await new Promise(resolve => {
|
|
8563
|
-
worker.once("online", resolve);
|
|
8564
|
-
});
|
|
8565
8563
|
worker.once("exit", () => {
|
|
8566
8564
|
worker = null;
|
|
8567
8565
|
});
|
|
8566
|
+
await new Promise(resolve => {
|
|
8567
|
+
worker.once("online", resolve);
|
|
8568
|
+
});
|
|
8568
8569
|
return worker;
|
|
8569
8570
|
};
|
|
8570
8571
|
|
|
@@ -8575,6 +8576,7 @@ const createReloadableWorker = (workerFileUrl, options = {}) => {
|
|
|
8575
8576
|
|
|
8576
8577
|
return {
|
|
8577
8578
|
isPrimary,
|
|
8579
|
+
isWorker: !isPrimary,
|
|
8578
8580
|
load,
|
|
8579
8581
|
reload,
|
|
8580
8582
|
terminate
|
|
@@ -13280,7 +13282,7 @@ const jsenvPluginAsJsClassicHtml = ({
|
|
|
13280
13282
|
appliesDuring: "*",
|
|
13281
13283
|
transformUrlContent: {
|
|
13282
13284
|
html: async (urlInfo, context) => {
|
|
13283
|
-
const shouldTransformScriptTypeModule = !context.isSupportedOnCurrentClients("script_type_module") || !context.isSupportedOnCurrentClients("import_dynamic");
|
|
13285
|
+
const shouldTransformScriptTypeModule = !context.isSupportedOnCurrentClients("script_type_module") || !context.isSupportedOnCurrentClients("import_dynamic") || !context.isSupportedOnCurrentClients("import_meta");
|
|
13284
13286
|
const htmlAst = parseHtmlString(urlInfo.content);
|
|
13285
13287
|
const preloadAsScriptNodes = [];
|
|
13286
13288
|
const modulePreloadNodes = [];
|
|
@@ -13887,14 +13889,16 @@ const featureCompats = {
|
|
|
13887
13889
|
android: "4.4",
|
|
13888
13890
|
samsung: "4"
|
|
13889
13891
|
},
|
|
13892
|
+
// https://caniuse.com/?search=import.meta
|
|
13890
13893
|
import_meta: {
|
|
13894
|
+
android: "9",
|
|
13891
13895
|
chrome: "64",
|
|
13892
13896
|
edge: "79",
|
|
13893
13897
|
firefox: "62",
|
|
13894
|
-
safari: "11.1",
|
|
13895
|
-
opera: "51",
|
|
13896
13898
|
ios: "12",
|
|
13897
|
-
|
|
13899
|
+
opera: "51",
|
|
13900
|
+
safari: "11.1",
|
|
13901
|
+
samsung: "9.2"
|
|
13898
13902
|
},
|
|
13899
13903
|
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#browser_compatibility
|
|
13900
13904
|
import_dynamic: {
|
|
@@ -19269,14 +19273,10 @@ const startDevServer = async ({
|
|
|
19269
19273
|
"./jsenv.config.mjs": true
|
|
19270
19274
|
},
|
|
19271
19275
|
devServerMainFile = getCallerPosition().url,
|
|
19272
|
-
|
|
19273
|
-
// - inside a forked child process
|
|
19274
|
-
// - debugged by vscode
|
|
19275
|
-
// otherwise we get net:ERR_CONNECTION_REFUSED
|
|
19276
|
-
devServerAutoreload = typeof process.send !== "function" && !process.env.VSCODE_INSPECTOR_OPTIONS,
|
|
19276
|
+
devServerAutoreload = true,
|
|
19277
19277
|
clientFiles = {
|
|
19278
19278
|
"./src/": true,
|
|
19279
|
-
"./
|
|
19279
|
+
"./tests/": true
|
|
19280
19280
|
},
|
|
19281
19281
|
cooldownBetweenFileEvents,
|
|
19282
19282
|
clientAutoreload = true,
|
|
@@ -19303,7 +19303,7 @@ const startDevServer = async ({
|
|
|
19303
19303
|
"./src/**/*.html": true
|
|
19304
19304
|
},
|
|
19305
19305
|
test: {
|
|
19306
|
-
"./
|
|
19306
|
+
"./tests/**/*.test.html": true
|
|
19307
19307
|
}
|
|
19308
19308
|
},
|
|
19309
19309
|
// toolbar = false,
|
|
@@ -19380,10 +19380,12 @@ const startDevServer = async ({
|
|
|
19380
19380
|
reloadableWorker.terminate();
|
|
19381
19381
|
});
|
|
19382
19382
|
const worker = await reloadableWorker.load();
|
|
19383
|
-
|
|
19384
|
-
|
|
19385
|
-
|
|
19386
|
-
|
|
19383
|
+
const messagePromise = new Promise(resolve => {
|
|
19384
|
+
worker.once("message", resolve);
|
|
19385
|
+
});
|
|
19386
|
+
await messagePromise; // if (!keepProcessAlive) {
|
|
19387
|
+
// worker.unref()
|
|
19388
|
+
// }
|
|
19387
19389
|
|
|
19388
19390
|
return {
|
|
19389
19391
|
origin: `${protocol}://127.0.0.1:${port}`,
|
|
@@ -19499,6 +19501,11 @@ const startDevServer = async ({
|
|
|
19499
19501
|
kitchen.pluginController.callHooks("destroy", {});
|
|
19500
19502
|
};
|
|
19501
19503
|
});
|
|
19504
|
+
|
|
19505
|
+
if (reloadableWorker.isWorker) {
|
|
19506
|
+
parentPort.postMessage(server.origin);
|
|
19507
|
+
}
|
|
19508
|
+
|
|
19502
19509
|
return {
|
|
19503
19510
|
origin: server.origin,
|
|
19504
19511
|
stop: () => {
|
|
@@ -20207,7 +20214,9 @@ const run = async ({
|
|
|
20207
20214
|
const runOperation = Abort.startOperation();
|
|
20208
20215
|
runOperation.addAbortSignal(signal);
|
|
20209
20216
|
|
|
20210
|
-
if (
|
|
20217
|
+
if ( // ideally we would rather log than the timeout is ignored
|
|
20218
|
+
// when keepRunning is true
|
|
20219
|
+
!keepRunning && typeof allocatedMs === "number" && allocatedMs !== Infinity) {
|
|
20211
20220
|
const timeoutAbortSource = runOperation.timeout(allocatedMs);
|
|
20212
20221
|
resultTransformer = composeTransformer$1(resultTransformer, result => {
|
|
20213
20222
|
if (result.status === "errored" && Abort.isAbortError(result.error) && timeoutAbortSource.signal.aborted) {
|
|
@@ -21224,15 +21233,6 @@ const executeInParallel = async ({
|
|
|
21224
21233
|
return executionResults;
|
|
21225
21234
|
};
|
|
21226
21235
|
|
|
21227
|
-
const defaultCoverageConfig = {
|
|
21228
|
-
"./index.js": true,
|
|
21229
|
-
"./main.js": true,
|
|
21230
|
-
"./src/**/*.js": true,
|
|
21231
|
-
"./**/*.test.*": false,
|
|
21232
|
-
// contains .test. -> nope
|
|
21233
|
-
"./**/test/": false // inside a test folder -> nope,
|
|
21234
|
-
|
|
21235
|
-
};
|
|
21236
21236
|
/**
|
|
21237
21237
|
* Execute a list of files and log how it goes
|
|
21238
21238
|
* @param {Object} testPlanParameters
|
|
@@ -21276,7 +21276,15 @@ const executeTestPlan = async ({
|
|
|
21276
21276
|
gcBetweenExecutions = logMemoryHeapUsage,
|
|
21277
21277
|
coverage = process.argv.includes("--cover") || process.argv.includes("--coverage"),
|
|
21278
21278
|
coverageTempDirectoryRelativeUrl = "./.coverage/tmp/",
|
|
21279
|
-
coverageConfig =
|
|
21279
|
+
coverageConfig = {
|
|
21280
|
+
"./src/**/*.js": true,
|
|
21281
|
+
"./**/*.test.*": false,
|
|
21282
|
+
// contains .test. -> no
|
|
21283
|
+
"./**/test/": false,
|
|
21284
|
+
// inside a test directory -> no
|
|
21285
|
+
"./**/tests/": false // inside a tests directory -> no
|
|
21286
|
+
|
|
21287
|
+
},
|
|
21280
21288
|
coverageIncludeMissing = true,
|
|
21281
21289
|
coverageAndExecutionAllowed = false,
|
|
21282
21290
|
coverageForceIstanbul = false,
|
|
@@ -21517,7 +21525,7 @@ const createRuntimeFromPlaywright = ({
|
|
|
21517
21525
|
keepRunning,
|
|
21518
21526
|
onConsole,
|
|
21519
21527
|
executablePath,
|
|
21520
|
-
headful =
|
|
21528
|
+
headful = keepRunning,
|
|
21521
21529
|
ignoreHTTPSErrors = true
|
|
21522
21530
|
}) => {
|
|
21523
21531
|
const cleanupCallbackList = createCallbackListNotifiedOnce();
|
|
@@ -23531,17 +23539,18 @@ const build = async ({
|
|
|
23531
23539
|
buildDirectoryUrl,
|
|
23532
23540
|
entryPoints = {},
|
|
23533
23541
|
baseUrl = "/",
|
|
23534
|
-
// default runtimeCompat corresponds to
|
|
23535
|
-
//
|
|
23542
|
+
// default runtimeCompat corresponds to
|
|
23543
|
+
// "we can keep <script type="module"> intact":
|
|
23544
|
+
// so script_type_module + dynamic_import + import_meta
|
|
23536
23545
|
runtimeCompat = {
|
|
23537
23546
|
// android: "8",
|
|
23538
|
-
chrome: "
|
|
23547
|
+
chrome: "64",
|
|
23539
23548
|
edge: "79",
|
|
23540
23549
|
firefox: "67",
|
|
23541
|
-
ios: "
|
|
23542
|
-
opera: "
|
|
23550
|
+
ios: "12",
|
|
23551
|
+
opera: "51",
|
|
23543
23552
|
safari: "11.3",
|
|
23544
|
-
samsung: "
|
|
23553
|
+
samsung: "9.2"
|
|
23545
23554
|
},
|
|
23546
23555
|
plugins = [],
|
|
23547
23556
|
sourcemaps = false,
|
|
@@ -24756,17 +24765,13 @@ const startBuildServer = async ({
|
|
|
24756
24765
|
keepProcessAlive = true,
|
|
24757
24766
|
rootDirectoryUrl,
|
|
24758
24767
|
buildDirectoryUrl,
|
|
24759
|
-
|
|
24768
|
+
buildIndexPath = "/index.html",
|
|
24760
24769
|
buildServerFiles = {
|
|
24761
24770
|
"./package.json": true,
|
|
24762
24771
|
"./jsenv.config.mjs": true
|
|
24763
24772
|
},
|
|
24764
24773
|
buildServerMainFile = getCallerPosition().url,
|
|
24765
|
-
|
|
24766
|
-
// - inside a forked child process
|
|
24767
|
-
// - debugged by vscode
|
|
24768
|
-
// otherwise we get net:ERR_CONNECTION_REFUSED
|
|
24769
|
-
buildServerAutoreload = typeof process.send !== "function" && !process.env.VSCODE_INSPECTOR_OPTIONS,
|
|
24774
|
+
buildServerAutoreload = true,
|
|
24770
24775
|
cooldownBetweenFileEvents
|
|
24771
24776
|
}) => {
|
|
24772
24777
|
const logger = createLogger({
|
|
@@ -24774,6 +24779,23 @@ const startBuildServer = async ({
|
|
|
24774
24779
|
});
|
|
24775
24780
|
rootDirectoryUrl = assertAndNormalizeDirectoryUrl(rootDirectoryUrl);
|
|
24776
24781
|
buildDirectoryUrl = assertAndNormalizeDirectoryUrl(buildDirectoryUrl);
|
|
24782
|
+
|
|
24783
|
+
if (buildIndexPath) {
|
|
24784
|
+
if (typeof buildIndexPath !== "string") {
|
|
24785
|
+
throw new TypeError(`buildIndexPath must be a string, got ${buildIndexPath}`);
|
|
24786
|
+
}
|
|
24787
|
+
|
|
24788
|
+
if (buildIndexPath[0] !== "/") {
|
|
24789
|
+
const buildIndexUrl = new URL(buildIndexPath, buildDirectoryUrl).href;
|
|
24790
|
+
|
|
24791
|
+
if (!buildIndexUrl.startsWith(buildDirectoryUrl)) {
|
|
24792
|
+
throw new Error(`buildIndexPath must be relative, got ${buildIndexPath}`);
|
|
24793
|
+
}
|
|
24794
|
+
|
|
24795
|
+
buildIndexPath = buildIndexUrl.slice(buildDirectoryUrl.length);
|
|
24796
|
+
}
|
|
24797
|
+
}
|
|
24798
|
+
|
|
24777
24799
|
const operation = Abort.startOperation();
|
|
24778
24800
|
operation.addAbortSignal(signal);
|
|
24779
24801
|
|
|
@@ -24844,10 +24866,12 @@ const startBuildServer = async ({
|
|
|
24844
24866
|
reloadableWorker.terminate();
|
|
24845
24867
|
});
|
|
24846
24868
|
const worker = await reloadableWorker.load();
|
|
24847
|
-
|
|
24848
|
-
|
|
24849
|
-
|
|
24850
|
-
|
|
24869
|
+
const messagePromise = new Promise(resolve => {
|
|
24870
|
+
worker.once("message", resolve);
|
|
24871
|
+
});
|
|
24872
|
+
await messagePromise; // if (!keepProcessAlive) {
|
|
24873
|
+
// worker.unref()
|
|
24874
|
+
// }
|
|
24851
24875
|
|
|
24852
24876
|
return {
|
|
24853
24877
|
origin: `${protocol}://127.0.0.1:${port}`,
|
|
@@ -24866,7 +24890,8 @@ const startBuildServer = async ({
|
|
|
24866
24890
|
stopOnExit: false,
|
|
24867
24891
|
stopOnSIGINT: false,
|
|
24868
24892
|
stopOnInternalError: false,
|
|
24869
|
-
|
|
24893
|
+
// the worker should be kept alive by the parent otherwise
|
|
24894
|
+
keepProcessAlive,
|
|
24870
24895
|
logLevel: serverLogLevel,
|
|
24871
24896
|
startLog: false,
|
|
24872
24897
|
protocol,
|
|
@@ -24892,7 +24917,7 @@ const startBuildServer = async ({
|
|
|
24892
24917
|
requestToResponse: composeServices({ ...services,
|
|
24893
24918
|
build_files_service: createBuildFilesService({
|
|
24894
24919
|
buildDirectoryUrl,
|
|
24895
|
-
|
|
24920
|
+
buildIndexPath
|
|
24896
24921
|
})
|
|
24897
24922
|
})
|
|
24898
24923
|
});
|
|
@@ -24902,6 +24927,11 @@ const startBuildServer = async ({
|
|
|
24902
24927
|
logger.info(`- ${server.origins[key]}`);
|
|
24903
24928
|
});
|
|
24904
24929
|
logger.info(``);
|
|
24930
|
+
|
|
24931
|
+
if (reloadableWorker.isWorker) {
|
|
24932
|
+
parentPort.postMessage(server.origin);
|
|
24933
|
+
}
|
|
24934
|
+
|
|
24905
24935
|
return {
|
|
24906
24936
|
origin: server.origin,
|
|
24907
24937
|
stop: () => {
|
|
@@ -24912,14 +24942,14 @@ const startBuildServer = async ({
|
|
|
24912
24942
|
|
|
24913
24943
|
const createBuildFilesService = ({
|
|
24914
24944
|
buildDirectoryUrl,
|
|
24915
|
-
|
|
24945
|
+
buildIndexPath
|
|
24916
24946
|
}) => {
|
|
24917
24947
|
return request => {
|
|
24918
24948
|
const urlIsVersioned = new URL(request.ressource, request.origin).searchParams.has("v");
|
|
24919
24949
|
|
|
24920
|
-
if (
|
|
24950
|
+
if (buildIndexPath && request.ressource === "/") {
|
|
24921
24951
|
request = { ...request,
|
|
24922
|
-
ressource:
|
|
24952
|
+
ressource: `/${buildIndexPath}`
|
|
24923
24953
|
};
|
|
24924
24954
|
}
|
|
24925
24955
|
|
|
@@ -25160,4 +25190,4 @@ const jsenvPluginInjectGlobals = urlAssociations => {
|
|
|
25160
25190
|
};
|
|
25161
25191
|
};
|
|
25162
25192
|
|
|
25163
|
-
export { build, chromium, chromiumIsolatedTab,
|
|
25193
|
+
export { build, chromium, chromiumIsolatedTab, execute, executeTestPlan, firefox, firefoxIsolatedTab, jsenvPluginInjectGlobals, nodeProcess, startBuildServer, startDevServer, webkit, webkitIsolatedTab };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jsenv/core",
|
|
3
|
-
"version": "27.0.0-alpha.
|
|
3
|
+
"version": "27.0.0-alpha.93",
|
|
4
4
|
"description": "Tool to develop, test and build js projects",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
@@ -71,13 +71,13 @@
|
|
|
71
71
|
"@jsenv/importmap": "1.2.1",
|
|
72
72
|
"@jsenv/integrity": "0.0.1",
|
|
73
73
|
"@jsenv/node-esm-resolution": "0.1.0",
|
|
74
|
-
"@jsenv/server": "12.7.
|
|
74
|
+
"@jsenv/server": "12.7.3",
|
|
75
75
|
"@jsenv/uneval": "1.6.0",
|
|
76
76
|
"@jsenv/url-meta": "7.0.0",
|
|
77
77
|
"@jsenv/urls": "1.2.6",
|
|
78
78
|
"@jsenv/utils": "2.0.1",
|
|
79
79
|
"@jsenv/babel-plugins": "1.0.5",
|
|
80
|
-
"@jsenv/log": "2.0
|
|
80
|
+
"@jsenv/log": "2.1.0",
|
|
81
81
|
"@jsenv/sourcemap": "1.0.1",
|
|
82
82
|
"acorn-import-assertions": "1.8.0",
|
|
83
83
|
"cuid": "2.1.8",
|
|
@@ -97,16 +97,16 @@
|
|
|
97
97
|
"devDependencies": {
|
|
98
98
|
"@babel/eslint-parser": "7.18.2",
|
|
99
99
|
"@babel/plugin-syntax-import-assertions": "7.17.12",
|
|
100
|
-
"@jsenv/assert": "2.
|
|
100
|
+
"@jsenv/assert": "2.6.0",
|
|
101
101
|
"@jsenv/eslint-config": "16.0.9",
|
|
102
|
-
"@jsenv/file-size-impact": "
|
|
103
|
-
"@jsenv/https-local": "
|
|
104
|
-
"@jsenv/package-workspace": "0.
|
|
105
|
-
"@jsenv/performance-impact": "
|
|
102
|
+
"@jsenv/file-size-impact": "13.0.0",
|
|
103
|
+
"@jsenv/https-local": "2.1.0",
|
|
104
|
+
"@jsenv/package-workspace": "0.3.0",
|
|
105
|
+
"@jsenv/performance-impact": "3.0.0",
|
|
106
106
|
"eslint": "8.18.0",
|
|
107
107
|
"eslint-plugin-html": "6.2.0",
|
|
108
108
|
"eslint-plugin-import": "2.26.0",
|
|
109
|
-
"eslint-plugin-react": "7.30.
|
|
109
|
+
"eslint-plugin-react": "7.30.1",
|
|
110
110
|
"playwright": "1.22.2",
|
|
111
111
|
"prettier": "2.7.1"
|
|
112
112
|
}
|
package/src/build/build.js
CHANGED
|
@@ -85,17 +85,18 @@ export const build = async ({
|
|
|
85
85
|
entryPoints = {},
|
|
86
86
|
baseUrl = "/",
|
|
87
87
|
|
|
88
|
-
// default runtimeCompat corresponds to
|
|
89
|
-
//
|
|
88
|
+
// default runtimeCompat corresponds to
|
|
89
|
+
// "we can keep <script type="module"> intact":
|
|
90
|
+
// so script_type_module + dynamic_import + import_meta
|
|
90
91
|
runtimeCompat = {
|
|
91
92
|
// android: "8",
|
|
92
|
-
chrome: "
|
|
93
|
+
chrome: "64",
|
|
93
94
|
edge: "79",
|
|
94
95
|
firefox: "67",
|
|
95
|
-
ios: "
|
|
96
|
-
opera: "
|
|
96
|
+
ios: "12",
|
|
97
|
+
opera: "51",
|
|
97
98
|
safari: "11.3",
|
|
98
|
-
samsung: "
|
|
99
|
+
samsung: "9.2",
|
|
99
100
|
},
|
|
100
101
|
plugins = [],
|
|
101
102
|
sourcemaps = false,
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
* we want to be in the user shoes and we should not alter build files.
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
+
import { parentPort } from "node:worker_threads"
|
|
16
17
|
import {
|
|
17
18
|
jsenvAccessControlAllowedHeaders,
|
|
18
19
|
startServer,
|
|
@@ -50,23 +51,34 @@ export const startBuildServer = async ({
|
|
|
50
51
|
|
|
51
52
|
rootDirectoryUrl,
|
|
52
53
|
buildDirectoryUrl,
|
|
53
|
-
|
|
54
|
+
buildIndexPath = "/index.html",
|
|
54
55
|
buildServerFiles = {
|
|
55
56
|
"./package.json": true,
|
|
56
57
|
"./jsenv.config.mjs": true,
|
|
57
58
|
},
|
|
58
59
|
buildServerMainFile = getCallerPosition().url,
|
|
59
|
-
|
|
60
|
-
// - inside a forked child process
|
|
61
|
-
// - debugged by vscode
|
|
62
|
-
// otherwise we get net:ERR_CONNECTION_REFUSED
|
|
63
|
-
buildServerAutoreload = typeof process.send !== "function" &&
|
|
64
|
-
!process.env.VSCODE_INSPECTOR_OPTIONS,
|
|
60
|
+
buildServerAutoreload = true,
|
|
65
61
|
cooldownBetweenFileEvents,
|
|
66
62
|
}) => {
|
|
67
63
|
const logger = createLogger({ logLevel })
|
|
68
64
|
rootDirectoryUrl = assertAndNormalizeDirectoryUrl(rootDirectoryUrl)
|
|
69
65
|
buildDirectoryUrl = assertAndNormalizeDirectoryUrl(buildDirectoryUrl)
|
|
66
|
+
if (buildIndexPath) {
|
|
67
|
+
if (typeof buildIndexPath !== "string") {
|
|
68
|
+
throw new TypeError(
|
|
69
|
+
`buildIndexPath must be a string, got ${buildIndexPath}`,
|
|
70
|
+
)
|
|
71
|
+
}
|
|
72
|
+
if (buildIndexPath[0] !== "/") {
|
|
73
|
+
const buildIndexUrl = new URL(buildIndexPath, buildDirectoryUrl).href
|
|
74
|
+
if (!buildIndexUrl.startsWith(buildDirectoryUrl)) {
|
|
75
|
+
throw new Error(
|
|
76
|
+
`buildIndexPath must be relative, got ${buildIndexPath}`,
|
|
77
|
+
)
|
|
78
|
+
}
|
|
79
|
+
buildIndexPath = buildIndexUrl.slice(buildDirectoryUrl.length)
|
|
80
|
+
}
|
|
81
|
+
}
|
|
70
82
|
|
|
71
83
|
const operation = Abort.startOperation()
|
|
72
84
|
operation.addAbortSignal(signal)
|
|
@@ -119,9 +131,13 @@ export const startBuildServer = async ({
|
|
|
119
131
|
reloadableWorker.terminate()
|
|
120
132
|
})
|
|
121
133
|
const worker = await reloadableWorker.load()
|
|
122
|
-
|
|
123
|
-
worker.
|
|
124
|
-
}
|
|
134
|
+
const messagePromise = new Promise((resolve) => {
|
|
135
|
+
worker.once("message", resolve)
|
|
136
|
+
})
|
|
137
|
+
await messagePromise
|
|
138
|
+
// if (!keepProcessAlive) {
|
|
139
|
+
// worker.unref()
|
|
140
|
+
// }
|
|
125
141
|
return {
|
|
126
142
|
origin: `${protocol}://127.0.0.1:${port}`,
|
|
127
143
|
stop: () => {
|
|
@@ -139,7 +155,8 @@ export const startBuildServer = async ({
|
|
|
139
155
|
stopOnExit: false,
|
|
140
156
|
stopOnSIGINT: false,
|
|
141
157
|
stopOnInternalError: false,
|
|
142
|
-
|
|
158
|
+
// the worker should be kept alive by the parent otherwise
|
|
159
|
+
keepProcessAlive,
|
|
143
160
|
logLevel: serverLogLevel,
|
|
144
161
|
startLog: false,
|
|
145
162
|
|
|
@@ -168,7 +185,7 @@ export const startBuildServer = async ({
|
|
|
168
185
|
...services,
|
|
169
186
|
build_files_service: createBuildFilesService({
|
|
170
187
|
buildDirectoryUrl,
|
|
171
|
-
|
|
188
|
+
buildIndexPath,
|
|
172
189
|
}),
|
|
173
190
|
}),
|
|
174
191
|
})
|
|
@@ -178,6 +195,9 @@ export const startBuildServer = async ({
|
|
|
178
195
|
logger.info(`- ${server.origins[key]}`)
|
|
179
196
|
})
|
|
180
197
|
logger.info(``)
|
|
198
|
+
if (reloadableWorker.isWorker) {
|
|
199
|
+
parentPort.postMessage(server.origin)
|
|
200
|
+
}
|
|
181
201
|
return {
|
|
182
202
|
origin: server.origin,
|
|
183
203
|
stop: () => {
|
|
@@ -186,16 +206,16 @@ export const startBuildServer = async ({
|
|
|
186
206
|
}
|
|
187
207
|
}
|
|
188
208
|
|
|
189
|
-
const createBuildFilesService = ({ buildDirectoryUrl,
|
|
209
|
+
const createBuildFilesService = ({ buildDirectoryUrl, buildIndexPath }) => {
|
|
190
210
|
return (request) => {
|
|
191
211
|
const urlIsVersioned = new URL(
|
|
192
212
|
request.ressource,
|
|
193
213
|
request.origin,
|
|
194
214
|
).searchParams.has("v")
|
|
195
|
-
if (
|
|
215
|
+
if (buildIndexPath && request.ressource === "/") {
|
|
196
216
|
request = {
|
|
197
217
|
...request,
|
|
198
|
-
ressource:
|
|
218
|
+
ressource: `/${buildIndexPath}`,
|
|
199
219
|
}
|
|
200
220
|
}
|
|
201
221
|
return fetchFileSystem(
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { parentPort } from "node:worker_threads"
|
|
1
2
|
import { findFreePort } from "@jsenv/server"
|
|
2
3
|
import {
|
|
3
4
|
assertAndNormalizeDirectoryUrl,
|
|
@@ -36,15 +37,10 @@ export const startDevServer = async ({
|
|
|
36
37
|
"./jsenv.config.mjs": true,
|
|
37
38
|
},
|
|
38
39
|
devServerMainFile = getCallerPosition().url,
|
|
39
|
-
|
|
40
|
-
// - inside a forked child process
|
|
41
|
-
// - debugged by vscode
|
|
42
|
-
// otherwise we get net:ERR_CONNECTION_REFUSED
|
|
43
|
-
devServerAutoreload = typeof process.send !== "function" &&
|
|
44
|
-
!process.env.VSCODE_INSPECTOR_OPTIONS,
|
|
40
|
+
devServerAutoreload = true,
|
|
45
41
|
clientFiles = {
|
|
46
42
|
"./src/": true,
|
|
47
|
-
"./
|
|
43
|
+
"./tests/": true,
|
|
48
44
|
},
|
|
49
45
|
cooldownBetweenFileEvents,
|
|
50
46
|
clientAutoreload = true,
|
|
@@ -72,7 +68,7 @@ export const startDevServer = async ({
|
|
|
72
68
|
"./src/**/*.html": true,
|
|
73
69
|
},
|
|
74
70
|
test: {
|
|
75
|
-
"./
|
|
71
|
+
"./tests/**/*.test.html": true,
|
|
76
72
|
},
|
|
77
73
|
},
|
|
78
74
|
// toolbar = false,
|
|
@@ -130,9 +126,13 @@ export const startDevServer = async ({
|
|
|
130
126
|
})
|
|
131
127
|
|
|
132
128
|
const worker = await reloadableWorker.load()
|
|
133
|
-
|
|
134
|
-
worker.
|
|
135
|
-
}
|
|
129
|
+
const messagePromise = new Promise((resolve) => {
|
|
130
|
+
worker.once("message", resolve)
|
|
131
|
+
})
|
|
132
|
+
await messagePromise
|
|
133
|
+
// if (!keepProcessAlive) {
|
|
134
|
+
// worker.unref()
|
|
135
|
+
// }
|
|
136
136
|
return {
|
|
137
137
|
origin: `${protocol}://127.0.0.1:${port}`,
|
|
138
138
|
stop: () => {
|
|
@@ -230,6 +230,9 @@ export const startDevServer = async ({
|
|
|
230
230
|
kitchen.pluginController.callHooks("destroy", {})
|
|
231
231
|
}
|
|
232
232
|
})
|
|
233
|
+
if (reloadableWorker.isWorker) {
|
|
234
|
+
parentPort.postMessage(server.origin)
|
|
235
|
+
}
|
|
233
236
|
return {
|
|
234
237
|
origin: server.origin,
|
|
235
238
|
stop: () => {
|
package/src/execute/run.js
CHANGED
|
@@ -25,7 +25,13 @@ export const run = async ({
|
|
|
25
25
|
|
|
26
26
|
const runOperation = Abort.startOperation()
|
|
27
27
|
runOperation.addAbortSignal(signal)
|
|
28
|
-
if (
|
|
28
|
+
if (
|
|
29
|
+
// ideally we would rather log than the timeout is ignored
|
|
30
|
+
// when keepRunning is true
|
|
31
|
+
!keepRunning &&
|
|
32
|
+
typeof allocatedMs === "number" &&
|
|
33
|
+
allocatedMs !== Infinity
|
|
34
|
+
) {
|
|
29
35
|
const timeoutAbortSource = runOperation.timeout(allocatedMs)
|
|
30
36
|
resultTransformer = composeTransformer(resultTransformer, (result) => {
|
|
31
37
|
if (
|
|
@@ -30,16 +30,15 @@ export const createReloadableWorker = (workerFileUrl, options = {}) => {
|
|
|
30
30
|
workerFilePath,
|
|
31
31
|
},
|
|
32
32
|
})
|
|
33
|
-
|
|
34
33
|
worker.once("error", (error) => {
|
|
35
34
|
console.error(error)
|
|
36
35
|
})
|
|
37
|
-
await new Promise((resolve) => {
|
|
38
|
-
worker.once("online", resolve)
|
|
39
|
-
})
|
|
40
36
|
worker.once("exit", () => {
|
|
41
37
|
worker = null
|
|
42
38
|
})
|
|
39
|
+
await new Promise((resolve) => {
|
|
40
|
+
worker.once("online", resolve)
|
|
41
|
+
})
|
|
43
42
|
return worker
|
|
44
43
|
}
|
|
45
44
|
|
|
@@ -50,6 +49,7 @@ export const createReloadableWorker = (workerFileUrl, options = {}) => {
|
|
|
50
49
|
|
|
51
50
|
return {
|
|
52
51
|
isPrimary,
|
|
52
|
+
isWorker: !isPrimary,
|
|
53
53
|
load,
|
|
54
54
|
reload,
|
|
55
55
|
terminate,
|
package/src/main.js
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
// dev
|
|
2
2
|
export { startDevServer } from "./dev/start_dev_server.js"
|
|
3
3
|
// test
|
|
4
|
-
export {
|
|
5
|
-
executeTestPlan,
|
|
6
|
-
defaultCoverageConfig,
|
|
7
|
-
} from "./test/execute_test_plan.js"
|
|
4
|
+
export { executeTestPlan } from "./test/execute_test_plan.js"
|
|
8
5
|
export {
|
|
9
6
|
chromium,
|
|
10
7
|
chromiumIsolatedTab,
|
|
@@ -18,14 +18,16 @@ export const featureCompats = {
|
|
|
18
18
|
android: "4.4",
|
|
19
19
|
samsung: "4",
|
|
20
20
|
},
|
|
21
|
+
// https://caniuse.com/?search=import.meta
|
|
21
22
|
import_meta: {
|
|
23
|
+
android: "9",
|
|
22
24
|
chrome: "64",
|
|
23
25
|
edge: "79",
|
|
24
26
|
firefox: "62",
|
|
25
|
-
safari: "11.1",
|
|
26
|
-
opera: "51",
|
|
27
27
|
ios: "12",
|
|
28
|
-
|
|
28
|
+
opera: "51",
|
|
29
|
+
safari: "11.1",
|
|
30
|
+
samsung: "9.2",
|
|
29
31
|
},
|
|
30
32
|
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#browser_compatibility
|
|
31
33
|
import_dynamic: {
|
|
@@ -27,7 +27,8 @@ export const jsenvPluginAsJsClassicHtml = ({
|
|
|
27
27
|
html: async (urlInfo, context) => {
|
|
28
28
|
const shouldTransformScriptTypeModule =
|
|
29
29
|
!context.isSupportedOnCurrentClients("script_type_module") ||
|
|
30
|
-
!context.isSupportedOnCurrentClients("import_dynamic")
|
|
30
|
+
!context.isSupportedOnCurrentClients("import_dynamic") ||
|
|
31
|
+
!context.isSupportedOnCurrentClients("import_meta")
|
|
31
32
|
const htmlAst = parseHtmlString(urlInfo.content)
|
|
32
33
|
const preloadAsScriptNodes = []
|
|
33
34
|
const modulePreloadNodes = []
|
|
@@ -11,14 +11,6 @@ import { generateCoverageHtmlDirectory } from "./coverage/coverage_reporter_html
|
|
|
11
11
|
import { generateCoverageTextLog } from "./coverage/coverage_reporter_text_log.js"
|
|
12
12
|
import { executePlan } from "./execute_plan.js"
|
|
13
13
|
|
|
14
|
-
export const defaultCoverageConfig = {
|
|
15
|
-
"./index.js": true,
|
|
16
|
-
"./main.js": true,
|
|
17
|
-
"./src/**/*.js": true,
|
|
18
|
-
"./**/*.test.*": false, // contains .test. -> nope
|
|
19
|
-
"./**/test/": false, // inside a test folder -> nope,
|
|
20
|
-
}
|
|
21
|
-
|
|
22
14
|
/**
|
|
23
15
|
* Execute a list of files and log how it goes
|
|
24
16
|
* @param {Object} testPlanParameters
|
|
@@ -64,7 +56,12 @@ export const executeTestPlan = async ({
|
|
|
64
56
|
coverage = process.argv.includes("--cover") ||
|
|
65
57
|
process.argv.includes("--coverage"),
|
|
66
58
|
coverageTempDirectoryRelativeUrl = "./.coverage/tmp/",
|
|
67
|
-
coverageConfig =
|
|
59
|
+
coverageConfig = {
|
|
60
|
+
"./src/**/*.js": true,
|
|
61
|
+
"./**/*.test.*": false, // contains .test. -> no
|
|
62
|
+
"./**/test/": false, // inside a test directory -> no
|
|
63
|
+
"./**/tests/": false, // inside a tests directory -> no
|
|
64
|
+
},
|
|
68
65
|
coverageIncludeMissing = true,
|
|
69
66
|
coverageAndExecutionAllowed = false,
|
|
70
67
|
coverageForceIstanbul = false,
|