@zelgadis87/utils-core 4.3.2 → 4.3.4
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/tsconfig.tsbuildinfo +1 -1
- package/dist/types/arrays.d.ts +2 -0
- package/dist/types/strings.d.ts +5 -0
- package/dist/utils/index.d.ts +0 -2
- package/esbuild/index.cjs +400 -389
- package/esbuild/index.mjs +395 -388
- package/package.json +1 -1
- package/src/time/TimeDuration.ts +1 -2
- package/src/utils/groupBy.ts +8 -0
- package/dist/utils/pad.d.ts +0 -3
- package/dist/utils/pluralize.d.ts +0 -1
package/esbuild/index.cjs
CHANGED
|
@@ -212,6 +212,7 @@ __export(src_exports, {
|
|
|
212
212
|
dictToEntries: () => dictToEntries,
|
|
213
213
|
dictToList: () => dictToList,
|
|
214
214
|
divideBy: () => divideBy,
|
|
215
|
+
ellipsis: () => ellipsis,
|
|
215
216
|
ensureArray: () => ensureArray,
|
|
216
217
|
ensureDefined: () => ensureDefined,
|
|
217
218
|
ensureNegativeNumber: () => ensureNegativeNumber,
|
|
@@ -223,6 +224,7 @@ __export(src_exports, {
|
|
|
223
224
|
extendArray: () => extendArray,
|
|
224
225
|
extendArrayWith: () => extendArrayWith,
|
|
225
226
|
fill: () => fill,
|
|
227
|
+
flatMapTruthys: () => flatMapTruthys,
|
|
226
228
|
groupByNumber: () => groupByNumber,
|
|
227
229
|
groupByNumberWith: () => groupByNumberWith,
|
|
228
230
|
groupByString: () => groupByString,
|
|
@@ -262,6 +264,7 @@ __export(src_exports, {
|
|
|
262
264
|
last: () => last,
|
|
263
265
|
mapDefined: () => mapDefined,
|
|
264
266
|
mapEntries: () => mapEntries,
|
|
267
|
+
mapTruthys: () => mapTruthys,
|
|
265
268
|
max: () => max,
|
|
266
269
|
maxBy: () => maxBy,
|
|
267
270
|
min: () => min,
|
|
@@ -270,8 +273,9 @@ __export(src_exports, {
|
|
|
270
273
|
noop: () => noop,
|
|
271
274
|
omit: () => omit,
|
|
272
275
|
pad: () => pad,
|
|
276
|
+
padLeft: () => padLeft,
|
|
277
|
+
padRight: () => padRight,
|
|
273
278
|
pick: () => pick,
|
|
274
|
-
pluralize: () => pluralize,
|
|
275
279
|
promiseSequence: () => promiseSequence,
|
|
276
280
|
randomInterval: () => randomInterval,
|
|
277
281
|
randomPercentage: () => randomPercentage,
|
|
@@ -359,6 +363,12 @@ function sortedArray(arr, sortFn) {
|
|
|
359
363
|
function includes(arr, item, fromIndex) {
|
|
360
364
|
return arr.includes(item, fromIndex);
|
|
361
365
|
}
|
|
366
|
+
function mapTruthys(arr, mapper) {
|
|
367
|
+
return arr.map(mapper).filter((value) => value !== void 0);
|
|
368
|
+
}
|
|
369
|
+
function flatMapTruthys(arr, mapper) {
|
|
370
|
+
return arr.flatMap(mapper).filter((value) => value !== void 0);
|
|
371
|
+
}
|
|
362
372
|
|
|
363
373
|
// src/types/booleans.ts
|
|
364
374
|
function isTrue(x) {
|
|
@@ -521,6 +531,29 @@ function stringToNumber(s) {
|
|
|
521
531
|
return null;
|
|
522
532
|
return Number(s);
|
|
523
533
|
}
|
|
534
|
+
function pad(str, n, char, where = "left") {
|
|
535
|
+
const length = ensureDefined(str).length;
|
|
536
|
+
if (length >= ensureDefined(n)) return str;
|
|
537
|
+
if (ensureDefined(char).length !== 1)
|
|
538
|
+
throw new Error("Illegal pad character");
|
|
539
|
+
const padding = repeat(char, n - length);
|
|
540
|
+
return (where === "left" ? padding : "") + str + (where === "right" ? padding : "");
|
|
541
|
+
}
|
|
542
|
+
function padLeft(str, n, char) {
|
|
543
|
+
return pad(str, n, char, "left");
|
|
544
|
+
}
|
|
545
|
+
function padRight(str, n, char) {
|
|
546
|
+
return pad(str, n, char, "right");
|
|
547
|
+
}
|
|
548
|
+
function ellipsis(str, maxLength, padChar, padWhere = "left") {
|
|
549
|
+
if (maxLength < 4)
|
|
550
|
+
throw new Error("Invalid argument maxLength");
|
|
551
|
+
if (str.length <= maxLength) {
|
|
552
|
+
return pad(str, maxLength, padChar, padWhere);
|
|
553
|
+
} else {
|
|
554
|
+
return str.substring(0, maxLength - 3) + "...";
|
|
555
|
+
}
|
|
556
|
+
}
|
|
524
557
|
var StringParts = class _StringParts {
|
|
525
558
|
_parts;
|
|
526
559
|
constructor(...parts) {
|
|
@@ -961,397 +994,25 @@ function randomPercentage(min2, max2) {
|
|
|
961
994
|
return randomInterval(min2, max2) / 100;
|
|
962
995
|
}
|
|
963
996
|
|
|
964
|
-
// src/
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
function constant(v) {
|
|
971
|
-
return () => v;
|
|
972
|
-
}
|
|
973
|
-
function identity(t) {
|
|
974
|
-
return t;
|
|
975
|
-
}
|
|
976
|
-
var constantNull = constant(null);
|
|
977
|
-
var constantTrue = constant(true);
|
|
978
|
-
var constantFalse = constant(false);
|
|
979
|
-
var constantZero = constant(0);
|
|
980
|
-
var constantOne = constant(1);
|
|
981
|
-
|
|
982
|
-
// src/utils/entries.ts
|
|
983
|
-
function dictToEntries(obj) {
|
|
984
|
-
return Object.entries(obj);
|
|
985
|
-
}
|
|
986
|
-
function entriesToDict(entries) {
|
|
987
|
-
return Object.fromEntries(entries);
|
|
988
|
-
}
|
|
989
|
-
function mapEntries(dict, mapper) {
|
|
990
|
-
return entriesToDict(dictToEntries(dict).map((entry) => mapper(entry)));
|
|
991
|
-
}
|
|
992
|
-
|
|
993
|
-
// src/utils/groupBy.ts
|
|
994
|
-
function groupByString(arr, field) {
|
|
995
|
-
return groupByStringWith(arr, (t) => t[field]);
|
|
996
|
-
}
|
|
997
|
-
function groupByNumber(arr, field) {
|
|
998
|
-
return groupByNumberWith(arr, (t) => t[field]);
|
|
999
|
-
}
|
|
1000
|
-
function groupBySymbol(arr, field) {
|
|
1001
|
-
return groupBySymbolWith(arr, (t) => t[field]);
|
|
1002
|
-
}
|
|
1003
|
-
function groupByStringWith(arr, getter) {
|
|
1004
|
-
return doGroupByWith(arr, getter);
|
|
1005
|
-
}
|
|
1006
|
-
function groupByNumberWith(arr, getter) {
|
|
1007
|
-
return doGroupByWith(arr, getter);
|
|
1008
|
-
}
|
|
1009
|
-
function groupBySymbolWith(arr, getter) {
|
|
1010
|
-
return doGroupByWith(arr, getter);
|
|
1011
|
-
}
|
|
1012
|
-
function doGroupByWith(arr, getter) {
|
|
1013
|
-
return arr.reduce((dict, cur) => {
|
|
1014
|
-
const key = getter(cur);
|
|
1015
|
-
if (key !== null && key !== void 0) {
|
|
1016
|
-
const arr2 = dict[key] ?? [];
|
|
1017
|
-
arr2.push(cur);
|
|
1018
|
-
dict[key] = arr2;
|
|
1019
|
-
}
|
|
1020
|
-
return dict;
|
|
1021
|
-
}, {});
|
|
1022
|
-
}
|
|
1023
|
-
|
|
1024
|
-
// src/utils/iff.ts
|
|
1025
|
-
function iff(firstPredicate, valueIfTrue) {
|
|
1026
|
-
if (firstPredicate === true || firstPredicate instanceof Function && firstPredicate() === true) {
|
|
1027
|
-
const ret = {
|
|
1028
|
-
elseIf: () => ret,
|
|
1029
|
-
otherwise: () => valueIfTrue
|
|
1030
|
-
};
|
|
1031
|
-
return ret;
|
|
1032
|
-
} else {
|
|
1033
|
-
const ret = {
|
|
1034
|
-
elseIf: (elseIf, valueIfElseIfTrue) => iff(elseIf, valueIfElseIfTrue),
|
|
1035
|
-
otherwise: (valueIfElse) => valueIfElse
|
|
1036
|
-
};
|
|
1037
|
-
return ret;
|
|
997
|
+
// src/time/TimeDuration.ts
|
|
998
|
+
var TimeDuration = class _TimeDuration extends TimeBase {
|
|
999
|
+
constructor(value, unit) {
|
|
1000
|
+
super(value, unit);
|
|
1001
|
+
if (value < 0)
|
|
1002
|
+
throw new Error("Duration cannot be less than 0");
|
|
1038
1003
|
}
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
// src/utils/indexBy.ts
|
|
1042
|
-
function indexByString(arr, field) {
|
|
1043
|
-
return indexByStringWith(arr, (t) => t[field]);
|
|
1044
|
-
}
|
|
1045
|
-
function indexByNumber(arr, field) {
|
|
1046
|
-
return indexByNumberWith(arr, (t) => t[field]);
|
|
1047
|
-
}
|
|
1048
|
-
function indexBySymbol(arr, field) {
|
|
1049
|
-
return indexBySymbolWith(arr, (t) => t[field]);
|
|
1050
|
-
}
|
|
1051
|
-
function indexByStringWith(arr, getter) {
|
|
1052
|
-
return doIndexByWith(arr, getter);
|
|
1053
|
-
}
|
|
1054
|
-
function indexByNumberWith(arr, getter) {
|
|
1055
|
-
return doIndexByWith(arr, getter);
|
|
1056
|
-
}
|
|
1057
|
-
function indexBySymbolWith(arr, getter) {
|
|
1058
|
-
return doIndexByWith(arr, getter);
|
|
1059
|
-
}
|
|
1060
|
-
function doIndexByWith(arr, getter) {
|
|
1061
|
-
return arr.reduce((dict, cur) => {
|
|
1062
|
-
const key = getter(cur);
|
|
1063
|
-
if (key !== null && key !== void 0)
|
|
1064
|
-
dict[key] = cur;
|
|
1065
|
-
return dict;
|
|
1066
|
-
}, {});
|
|
1067
|
-
}
|
|
1068
|
-
|
|
1069
|
-
// src/utils/jsonCloneDeep.ts
|
|
1070
|
-
function jsonCloneDeep(a) {
|
|
1071
|
-
if (null === a || "object" !== typeof a) return a;
|
|
1072
|
-
if (a instanceof Date) {
|
|
1073
|
-
return new Date(a.getTime());
|
|
1074
|
-
} else if (a instanceof Array) {
|
|
1075
|
-
const copy = [];
|
|
1076
|
-
for (let i = 0, len = a.length; i < len; i++) {
|
|
1077
|
-
copy[i] = jsonCloneDeep(a[i]);
|
|
1078
|
-
}
|
|
1079
|
-
return copy;
|
|
1080
|
-
} else if (a instanceof Object) {
|
|
1081
|
-
const copy = {};
|
|
1082
|
-
for (let attr in a) {
|
|
1083
|
-
if (a.hasOwnProperty(attr))
|
|
1084
|
-
copy[attr] = jsonCloneDeep(a[attr]);
|
|
1085
|
-
}
|
|
1086
|
-
return copy;
|
|
1004
|
+
create(value, unit) {
|
|
1005
|
+
return new _TimeDuration(value, unit);
|
|
1087
1006
|
}
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
// src/utils/math.ts
|
|
1092
|
-
function clamp(n, min2, max2) {
|
|
1093
|
-
if (min2 === null || max2 === null || n === null || isNaN(min2) || isNaN(max2) || isNaN(n) || min2 > max2)
|
|
1094
|
-
throw new Error();
|
|
1095
|
-
if (n > max2) {
|
|
1096
|
-
return max2;
|
|
1097
|
-
} else if (n < min2) {
|
|
1098
|
-
return min2;
|
|
1099
|
-
} else {
|
|
1100
|
-
return n;
|
|
1007
|
+
addDuration(duration) {
|
|
1008
|
+
return this.addUnits(duration.ms, TimeUnit.MILLISECONDS);
|
|
1101
1009
|
}
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
const f = 1 / arr.length;
|
|
1105
|
-
return arr.reduce((tot, cur) => tot + cur * f, 0);
|
|
1106
|
-
}
|
|
1107
|
-
function sum(arr) {
|
|
1108
|
-
return arr.reduce((tot, cur) => tot + cur, 0);
|
|
1109
|
-
}
|
|
1110
|
-
function sumBy(arr, getter) {
|
|
1111
|
-
return sum(arr.map(getter));
|
|
1112
|
-
}
|
|
1113
|
-
function min(arr) {
|
|
1114
|
-
if (arr.length === 0) throw new Error("Cannot calculate value on empty array");
|
|
1115
|
-
return arr.reduce((min2, cur) => cur < min2 ? cur : min2);
|
|
1116
|
-
}
|
|
1117
|
-
function minBy(arr, getter) {
|
|
1118
|
-
return min(arr.map(getter));
|
|
1119
|
-
}
|
|
1120
|
-
function max(arr) {
|
|
1121
|
-
if (arr.length === 0) throw new Error("Cannot calculate value on empty array");
|
|
1122
|
-
return arr.reduce((max2, cur) => cur > max2 ? cur : max2);
|
|
1123
|
-
}
|
|
1124
|
-
function maxBy(arr, getter) {
|
|
1125
|
-
return max(arr.map(getter));
|
|
1126
|
-
}
|
|
1127
|
-
|
|
1128
|
-
// src/utils/noop.ts
|
|
1129
|
-
function noop() {
|
|
1130
|
-
}
|
|
1131
|
-
|
|
1132
|
-
// src/utils/omit.ts
|
|
1133
|
-
function omit(o, ...keys) {
|
|
1134
|
-
return keys.reduce((obj, key) => {
|
|
1135
|
-
delete obj[key];
|
|
1136
|
-
return obj;
|
|
1137
|
-
}, { ...o });
|
|
1138
|
-
}
|
|
1139
|
-
|
|
1140
|
-
// src/utils/pad.ts
|
|
1141
|
-
function pad(str, n, char, where = "left") {
|
|
1142
|
-
const length = ensureDefined(str).length;
|
|
1143
|
-
if (length >= ensureDefined(n)) return str;
|
|
1144
|
-
if (ensureDefined(char).length !== 1)
|
|
1145
|
-
throw new Error("Illegal pad character");
|
|
1146
|
-
const padding = repeat(char, n - length);
|
|
1147
|
-
return (where === "left" ? padding : "") + str + (where === "right" ? padding : "");
|
|
1148
|
-
}
|
|
1149
|
-
|
|
1150
|
-
// src/utils/pluralize.ts
|
|
1151
|
-
function pluralize(n, singular, plural) {
|
|
1152
|
-
if (!singular || !singular.length)
|
|
1153
|
-
throw new Error();
|
|
1154
|
-
if (n === 1)
|
|
1155
|
-
return singular;
|
|
1156
|
-
plural = plural ?? singular + "s";
|
|
1157
|
-
const firstUppercase = singular.charAt(0) === singular.charAt(0).toUpperCase();
|
|
1158
|
-
if (firstUppercase) {
|
|
1159
|
-
const PLURAL = plural.toUpperCase();
|
|
1160
|
-
const isAllUppercase = plural === PLURAL;
|
|
1161
|
-
plural = isAllUppercase ? PLURAL : plural.charAt(0).toUpperCase() + plural.slice(1).toLowerCase();
|
|
1010
|
+
removeDuration(duration) {
|
|
1011
|
+
return this.removeUnits(duration.ms, TimeUnit.MILLISECONDS);
|
|
1162
1012
|
}
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
// src/utils/round.ts
|
|
1167
|
-
var roundModes = {
|
|
1168
|
-
"toNearest": Math.round,
|
|
1169
|
-
"toLower": Math.floor,
|
|
1170
|
-
"toUpper": Math.ceil,
|
|
1171
|
-
"towardsZero": (n) => n > 0 ? Math.floor(n) : Math.ceil(n),
|
|
1172
|
-
"awayFromZero": (n) => n > 0 ? Math.ceil(n) : Math.floor(n)
|
|
1173
|
-
};
|
|
1174
|
-
function round(n, precision = 0, mode = "toNearest") {
|
|
1175
|
-
const base = 10;
|
|
1176
|
-
const power = Math.pow(base, precision);
|
|
1177
|
-
return roundModes[mode](n * power) / power;
|
|
1178
|
-
}
|
|
1179
|
-
var roundToNearest = (n, precision = 0) => round(n, precision, "toNearest");
|
|
1180
|
-
var roundToLower = (n, precision = 0) => round(n, precision, "toLower");
|
|
1181
|
-
var roundToUpper = (n, precision = 0) => round(n, precision, "toUpper");
|
|
1182
|
-
var roundTowardsZero = (n, precision = 0) => round(n, precision, "towardsZero");
|
|
1183
|
-
var roundAwayFromZero = (n, precision = 0) => round(n, precision, "awayFromZero");
|
|
1184
|
-
|
|
1185
|
-
// src/utils/sortBy.ts
|
|
1186
|
-
function sortBy(keyOrGetter, direction = "ASC", nulls = "LAST") {
|
|
1187
|
-
const directionNum = direction === "ASC" ? -1 : 1;
|
|
1188
|
-
const nullsNum = nulls === "LAST" ? -1 : 1;
|
|
1189
|
-
const sortByNum = (a, b) => {
|
|
1190
|
-
if (a === b)
|
|
1191
|
-
return -1;
|
|
1192
|
-
const aDefined = !(a === null || a === void 0 || isNaN(a));
|
|
1193
|
-
const bDefined = !(b === null || b === void 0 || isNaN(b));
|
|
1194
|
-
if (!aDefined && !bDefined)
|
|
1195
|
-
return -1;
|
|
1196
|
-
if (aDefined !== bDefined)
|
|
1197
|
-
return nullsNum * (aDefined ? 1 : -1);
|
|
1198
|
-
return (a > b ? -1 : 1) * directionNum;
|
|
1199
|
-
};
|
|
1200
|
-
if (typeof keyOrGetter === "function") {
|
|
1201
|
-
return (a, b) => sortByNum(keyOrGetter(a), keyOrGetter(b));
|
|
1202
|
-
} else {
|
|
1203
|
-
return (a, b) => sortByNum(a[keyOrGetter], b[keyOrGetter]);
|
|
1204
|
-
}
|
|
1205
|
-
}
|
|
1206
|
-
|
|
1207
|
-
// src/async/RateThrottler.ts
|
|
1208
|
-
var RateThrottler = class {
|
|
1209
|
-
constructor(_frequency) {
|
|
1210
|
-
this._frequency = _frequency;
|
|
1211
|
-
const initialOffset = this.cooldown.divideBy(_frequency.times);
|
|
1212
|
-
this._availableSlots = new Array(_frequency.times).fill(0).map((_, i) => TimeInstant.now().addMs(i * initialOffset.ms));
|
|
1213
|
-
this._waitingRequests = [];
|
|
1214
|
-
}
|
|
1215
|
-
_availableSlots;
|
|
1216
|
-
_waitingRequests;
|
|
1217
|
-
get cooldown() {
|
|
1218
|
-
return this._frequency.period;
|
|
1219
|
-
}
|
|
1220
|
-
async execute(fn) {
|
|
1221
|
-
const wrappedFn = async () => {
|
|
1222
|
-
const slot = this._availableSlots.shift();
|
|
1223
|
-
try {
|
|
1224
|
-
return slot.promise().then(() => fn());
|
|
1225
|
-
} finally {
|
|
1226
|
-
this._availableSlots.push(TimeInstant.now().addDuration(this.cooldown));
|
|
1227
|
-
if (this._waitingRequests.length > 0) this._waitingRequests.shift().resolve();
|
|
1228
|
-
}
|
|
1229
|
-
};
|
|
1230
|
-
if (this._availableSlots.length > 0) {
|
|
1231
|
-
return wrappedFn();
|
|
1232
|
-
} else {
|
|
1233
|
-
const waitingRequest = new Deferred_default();
|
|
1234
|
-
this._waitingRequests.push(waitingRequest);
|
|
1235
|
-
return waitingRequest.then(() => wrappedFn());
|
|
1236
|
-
}
|
|
1237
|
-
}
|
|
1238
|
-
};
|
|
1239
|
-
|
|
1240
|
-
// src/async/Semaphore.ts
|
|
1241
|
-
var Semaphore = class {
|
|
1242
|
-
constructor(_availableSlots = 1) {
|
|
1243
|
-
this._availableSlots = _availableSlots;
|
|
1244
|
-
this._queuedRequests = [];
|
|
1245
|
-
}
|
|
1246
|
-
_queuedRequests;
|
|
1247
|
-
_inProgress = 0;
|
|
1248
|
-
async _awaitSlot() {
|
|
1249
|
-
if (this._availableSlots > 0) {
|
|
1250
|
-
this._availableSlots -= 1;
|
|
1251
|
-
this._inProgress += 1;
|
|
1252
|
-
return void 0;
|
|
1253
|
-
} else {
|
|
1254
|
-
const deferred = new Deferred_default();
|
|
1255
|
-
this._queuedRequests.push(deferred);
|
|
1256
|
-
return deferred.asPromise();
|
|
1257
|
-
}
|
|
1258
|
-
}
|
|
1259
|
-
_releaseSlot() {
|
|
1260
|
-
const waitingSlotToResolve = this._queuedRequests.shift();
|
|
1261
|
-
if (waitingSlotToResolve) {
|
|
1262
|
-
waitingSlotToResolve.resolve();
|
|
1263
|
-
} else {
|
|
1264
|
-
this._availableSlots += 1;
|
|
1265
|
-
this._inProgress -= 1;
|
|
1266
|
-
}
|
|
1267
|
-
}
|
|
1268
|
-
async execute(fn, cooldown = TimeDuration.ZERO) {
|
|
1269
|
-
return this._awaitSlot().then(() => fn()).finally(() => {
|
|
1270
|
-
void cooldown.promise().then(() => this._releaseSlot());
|
|
1271
|
-
});
|
|
1272
|
-
}
|
|
1273
|
-
get availableSlots() {
|
|
1274
|
-
return this._availableSlots;
|
|
1275
|
-
}
|
|
1276
|
-
get queueSize() {
|
|
1277
|
-
return this._queuedRequests.length;
|
|
1278
|
-
}
|
|
1279
|
-
get inProgressSize() {
|
|
1280
|
-
return this._inProgress;
|
|
1281
|
-
}
|
|
1282
|
-
};
|
|
1283
|
-
|
|
1284
|
-
// src/utils/throttle.ts
|
|
1285
|
-
function throttle(fn, frequence) {
|
|
1286
|
-
const semaphore = new RateThrottler(frequence);
|
|
1287
|
-
return (...t) => {
|
|
1288
|
-
return semaphore.execute(async () => fn(...t));
|
|
1289
|
-
};
|
|
1290
|
-
}
|
|
1291
|
-
|
|
1292
|
-
// src/utils/uniqBy.ts
|
|
1293
|
-
function uniqBy(arr, getter) {
|
|
1294
|
-
return arr.reduce((dict, cur) => {
|
|
1295
|
-
const key = getter(cur);
|
|
1296
|
-
if (dict.keys.includes(key)) {
|
|
1297
|
-
return dict;
|
|
1298
|
-
} else {
|
|
1299
|
-
return {
|
|
1300
|
-
keys: [...dict.keys, key],
|
|
1301
|
-
values: [...dict.values, cur]
|
|
1302
|
-
};
|
|
1303
|
-
}
|
|
1304
|
-
}, { keys: [], values: [] }).values;
|
|
1305
|
-
}
|
|
1306
|
-
|
|
1307
|
-
// src/utils/uniq.ts
|
|
1308
|
-
function uniq(arr) {
|
|
1309
|
-
return uniqBy(arr, identity);
|
|
1310
|
-
}
|
|
1311
|
-
|
|
1312
|
-
// src/utils/uniqByKey.ts
|
|
1313
|
-
function uniqByKey(arr, key) {
|
|
1314
|
-
return uniqBy(arr, (item) => item[key]);
|
|
1315
|
-
}
|
|
1316
|
-
|
|
1317
|
-
// src/utils/withTryCatch.ts
|
|
1318
|
-
function withTryCatch(fn) {
|
|
1319
|
-
try {
|
|
1320
|
-
return fn();
|
|
1321
|
-
} catch (e) {
|
|
1322
|
-
return asError(e);
|
|
1323
|
-
}
|
|
1324
|
-
}
|
|
1325
|
-
|
|
1326
|
-
// src/utils/withTryCatchAsync.ts
|
|
1327
|
-
async function withTryCatchAsync(fn) {
|
|
1328
|
-
return fn().catch((e) => asError(e));
|
|
1329
|
-
}
|
|
1330
|
-
|
|
1331
|
-
// src/utils/wrap.ts
|
|
1332
|
-
function wrap(str, delimiter) {
|
|
1333
|
-
return delimiter + str + delimiter;
|
|
1334
|
-
}
|
|
1335
|
-
|
|
1336
|
-
// src/time/TimeDuration.ts
|
|
1337
|
-
var TimeDuration = class _TimeDuration extends TimeBase {
|
|
1338
|
-
constructor(value, unit) {
|
|
1339
|
-
super(value, unit);
|
|
1340
|
-
if (value < 0)
|
|
1341
|
-
throw new Error("Duration cannot be less than 0");
|
|
1342
|
-
}
|
|
1343
|
-
create(value, unit) {
|
|
1344
|
-
return new _TimeDuration(value, unit);
|
|
1345
|
-
}
|
|
1346
|
-
addDuration(duration) {
|
|
1347
|
-
return this.addUnits(duration.ms, TimeUnit.MILLISECONDS);
|
|
1348
|
-
}
|
|
1349
|
-
removeDuration(duration) {
|
|
1350
|
-
return this.removeUnits(duration.ms, TimeUnit.MILLISECONDS);
|
|
1351
|
-
}
|
|
1352
|
-
removeUnits(n, unit) {
|
|
1353
|
-
const nn = Math.min(n, this.getUnit(unit));
|
|
1354
|
-
return super.removeUnits(nn, unit);
|
|
1013
|
+
removeUnits(n, unit) {
|
|
1014
|
+
const nn = Math.min(n, this.getUnit(unit));
|
|
1015
|
+
return super.removeUnits(nn, unit);
|
|
1355
1016
|
}
|
|
1356
1017
|
/** @deprecated: Use multiplyBy instead **/
|
|
1357
1018
|
multiply(times) {
|
|
@@ -1997,6 +1658,10 @@ function isTimeInstant(x) {
|
|
|
1997
1658
|
}
|
|
1998
1659
|
var TimeInstant_default = TimeInstant;
|
|
1999
1660
|
|
|
1661
|
+
// src/utils/noop.ts
|
|
1662
|
+
function noop() {
|
|
1663
|
+
}
|
|
1664
|
+
|
|
2000
1665
|
// src/Logger.ts
|
|
2001
1666
|
var LEVELS = ["log", "debug", "info", "warn", "error"];
|
|
2002
1667
|
var timestamp = () => TimeInstant_default.now().asTimeString();
|
|
@@ -2148,6 +1813,96 @@ var ErrorCannotInstantiatePresentOptionalWithEmptyValue = class extends Error {
|
|
|
2148
1813
|
}
|
|
2149
1814
|
};
|
|
2150
1815
|
|
|
1816
|
+
// src/async/RateThrottler.ts
|
|
1817
|
+
var RateThrottler = class {
|
|
1818
|
+
constructor(_frequency) {
|
|
1819
|
+
this._frequency = _frequency;
|
|
1820
|
+
const initialOffset = this.cooldown.divideBy(_frequency.times);
|
|
1821
|
+
this._availableSlots = new Array(_frequency.times).fill(0).map((_, i) => TimeInstant.now().addMs(i * initialOffset.ms));
|
|
1822
|
+
this._waitingRequests = [];
|
|
1823
|
+
}
|
|
1824
|
+
_availableSlots;
|
|
1825
|
+
_waitingRequests;
|
|
1826
|
+
get cooldown() {
|
|
1827
|
+
return this._frequency.period;
|
|
1828
|
+
}
|
|
1829
|
+
async execute(fn) {
|
|
1830
|
+
const wrappedFn = async () => {
|
|
1831
|
+
const slot = this._availableSlots.shift();
|
|
1832
|
+
try {
|
|
1833
|
+
return slot.promise().then(() => fn());
|
|
1834
|
+
} finally {
|
|
1835
|
+
this._availableSlots.push(TimeInstant.now().addDuration(this.cooldown));
|
|
1836
|
+
if (this._waitingRequests.length > 0) this._waitingRequests.shift().resolve();
|
|
1837
|
+
}
|
|
1838
|
+
};
|
|
1839
|
+
if (this._availableSlots.length > 0) {
|
|
1840
|
+
return wrappedFn();
|
|
1841
|
+
} else {
|
|
1842
|
+
const waitingRequest = new Deferred_default();
|
|
1843
|
+
this._waitingRequests.push(waitingRequest);
|
|
1844
|
+
return waitingRequest.then(() => wrappedFn());
|
|
1845
|
+
}
|
|
1846
|
+
}
|
|
1847
|
+
};
|
|
1848
|
+
|
|
1849
|
+
// src/async/Semaphore.ts
|
|
1850
|
+
var Semaphore = class {
|
|
1851
|
+
constructor(_availableSlots = 1) {
|
|
1852
|
+
this._availableSlots = _availableSlots;
|
|
1853
|
+
this._queuedRequests = [];
|
|
1854
|
+
}
|
|
1855
|
+
_queuedRequests;
|
|
1856
|
+
_inProgress = 0;
|
|
1857
|
+
async _awaitSlot() {
|
|
1858
|
+
if (this._availableSlots > 0) {
|
|
1859
|
+
this._availableSlots -= 1;
|
|
1860
|
+
this._inProgress += 1;
|
|
1861
|
+
return void 0;
|
|
1862
|
+
} else {
|
|
1863
|
+
const deferred = new Deferred_default();
|
|
1864
|
+
this._queuedRequests.push(deferred);
|
|
1865
|
+
return deferred.asPromise();
|
|
1866
|
+
}
|
|
1867
|
+
}
|
|
1868
|
+
_releaseSlot() {
|
|
1869
|
+
const waitingSlotToResolve = this._queuedRequests.shift();
|
|
1870
|
+
if (waitingSlotToResolve) {
|
|
1871
|
+
waitingSlotToResolve.resolve();
|
|
1872
|
+
} else {
|
|
1873
|
+
this._availableSlots += 1;
|
|
1874
|
+
this._inProgress -= 1;
|
|
1875
|
+
}
|
|
1876
|
+
}
|
|
1877
|
+
async execute(fn, cooldown = TimeDuration.ZERO) {
|
|
1878
|
+
return this._awaitSlot().then(() => fn()).finally(() => {
|
|
1879
|
+
void cooldown.promise().then(() => this._releaseSlot());
|
|
1880
|
+
});
|
|
1881
|
+
}
|
|
1882
|
+
get availableSlots() {
|
|
1883
|
+
return this._availableSlots;
|
|
1884
|
+
}
|
|
1885
|
+
get queueSize() {
|
|
1886
|
+
return this._queuedRequests.length;
|
|
1887
|
+
}
|
|
1888
|
+
get inProgressSize() {
|
|
1889
|
+
return this._inProgress;
|
|
1890
|
+
}
|
|
1891
|
+
};
|
|
1892
|
+
|
|
1893
|
+
// src/utils/constant.ts
|
|
1894
|
+
function constant(v) {
|
|
1895
|
+
return () => v;
|
|
1896
|
+
}
|
|
1897
|
+
function identity(t) {
|
|
1898
|
+
return t;
|
|
1899
|
+
}
|
|
1900
|
+
var constantNull = constant(null);
|
|
1901
|
+
var constantTrue = constant(true);
|
|
1902
|
+
var constantFalse = constant(false);
|
|
1903
|
+
var constantZero = constant(0);
|
|
1904
|
+
var constantOne = constant(1);
|
|
1905
|
+
|
|
2151
1906
|
// src/sorting/ComparisonChain.ts
|
|
2152
1907
|
var defaultCompareValueOptions = {
|
|
2153
1908
|
nullsFirst: false,
|
|
@@ -2596,6 +2351,258 @@ var TimeRange = class _TimeRange {
|
|
|
2596
2351
|
}
|
|
2597
2352
|
};
|
|
2598
2353
|
|
|
2354
|
+
// src/utils/bindThis.ts
|
|
2355
|
+
function bindThis(fn, _this) {
|
|
2356
|
+
return fn.bind(_this);
|
|
2357
|
+
}
|
|
2358
|
+
|
|
2359
|
+
// src/utils/entries.ts
|
|
2360
|
+
function dictToEntries(obj) {
|
|
2361
|
+
return Object.entries(obj);
|
|
2362
|
+
}
|
|
2363
|
+
function entriesToDict(entries) {
|
|
2364
|
+
return Object.fromEntries(entries);
|
|
2365
|
+
}
|
|
2366
|
+
function mapEntries(dict, mapper) {
|
|
2367
|
+
return entriesToDict(dictToEntries(dict).map((entry) => mapper(entry)));
|
|
2368
|
+
}
|
|
2369
|
+
|
|
2370
|
+
// src/utils/groupBy.ts
|
|
2371
|
+
function groupByString(arr, field) {
|
|
2372
|
+
return groupByStringWith(arr, (t) => t[field]);
|
|
2373
|
+
}
|
|
2374
|
+
function groupByNumber(arr, field) {
|
|
2375
|
+
return groupByNumberWith(arr, (t) => t[field]);
|
|
2376
|
+
}
|
|
2377
|
+
function groupBySymbol(arr, field) {
|
|
2378
|
+
return groupBySymbolWith(arr, (t) => t[field]);
|
|
2379
|
+
}
|
|
2380
|
+
function groupByStringWith(arr, getter) {
|
|
2381
|
+
return doGroupByWith(arr, getter);
|
|
2382
|
+
}
|
|
2383
|
+
function groupByNumberWith(arr, getter) {
|
|
2384
|
+
return doGroupByWith(arr, getter);
|
|
2385
|
+
}
|
|
2386
|
+
function groupBySymbolWith(arr, getter) {
|
|
2387
|
+
return doGroupByWith(arr, getter);
|
|
2388
|
+
}
|
|
2389
|
+
function doGroupByWith(arr, getter) {
|
|
2390
|
+
return arr.reduce((dict, cur) => {
|
|
2391
|
+
const key = getter(cur);
|
|
2392
|
+
if (key !== null && key !== void 0) {
|
|
2393
|
+
const arr2 = dict[key] ?? [];
|
|
2394
|
+
arr2.push(cur);
|
|
2395
|
+
dict[key] = arr2;
|
|
2396
|
+
}
|
|
2397
|
+
return dict;
|
|
2398
|
+
}, {});
|
|
2399
|
+
}
|
|
2400
|
+
|
|
2401
|
+
// src/utils/iff.ts
|
|
2402
|
+
function iff(firstPredicate, valueIfTrue) {
|
|
2403
|
+
if (firstPredicate === true || firstPredicate instanceof Function && firstPredicate() === true) {
|
|
2404
|
+
const ret = {
|
|
2405
|
+
elseIf: () => ret,
|
|
2406
|
+
otherwise: () => valueIfTrue
|
|
2407
|
+
};
|
|
2408
|
+
return ret;
|
|
2409
|
+
} else {
|
|
2410
|
+
const ret = {
|
|
2411
|
+
elseIf: (elseIf, valueIfElseIfTrue) => iff(elseIf, valueIfElseIfTrue),
|
|
2412
|
+
otherwise: (valueIfElse) => valueIfElse
|
|
2413
|
+
};
|
|
2414
|
+
return ret;
|
|
2415
|
+
}
|
|
2416
|
+
}
|
|
2417
|
+
|
|
2418
|
+
// src/utils/indexBy.ts
|
|
2419
|
+
function indexByString(arr, field) {
|
|
2420
|
+
return indexByStringWith(arr, (t) => t[field]);
|
|
2421
|
+
}
|
|
2422
|
+
function indexByNumber(arr, field) {
|
|
2423
|
+
return indexByNumberWith(arr, (t) => t[field]);
|
|
2424
|
+
}
|
|
2425
|
+
function indexBySymbol(arr, field) {
|
|
2426
|
+
return indexBySymbolWith(arr, (t) => t[field]);
|
|
2427
|
+
}
|
|
2428
|
+
function indexByStringWith(arr, getter) {
|
|
2429
|
+
return doIndexByWith(arr, getter);
|
|
2430
|
+
}
|
|
2431
|
+
function indexByNumberWith(arr, getter) {
|
|
2432
|
+
return doIndexByWith(arr, getter);
|
|
2433
|
+
}
|
|
2434
|
+
function indexBySymbolWith(arr, getter) {
|
|
2435
|
+
return doIndexByWith(arr, getter);
|
|
2436
|
+
}
|
|
2437
|
+
function doIndexByWith(arr, getter) {
|
|
2438
|
+
return arr.reduce((dict, cur) => {
|
|
2439
|
+
const key = getter(cur);
|
|
2440
|
+
if (key !== null && key !== void 0)
|
|
2441
|
+
dict[key] = cur;
|
|
2442
|
+
return dict;
|
|
2443
|
+
}, {});
|
|
2444
|
+
}
|
|
2445
|
+
|
|
2446
|
+
// src/utils/jsonCloneDeep.ts
|
|
2447
|
+
function jsonCloneDeep(a) {
|
|
2448
|
+
if (null === a || "object" !== typeof a) return a;
|
|
2449
|
+
if (a instanceof Date) {
|
|
2450
|
+
return new Date(a.getTime());
|
|
2451
|
+
} else if (a instanceof Array) {
|
|
2452
|
+
const copy = [];
|
|
2453
|
+
for (let i = 0, len = a.length; i < len; i++) {
|
|
2454
|
+
copy[i] = jsonCloneDeep(a[i]);
|
|
2455
|
+
}
|
|
2456
|
+
return copy;
|
|
2457
|
+
} else if (a instanceof Object) {
|
|
2458
|
+
const copy = {};
|
|
2459
|
+
for (let attr in a) {
|
|
2460
|
+
if (a.hasOwnProperty(attr))
|
|
2461
|
+
copy[attr] = jsonCloneDeep(a[attr]);
|
|
2462
|
+
}
|
|
2463
|
+
return copy;
|
|
2464
|
+
}
|
|
2465
|
+
throw new Error("Unable to copy obj! Its type isn't supported.");
|
|
2466
|
+
}
|
|
2467
|
+
|
|
2468
|
+
// src/utils/math.ts
|
|
2469
|
+
function clamp(n, min2, max2) {
|
|
2470
|
+
if (min2 === null || max2 === null || n === null || isNaN(min2) || isNaN(max2) || isNaN(n) || min2 > max2)
|
|
2471
|
+
throw new Error();
|
|
2472
|
+
if (n > max2) {
|
|
2473
|
+
return max2;
|
|
2474
|
+
} else if (n < min2) {
|
|
2475
|
+
return min2;
|
|
2476
|
+
} else {
|
|
2477
|
+
return n;
|
|
2478
|
+
}
|
|
2479
|
+
}
|
|
2480
|
+
function average(arr) {
|
|
2481
|
+
const f = 1 / arr.length;
|
|
2482
|
+
return arr.reduce((tot, cur) => tot + cur * f, 0);
|
|
2483
|
+
}
|
|
2484
|
+
function sum(arr) {
|
|
2485
|
+
return arr.reduce((tot, cur) => tot + cur, 0);
|
|
2486
|
+
}
|
|
2487
|
+
function sumBy(arr, getter) {
|
|
2488
|
+
return sum(arr.map(getter));
|
|
2489
|
+
}
|
|
2490
|
+
function min(arr) {
|
|
2491
|
+
if (arr.length === 0) throw new Error("Cannot calculate value on empty array");
|
|
2492
|
+
return arr.reduce((min2, cur) => cur < min2 ? cur : min2);
|
|
2493
|
+
}
|
|
2494
|
+
function minBy(arr, getter) {
|
|
2495
|
+
return min(arr.map(getter));
|
|
2496
|
+
}
|
|
2497
|
+
function max(arr) {
|
|
2498
|
+
if (arr.length === 0) throw new Error("Cannot calculate value on empty array");
|
|
2499
|
+
return arr.reduce((max2, cur) => cur > max2 ? cur : max2);
|
|
2500
|
+
}
|
|
2501
|
+
function maxBy(arr, getter) {
|
|
2502
|
+
return max(arr.map(getter));
|
|
2503
|
+
}
|
|
2504
|
+
|
|
2505
|
+
// src/utils/omit.ts
|
|
2506
|
+
function omit(o, ...keys) {
|
|
2507
|
+
return keys.reduce((obj, key) => {
|
|
2508
|
+
delete obj[key];
|
|
2509
|
+
return obj;
|
|
2510
|
+
}, { ...o });
|
|
2511
|
+
}
|
|
2512
|
+
|
|
2513
|
+
// src/utils/round.ts
|
|
2514
|
+
var roundModes = {
|
|
2515
|
+
"toNearest": Math.round,
|
|
2516
|
+
"toLower": Math.floor,
|
|
2517
|
+
"toUpper": Math.ceil,
|
|
2518
|
+
"towardsZero": (n) => n > 0 ? Math.floor(n) : Math.ceil(n),
|
|
2519
|
+
"awayFromZero": (n) => n > 0 ? Math.ceil(n) : Math.floor(n)
|
|
2520
|
+
};
|
|
2521
|
+
function round(n, precision = 0, mode = "toNearest") {
|
|
2522
|
+
const base = 10;
|
|
2523
|
+
const power = Math.pow(base, precision);
|
|
2524
|
+
return roundModes[mode](n * power) / power;
|
|
2525
|
+
}
|
|
2526
|
+
var roundToNearest = (n, precision = 0) => round(n, precision, "toNearest");
|
|
2527
|
+
var roundToLower = (n, precision = 0) => round(n, precision, "toLower");
|
|
2528
|
+
var roundToUpper = (n, precision = 0) => round(n, precision, "toUpper");
|
|
2529
|
+
var roundTowardsZero = (n, precision = 0) => round(n, precision, "towardsZero");
|
|
2530
|
+
var roundAwayFromZero = (n, precision = 0) => round(n, precision, "awayFromZero");
|
|
2531
|
+
|
|
2532
|
+
// src/utils/sortBy.ts
|
|
2533
|
+
function sortBy(keyOrGetter, direction = "ASC", nulls = "LAST") {
|
|
2534
|
+
const directionNum = direction === "ASC" ? -1 : 1;
|
|
2535
|
+
const nullsNum = nulls === "LAST" ? -1 : 1;
|
|
2536
|
+
const sortByNum = (a, b) => {
|
|
2537
|
+
if (a === b)
|
|
2538
|
+
return -1;
|
|
2539
|
+
const aDefined = !(a === null || a === void 0 || isNaN(a));
|
|
2540
|
+
const bDefined = !(b === null || b === void 0 || isNaN(b));
|
|
2541
|
+
if (!aDefined && !bDefined)
|
|
2542
|
+
return -1;
|
|
2543
|
+
if (aDefined !== bDefined)
|
|
2544
|
+
return nullsNum * (aDefined ? 1 : -1);
|
|
2545
|
+
return (a > b ? -1 : 1) * directionNum;
|
|
2546
|
+
};
|
|
2547
|
+
if (typeof keyOrGetter === "function") {
|
|
2548
|
+
return (a, b) => sortByNum(keyOrGetter(a), keyOrGetter(b));
|
|
2549
|
+
} else {
|
|
2550
|
+
return (a, b) => sortByNum(a[keyOrGetter], b[keyOrGetter]);
|
|
2551
|
+
}
|
|
2552
|
+
}
|
|
2553
|
+
|
|
2554
|
+
// src/utils/throttle.ts
|
|
2555
|
+
function throttle(fn, frequence) {
|
|
2556
|
+
const semaphore = new RateThrottler(frequence);
|
|
2557
|
+
return (...t) => {
|
|
2558
|
+
return semaphore.execute(async () => fn(...t));
|
|
2559
|
+
};
|
|
2560
|
+
}
|
|
2561
|
+
|
|
2562
|
+
// src/utils/uniqBy.ts
|
|
2563
|
+
function uniqBy(arr, getter) {
|
|
2564
|
+
return arr.reduce((dict, cur) => {
|
|
2565
|
+
const key = getter(cur);
|
|
2566
|
+
if (dict.keys.includes(key)) {
|
|
2567
|
+
return dict;
|
|
2568
|
+
} else {
|
|
2569
|
+
return {
|
|
2570
|
+
keys: [...dict.keys, key],
|
|
2571
|
+
values: [...dict.values, cur]
|
|
2572
|
+
};
|
|
2573
|
+
}
|
|
2574
|
+
}, { keys: [], values: [] }).values;
|
|
2575
|
+
}
|
|
2576
|
+
|
|
2577
|
+
// src/utils/uniq.ts
|
|
2578
|
+
function uniq(arr) {
|
|
2579
|
+
return uniqBy(arr, identity);
|
|
2580
|
+
}
|
|
2581
|
+
|
|
2582
|
+
// src/utils/uniqByKey.ts
|
|
2583
|
+
function uniqByKey(arr, key) {
|
|
2584
|
+
return uniqBy(arr, (item) => item[key]);
|
|
2585
|
+
}
|
|
2586
|
+
|
|
2587
|
+
// src/utils/withTryCatch.ts
|
|
2588
|
+
function withTryCatch(fn) {
|
|
2589
|
+
try {
|
|
2590
|
+
return fn();
|
|
2591
|
+
} catch (e) {
|
|
2592
|
+
return asError(e);
|
|
2593
|
+
}
|
|
2594
|
+
}
|
|
2595
|
+
|
|
2596
|
+
// src/utils/withTryCatchAsync.ts
|
|
2597
|
+
async function withTryCatchAsync(fn) {
|
|
2598
|
+
return fn().catch((e) => asError(e));
|
|
2599
|
+
}
|
|
2600
|
+
|
|
2601
|
+
// src/utils/wrap.ts
|
|
2602
|
+
function wrap(str, delimiter) {
|
|
2603
|
+
return delimiter + str + delimiter;
|
|
2604
|
+
}
|
|
2605
|
+
|
|
2599
2606
|
// src/upgrade/errors.ts
|
|
2600
2607
|
var UnavailableUpgradeError = class extends Error {
|
|
2601
2608
|
constructor(data, from, to) {
|
|
@@ -2766,6 +2773,7 @@ function isUpgradable(obj) {
|
|
|
2766
2773
|
dictToEntries,
|
|
2767
2774
|
dictToList,
|
|
2768
2775
|
divideBy,
|
|
2776
|
+
ellipsis,
|
|
2769
2777
|
ensureArray,
|
|
2770
2778
|
ensureDefined,
|
|
2771
2779
|
ensureNegativeNumber,
|
|
@@ -2777,6 +2785,7 @@ function isUpgradable(obj) {
|
|
|
2777
2785
|
extendArray,
|
|
2778
2786
|
extendArrayWith,
|
|
2779
2787
|
fill,
|
|
2788
|
+
flatMapTruthys,
|
|
2780
2789
|
groupByNumber,
|
|
2781
2790
|
groupByNumberWith,
|
|
2782
2791
|
groupByString,
|
|
@@ -2816,6 +2825,7 @@ function isUpgradable(obj) {
|
|
|
2816
2825
|
last,
|
|
2817
2826
|
mapDefined,
|
|
2818
2827
|
mapEntries,
|
|
2828
|
+
mapTruthys,
|
|
2819
2829
|
max,
|
|
2820
2830
|
maxBy,
|
|
2821
2831
|
min,
|
|
@@ -2824,8 +2834,9 @@ function isUpgradable(obj) {
|
|
|
2824
2834
|
noop,
|
|
2825
2835
|
omit,
|
|
2826
2836
|
pad,
|
|
2837
|
+
padLeft,
|
|
2838
|
+
padRight,
|
|
2827
2839
|
pick,
|
|
2828
|
-
pluralize,
|
|
2829
2840
|
promiseSequence,
|
|
2830
2841
|
randomInterval,
|
|
2831
2842
|
randomPercentage,
|