@jsenv/core 27.0.0-alpha.90 → 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 +109 -61
- package/package.json +14 -14
- 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}`;
|
|
@@ -7825,6 +7826,24 @@ const readFileSync = (value, {
|
|
|
7825
7826
|
};
|
|
7826
7827
|
|
|
7827
7828
|
const guardTooFastSecondCall = (callback, cooldownBetweenFileEvents = 40) => {
|
|
7829
|
+
let previousCallMs;
|
|
7830
|
+
return (...args) => {
|
|
7831
|
+
const nowMs = Date.now();
|
|
7832
|
+
|
|
7833
|
+
if (previousCallMs) {
|
|
7834
|
+
const msEllapsed = nowMs - previousCallMs;
|
|
7835
|
+
|
|
7836
|
+
if (msEllapsed < cooldownBetweenFileEvents) {
|
|
7837
|
+
previousCallMs = null;
|
|
7838
|
+
return;
|
|
7839
|
+
}
|
|
7840
|
+
}
|
|
7841
|
+
|
|
7842
|
+
previousCallMs = nowMs;
|
|
7843
|
+
callback(...args);
|
|
7844
|
+
};
|
|
7845
|
+
};
|
|
7846
|
+
const guardTooFastSecondCallPerFile = (callback, cooldownBetweenFileEvents = 40) => {
|
|
7828
7847
|
const previousCallMsMap = new Map();
|
|
7829
7848
|
return fileEvent => {
|
|
7830
7849
|
const {
|
|
@@ -7936,15 +7955,15 @@ const registerDirectoryLifecycle = (source, {
|
|
|
7936
7955
|
|
|
7937
7956
|
if (cooldownBetweenFileEvents) {
|
|
7938
7957
|
if (added) {
|
|
7939
|
-
added =
|
|
7958
|
+
added = guardTooFastSecondCallPerFile(added, cooldownBetweenFileEvents);
|
|
7940
7959
|
}
|
|
7941
7960
|
|
|
7942
7961
|
if (updated) {
|
|
7943
|
-
updated =
|
|
7962
|
+
updated = guardTooFastSecondCallPerFile(updated, cooldownBetweenFileEvents);
|
|
7944
7963
|
}
|
|
7945
7964
|
|
|
7946
7965
|
if (removed) {
|
|
7947
|
-
removed =
|
|
7966
|
+
removed = guardTooFastSecondCallPerFile(removed, cooldownBetweenFileEvents);
|
|
7948
7967
|
}
|
|
7949
7968
|
}
|
|
7950
7969
|
|
|
@@ -8541,12 +8560,12 @@ const createReloadableWorker = (workerFileUrl, options = {}) => {
|
|
|
8541
8560
|
worker.once("error", error => {
|
|
8542
8561
|
console.error(error);
|
|
8543
8562
|
});
|
|
8544
|
-
await new Promise(resolve => {
|
|
8545
|
-
worker.once("online", resolve);
|
|
8546
|
-
});
|
|
8547
8563
|
worker.once("exit", () => {
|
|
8548
8564
|
worker = null;
|
|
8549
8565
|
});
|
|
8566
|
+
await new Promise(resolve => {
|
|
8567
|
+
worker.once("online", resolve);
|
|
8568
|
+
});
|
|
8550
8569
|
return worker;
|
|
8551
8570
|
};
|
|
8552
8571
|
|
|
@@ -8557,6 +8576,7 @@ const createReloadableWorker = (workerFileUrl, options = {}) => {
|
|
|
8557
8576
|
|
|
8558
8577
|
return {
|
|
8559
8578
|
isPrimary,
|
|
8579
|
+
isWorker: !isPrimary,
|
|
8560
8580
|
load,
|
|
8561
8581
|
reload,
|
|
8562
8582
|
terminate
|
|
@@ -13262,7 +13282,7 @@ const jsenvPluginAsJsClassicHtml = ({
|
|
|
13262
13282
|
appliesDuring: "*",
|
|
13263
13283
|
transformUrlContent: {
|
|
13264
13284
|
html: async (urlInfo, context) => {
|
|
13265
|
-
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");
|
|
13266
13286
|
const htmlAst = parseHtmlString(urlInfo.content);
|
|
13267
13287
|
const preloadAsScriptNodes = [];
|
|
13268
13288
|
const modulePreloadNodes = [];
|
|
@@ -13869,14 +13889,16 @@ const featureCompats = {
|
|
|
13869
13889
|
android: "4.4",
|
|
13870
13890
|
samsung: "4"
|
|
13871
13891
|
},
|
|
13892
|
+
// https://caniuse.com/?search=import.meta
|
|
13872
13893
|
import_meta: {
|
|
13894
|
+
android: "9",
|
|
13873
13895
|
chrome: "64",
|
|
13874
13896
|
edge: "79",
|
|
13875
13897
|
firefox: "62",
|
|
13876
|
-
safari: "11.1",
|
|
13877
|
-
opera: "51",
|
|
13878
13898
|
ios: "12",
|
|
13879
|
-
|
|
13899
|
+
opera: "51",
|
|
13900
|
+
safari: "11.1",
|
|
13901
|
+
samsung: "9.2"
|
|
13880
13902
|
},
|
|
13881
13903
|
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#browser_compatibility
|
|
13882
13904
|
import_dynamic: {
|
|
@@ -19251,14 +19273,10 @@ const startDevServer = async ({
|
|
|
19251
19273
|
"./jsenv.config.mjs": true
|
|
19252
19274
|
},
|
|
19253
19275
|
devServerMainFile = getCallerPosition().url,
|
|
19254
|
-
|
|
19255
|
-
// - inside a forked child process
|
|
19256
|
-
// - debugged by vscode
|
|
19257
|
-
// otherwise we get net:ERR_CONNECTION_REFUSED
|
|
19258
|
-
devServerAutoreload = typeof process.send !== "function" && !process.env.VSCODE_INSPECTOR_OPTIONS,
|
|
19276
|
+
devServerAutoreload = true,
|
|
19259
19277
|
clientFiles = {
|
|
19260
19278
|
"./src/": true,
|
|
19261
|
-
"./
|
|
19279
|
+
"./tests/": true
|
|
19262
19280
|
},
|
|
19263
19281
|
cooldownBetweenFileEvents,
|
|
19264
19282
|
clientAutoreload = true,
|
|
@@ -19285,7 +19303,7 @@ const startDevServer = async ({
|
|
|
19285
19303
|
"./src/**/*.html": true
|
|
19286
19304
|
},
|
|
19287
19305
|
test: {
|
|
19288
|
-
"./
|
|
19306
|
+
"./tests/**/*.test.html": true
|
|
19289
19307
|
}
|
|
19290
19308
|
},
|
|
19291
19309
|
// toolbar = false,
|
|
@@ -19362,10 +19380,12 @@ const startDevServer = async ({
|
|
|
19362
19380
|
reloadableWorker.terminate();
|
|
19363
19381
|
});
|
|
19364
19382
|
const worker = await reloadableWorker.load();
|
|
19365
|
-
|
|
19366
|
-
|
|
19367
|
-
|
|
19368
|
-
|
|
19383
|
+
const messagePromise = new Promise(resolve => {
|
|
19384
|
+
worker.once("message", resolve);
|
|
19385
|
+
});
|
|
19386
|
+
await messagePromise; // if (!keepProcessAlive) {
|
|
19387
|
+
// worker.unref()
|
|
19388
|
+
// }
|
|
19369
19389
|
|
|
19370
19390
|
return {
|
|
19371
19391
|
origin: `${protocol}://127.0.0.1:${port}`,
|
|
@@ -19481,6 +19501,11 @@ const startDevServer = async ({
|
|
|
19481
19501
|
kitchen.pluginController.callHooks("destroy", {});
|
|
19482
19502
|
};
|
|
19483
19503
|
});
|
|
19504
|
+
|
|
19505
|
+
if (reloadableWorker.isWorker) {
|
|
19506
|
+
parentPort.postMessage(server.origin);
|
|
19507
|
+
}
|
|
19508
|
+
|
|
19484
19509
|
return {
|
|
19485
19510
|
origin: server.origin,
|
|
19486
19511
|
stop: () => {
|
|
@@ -20189,7 +20214,9 @@ const run = async ({
|
|
|
20189
20214
|
const runOperation = Abort.startOperation();
|
|
20190
20215
|
runOperation.addAbortSignal(signal);
|
|
20191
20216
|
|
|
20192
|
-
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) {
|
|
20193
20220
|
const timeoutAbortSource = runOperation.timeout(allocatedMs);
|
|
20194
20221
|
resultTransformer = composeTransformer$1(resultTransformer, result => {
|
|
20195
20222
|
if (result.status === "errored" && Abort.isAbortError(result.error) && timeoutAbortSource.signal.aborted) {
|
|
@@ -21206,15 +21233,6 @@ const executeInParallel = async ({
|
|
|
21206
21233
|
return executionResults;
|
|
21207
21234
|
};
|
|
21208
21235
|
|
|
21209
|
-
const defaultCoverageConfig = {
|
|
21210
|
-
"./index.js": true,
|
|
21211
|
-
"./main.js": true,
|
|
21212
|
-
"./src/**/*.js": true,
|
|
21213
|
-
"./**/*.test.*": false,
|
|
21214
|
-
// contains .test. -> nope
|
|
21215
|
-
"./**/test/": false // inside a test folder -> nope,
|
|
21216
|
-
|
|
21217
|
-
};
|
|
21218
21236
|
/**
|
|
21219
21237
|
* Execute a list of files and log how it goes
|
|
21220
21238
|
* @param {Object} testPlanParameters
|
|
@@ -21258,7 +21276,15 @@ const executeTestPlan = async ({
|
|
|
21258
21276
|
gcBetweenExecutions = logMemoryHeapUsage,
|
|
21259
21277
|
coverage = process.argv.includes("--cover") || process.argv.includes("--coverage"),
|
|
21260
21278
|
coverageTempDirectoryRelativeUrl = "./.coverage/tmp/",
|
|
21261
|
-
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
|
+
},
|
|
21262
21288
|
coverageIncludeMissing = true,
|
|
21263
21289
|
coverageAndExecutionAllowed = false,
|
|
21264
21290
|
coverageForceIstanbul = false,
|
|
@@ -21499,7 +21525,7 @@ const createRuntimeFromPlaywright = ({
|
|
|
21499
21525
|
keepRunning,
|
|
21500
21526
|
onConsole,
|
|
21501
21527
|
executablePath,
|
|
21502
|
-
headful =
|
|
21528
|
+
headful = keepRunning,
|
|
21503
21529
|
ignoreHTTPSErrors = true
|
|
21504
21530
|
}) => {
|
|
21505
21531
|
const cleanupCallbackList = createCallbackListNotifiedOnce();
|
|
@@ -23513,17 +23539,18 @@ const build = async ({
|
|
|
23513
23539
|
buildDirectoryUrl,
|
|
23514
23540
|
entryPoints = {},
|
|
23515
23541
|
baseUrl = "/",
|
|
23516
|
-
// default runtimeCompat corresponds to
|
|
23517
|
-
//
|
|
23542
|
+
// default runtimeCompat corresponds to
|
|
23543
|
+
// "we can keep <script type="module"> intact":
|
|
23544
|
+
// so script_type_module + dynamic_import + import_meta
|
|
23518
23545
|
runtimeCompat = {
|
|
23519
23546
|
// android: "8",
|
|
23520
|
-
chrome: "
|
|
23547
|
+
chrome: "64",
|
|
23521
23548
|
edge: "79",
|
|
23522
23549
|
firefox: "67",
|
|
23523
|
-
ios: "
|
|
23524
|
-
opera: "
|
|
23550
|
+
ios: "12",
|
|
23551
|
+
opera: "51",
|
|
23525
23552
|
safari: "11.3",
|
|
23526
|
-
samsung: "
|
|
23553
|
+
samsung: "9.2"
|
|
23527
23554
|
},
|
|
23528
23555
|
plugins = [],
|
|
23529
23556
|
sourcemaps = false,
|
|
@@ -24738,17 +24765,13 @@ const startBuildServer = async ({
|
|
|
24738
24765
|
keepProcessAlive = true,
|
|
24739
24766
|
rootDirectoryUrl,
|
|
24740
24767
|
buildDirectoryUrl,
|
|
24741
|
-
|
|
24768
|
+
buildIndexPath = "/index.html",
|
|
24742
24769
|
buildServerFiles = {
|
|
24743
24770
|
"./package.json": true,
|
|
24744
24771
|
"./jsenv.config.mjs": true
|
|
24745
24772
|
},
|
|
24746
24773
|
buildServerMainFile = getCallerPosition().url,
|
|
24747
|
-
|
|
24748
|
-
// - inside a forked child process
|
|
24749
|
-
// - debugged by vscode
|
|
24750
|
-
// otherwise we get net:ERR_CONNECTION_REFUSED
|
|
24751
|
-
buildServerAutoreload = typeof process.send !== "function" && !process.env.VSCODE_INSPECTOR_OPTIONS,
|
|
24774
|
+
buildServerAutoreload = true,
|
|
24752
24775
|
cooldownBetweenFileEvents
|
|
24753
24776
|
}) => {
|
|
24754
24777
|
const logger = createLogger({
|
|
@@ -24756,6 +24779,23 @@ const startBuildServer = async ({
|
|
|
24756
24779
|
});
|
|
24757
24780
|
rootDirectoryUrl = assertAndNormalizeDirectoryUrl(rootDirectoryUrl);
|
|
24758
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
|
+
|
|
24759
24799
|
const operation = Abort.startOperation();
|
|
24760
24800
|
operation.addAbortSignal(signal);
|
|
24761
24801
|
|
|
@@ -24826,10 +24866,12 @@ const startBuildServer = async ({
|
|
|
24826
24866
|
reloadableWorker.terminate();
|
|
24827
24867
|
});
|
|
24828
24868
|
const worker = await reloadableWorker.load();
|
|
24829
|
-
|
|
24830
|
-
|
|
24831
|
-
|
|
24832
|
-
|
|
24869
|
+
const messagePromise = new Promise(resolve => {
|
|
24870
|
+
worker.once("message", resolve);
|
|
24871
|
+
});
|
|
24872
|
+
await messagePromise; // if (!keepProcessAlive) {
|
|
24873
|
+
// worker.unref()
|
|
24874
|
+
// }
|
|
24833
24875
|
|
|
24834
24876
|
return {
|
|
24835
24877
|
origin: `${protocol}://127.0.0.1:${port}`,
|
|
@@ -24848,7 +24890,8 @@ const startBuildServer = async ({
|
|
|
24848
24890
|
stopOnExit: false,
|
|
24849
24891
|
stopOnSIGINT: false,
|
|
24850
24892
|
stopOnInternalError: false,
|
|
24851
|
-
|
|
24893
|
+
// the worker should be kept alive by the parent otherwise
|
|
24894
|
+
keepProcessAlive,
|
|
24852
24895
|
logLevel: serverLogLevel,
|
|
24853
24896
|
startLog: false,
|
|
24854
24897
|
protocol,
|
|
@@ -24874,7 +24917,7 @@ const startBuildServer = async ({
|
|
|
24874
24917
|
requestToResponse: composeServices({ ...services,
|
|
24875
24918
|
build_files_service: createBuildFilesService({
|
|
24876
24919
|
buildDirectoryUrl,
|
|
24877
|
-
|
|
24920
|
+
buildIndexPath
|
|
24878
24921
|
})
|
|
24879
24922
|
})
|
|
24880
24923
|
});
|
|
@@ -24884,6 +24927,11 @@ const startBuildServer = async ({
|
|
|
24884
24927
|
logger.info(`- ${server.origins[key]}`);
|
|
24885
24928
|
});
|
|
24886
24929
|
logger.info(``);
|
|
24930
|
+
|
|
24931
|
+
if (reloadableWorker.isWorker) {
|
|
24932
|
+
parentPort.postMessage(server.origin);
|
|
24933
|
+
}
|
|
24934
|
+
|
|
24887
24935
|
return {
|
|
24888
24936
|
origin: server.origin,
|
|
24889
24937
|
stop: () => {
|
|
@@ -24894,14 +24942,14 @@ const startBuildServer = async ({
|
|
|
24894
24942
|
|
|
24895
24943
|
const createBuildFilesService = ({
|
|
24896
24944
|
buildDirectoryUrl,
|
|
24897
|
-
|
|
24945
|
+
buildIndexPath
|
|
24898
24946
|
}) => {
|
|
24899
24947
|
return request => {
|
|
24900
24948
|
const urlIsVersioned = new URL(request.ressource, request.origin).searchParams.has("v");
|
|
24901
24949
|
|
|
24902
|
-
if (
|
|
24950
|
+
if (buildIndexPath && request.ressource === "/") {
|
|
24903
24951
|
request = { ...request,
|
|
24904
|
-
ressource:
|
|
24952
|
+
ressource: `/${buildIndexPath}`
|
|
24905
24953
|
};
|
|
24906
24954
|
}
|
|
24907
24955
|
|
|
@@ -25142,4 +25190,4 @@ const jsenvPluginInjectGlobals = urlAssociations => {
|
|
|
25142
25190
|
};
|
|
25143
25191
|
};
|
|
25144
25192
|
|
|
25145
|
-
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": {
|
|
@@ -67,17 +67,17 @@
|
|
|
67
67
|
"@financial-times/polyfill-useragent-normaliser": "2.0.1",
|
|
68
68
|
"@jsenv/ast": "1.1.1",
|
|
69
69
|
"@jsenv/abort": "4.2.3",
|
|
70
|
-
"@jsenv/filesystem": "4.0
|
|
70
|
+
"@jsenv/filesystem": "4.1.0",
|
|
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",
|
|
@@ -87,27 +87,27 @@
|
|
|
87
87
|
"istanbul-lib-report": "3.0.0",
|
|
88
88
|
"istanbul-reports": "3.1.4",
|
|
89
89
|
"pidtree": "0.6.0",
|
|
90
|
-
"rollup": "2.75.
|
|
90
|
+
"rollup": "2.75.7",
|
|
91
91
|
"string-width": "5.1.2",
|
|
92
92
|
"strip-ansi": "7.0.1",
|
|
93
93
|
"terser": "5.14.1",
|
|
94
|
-
"v8-to-istanbul": "9.0.
|
|
94
|
+
"v8-to-istanbul": "9.0.1",
|
|
95
95
|
"wrap-ansi": "8.0.1"
|
|
96
96
|
},
|
|
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": "
|
|
106
|
-
"eslint": "8.
|
|
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
|
+
"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
|
}
|
|
113
|
-
}
|
|
113
|
+
}
|
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,
|