@jsenv/core 41.3.0 → 41.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/build/build.js +258 -0
- package/dist/js/dependency_status.js +61 -0
- package/dist/start_dev_server/jsenv_core_packages.js +262 -10
- package/dist/start_dev_server/start_dev_server.js +467 -23
- package/package.json +6 -6
- package/src/dev/dev_server_plugins/dev_server_plugin_serve_source_files.js +42 -21
- package/src/dev/start_dev_server.js +28 -0
- package/src/helpers/watch_dependencies.js +110 -0
- package/src/kitchen/errors.js +43 -0
- package/src/kitchen/package_dependencies.js +160 -0
- package/src/plugins/autoreload/jsenv_plugin_autoreload.js +2 -0
- package/src/plugins/autoreload/jsenv_plugin_autoreload_server.js +10 -0
- package/src/plugins/dependency_status/client/dependency_status.js +59 -0
- package/src/plugins/dependency_status/jsenv_plugin_dependency_status.js +64 -0
- package/src/plugins/plugins.js +5 -0
- package/src/plugins/workspace_bundle/jsenv_plugin_workspace_bundle.js +10 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createSupportsColor, isUnicodeSupported, eastAsianWidth, clearTerminal, eraseLines } from "./jsenv_core_node_modules.js";
|
|
2
2
|
import { stripVTControlCharacters } from "node:util";
|
|
3
3
|
import { readFileSync, existsSync, chmodSync, statSync, lstatSync, readdirSync, openSync, closeSync, unlinkSync, rmdirSync, mkdirSync, writeFileSync as writeFileSync$1, watch, realpathSync } from "node:fs";
|
|
4
|
-
import { extname } from "node:path";
|
|
4
|
+
import { extname, basename, dirname } from "node:path";
|
|
5
5
|
import crypto, { createHash } from "node:crypto";
|
|
6
6
|
import { pathToFileURL, fileURLToPath } from "node:url";
|
|
7
7
|
|
|
@@ -3382,6 +3382,21 @@ const writeFileSync = (destination, content = "", { force } = {}) => {
|
|
|
3382
3382
|
}
|
|
3383
3383
|
};
|
|
3384
3384
|
|
|
3385
|
+
const callOnceIdle = (callback, idleMs) => {
|
|
3386
|
+
let timeoutId;
|
|
3387
|
+
return (...args) => {
|
|
3388
|
+
if (timeoutId) {
|
|
3389
|
+
clearTimeout(timeoutId);
|
|
3390
|
+
}
|
|
3391
|
+
timeoutId = setTimeout(() => {
|
|
3392
|
+
callback(...args);
|
|
3393
|
+
}, idleMs);
|
|
3394
|
+
if (timeoutId.unref) {
|
|
3395
|
+
timeoutId.unref();
|
|
3396
|
+
}
|
|
3397
|
+
};
|
|
3398
|
+
};
|
|
3399
|
+
|
|
3385
3400
|
const callOnceIdlePerFile = (callback, idleMs) => {
|
|
3386
3401
|
const timeoutIdMap = new Map();
|
|
3387
3402
|
return (fileEvent) => {
|
|
@@ -3433,6 +3448,25 @@ const createWatcher = (sourcePath, options) => {
|
|
|
3433
3448
|
return watcher;
|
|
3434
3449
|
};
|
|
3435
3450
|
|
|
3451
|
+
const guardTooFastSecondCall = (
|
|
3452
|
+
callback,
|
|
3453
|
+
cooldownBetweenFileEvents = 40,
|
|
3454
|
+
) => {
|
|
3455
|
+
let previousCallMs;
|
|
3456
|
+
return (...args) => {
|
|
3457
|
+
const nowMs = Date.now();
|
|
3458
|
+
if (previousCallMs) {
|
|
3459
|
+
const msEllapsed = nowMs - previousCallMs;
|
|
3460
|
+
if (msEllapsed < cooldownBetweenFileEvents) {
|
|
3461
|
+
previousCallMs = null;
|
|
3462
|
+
return;
|
|
3463
|
+
}
|
|
3464
|
+
}
|
|
3465
|
+
previousCallMs = nowMs;
|
|
3466
|
+
callback(...args);
|
|
3467
|
+
};
|
|
3468
|
+
};
|
|
3469
|
+
|
|
3436
3470
|
const guardTooFastSecondCallPerFile = (
|
|
3437
3471
|
callback,
|
|
3438
3472
|
cooldownBetweenFileEvents = 40,
|
|
@@ -3476,8 +3510,8 @@ callback: ${callback}`);
|
|
|
3476
3510
|
return { registerCleanupCallback, cleanup };
|
|
3477
3511
|
};
|
|
3478
3512
|
|
|
3479
|
-
const isLinux = process.platform === "linux";
|
|
3480
|
-
const fsWatchSupportsRecursive = !isLinux;
|
|
3513
|
+
const isLinux$1 = process.platform === "linux";
|
|
3514
|
+
const fsWatchSupportsRecursive = !isLinux$1;
|
|
3481
3515
|
|
|
3482
3516
|
const registerDirectoryLifecycle = (
|
|
3483
3517
|
source,
|
|
@@ -3502,15 +3536,15 @@ const registerDirectoryLifecycle = (
|
|
|
3502
3536
|
},
|
|
3503
3537
|
) => {
|
|
3504
3538
|
const sourceUrl = assertAndNormalizeDirectoryUrl(source);
|
|
3505
|
-
if (!undefinedOrFunction(added)) {
|
|
3539
|
+
if (!undefinedOrFunction$1(added)) {
|
|
3506
3540
|
throw new TypeError(`added must be a function or undefined, got ${added}`);
|
|
3507
3541
|
}
|
|
3508
|
-
if (!undefinedOrFunction(updated)) {
|
|
3542
|
+
if (!undefinedOrFunction$1(updated)) {
|
|
3509
3543
|
throw new TypeError(
|
|
3510
3544
|
`updated must be a function or undefined, got ${updated}`,
|
|
3511
3545
|
);
|
|
3512
3546
|
}
|
|
3513
|
-
if (!undefinedOrFunction(removed)) {
|
|
3547
|
+
if (!undefinedOrFunction$1(removed)) {
|
|
3514
3548
|
throw new TypeError(
|
|
3515
3549
|
`removed must be a function or undefined, got ${removed}`,
|
|
3516
3550
|
);
|
|
@@ -3805,7 +3839,7 @@ const registerDirectoryLifecycle = (
|
|
|
3805
3839
|
}
|
|
3806
3840
|
};
|
|
3807
3841
|
const handleEntryUpdated = (entryInfo) => {
|
|
3808
|
-
if (updated && entryInfo.patternValue && shouldCallUpdated(entryInfo)) {
|
|
3842
|
+
if (updated && entryInfo.patternValue && shouldCallUpdated$1(entryInfo)) {
|
|
3809
3843
|
infoMap.set(entryInfo.relativeUrl, entryInfo);
|
|
3810
3844
|
updated({
|
|
3811
3845
|
relativeUrl: entryInfo.relativeUrl,
|
|
@@ -3848,7 +3882,7 @@ ${relativeUrls.join("\n")}`,
|
|
|
3848
3882
|
return tracker.cleanup;
|
|
3849
3883
|
};
|
|
3850
3884
|
|
|
3851
|
-
const shouldCallUpdated = (entryInfo) => {
|
|
3885
|
+
const shouldCallUpdated$1 = (entryInfo) => {
|
|
3852
3886
|
const { stat, previousInfo } = entryInfo;
|
|
3853
3887
|
if (!stat.atimeMs) {
|
|
3854
3888
|
return true;
|
|
@@ -3862,7 +3896,7 @@ const shouldCallUpdated = (entryInfo) => {
|
|
|
3862
3896
|
return true;
|
|
3863
3897
|
};
|
|
3864
3898
|
|
|
3865
|
-
const undefinedOrFunction = (value) => {
|
|
3899
|
+
const undefinedOrFunction$1 = (value) => {
|
|
3866
3900
|
return typeof value === "undefined" || typeof value === "function";
|
|
3867
3901
|
};
|
|
3868
3902
|
|
|
@@ -3891,6 +3925,224 @@ const fileSystemPathToDirectoryRelativeUrlAndFilename = (path) => {
|
|
|
3891
3925
|
};
|
|
3892
3926
|
};
|
|
3893
3927
|
|
|
3928
|
+
const isMacos = process.platform === "darwin";
|
|
3929
|
+
const isLinux = process.platform === "linux";
|
|
3930
|
+
const isFreeBSD = process.platform === "freebsd";
|
|
3931
|
+
|
|
3932
|
+
const registerFileLifecycle = (
|
|
3933
|
+
source,
|
|
3934
|
+
{
|
|
3935
|
+
added,
|
|
3936
|
+
updated,
|
|
3937
|
+
removed,
|
|
3938
|
+
notifyExistent = false,
|
|
3939
|
+
keepProcessAlive = true,
|
|
3940
|
+
cooldownBetweenFileEvents = 0,
|
|
3941
|
+
idleMs = 50,
|
|
3942
|
+
},
|
|
3943
|
+
) => {
|
|
3944
|
+
const sourceUrl = assertAndNormalizeFileUrl(source);
|
|
3945
|
+
if (!undefinedOrFunction(added)) {
|
|
3946
|
+
throw new TypeError(`added must be a function or undefined, got ${added}`);
|
|
3947
|
+
}
|
|
3948
|
+
if (!undefinedOrFunction(updated)) {
|
|
3949
|
+
throw new TypeError(
|
|
3950
|
+
`updated must be a function or undefined, got ${updated}`,
|
|
3951
|
+
);
|
|
3952
|
+
}
|
|
3953
|
+
if (!undefinedOrFunction(removed)) {
|
|
3954
|
+
throw new TypeError(
|
|
3955
|
+
`removed must be a function or undefined, got ${removed}`,
|
|
3956
|
+
);
|
|
3957
|
+
}
|
|
3958
|
+
if (idleMs) {
|
|
3959
|
+
if (updated) {
|
|
3960
|
+
updated = callOnceIdle(updated, idleMs);
|
|
3961
|
+
}
|
|
3962
|
+
}
|
|
3963
|
+
if (cooldownBetweenFileEvents) {
|
|
3964
|
+
if (added) {
|
|
3965
|
+
added = guardTooFastSecondCall(added, cooldownBetweenFileEvents);
|
|
3966
|
+
}
|
|
3967
|
+
if (updated) {
|
|
3968
|
+
updated = guardTooFastSecondCall(updated, cooldownBetweenFileEvents);
|
|
3969
|
+
}
|
|
3970
|
+
if (removed) {
|
|
3971
|
+
removed = guardTooFastSecondCall(removed, cooldownBetweenFileEvents);
|
|
3972
|
+
}
|
|
3973
|
+
}
|
|
3974
|
+
|
|
3975
|
+
const tracker = trackResources();
|
|
3976
|
+
|
|
3977
|
+
const handleFileFound = ({ stat, existent }) => {
|
|
3978
|
+
const fileMutationStopWatching = watchFileMutation(sourceUrl, {
|
|
3979
|
+
updated,
|
|
3980
|
+
removed: () => {
|
|
3981
|
+
fileMutationStopTracking();
|
|
3982
|
+
watchFileAdded();
|
|
3983
|
+
if (removed) {
|
|
3984
|
+
removed();
|
|
3985
|
+
}
|
|
3986
|
+
},
|
|
3987
|
+
keepProcessAlive,
|
|
3988
|
+
stat,
|
|
3989
|
+
});
|
|
3990
|
+
const fileMutationStopTracking = tracker.registerCleanupCallback(
|
|
3991
|
+
fileMutationStopWatching,
|
|
3992
|
+
);
|
|
3993
|
+
|
|
3994
|
+
if (added) {
|
|
3995
|
+
if (existent) {
|
|
3996
|
+
if (notifyExistent) {
|
|
3997
|
+
added({ existent: true });
|
|
3998
|
+
}
|
|
3999
|
+
} else {
|
|
4000
|
+
added({});
|
|
4001
|
+
}
|
|
4002
|
+
}
|
|
4003
|
+
};
|
|
4004
|
+
|
|
4005
|
+
const watchFileAdded = () => {
|
|
4006
|
+
const fileCreationStopWatching = watchFileCreation(
|
|
4007
|
+
sourceUrl,
|
|
4008
|
+
(stat) => {
|
|
4009
|
+
fileCreationgStopTracking();
|
|
4010
|
+
handleFileFound({ stat, existent: false });
|
|
4011
|
+
},
|
|
4012
|
+
keepProcessAlive,
|
|
4013
|
+
);
|
|
4014
|
+
const fileCreationgStopTracking = tracker.registerCleanupCallback(
|
|
4015
|
+
fileCreationStopWatching,
|
|
4016
|
+
);
|
|
4017
|
+
};
|
|
4018
|
+
|
|
4019
|
+
const { type, stat } = readFileInfo(sourceUrl);
|
|
4020
|
+
if (type === null) {
|
|
4021
|
+
if (added) {
|
|
4022
|
+
watchFileAdded();
|
|
4023
|
+
} else {
|
|
4024
|
+
throw new Error(
|
|
4025
|
+
`${urlToFileSystemPath(sourceUrl)} must lead to a file, found nothing`,
|
|
4026
|
+
);
|
|
4027
|
+
}
|
|
4028
|
+
} else if (type === "file") {
|
|
4029
|
+
handleFileFound({ stat, existent: true });
|
|
4030
|
+
} else {
|
|
4031
|
+
throw new Error(
|
|
4032
|
+
`${urlToFileSystemPath(
|
|
4033
|
+
sourceUrl,
|
|
4034
|
+
)} must lead to a file, type found instead`,
|
|
4035
|
+
);
|
|
4036
|
+
}
|
|
4037
|
+
|
|
4038
|
+
return tracker.cleanup;
|
|
4039
|
+
};
|
|
4040
|
+
|
|
4041
|
+
const readFileInfo = (url) => {
|
|
4042
|
+
try {
|
|
4043
|
+
const stat = readEntryStatSync(new URL(url));
|
|
4044
|
+
return {
|
|
4045
|
+
type: statsToType(stat),
|
|
4046
|
+
stat,
|
|
4047
|
+
};
|
|
4048
|
+
} catch (e) {
|
|
4049
|
+
if (e.code === "ENOENT") {
|
|
4050
|
+
return {
|
|
4051
|
+
type: null,
|
|
4052
|
+
stat: null,
|
|
4053
|
+
};
|
|
4054
|
+
}
|
|
4055
|
+
throw e;
|
|
4056
|
+
}
|
|
4057
|
+
};
|
|
4058
|
+
|
|
4059
|
+
const undefinedOrFunction = (value) =>
|
|
4060
|
+
typeof value === "undefined" || typeof value === "function";
|
|
4061
|
+
|
|
4062
|
+
const watchFileCreation = (source, callback, keepProcessAlive) => {
|
|
4063
|
+
const sourcePath = urlToFileSystemPath(source);
|
|
4064
|
+
const sourceFilename = basename(sourcePath);
|
|
4065
|
+
const directoryPath = dirname(sourcePath);
|
|
4066
|
+
let directoryWatcher = createWatcher(directoryPath, {
|
|
4067
|
+
persistent: keepProcessAlive,
|
|
4068
|
+
});
|
|
4069
|
+
directoryWatcher.on("change", (eventType, filename) => {
|
|
4070
|
+
if (filename && filename !== sourceFilename) return;
|
|
4071
|
+
|
|
4072
|
+
const { type, stat } = readFileInfo(source);
|
|
4073
|
+
// ignore if something else with that name gets created
|
|
4074
|
+
// we are only interested into files
|
|
4075
|
+
if (type !== "file") {
|
|
4076
|
+
return;
|
|
4077
|
+
}
|
|
4078
|
+
directoryWatcher.close();
|
|
4079
|
+
directoryWatcher = undefined;
|
|
4080
|
+
callback(stat);
|
|
4081
|
+
});
|
|
4082
|
+
|
|
4083
|
+
return () => {
|
|
4084
|
+
if (directoryWatcher) {
|
|
4085
|
+
directoryWatcher.close();
|
|
4086
|
+
}
|
|
4087
|
+
};
|
|
4088
|
+
};
|
|
4089
|
+
|
|
4090
|
+
const watchFileMutation = (
|
|
4091
|
+
sourceUrl,
|
|
4092
|
+
{ updated, removed, keepProcessAlive, stat },
|
|
4093
|
+
) => {
|
|
4094
|
+
let prevStat = stat;
|
|
4095
|
+
let watcher;
|
|
4096
|
+
|
|
4097
|
+
const onChange = () => {
|
|
4098
|
+
const { type, stat } = readFileInfo(sourceUrl);
|
|
4099
|
+
|
|
4100
|
+
if (type === null) {
|
|
4101
|
+
stopWatching();
|
|
4102
|
+
if (removed) {
|
|
4103
|
+
removed();
|
|
4104
|
+
}
|
|
4105
|
+
} else if (type === "file") {
|
|
4106
|
+
if (updated && shouldCallUpdated(stat, prevStat)) {
|
|
4107
|
+
updated();
|
|
4108
|
+
}
|
|
4109
|
+
if ((isMacos || isLinux || isFreeBSD) && prevStat.ino !== stat.ino) {
|
|
4110
|
+
stopWatching();
|
|
4111
|
+
watch();
|
|
4112
|
+
}
|
|
4113
|
+
}
|
|
4114
|
+
prevStat = stat;
|
|
4115
|
+
};
|
|
4116
|
+
|
|
4117
|
+
const watch = () => {
|
|
4118
|
+
watcher = createWatcher(urlToFileSystemPath(sourceUrl), {
|
|
4119
|
+
persistent: keepProcessAlive,
|
|
4120
|
+
});
|
|
4121
|
+
watcher.on("change", onChange);
|
|
4122
|
+
};
|
|
4123
|
+
const stopWatching = () => {
|
|
4124
|
+
if (watcher) {
|
|
4125
|
+
watcher.close();
|
|
4126
|
+
watcher = undefined;
|
|
4127
|
+
}
|
|
4128
|
+
};
|
|
4129
|
+
watch();
|
|
4130
|
+
return stopWatching;
|
|
4131
|
+
};
|
|
4132
|
+
|
|
4133
|
+
const shouldCallUpdated = (stat, prevStat) => {
|
|
4134
|
+
if (!stat.atimeMs) {
|
|
4135
|
+
return true;
|
|
4136
|
+
}
|
|
4137
|
+
if (stat.atimeMs <= stat.mtimeMs) {
|
|
4138
|
+
return true;
|
|
4139
|
+
}
|
|
4140
|
+
if (stat.mtimeMs !== prevStat.mtimeMs) {
|
|
4141
|
+
return true;
|
|
4142
|
+
}
|
|
4143
|
+
return false;
|
|
4144
|
+
};
|
|
4145
|
+
|
|
3894
4146
|
/*
|
|
3895
4147
|
* - Buffer documentation on Node.js
|
|
3896
4148
|
* https://nodejs.org/docs/latest-v13.x/api/buffer.html
|
|
@@ -6419,4 +6671,4 @@ const isResponseEligibleForIntegrityValidation = (response) => {
|
|
|
6419
6671
|
return ["basic", "cors", "default"].includes(response.type);
|
|
6420
6672
|
};
|
|
6421
6673
|
|
|
6422
|
-
export { ANSI, CONTENT_TYPE, DATA_URL, JS_QUOTES, RUNTIME_COMPAT, URL_META, applyFileSystemMagicResolution, applyNodeEsmResolution, asSpecifierWithoutSearch, asUrlWithoutSearch, assertAndNormalizeDirectoryUrl, bufferToEtag, compareFileUrls, composeTwoImportMaps, createDetailedMessage$1 as createDetailedMessage, createLogger, createTaskLog, ensurePathnameTrailingSlash, ensureWindowsDriveLetter, errorToHTML, formatError, generateContentFrame, getCallerPosition, getExtensionsToTry, injectQueryParams, injectQueryParamsIntoSpecifier, isFileSystemPath, isSpecifierForNodeBuiltin, lookupPackageDirectory, moveUrl, normalizeImportMap, normalizeUrl, readCustomConditionsFromProcessArgs, readEntryStatSync, readPackageAtOrNull, registerDirectoryLifecycle, resolveImport, setUrlBasename, setUrlExtension, setUrlFilename, stringifyUrlSite, urlIsOrIsInsideOf, urlToBasename, urlToExtension$1 as urlToExtension, urlToFileSystemPath, urlToFilename$1 as urlToFilename, urlToPathname$1 as urlToPathname, urlToRelativeUrl, validateResponseIntegrity, writeFileSync };
|
|
6674
|
+
export { ANSI, CONTENT_TYPE, DATA_URL, JS_QUOTES, RUNTIME_COMPAT, URL_META, applyFileSystemMagicResolution, applyNodeEsmResolution, asSpecifierWithoutSearch, asUrlWithoutSearch, assertAndNormalizeDirectoryUrl, bufferToEtag, compareFileUrls, composeTwoImportMaps, createDetailedMessage$1 as createDetailedMessage, createLogger, createTaskLog, ensurePathnameTrailingSlash, ensureWindowsDriveLetter, errorToHTML, formatError, generateContentFrame, getCallerPosition, getExtensionsToTry, injectQueryParams, injectQueryParamsIntoSpecifier, isFileSystemPath, isSpecifierForNodeBuiltin, lookupPackageDirectory, moveUrl, normalizeImportMap, normalizeUrl, readCustomConditionsFromProcessArgs, readEntryStatSync, readPackageAtOrNull, registerDirectoryLifecycle, registerFileLifecycle, resolveImport, setUrlBasename, setUrlExtension, setUrlFilename, stringifyUrlSite, urlIsOrIsInsideOf, urlToBasename, urlToExtension$1 as urlToExtension, urlToFileSystemPath, urlToFilename$1 as urlToFilename, urlToPathname$1 as urlToPathname, urlToRelativeUrl, validateResponseIntegrity, writeFileSync };
|