@jsenv/core 40.12.1 → 40.12.3
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/browserslist_index/browserslist_index.js +25 -10
- package/dist/build/build.js +15 -28
- package/dist/build/jsenv_core_packages.js +68 -41
- package/dist/client/inline_content/inline_content.js +0 -2
- package/dist/client/ribbon/ribbon.js +8 -8
- package/dist/start_build_server/jsenv_core_packages.js +68 -39
- package/dist/start_dev_server/jsenv_core_packages.js +68 -41
- package/dist/start_dev_server/start_dev_server.js +15 -28
- package/package.json +16 -16
- package/src/kitchen/client/inline_content.js +0 -2
- package/src/kitchen/kitchen.js +2 -3
- package/src/plugins/autoreload_on_server_restart/jsenv_plugin_autoreload_on_server_restart.js +2 -3
- package/src/plugins/html_syntax_error_fallback/jsenv_plugin_html_syntax_error_fallback.js +2 -3
- package/src/plugins/import_meta_css/jsenv_plugin_import_meta_css.js +4 -6
- package/src/plugins/import_meta_hot/jsenv_plugin_import_meta_hot.js +2 -3
- package/src/plugins/protocol_file/client/directory_listing.css +27 -27
- package/src/plugins/protocol_file/jsenv_plugin_directory_listing.js +2 -3
- package/src/plugins/protocol_file/jsenv_plugin_fs_redirection.js +2 -13
- package/src/plugins/ribbon/client/ribbon.js +8 -8
package/dist/build/build.js
CHANGED
|
@@ -2902,9 +2902,8 @@ const shouldHandleSourcemap = (urlInfo) => {
|
|
|
2902
2902
|
return true;
|
|
2903
2903
|
};
|
|
2904
2904
|
|
|
2905
|
-
const inlineContentClientFileUrl = import.meta
|
|
2906
|
-
"../client/inline_content/inline_content.js"
|
|
2907
|
-
);
|
|
2905
|
+
const inlineContentClientFileUrl = import.meta
|
|
2906
|
+
.resolve("../client/inline_content/inline_content.js");
|
|
2908
2907
|
|
|
2909
2908
|
const createKitchen = ({
|
|
2910
2909
|
name,
|
|
@@ -4101,9 +4100,8 @@ const jsenvPluginInlining = () => {
|
|
|
4101
4100
|
};
|
|
4102
4101
|
|
|
4103
4102
|
const jsenvPluginHtmlSyntaxErrorFallback = () => {
|
|
4104
|
-
const htmlSyntaxErrorFileUrl = import.meta
|
|
4105
|
-
"../client/html_syntax_error/html_syntax_error.html"
|
|
4106
|
-
);
|
|
4103
|
+
const htmlSyntaxErrorFileUrl = import.meta
|
|
4104
|
+
.resolve("../client/html_syntax_error/html_syntax_error.html");
|
|
4107
4105
|
|
|
4108
4106
|
return {
|
|
4109
4107
|
mustStayFirst: true,
|
|
@@ -6550,9 +6548,8 @@ const jsenvPluginVersionSearchParam = () => {
|
|
|
6550
6548
|
*/
|
|
6551
6549
|
|
|
6552
6550
|
|
|
6553
|
-
const htmlFileUrlForDirectory = import.meta
|
|
6554
|
-
"../client/directory_listing/directory_listing.html"
|
|
6555
|
-
);
|
|
6551
|
+
const htmlFileUrlForDirectory = import.meta
|
|
6552
|
+
.resolve("../client/directory_listing/directory_listing.html");
|
|
6556
6553
|
|
|
6557
6554
|
const jsenvPluginDirectoryListing = ({
|
|
6558
6555
|
spa,
|
|
@@ -7039,13 +7036,7 @@ const jsenvPluginFsRedirection = ({
|
|
|
7039
7036
|
// 2. The url pathname does not have an extension
|
|
7040
7037
|
// This point assume client is requesting a file when there is an extension
|
|
7041
7038
|
// and it assumes all routes will not use extension
|
|
7042
|
-
|
|
7043
|
-
// In that case we assume client explicitely asks to load a directory
|
|
7044
|
-
if (
|
|
7045
|
-
spa &&
|
|
7046
|
-
!urlToExtension(urlObject) &&
|
|
7047
|
-
!urlToPathname(urlObject).endsWith("/")
|
|
7048
|
-
) {
|
|
7039
|
+
if (spa && !urlToExtension(urlObject)) {
|
|
7049
7040
|
const { requestedUrl, rootDirectoryUrl, mainFilePath } =
|
|
7050
7041
|
reference.ownerUrlInfo.context;
|
|
7051
7042
|
const closestHtmlRootFile = getClosestHtmlRootFile(
|
|
@@ -7817,12 +7808,10 @@ const jsenvPluginNodeRuntime = ({ runtimeCompat }) => {
|
|
|
7817
7808
|
|
|
7818
7809
|
|
|
7819
7810
|
const jsenvPluginImportMetaCss = () => {
|
|
7820
|
-
const importMetaCssClientFileUrl = import.meta
|
|
7821
|
-
"../client/import_meta_css/import_meta_css.js"
|
|
7822
|
-
|
|
7823
|
-
|
|
7824
|
-
"../client/import_meta_css/import_meta_css_build.js",
|
|
7825
|
-
);
|
|
7811
|
+
const importMetaCssClientFileUrl = import.meta
|
|
7812
|
+
.resolve("../client/import_meta_css/import_meta_css.js");
|
|
7813
|
+
const importMetaCssBuildFileUrl = import.meta
|
|
7814
|
+
.resolve("../client/import_meta_css/import_meta_css_build.js");
|
|
7826
7815
|
|
|
7827
7816
|
return {
|
|
7828
7817
|
name: "jsenv:import_meta_css",
|
|
@@ -8154,9 +8143,8 @@ const htmlNodeCanHotReload = (node) => {
|
|
|
8154
8143
|
};
|
|
8155
8144
|
|
|
8156
8145
|
const jsenvPluginImportMetaHot = () => {
|
|
8157
|
-
const importMetaHotClientFileUrl = import.meta
|
|
8158
|
-
"../client/import_meta_hot/import_meta_hot.js"
|
|
8159
|
-
);
|
|
8146
|
+
const importMetaHotClientFileUrl = import.meta
|
|
8147
|
+
.resolve("../client/import_meta_hot/import_meta_hot.js");
|
|
8160
8148
|
|
|
8161
8149
|
return {
|
|
8162
8150
|
name: "jsenv:import_meta_hot",
|
|
@@ -8948,9 +8936,8 @@ const jsenvPluginChromeDevtoolsJson = () => {
|
|
|
8948
8936
|
};
|
|
8949
8937
|
|
|
8950
8938
|
const jsenvPluginAutoreloadOnServerRestart = () => {
|
|
8951
|
-
const autoreloadOnRestartClientFileUrl = import.meta
|
|
8952
|
-
"@jsenv/server/src/services/autoreload_on_server_restart/client/autoreload_on_server_restart.js"
|
|
8953
|
-
);
|
|
8939
|
+
const autoreloadOnRestartClientFileUrl = import.meta
|
|
8940
|
+
.resolve("@jsenv/server/src/services/autoreload_on_server_restart/client/autoreload_on_server_restart.js");
|
|
8954
8941
|
|
|
8955
8942
|
return {
|
|
8956
8943
|
name: "jsenv:autoreload_on_server_restart",
|
|
@@ -521,8 +521,6 @@ const SIGINT_CALLBACK = {
|
|
|
521
521
|
* https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs#syntax
|
|
522
522
|
*/
|
|
523
523
|
|
|
524
|
-
/* eslint-env browser, node */
|
|
525
|
-
|
|
526
524
|
const DATA_URL = {
|
|
527
525
|
parse: (string) => {
|
|
528
526
|
const afterDataProtocol = string.slice("data:".length);
|
|
@@ -852,19 +850,47 @@ const setDecimalsPrecision = (
|
|
|
852
850
|
// return numberTruncated
|
|
853
851
|
// }
|
|
854
852
|
|
|
855
|
-
const
|
|
856
|
-
year:
|
|
857
|
-
month:
|
|
858
|
-
week:
|
|
859
|
-
day:
|
|
860
|
-
hour:
|
|
861
|
-
minute:
|
|
862
|
-
second:
|
|
853
|
+
const UNIT_MS = {
|
|
854
|
+
year: 31_557_600_000,
|
|
855
|
+
month: 2_629_000_000,
|
|
856
|
+
week: 604_800_000,
|
|
857
|
+
day: 86_400_000,
|
|
858
|
+
hour: 3_600_000,
|
|
859
|
+
minute: 60_000,
|
|
860
|
+
second: 1000,
|
|
861
|
+
};
|
|
862
|
+
const UNIT_KEYS = Object.keys(UNIT_MS);
|
|
863
|
+
const SMALLEST_UNIT_NAME = UNIT_KEYS[UNIT_KEYS.length - 1];
|
|
864
|
+
const TIME_DICTIONARY_EN = {
|
|
865
|
+
year: { long: "year", plural: "years", short: "y" },
|
|
866
|
+
month: { long: "month", plural: "months", short: "m" },
|
|
867
|
+
week: { long: "week", plural: "weeks", short: "w" },
|
|
868
|
+
day: { long: "day", plural: "days", short: "d" },
|
|
869
|
+
hour: { long: "hour", plural: "hours", short: "h" },
|
|
870
|
+
minute: { long: "minute", plural: "minutes", short: "m" },
|
|
871
|
+
second: { long: "second", plural: "seconds", short: "s" },
|
|
872
|
+
joinDuration: (primary, remaining) => `${primary} and ${remaining}`,
|
|
873
|
+
};
|
|
874
|
+
const TIME_DICTIONARY_FR = {
|
|
875
|
+
year: { long: "an", plural: "ans", short: "a" },
|
|
876
|
+
month: { long: "mois", plural: "mois", short: "m" },
|
|
877
|
+
week: { long: "semaine", plural: "semaines", short: "s" },
|
|
878
|
+
day: { long: "jour", plural: "jours", short: "j" },
|
|
879
|
+
hour: { long: "heure", plural: "heures", short: "h" },
|
|
880
|
+
minute: { long: "minute", plural: "minutes", short: "m" },
|
|
881
|
+
second: { long: "seconde", plural: "secondes", short: "s" },
|
|
882
|
+
joinDuration: (primary, remaining) => `${primary} et ${remaining}`,
|
|
863
883
|
};
|
|
864
884
|
|
|
865
885
|
const humanizeDuration = (
|
|
866
886
|
ms,
|
|
867
|
-
{
|
|
887
|
+
{
|
|
888
|
+
short,
|
|
889
|
+
rounded = true,
|
|
890
|
+
decimals,
|
|
891
|
+
lang = "en",
|
|
892
|
+
timeDictionnary = lang === "fr" ? TIME_DICTIONARY_FR : TIME_DICTIONARY_EN,
|
|
893
|
+
} = {},
|
|
868
894
|
) => {
|
|
869
895
|
// ignore ms below meaningfulMs so that:
|
|
870
896
|
// humanizeDuration(0.5) -> "0 second"
|
|
@@ -874,7 +900,9 @@ const humanizeDuration = (
|
|
|
874
900
|
// yes we could return "0.1 millisecond" but we choosed consistency over precision
|
|
875
901
|
// so that the prefered unit is "second" (and does not become millisecond when ms is super small)
|
|
876
902
|
if (ms < 1) {
|
|
877
|
-
return short
|
|
903
|
+
return short
|
|
904
|
+
? `0${timeDictionnary.second.short}`
|
|
905
|
+
: `0 ${timeDictionnary.second.long}`;
|
|
878
906
|
}
|
|
879
907
|
const { primary, remaining } = parseMs(ms);
|
|
880
908
|
if (!remaining) {
|
|
@@ -883,52 +911,51 @@ const humanizeDuration = (
|
|
|
883
911
|
decimals === undefined ? (primary.name === "second" ? 1 : 0) : decimals,
|
|
884
912
|
short,
|
|
885
913
|
rounded,
|
|
914
|
+
timeDictionnary,
|
|
886
915
|
});
|
|
887
916
|
}
|
|
888
|
-
|
|
917
|
+
const primaryText = humanizeDurationUnit(primary, {
|
|
889
918
|
decimals: decimals === undefined ? 0 : decimals,
|
|
890
919
|
short,
|
|
891
920
|
rounded,
|
|
892
|
-
|
|
921
|
+
timeDictionnary,
|
|
922
|
+
});
|
|
923
|
+
const remainingText = humanizeDurationUnit(remaining, {
|
|
893
924
|
decimals: decimals === undefined ? 0 : decimals,
|
|
894
925
|
short,
|
|
895
926
|
rounded,
|
|
896
|
-
|
|
927
|
+
timeDictionnary,
|
|
928
|
+
});
|
|
929
|
+
return timeDictionnary.joinDuration(primaryText, remainingText);
|
|
897
930
|
};
|
|
898
|
-
const humanizeDurationUnit = (
|
|
931
|
+
const humanizeDurationUnit = (
|
|
932
|
+
unit,
|
|
933
|
+
{ decimals, short, rounded, timeDictionnary },
|
|
934
|
+
) => {
|
|
899
935
|
const count = rounded
|
|
900
936
|
? setRoundedPrecision(unit.count, { decimals })
|
|
901
937
|
: setPrecision(unit.count, { decimals });
|
|
902
|
-
|
|
938
|
+
const name = unit.name;
|
|
903
939
|
if (short) {
|
|
904
|
-
|
|
905
|
-
return `${count}${
|
|
940
|
+
const unitText = timeDictionnary[name].short;
|
|
941
|
+
return `${count}${unitText}`;
|
|
906
942
|
}
|
|
907
943
|
if (count <= 1) {
|
|
908
|
-
|
|
944
|
+
const unitText = timeDictionnary[name].long;
|
|
945
|
+
return `${count} ${unitText}`;
|
|
909
946
|
}
|
|
910
|
-
|
|
911
|
-
}
|
|
912
|
-
const MS_PER_UNITS = {
|
|
913
|
-
year: 31_557_600_000,
|
|
914
|
-
month: 2_629_000_000,
|
|
915
|
-
week: 604_800_000,
|
|
916
|
-
day: 86_400_000,
|
|
917
|
-
hour: 3_600_000,
|
|
918
|
-
minute: 60_000,
|
|
919
|
-
second: 1000,
|
|
947
|
+
const unitText = timeDictionnary[name].plural;
|
|
948
|
+
return `${count} ${unitText}`;
|
|
920
949
|
};
|
|
921
950
|
|
|
922
951
|
const parseMs = (ms) => {
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
const firstUnitIndex = unitNames.findIndex((unitName) => {
|
|
928
|
-
if (unitName === smallestUnitName) {
|
|
952
|
+
let firstUnitName = SMALLEST_UNIT_NAME;
|
|
953
|
+
let firstUnitCount = ms / UNIT_MS[SMALLEST_UNIT_NAME];
|
|
954
|
+
const firstUnitIndex = UNIT_KEYS.findIndex((unitName) => {
|
|
955
|
+
if (unitName === SMALLEST_UNIT_NAME) {
|
|
929
956
|
return false;
|
|
930
957
|
}
|
|
931
|
-
const msPerUnit =
|
|
958
|
+
const msPerUnit = UNIT_MS[unitName];
|
|
932
959
|
const unitCount = Math.floor(ms / msPerUnit);
|
|
933
960
|
if (unitCount) {
|
|
934
961
|
firstUnitName = unitName;
|
|
@@ -937,7 +964,7 @@ const parseMs = (ms) => {
|
|
|
937
964
|
}
|
|
938
965
|
return false;
|
|
939
966
|
});
|
|
940
|
-
if (firstUnitName ===
|
|
967
|
+
if (firstUnitName === SMALLEST_UNIT_NAME) {
|
|
941
968
|
return {
|
|
942
969
|
primary: {
|
|
943
970
|
name: firstUnitName,
|
|
@@ -945,9 +972,9 @@ const parseMs = (ms) => {
|
|
|
945
972
|
},
|
|
946
973
|
};
|
|
947
974
|
}
|
|
948
|
-
const remainingMs = ms - firstUnitCount *
|
|
949
|
-
const remainingUnitName =
|
|
950
|
-
const remainingUnitCount = remainingMs /
|
|
975
|
+
const remainingMs = ms - firstUnitCount * UNIT_MS[firstUnitName];
|
|
976
|
+
const remainingUnitName = UNIT_KEYS[firstUnitIndex + 1];
|
|
977
|
+
const remainingUnitCount = remainingMs / UNIT_MS[remainingUnitName];
|
|
951
978
|
// - 1 year and 1 second is too much information
|
|
952
979
|
// so we don't check the remaining units
|
|
953
980
|
// - 1 year and 0.0001 week is awful
|
|
@@ -2,14 +2,14 @@ const injectRibbon = ({ text }) => {
|
|
|
2
2
|
const css = /* css */ `
|
|
3
3
|
#jsenv_ribbon_container {
|
|
4
4
|
position: fixed;
|
|
5
|
-
z-index: 1001;
|
|
6
5
|
top: 0;
|
|
7
6
|
right: 0;
|
|
7
|
+
z-index: 1001;
|
|
8
8
|
width: 100px;
|
|
9
9
|
height: 100px;
|
|
10
|
-
overflow: hidden;
|
|
11
10
|
opacity: 0.5;
|
|
12
11
|
pointer-events: none;
|
|
12
|
+
overflow: hidden;
|
|
13
13
|
}
|
|
14
14
|
#jsenv_ribbon {
|
|
15
15
|
position: absolute;
|
|
@@ -20,20 +20,20 @@ const injectRibbon = ({ text }) => {
|
|
|
20
20
|
}
|
|
21
21
|
#jsenv_ribbon_text {
|
|
22
22
|
position: absolute;
|
|
23
|
-
left: 0px;
|
|
24
23
|
top: 20px;
|
|
25
|
-
|
|
24
|
+
left: 0px;
|
|
26
25
|
display: block;
|
|
27
26
|
width: 125px;
|
|
28
|
-
line-height: 36px;
|
|
29
|
-
background-color: orange;
|
|
30
27
|
color: rgb(55, 7, 7);
|
|
31
|
-
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.1);
|
|
32
28
|
font-weight: 700;
|
|
33
29
|
font-size: 16px;
|
|
34
30
|
font-family: "Lato", sans-serif;
|
|
35
|
-
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
|
|
36
31
|
text-align: center;
|
|
32
|
+
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
|
|
33
|
+
line-height: 36px;
|
|
34
|
+
background-color: orange;
|
|
35
|
+
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.1);
|
|
36
|
+
transform: rotate(45deg);
|
|
37
37
|
user-select: none;
|
|
38
38
|
}
|
|
39
39
|
`;
|
|
@@ -760,19 +760,47 @@ const setDecimalsPrecision = (
|
|
|
760
760
|
// return numberTruncated
|
|
761
761
|
// }
|
|
762
762
|
|
|
763
|
-
const
|
|
764
|
-
year:
|
|
765
|
-
month:
|
|
766
|
-
week:
|
|
767
|
-
day:
|
|
768
|
-
hour:
|
|
769
|
-
minute:
|
|
770
|
-
second:
|
|
763
|
+
const UNIT_MS = {
|
|
764
|
+
year: 31_557_600_000,
|
|
765
|
+
month: 2_629_000_000,
|
|
766
|
+
week: 604_800_000,
|
|
767
|
+
day: 86_400_000,
|
|
768
|
+
hour: 3_600_000,
|
|
769
|
+
minute: 60_000,
|
|
770
|
+
second: 1000,
|
|
771
|
+
};
|
|
772
|
+
const UNIT_KEYS = Object.keys(UNIT_MS);
|
|
773
|
+
const SMALLEST_UNIT_NAME = UNIT_KEYS[UNIT_KEYS.length - 1];
|
|
774
|
+
const TIME_DICTIONARY_EN = {
|
|
775
|
+
year: { long: "year", plural: "years", short: "y" },
|
|
776
|
+
month: { long: "month", plural: "months", short: "m" },
|
|
777
|
+
week: { long: "week", plural: "weeks", short: "w" },
|
|
778
|
+
day: { long: "day", plural: "days", short: "d" },
|
|
779
|
+
hour: { long: "hour", plural: "hours", short: "h" },
|
|
780
|
+
minute: { long: "minute", plural: "minutes", short: "m" },
|
|
781
|
+
second: { long: "second", plural: "seconds", short: "s" },
|
|
782
|
+
joinDuration: (primary, remaining) => `${primary} and ${remaining}`,
|
|
783
|
+
};
|
|
784
|
+
const TIME_DICTIONARY_FR = {
|
|
785
|
+
year: { long: "an", plural: "ans", short: "a" },
|
|
786
|
+
month: { long: "mois", plural: "mois", short: "m" },
|
|
787
|
+
week: { long: "semaine", plural: "semaines", short: "s" },
|
|
788
|
+
day: { long: "jour", plural: "jours", short: "j" },
|
|
789
|
+
hour: { long: "heure", plural: "heures", short: "h" },
|
|
790
|
+
minute: { long: "minute", plural: "minutes", short: "m" },
|
|
791
|
+
second: { long: "seconde", plural: "secondes", short: "s" },
|
|
792
|
+
joinDuration: (primary, remaining) => `${primary} et ${remaining}`,
|
|
771
793
|
};
|
|
772
794
|
|
|
773
795
|
const humanizeDuration = (
|
|
774
796
|
ms,
|
|
775
|
-
{
|
|
797
|
+
{
|
|
798
|
+
short,
|
|
799
|
+
rounded = true,
|
|
800
|
+
decimals,
|
|
801
|
+
lang = "en",
|
|
802
|
+
timeDictionnary = lang === "fr" ? TIME_DICTIONARY_FR : TIME_DICTIONARY_EN,
|
|
803
|
+
} = {},
|
|
776
804
|
) => {
|
|
777
805
|
// ignore ms below meaningfulMs so that:
|
|
778
806
|
// humanizeDuration(0.5) -> "0 second"
|
|
@@ -782,7 +810,9 @@ const humanizeDuration = (
|
|
|
782
810
|
// yes we could return "0.1 millisecond" but we choosed consistency over precision
|
|
783
811
|
// so that the prefered unit is "second" (and does not become millisecond when ms is super small)
|
|
784
812
|
if (ms < 1) {
|
|
785
|
-
return short
|
|
813
|
+
return short
|
|
814
|
+
? `0${timeDictionnary.second.short}`
|
|
815
|
+
: `0 ${timeDictionnary.second.long}`;
|
|
786
816
|
}
|
|
787
817
|
const { primary, remaining } = parseMs(ms);
|
|
788
818
|
if (!remaining) {
|
|
@@ -791,52 +821,51 @@ const humanizeDuration = (
|
|
|
791
821
|
decimals === undefined ? (primary.name === "second" ? 1 : 0) : decimals,
|
|
792
822
|
short,
|
|
793
823
|
rounded,
|
|
824
|
+
timeDictionnary,
|
|
794
825
|
});
|
|
795
826
|
}
|
|
796
|
-
|
|
827
|
+
const primaryText = humanizeDurationUnit(primary, {
|
|
797
828
|
decimals: decimals === undefined ? 0 : decimals,
|
|
798
829
|
short,
|
|
799
830
|
rounded,
|
|
800
|
-
|
|
831
|
+
timeDictionnary,
|
|
832
|
+
});
|
|
833
|
+
const remainingText = humanizeDurationUnit(remaining, {
|
|
801
834
|
decimals: decimals === undefined ? 0 : decimals,
|
|
802
835
|
short,
|
|
803
836
|
rounded,
|
|
804
|
-
|
|
837
|
+
timeDictionnary,
|
|
838
|
+
});
|
|
839
|
+
return timeDictionnary.joinDuration(primaryText, remainingText);
|
|
805
840
|
};
|
|
806
|
-
const humanizeDurationUnit = (
|
|
841
|
+
const humanizeDurationUnit = (
|
|
842
|
+
unit,
|
|
843
|
+
{ decimals, short, rounded, timeDictionnary },
|
|
844
|
+
) => {
|
|
807
845
|
const count = rounded
|
|
808
846
|
? setRoundedPrecision(unit.count, { decimals })
|
|
809
847
|
: setPrecision(unit.count, { decimals });
|
|
810
|
-
|
|
848
|
+
const name = unit.name;
|
|
811
849
|
if (short) {
|
|
812
|
-
|
|
813
|
-
return `${count}${
|
|
850
|
+
const unitText = timeDictionnary[name].short;
|
|
851
|
+
return `${count}${unitText}`;
|
|
814
852
|
}
|
|
815
853
|
if (count <= 1) {
|
|
816
|
-
|
|
854
|
+
const unitText = timeDictionnary[name].long;
|
|
855
|
+
return `${count} ${unitText}`;
|
|
817
856
|
}
|
|
818
|
-
|
|
819
|
-
}
|
|
820
|
-
const MS_PER_UNITS = {
|
|
821
|
-
year: 31_557_600_000,
|
|
822
|
-
month: 2_629_000_000,
|
|
823
|
-
week: 604_800_000,
|
|
824
|
-
day: 86_400_000,
|
|
825
|
-
hour: 3_600_000,
|
|
826
|
-
minute: 60_000,
|
|
827
|
-
second: 1000,
|
|
857
|
+
const unitText = timeDictionnary[name].plural;
|
|
858
|
+
return `${count} ${unitText}`;
|
|
828
859
|
};
|
|
829
860
|
|
|
830
861
|
const parseMs = (ms) => {
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
const firstUnitIndex = unitNames.findIndex((unitName) => {
|
|
836
|
-
if (unitName === smallestUnitName) {
|
|
862
|
+
let firstUnitName = SMALLEST_UNIT_NAME;
|
|
863
|
+
let firstUnitCount = ms / UNIT_MS[SMALLEST_UNIT_NAME];
|
|
864
|
+
const firstUnitIndex = UNIT_KEYS.findIndex((unitName) => {
|
|
865
|
+
if (unitName === SMALLEST_UNIT_NAME) {
|
|
837
866
|
return false;
|
|
838
867
|
}
|
|
839
|
-
const msPerUnit =
|
|
868
|
+
const msPerUnit = UNIT_MS[unitName];
|
|
840
869
|
const unitCount = Math.floor(ms / msPerUnit);
|
|
841
870
|
if (unitCount) {
|
|
842
871
|
firstUnitName = unitName;
|
|
@@ -845,7 +874,7 @@ const parseMs = (ms) => {
|
|
|
845
874
|
}
|
|
846
875
|
return false;
|
|
847
876
|
});
|
|
848
|
-
if (firstUnitName ===
|
|
877
|
+
if (firstUnitName === SMALLEST_UNIT_NAME) {
|
|
849
878
|
return {
|
|
850
879
|
primary: {
|
|
851
880
|
name: firstUnitName,
|
|
@@ -853,9 +882,9 @@ const parseMs = (ms) => {
|
|
|
853
882
|
},
|
|
854
883
|
};
|
|
855
884
|
}
|
|
856
|
-
const remainingMs = ms - firstUnitCount *
|
|
857
|
-
const remainingUnitName =
|
|
858
|
-
const remainingUnitCount = remainingMs /
|
|
885
|
+
const remainingMs = ms - firstUnitCount * UNIT_MS[firstUnitName];
|
|
886
|
+
const remainingUnitName = UNIT_KEYS[firstUnitIndex + 1];
|
|
887
|
+
const remainingUnitCount = remainingMs / UNIT_MS[remainingUnitName];
|
|
859
888
|
// - 1 year and 1 second is too much information
|
|
860
889
|
// so we don't check the remaining units
|
|
861
890
|
// - 1 year and 0.0001 week is awful
|
|
@@ -10,8 +10,6 @@ import { pathToFileURL, fileURLToPath } from "node:url";
|
|
|
10
10
|
* https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs#syntax
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
/* eslint-env browser, node */
|
|
14
|
-
|
|
15
13
|
const DATA_URL = {
|
|
16
14
|
parse: (string) => {
|
|
17
15
|
const afterDataProtocol = string.slice("data:".length);
|
|
@@ -360,19 +358,47 @@ const setDecimalsPrecision = (
|
|
|
360
358
|
// return numberTruncated
|
|
361
359
|
// }
|
|
362
360
|
|
|
363
|
-
const
|
|
364
|
-
year:
|
|
365
|
-
month:
|
|
366
|
-
week:
|
|
367
|
-
day:
|
|
368
|
-
hour:
|
|
369
|
-
minute:
|
|
370
|
-
second:
|
|
361
|
+
const UNIT_MS = {
|
|
362
|
+
year: 31_557_600_000,
|
|
363
|
+
month: 2_629_000_000,
|
|
364
|
+
week: 604_800_000,
|
|
365
|
+
day: 86_400_000,
|
|
366
|
+
hour: 3_600_000,
|
|
367
|
+
minute: 60_000,
|
|
368
|
+
second: 1000,
|
|
369
|
+
};
|
|
370
|
+
const UNIT_KEYS = Object.keys(UNIT_MS);
|
|
371
|
+
const SMALLEST_UNIT_NAME = UNIT_KEYS[UNIT_KEYS.length - 1];
|
|
372
|
+
const TIME_DICTIONARY_EN = {
|
|
373
|
+
year: { long: "year", plural: "years", short: "y" },
|
|
374
|
+
month: { long: "month", plural: "months", short: "m" },
|
|
375
|
+
week: { long: "week", plural: "weeks", short: "w" },
|
|
376
|
+
day: { long: "day", plural: "days", short: "d" },
|
|
377
|
+
hour: { long: "hour", plural: "hours", short: "h" },
|
|
378
|
+
minute: { long: "minute", plural: "minutes", short: "m" },
|
|
379
|
+
second: { long: "second", plural: "seconds", short: "s" },
|
|
380
|
+
joinDuration: (primary, remaining) => `${primary} and ${remaining}`,
|
|
381
|
+
};
|
|
382
|
+
const TIME_DICTIONARY_FR = {
|
|
383
|
+
year: { long: "an", plural: "ans", short: "a" },
|
|
384
|
+
month: { long: "mois", plural: "mois", short: "m" },
|
|
385
|
+
week: { long: "semaine", plural: "semaines", short: "s" },
|
|
386
|
+
day: { long: "jour", plural: "jours", short: "j" },
|
|
387
|
+
hour: { long: "heure", plural: "heures", short: "h" },
|
|
388
|
+
minute: { long: "minute", plural: "minutes", short: "m" },
|
|
389
|
+
second: { long: "seconde", plural: "secondes", short: "s" },
|
|
390
|
+
joinDuration: (primary, remaining) => `${primary} et ${remaining}`,
|
|
371
391
|
};
|
|
372
392
|
|
|
373
393
|
const humanizeDuration = (
|
|
374
394
|
ms,
|
|
375
|
-
{
|
|
395
|
+
{
|
|
396
|
+
short,
|
|
397
|
+
rounded = true,
|
|
398
|
+
decimals,
|
|
399
|
+
lang = "en",
|
|
400
|
+
timeDictionnary = lang === "fr" ? TIME_DICTIONARY_FR : TIME_DICTIONARY_EN,
|
|
401
|
+
} = {},
|
|
376
402
|
) => {
|
|
377
403
|
// ignore ms below meaningfulMs so that:
|
|
378
404
|
// humanizeDuration(0.5) -> "0 second"
|
|
@@ -382,7 +408,9 @@ const humanizeDuration = (
|
|
|
382
408
|
// yes we could return "0.1 millisecond" but we choosed consistency over precision
|
|
383
409
|
// so that the prefered unit is "second" (and does not become millisecond when ms is super small)
|
|
384
410
|
if (ms < 1) {
|
|
385
|
-
return short
|
|
411
|
+
return short
|
|
412
|
+
? `0${timeDictionnary.second.short}`
|
|
413
|
+
: `0 ${timeDictionnary.second.long}`;
|
|
386
414
|
}
|
|
387
415
|
const { primary, remaining } = parseMs(ms);
|
|
388
416
|
if (!remaining) {
|
|
@@ -391,52 +419,51 @@ const humanizeDuration = (
|
|
|
391
419
|
decimals === undefined ? (primary.name === "second" ? 1 : 0) : decimals,
|
|
392
420
|
short,
|
|
393
421
|
rounded,
|
|
422
|
+
timeDictionnary,
|
|
394
423
|
});
|
|
395
424
|
}
|
|
396
|
-
|
|
425
|
+
const primaryText = humanizeDurationUnit(primary, {
|
|
397
426
|
decimals: decimals === undefined ? 0 : decimals,
|
|
398
427
|
short,
|
|
399
428
|
rounded,
|
|
400
|
-
|
|
429
|
+
timeDictionnary,
|
|
430
|
+
});
|
|
431
|
+
const remainingText = humanizeDurationUnit(remaining, {
|
|
401
432
|
decimals: decimals === undefined ? 0 : decimals,
|
|
402
433
|
short,
|
|
403
434
|
rounded,
|
|
404
|
-
|
|
435
|
+
timeDictionnary,
|
|
436
|
+
});
|
|
437
|
+
return timeDictionnary.joinDuration(primaryText, remainingText);
|
|
405
438
|
};
|
|
406
|
-
const humanizeDurationUnit = (
|
|
439
|
+
const humanizeDurationUnit = (
|
|
440
|
+
unit,
|
|
441
|
+
{ decimals, short, rounded, timeDictionnary },
|
|
442
|
+
) => {
|
|
407
443
|
const count = rounded
|
|
408
444
|
? setRoundedPrecision(unit.count, { decimals })
|
|
409
445
|
: setPrecision(unit.count, { decimals });
|
|
410
|
-
|
|
446
|
+
const name = unit.name;
|
|
411
447
|
if (short) {
|
|
412
|
-
|
|
413
|
-
return `${count}${
|
|
448
|
+
const unitText = timeDictionnary[name].short;
|
|
449
|
+
return `${count}${unitText}`;
|
|
414
450
|
}
|
|
415
451
|
if (count <= 1) {
|
|
416
|
-
|
|
452
|
+
const unitText = timeDictionnary[name].long;
|
|
453
|
+
return `${count} ${unitText}`;
|
|
417
454
|
}
|
|
418
|
-
|
|
419
|
-
}
|
|
420
|
-
const MS_PER_UNITS = {
|
|
421
|
-
year: 31_557_600_000,
|
|
422
|
-
month: 2_629_000_000,
|
|
423
|
-
week: 604_800_000,
|
|
424
|
-
day: 86_400_000,
|
|
425
|
-
hour: 3_600_000,
|
|
426
|
-
minute: 60_000,
|
|
427
|
-
second: 1000,
|
|
455
|
+
const unitText = timeDictionnary[name].plural;
|
|
456
|
+
return `${count} ${unitText}`;
|
|
428
457
|
};
|
|
429
458
|
|
|
430
459
|
const parseMs = (ms) => {
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
const firstUnitIndex = unitNames.findIndex((unitName) => {
|
|
436
|
-
if (unitName === smallestUnitName) {
|
|
460
|
+
let firstUnitName = SMALLEST_UNIT_NAME;
|
|
461
|
+
let firstUnitCount = ms / UNIT_MS[SMALLEST_UNIT_NAME];
|
|
462
|
+
const firstUnitIndex = UNIT_KEYS.findIndex((unitName) => {
|
|
463
|
+
if (unitName === SMALLEST_UNIT_NAME) {
|
|
437
464
|
return false;
|
|
438
465
|
}
|
|
439
|
-
const msPerUnit =
|
|
466
|
+
const msPerUnit = UNIT_MS[unitName];
|
|
440
467
|
const unitCount = Math.floor(ms / msPerUnit);
|
|
441
468
|
if (unitCount) {
|
|
442
469
|
firstUnitName = unitName;
|
|
@@ -445,7 +472,7 @@ const parseMs = (ms) => {
|
|
|
445
472
|
}
|
|
446
473
|
return false;
|
|
447
474
|
});
|
|
448
|
-
if (firstUnitName ===
|
|
475
|
+
if (firstUnitName === SMALLEST_UNIT_NAME) {
|
|
449
476
|
return {
|
|
450
477
|
primary: {
|
|
451
478
|
name: firstUnitName,
|
|
@@ -453,9 +480,9 @@ const parseMs = (ms) => {
|
|
|
453
480
|
},
|
|
454
481
|
};
|
|
455
482
|
}
|
|
456
|
-
const remainingMs = ms - firstUnitCount *
|
|
457
|
-
const remainingUnitName =
|
|
458
|
-
const remainingUnitCount = remainingMs /
|
|
483
|
+
const remainingMs = ms - firstUnitCount * UNIT_MS[firstUnitName];
|
|
484
|
+
const remainingUnitName = UNIT_KEYS[firstUnitIndex + 1];
|
|
485
|
+
const remainingUnitCount = remainingMs / UNIT_MS[remainingUnitName];
|
|
459
486
|
// - 1 year and 1 second is too much information
|
|
460
487
|
// so we don't check the remaining units
|
|
461
488
|
// - 1 year and 0.0001 week is awful
|