@jsenv/core 27.0.0-alpha.91 → 27.0.0-alpha.94
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 +114 -63
- package/package.json +10 -10
- package/src/build/build.js +7 -6
- package/src/build/start_build_server.js +36 -15
- package/src/dev/start_dev_server.js +18 -12
- 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}`,
|
|
@@ -19396,7 +19416,9 @@ const startDevServer = async ({
|
|
|
19396
19416
|
};
|
|
19397
19417
|
|
|
19398
19418
|
const stopWatchingClientFiles = registerDirectoryLifecycle(rootDirectoryUrl, {
|
|
19399
|
-
watchPatterns: clientFiles,
|
|
19419
|
+
watchPatterns: { ...clientFiles,
|
|
19420
|
+
".jsenv/": false
|
|
19421
|
+
},
|
|
19400
19422
|
cooldownBetweenFileEvents,
|
|
19401
19423
|
keepProcessAlive: false,
|
|
19402
19424
|
recursive: true,
|
|
@@ -19481,6 +19503,11 @@ const startDevServer = async ({
|
|
|
19481
19503
|
kitchen.pluginController.callHooks("destroy", {});
|
|
19482
19504
|
};
|
|
19483
19505
|
});
|
|
19506
|
+
|
|
19507
|
+
if (reloadableWorker.isWorker) {
|
|
19508
|
+
parentPort.postMessage(server.origin);
|
|
19509
|
+
}
|
|
19510
|
+
|
|
19484
19511
|
return {
|
|
19485
19512
|
origin: server.origin,
|
|
19486
19513
|
stop: () => {
|
|
@@ -20189,7 +20216,9 @@ const run = async ({
|
|
|
20189
20216
|
const runOperation = Abort.startOperation();
|
|
20190
20217
|
runOperation.addAbortSignal(signal);
|
|
20191
20218
|
|
|
20192
|
-
if (
|
|
20219
|
+
if ( // ideally we would rather log than the timeout is ignored
|
|
20220
|
+
// when keepRunning is true
|
|
20221
|
+
!keepRunning && typeof allocatedMs === "number" && allocatedMs !== Infinity) {
|
|
20193
20222
|
const timeoutAbortSource = runOperation.timeout(allocatedMs);
|
|
20194
20223
|
resultTransformer = composeTransformer$1(resultTransformer, result => {
|
|
20195
20224
|
if (result.status === "errored" && Abort.isAbortError(result.error) && timeoutAbortSource.signal.aborted) {
|
|
@@ -21206,15 +21235,6 @@ const executeInParallel = async ({
|
|
|
21206
21235
|
return executionResults;
|
|
21207
21236
|
};
|
|
21208
21237
|
|
|
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
21238
|
/**
|
|
21219
21239
|
* Execute a list of files and log how it goes
|
|
21220
21240
|
* @param {Object} testPlanParameters
|
|
@@ -21258,7 +21278,15 @@ const executeTestPlan = async ({
|
|
|
21258
21278
|
gcBetweenExecutions = logMemoryHeapUsage,
|
|
21259
21279
|
coverage = process.argv.includes("--cover") || process.argv.includes("--coverage"),
|
|
21260
21280
|
coverageTempDirectoryRelativeUrl = "./.coverage/tmp/",
|
|
21261
|
-
coverageConfig =
|
|
21281
|
+
coverageConfig = {
|
|
21282
|
+
"./src/**/*.js": true,
|
|
21283
|
+
"./**/*.test.*": false,
|
|
21284
|
+
// contains .test. -> no
|
|
21285
|
+
"./**/test/": false,
|
|
21286
|
+
// inside a test directory -> no
|
|
21287
|
+
"./**/tests/": false // inside a tests directory -> no
|
|
21288
|
+
|
|
21289
|
+
},
|
|
21262
21290
|
coverageIncludeMissing = true,
|
|
21263
21291
|
coverageAndExecutionAllowed = false,
|
|
21264
21292
|
coverageForceIstanbul = false,
|
|
@@ -21499,7 +21527,7 @@ const createRuntimeFromPlaywright = ({
|
|
|
21499
21527
|
keepRunning,
|
|
21500
21528
|
onConsole,
|
|
21501
21529
|
executablePath,
|
|
21502
|
-
headful =
|
|
21530
|
+
headful = keepRunning,
|
|
21503
21531
|
ignoreHTTPSErrors = true
|
|
21504
21532
|
}) => {
|
|
21505
21533
|
const cleanupCallbackList = createCallbackListNotifiedOnce();
|
|
@@ -23513,17 +23541,18 @@ const build = async ({
|
|
|
23513
23541
|
buildDirectoryUrl,
|
|
23514
23542
|
entryPoints = {},
|
|
23515
23543
|
baseUrl = "/",
|
|
23516
|
-
// default runtimeCompat corresponds to
|
|
23517
|
-
//
|
|
23544
|
+
// default runtimeCompat corresponds to
|
|
23545
|
+
// "we can keep <script type="module"> intact":
|
|
23546
|
+
// so script_type_module + dynamic_import + import_meta
|
|
23518
23547
|
runtimeCompat = {
|
|
23519
23548
|
// android: "8",
|
|
23520
|
-
chrome: "
|
|
23549
|
+
chrome: "64",
|
|
23521
23550
|
edge: "79",
|
|
23522
23551
|
firefox: "67",
|
|
23523
|
-
ios: "
|
|
23524
|
-
opera: "
|
|
23552
|
+
ios: "12",
|
|
23553
|
+
opera: "51",
|
|
23525
23554
|
safari: "11.3",
|
|
23526
|
-
samsung: "
|
|
23555
|
+
samsung: "9.2"
|
|
23527
23556
|
},
|
|
23528
23557
|
plugins = [],
|
|
23529
23558
|
sourcemaps = false,
|
|
@@ -24738,17 +24767,13 @@ const startBuildServer = async ({
|
|
|
24738
24767
|
keepProcessAlive = true,
|
|
24739
24768
|
rootDirectoryUrl,
|
|
24740
24769
|
buildDirectoryUrl,
|
|
24741
|
-
|
|
24770
|
+
buildIndexPath = "/index.html",
|
|
24742
24771
|
buildServerFiles = {
|
|
24743
24772
|
"./package.json": true,
|
|
24744
24773
|
"./jsenv.config.mjs": true
|
|
24745
24774
|
},
|
|
24746
24775
|
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,
|
|
24776
|
+
buildServerAutoreload = true,
|
|
24752
24777
|
cooldownBetweenFileEvents
|
|
24753
24778
|
}) => {
|
|
24754
24779
|
const logger = createLogger({
|
|
@@ -24756,6 +24781,23 @@ const startBuildServer = async ({
|
|
|
24756
24781
|
});
|
|
24757
24782
|
rootDirectoryUrl = assertAndNormalizeDirectoryUrl(rootDirectoryUrl);
|
|
24758
24783
|
buildDirectoryUrl = assertAndNormalizeDirectoryUrl(buildDirectoryUrl);
|
|
24784
|
+
|
|
24785
|
+
if (buildIndexPath) {
|
|
24786
|
+
if (typeof buildIndexPath !== "string") {
|
|
24787
|
+
throw new TypeError(`buildIndexPath must be a string, got ${buildIndexPath}`);
|
|
24788
|
+
}
|
|
24789
|
+
|
|
24790
|
+
if (buildIndexPath[0] !== "/") {
|
|
24791
|
+
const buildIndexUrl = new URL(buildIndexPath, buildDirectoryUrl).href;
|
|
24792
|
+
|
|
24793
|
+
if (!buildIndexUrl.startsWith(buildDirectoryUrl)) {
|
|
24794
|
+
throw new Error(`buildIndexPath must be relative, got ${buildIndexPath}`);
|
|
24795
|
+
}
|
|
24796
|
+
|
|
24797
|
+
buildIndexPath = buildIndexUrl.slice(buildDirectoryUrl.length);
|
|
24798
|
+
}
|
|
24799
|
+
}
|
|
24800
|
+
|
|
24759
24801
|
const operation = Abort.startOperation();
|
|
24760
24802
|
operation.addAbortSignal(signal);
|
|
24761
24803
|
|
|
@@ -24791,7 +24833,8 @@ const startBuildServer = async ({
|
|
|
24791
24833
|
const stopWatchingBuildServerFiles = registerDirectoryLifecycle(rootDirectoryUrl, {
|
|
24792
24834
|
watchPatterns: {
|
|
24793
24835
|
[buildServerMainFile]: true,
|
|
24794
|
-
...buildServerFiles
|
|
24836
|
+
...buildServerFiles,
|
|
24837
|
+
".jsenv/": false
|
|
24795
24838
|
},
|
|
24796
24839
|
cooldownBetweenFileEvents,
|
|
24797
24840
|
keepProcessAlive: false,
|
|
@@ -24826,10 +24869,12 @@ const startBuildServer = async ({
|
|
|
24826
24869
|
reloadableWorker.terminate();
|
|
24827
24870
|
});
|
|
24828
24871
|
const worker = await reloadableWorker.load();
|
|
24829
|
-
|
|
24830
|
-
|
|
24831
|
-
|
|
24832
|
-
|
|
24872
|
+
const messagePromise = new Promise(resolve => {
|
|
24873
|
+
worker.once("message", resolve);
|
|
24874
|
+
});
|
|
24875
|
+
await messagePromise; // if (!keepProcessAlive) {
|
|
24876
|
+
// worker.unref()
|
|
24877
|
+
// }
|
|
24833
24878
|
|
|
24834
24879
|
return {
|
|
24835
24880
|
origin: `${protocol}://127.0.0.1:${port}`,
|
|
@@ -24848,7 +24893,8 @@ const startBuildServer = async ({
|
|
|
24848
24893
|
stopOnExit: false,
|
|
24849
24894
|
stopOnSIGINT: false,
|
|
24850
24895
|
stopOnInternalError: false,
|
|
24851
|
-
|
|
24896
|
+
// the worker should be kept alive by the parent otherwise
|
|
24897
|
+
keepProcessAlive,
|
|
24852
24898
|
logLevel: serverLogLevel,
|
|
24853
24899
|
startLog: false,
|
|
24854
24900
|
protocol,
|
|
@@ -24874,7 +24920,7 @@ const startBuildServer = async ({
|
|
|
24874
24920
|
requestToResponse: composeServices({ ...services,
|
|
24875
24921
|
build_files_service: createBuildFilesService({
|
|
24876
24922
|
buildDirectoryUrl,
|
|
24877
|
-
|
|
24923
|
+
buildIndexPath
|
|
24878
24924
|
})
|
|
24879
24925
|
})
|
|
24880
24926
|
});
|
|
@@ -24884,6 +24930,11 @@ const startBuildServer = async ({
|
|
|
24884
24930
|
logger.info(`- ${server.origins[key]}`);
|
|
24885
24931
|
});
|
|
24886
24932
|
logger.info(``);
|
|
24933
|
+
|
|
24934
|
+
if (reloadableWorker.isWorker) {
|
|
24935
|
+
parentPort.postMessage(server.origin);
|
|
24936
|
+
}
|
|
24937
|
+
|
|
24887
24938
|
return {
|
|
24888
24939
|
origin: server.origin,
|
|
24889
24940
|
stop: () => {
|
|
@@ -24894,14 +24945,14 @@ const startBuildServer = async ({
|
|
|
24894
24945
|
|
|
24895
24946
|
const createBuildFilesService = ({
|
|
24896
24947
|
buildDirectoryUrl,
|
|
24897
|
-
|
|
24948
|
+
buildIndexPath
|
|
24898
24949
|
}) => {
|
|
24899
24950
|
return request => {
|
|
24900
24951
|
const urlIsVersioned = new URL(request.ressource, request.origin).searchParams.has("v");
|
|
24901
24952
|
|
|
24902
|
-
if (
|
|
24953
|
+
if (buildIndexPath && request.ressource === "/") {
|
|
24903
24954
|
request = { ...request,
|
|
24904
|
-
ressource:
|
|
24955
|
+
ressource: `/${buildIndexPath}`
|
|
24905
24956
|
};
|
|
24906
24957
|
}
|
|
24907
24958
|
|
|
@@ -25142,4 +25193,4 @@ const jsenvPluginInjectGlobals = urlAssociations => {
|
|
|
25142
25193
|
};
|
|
25143
25194
|
};
|
|
25144
25195
|
|
|
25145
|
-
export { build, chromium, chromiumIsolatedTab,
|
|
25196
|
+
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.94",
|
|
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",
|
|
@@ -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)
|
|
@@ -99,6 +111,7 @@ export const startBuildServer = async ({
|
|
|
99
111
|
watchPatterns: {
|
|
100
112
|
[buildServerMainFile]: true,
|
|
101
113
|
...buildServerFiles,
|
|
114
|
+
".jsenv/": false,
|
|
102
115
|
},
|
|
103
116
|
cooldownBetweenFileEvents,
|
|
104
117
|
keepProcessAlive: false,
|
|
@@ -119,9 +132,13 @@ export const startBuildServer = async ({
|
|
|
119
132
|
reloadableWorker.terminate()
|
|
120
133
|
})
|
|
121
134
|
const worker = await reloadableWorker.load()
|
|
122
|
-
|
|
123
|
-
worker.
|
|
124
|
-
}
|
|
135
|
+
const messagePromise = new Promise((resolve) => {
|
|
136
|
+
worker.once("message", resolve)
|
|
137
|
+
})
|
|
138
|
+
await messagePromise
|
|
139
|
+
// if (!keepProcessAlive) {
|
|
140
|
+
// worker.unref()
|
|
141
|
+
// }
|
|
125
142
|
return {
|
|
126
143
|
origin: `${protocol}://127.0.0.1:${port}`,
|
|
127
144
|
stop: () => {
|
|
@@ -139,7 +156,8 @@ export const startBuildServer = async ({
|
|
|
139
156
|
stopOnExit: false,
|
|
140
157
|
stopOnSIGINT: false,
|
|
141
158
|
stopOnInternalError: false,
|
|
142
|
-
|
|
159
|
+
// the worker should be kept alive by the parent otherwise
|
|
160
|
+
keepProcessAlive,
|
|
143
161
|
logLevel: serverLogLevel,
|
|
144
162
|
startLog: false,
|
|
145
163
|
|
|
@@ -168,7 +186,7 @@ export const startBuildServer = async ({
|
|
|
168
186
|
...services,
|
|
169
187
|
build_files_service: createBuildFilesService({
|
|
170
188
|
buildDirectoryUrl,
|
|
171
|
-
|
|
189
|
+
buildIndexPath,
|
|
172
190
|
}),
|
|
173
191
|
}),
|
|
174
192
|
})
|
|
@@ -178,6 +196,9 @@ export const startBuildServer = async ({
|
|
|
178
196
|
logger.info(`- ${server.origins[key]}`)
|
|
179
197
|
})
|
|
180
198
|
logger.info(``)
|
|
199
|
+
if (reloadableWorker.isWorker) {
|
|
200
|
+
parentPort.postMessage(server.origin)
|
|
201
|
+
}
|
|
181
202
|
return {
|
|
182
203
|
origin: server.origin,
|
|
183
204
|
stop: () => {
|
|
@@ -186,16 +207,16 @@ export const startBuildServer = async ({
|
|
|
186
207
|
}
|
|
187
208
|
}
|
|
188
209
|
|
|
189
|
-
const createBuildFilesService = ({ buildDirectoryUrl,
|
|
210
|
+
const createBuildFilesService = ({ buildDirectoryUrl, buildIndexPath }) => {
|
|
190
211
|
return (request) => {
|
|
191
212
|
const urlIsVersioned = new URL(
|
|
192
213
|
request.ressource,
|
|
193
214
|
request.origin,
|
|
194
215
|
).searchParams.has("v")
|
|
195
|
-
if (
|
|
216
|
+
if (buildIndexPath && request.ressource === "/") {
|
|
196
217
|
request = {
|
|
197
218
|
...request,
|
|
198
|
-
ressource:
|
|
219
|
+
ressource: `/${buildIndexPath}`,
|
|
199
220
|
}
|
|
200
221
|
}
|
|
201
222
|
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: () => {
|
|
@@ -155,7 +155,10 @@ export const startDevServer = async ({
|
|
|
155
155
|
})
|
|
156
156
|
}
|
|
157
157
|
const stopWatchingClientFiles = registerDirectoryLifecycle(rootDirectoryUrl, {
|
|
158
|
-
watchPatterns:
|
|
158
|
+
watchPatterns: {
|
|
159
|
+
...clientFiles,
|
|
160
|
+
".jsenv/": false,
|
|
161
|
+
},
|
|
159
162
|
cooldownBetweenFileEvents,
|
|
160
163
|
keepProcessAlive: false,
|
|
161
164
|
recursive: true,
|
|
@@ -230,6 +233,9 @@ export const startDevServer = async ({
|
|
|
230
233
|
kitchen.pluginController.callHooks("destroy", {})
|
|
231
234
|
}
|
|
232
235
|
})
|
|
236
|
+
if (reloadableWorker.isWorker) {
|
|
237
|
+
parentPort.postMessage(server.origin)
|
|
238
|
+
}
|
|
233
239
|
return {
|
|
234
240
|
origin: server.origin,
|
|
235
241
|
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,
|