@zelgadis87/utils-core 5.4.0 → 5.4.2
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/.rollup/index.cjs +195 -127
- package/.rollup/index.cjs.map +1 -1
- package/.rollup/index.d.ts +88 -7
- package/.rollup/index.mjs +195 -128
- package/.rollup/index.mjs.map +1 -1
- package/.rollup/tsconfig.tsbuildinfo +1 -1
- package/CHANGELOG.md +13 -0
- package/package.json +1 -1
- package/src/Optional.ts +25 -2
- package/src/utils/arrays.ts +4 -4
- package/src/utils/operations.ts +92 -4
package/.rollup/index.cjs
CHANGED
|
@@ -778,9 +778,9 @@ function filterMapReduce(array, filterFn, mapFn, reduceFn, initialValue) {
|
|
|
778
778
|
* @returns a tuple, where the first array contains items matching the predicate, and the second array contains items not matching the predicate.
|
|
779
779
|
*/
|
|
780
780
|
function partition(arr, predicate) {
|
|
781
|
-
return arr.reduce((
|
|
782
|
-
|
|
783
|
-
return
|
|
781
|
+
return [...arr].reduce((acc, item) => {
|
|
782
|
+
acc[(predicate(item) ? 0 : 1)].push(item);
|
|
783
|
+
return acc;
|
|
784
784
|
}, [[], []]);
|
|
785
785
|
}
|
|
786
786
|
/**
|
|
@@ -1103,130 +1103,6 @@ function tryToParseNumber(numberStr) {
|
|
|
1103
1103
|
});
|
|
1104
1104
|
}
|
|
1105
1105
|
|
|
1106
|
-
const Operation = {
|
|
1107
|
-
ok: (data) => {
|
|
1108
|
-
return { success: true, data };
|
|
1109
|
-
},
|
|
1110
|
-
ko: (error) => {
|
|
1111
|
-
return { success: false, error };
|
|
1112
|
-
},
|
|
1113
|
-
};
|
|
1114
|
-
|
|
1115
|
-
function asPromise(promisable) {
|
|
1116
|
-
return Promise.resolve(promisable);
|
|
1117
|
-
}
|
|
1118
|
-
function promiseSequence(...fns) {
|
|
1119
|
-
const fn = async function () {
|
|
1120
|
-
const results = [];
|
|
1121
|
-
for (let i = 0; i < fns.length; i++) {
|
|
1122
|
-
results[i] = await fns[i]();
|
|
1123
|
-
}
|
|
1124
|
-
return results;
|
|
1125
|
-
};
|
|
1126
|
-
return fn;
|
|
1127
|
-
}
|
|
1128
|
-
function delayPromise(duration) {
|
|
1129
|
-
return (result) => duration.promise().then(() => result);
|
|
1130
|
-
}
|
|
1131
|
-
class TimeoutError extends Error {
|
|
1132
|
-
}
|
|
1133
|
-
async function awaitAtMost(promise, duration) {
|
|
1134
|
-
return Promise.race([
|
|
1135
|
-
promise.then(value => ({ status: 'ok', value })),
|
|
1136
|
-
duration.promise().then(() => ({ status: 'timeout' }))
|
|
1137
|
-
]).then(({ status, value }) => {
|
|
1138
|
-
if (status === 'ok')
|
|
1139
|
-
return value;
|
|
1140
|
-
throw new TimeoutError("Time out reached while waiting for a promise to resolve.");
|
|
1141
|
-
});
|
|
1142
|
-
}
|
|
1143
|
-
const NEVER = new Promise(_resolve => { });
|
|
1144
|
-
|
|
1145
|
-
/**
|
|
1146
|
-
* Returns a random integer in the range [min, max].
|
|
1147
|
-
* @deprecated Use randomIntegerInInterval or randomDecimalInInterval instead
|
|
1148
|
-
*/
|
|
1149
|
-
function randomNumberInInterval(min, max) {
|
|
1150
|
-
return Math.floor(Math.random() * (max - min + 1) + min);
|
|
1151
|
-
}
|
|
1152
|
-
/**
|
|
1153
|
-
* Returns a random integer in the range [min, max].
|
|
1154
|
-
* @param min - Minimum value (inclusive)
|
|
1155
|
-
* @param max - Maximum value (inclusive)
|
|
1156
|
-
* @returns A random integer between min and max
|
|
1157
|
-
*/
|
|
1158
|
-
function randomIntegerInInterval(min, max) {
|
|
1159
|
-
return Math.floor(Math.random() * (max - min + 1) + min);
|
|
1160
|
-
}
|
|
1161
|
-
/**
|
|
1162
|
-
* Returns a random decimal in the range [min, max).
|
|
1163
|
-
* @param min - Minimum value (inclusive)
|
|
1164
|
-
* @param max - Maximum value (exclusive)
|
|
1165
|
-
* @returns A random decimal between min and max
|
|
1166
|
-
*/
|
|
1167
|
-
function randomDecimalInInterval(min, max) {
|
|
1168
|
-
return Math.random() * (max - min) + min;
|
|
1169
|
-
}
|
|
1170
|
-
const randomId = (length) => {
|
|
1171
|
-
const characters = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
|
1172
|
-
let result = '';
|
|
1173
|
-
for (let i = 0; i < length; i++) {
|
|
1174
|
-
result += characters.charAt(randomIntegerInInterval(0, characters.length - 1));
|
|
1175
|
-
}
|
|
1176
|
-
return result;
|
|
1177
|
-
};
|
|
1178
|
-
function randomPick(arr) {
|
|
1179
|
-
return first$1(randomPicks(arr, 1));
|
|
1180
|
-
}
|
|
1181
|
-
function randomPicks(arr, count) {
|
|
1182
|
-
const available = [...arr];
|
|
1183
|
-
const result = [];
|
|
1184
|
-
while (available.length > 0 && count > 0) {
|
|
1185
|
-
const randomIndex = randomIntegerInInterval(0, available.length - 1);
|
|
1186
|
-
result.push(available[randomIndex]);
|
|
1187
|
-
available.splice(randomIndex, 1);
|
|
1188
|
-
count--;
|
|
1189
|
-
}
|
|
1190
|
-
return result;
|
|
1191
|
-
}
|
|
1192
|
-
|
|
1193
|
-
function dictToEntries(obj) {
|
|
1194
|
-
return Object.entries(obj);
|
|
1195
|
-
}
|
|
1196
|
-
function entriesToDict(entries) {
|
|
1197
|
-
return Object.fromEntries(entries);
|
|
1198
|
-
}
|
|
1199
|
-
function entriesToEntries(dict, mapper) {
|
|
1200
|
-
return entriesToDict(dictToEntries(dict).map((entry) => mapper(entry)));
|
|
1201
|
-
}
|
|
1202
|
-
/** @deprecated[2025.08.01]: Compatibility layer. */
|
|
1203
|
-
const mapEntries = entriesToEntries;
|
|
1204
|
-
function entriesToList(dict, mapper) {
|
|
1205
|
-
return dictToEntries(dict).map((entry) => mapper(entry));
|
|
1206
|
-
}
|
|
1207
|
-
|
|
1208
|
-
function dictToList(obj) {
|
|
1209
|
-
return Object.keys(obj).map(key => obj[key]);
|
|
1210
|
-
}
|
|
1211
|
-
function pick(o, keys) {
|
|
1212
|
-
return keys.reduce((obj, key) => {
|
|
1213
|
-
obj[key] = o[key];
|
|
1214
|
-
return obj;
|
|
1215
|
-
}, {});
|
|
1216
|
-
}
|
|
1217
|
-
function shallowRecordEquals(a, b) {
|
|
1218
|
-
if (a === b)
|
|
1219
|
-
return true;
|
|
1220
|
-
const aKeys = Object.keys(a), bKeys = Object.keys(b);
|
|
1221
|
-
if (aKeys.length !== bKeys.length)
|
|
1222
|
-
return false;
|
|
1223
|
-
for (const key of aKeys) {
|
|
1224
|
-
if (a[key] !== b[key])
|
|
1225
|
-
return false;
|
|
1226
|
-
}
|
|
1227
|
-
return true;
|
|
1228
|
-
}
|
|
1229
|
-
|
|
1230
1106
|
class StringParts {
|
|
1231
1107
|
_parts;
|
|
1232
1108
|
constructor(...parts) {
|
|
@@ -1399,6 +1275,197 @@ function wrapWithString(str, start, end = start) {
|
|
|
1399
1275
|
return start + str + end;
|
|
1400
1276
|
}
|
|
1401
1277
|
|
|
1278
|
+
/**
|
|
1279
|
+
* An error class that aggregates multiple errors from a combined operation.
|
|
1280
|
+
* Used by `Operation.combine` to represent failures from multiple operations.
|
|
1281
|
+
*
|
|
1282
|
+
* @template E - The type of individual errors (defaults to Error, but can be any type)
|
|
1283
|
+
*/
|
|
1284
|
+
class OperationAggregateError extends Error {
|
|
1285
|
+
errors;
|
|
1286
|
+
constructor(errors) {
|
|
1287
|
+
super(`Operation failed with ${pluralize(errors.length, 'error')}`);
|
|
1288
|
+
this.errors = errors;
|
|
1289
|
+
this.name = 'OperationAggregateError';
|
|
1290
|
+
}
|
|
1291
|
+
/**
|
|
1292
|
+
* Returns the number of aggregated errors.
|
|
1293
|
+
*/
|
|
1294
|
+
get count() {
|
|
1295
|
+
return this.errors.length;
|
|
1296
|
+
}
|
|
1297
|
+
}
|
|
1298
|
+
const Operation = {
|
|
1299
|
+
ok: (data) => {
|
|
1300
|
+
return { success: true, data };
|
|
1301
|
+
},
|
|
1302
|
+
ko: (error) => {
|
|
1303
|
+
return { success: false, error };
|
|
1304
|
+
},
|
|
1305
|
+
/**
|
|
1306
|
+
* Type predicate that returns true if the operation is a success.
|
|
1307
|
+
* Useful for type narrowing in conditional blocks.
|
|
1308
|
+
*
|
|
1309
|
+
* @template T - The success data type
|
|
1310
|
+
* @param result - The operation result to check
|
|
1311
|
+
* @returns true if the operation succeeded, false otherwise
|
|
1312
|
+
*/
|
|
1313
|
+
isSuccess(result) {
|
|
1314
|
+
return result.success === true;
|
|
1315
|
+
},
|
|
1316
|
+
/**
|
|
1317
|
+
* Type predicate that returns true if the operation is a failure.
|
|
1318
|
+
* Useful for type narrowing in conditional blocks.
|
|
1319
|
+
*
|
|
1320
|
+
* @template E - The error type
|
|
1321
|
+
* @param result - The operation result to check
|
|
1322
|
+
* @returns true if the operation failed, false otherwise
|
|
1323
|
+
*/
|
|
1324
|
+
isFailure(result) {
|
|
1325
|
+
return result.success === false;
|
|
1326
|
+
},
|
|
1327
|
+
/**
|
|
1328
|
+
* Partitions an array of operations into successes and failures.
|
|
1329
|
+
*
|
|
1330
|
+
* @template T - The success data type of individual operations
|
|
1331
|
+
* @template E - The error type of individual operations (defaults to Error)
|
|
1332
|
+
* @param results - Array of operation results to partition
|
|
1333
|
+
* @returns A tuple of [successes, failures]
|
|
1334
|
+
*/
|
|
1335
|
+
partition: (results) => {
|
|
1336
|
+
return partition(results, r => r.success);
|
|
1337
|
+
},
|
|
1338
|
+
/**
|
|
1339
|
+
* Combines multiple operation results into a single result.
|
|
1340
|
+
* - If all operations succeed, returns success with an array of all data values.
|
|
1341
|
+
* - If any operation fails, returns failure with an `OperationAggregateError` containing all errors.
|
|
1342
|
+
*
|
|
1343
|
+
* @template T - The success data type of individual operations
|
|
1344
|
+
* @template E - The error type of individual operations (defaults to Error)
|
|
1345
|
+
* @param results - Array of operation results to combine
|
|
1346
|
+
* @returns A single operation with either all data or all aggregated errors
|
|
1347
|
+
*/
|
|
1348
|
+
combine: (results) => {
|
|
1349
|
+
const [successes, failures] = Operation.partition(results);
|
|
1350
|
+
return failures.length === 0 ? Operation.ok(successes.map(r => r.data)) : Operation.ko(new OperationAggregateError(failures.map(r => r.error)));
|
|
1351
|
+
},
|
|
1352
|
+
};
|
|
1353
|
+
|
|
1354
|
+
function asPromise(promisable) {
|
|
1355
|
+
return Promise.resolve(promisable);
|
|
1356
|
+
}
|
|
1357
|
+
function promiseSequence(...fns) {
|
|
1358
|
+
const fn = async function () {
|
|
1359
|
+
const results = [];
|
|
1360
|
+
for (let i = 0; i < fns.length; i++) {
|
|
1361
|
+
results[i] = await fns[i]();
|
|
1362
|
+
}
|
|
1363
|
+
return results;
|
|
1364
|
+
};
|
|
1365
|
+
return fn;
|
|
1366
|
+
}
|
|
1367
|
+
function delayPromise(duration) {
|
|
1368
|
+
return (result) => duration.promise().then(() => result);
|
|
1369
|
+
}
|
|
1370
|
+
class TimeoutError extends Error {
|
|
1371
|
+
}
|
|
1372
|
+
async function awaitAtMost(promise, duration) {
|
|
1373
|
+
return Promise.race([
|
|
1374
|
+
promise.then(value => ({ status: 'ok', value })),
|
|
1375
|
+
duration.promise().then(() => ({ status: 'timeout' }))
|
|
1376
|
+
]).then(({ status, value }) => {
|
|
1377
|
+
if (status === 'ok')
|
|
1378
|
+
return value;
|
|
1379
|
+
throw new TimeoutError("Time out reached while waiting for a promise to resolve.");
|
|
1380
|
+
});
|
|
1381
|
+
}
|
|
1382
|
+
const NEVER = new Promise(_resolve => { });
|
|
1383
|
+
|
|
1384
|
+
/**
|
|
1385
|
+
* Returns a random integer in the range [min, max].
|
|
1386
|
+
* @deprecated Use randomIntegerInInterval or randomDecimalInInterval instead
|
|
1387
|
+
*/
|
|
1388
|
+
function randomNumberInInterval(min, max) {
|
|
1389
|
+
return Math.floor(Math.random() * (max - min + 1) + min);
|
|
1390
|
+
}
|
|
1391
|
+
/**
|
|
1392
|
+
* Returns a random integer in the range [min, max].
|
|
1393
|
+
* @param min - Minimum value (inclusive)
|
|
1394
|
+
* @param max - Maximum value (inclusive)
|
|
1395
|
+
* @returns A random integer between min and max
|
|
1396
|
+
*/
|
|
1397
|
+
function randomIntegerInInterval(min, max) {
|
|
1398
|
+
return Math.floor(Math.random() * (max - min + 1) + min);
|
|
1399
|
+
}
|
|
1400
|
+
/**
|
|
1401
|
+
* Returns a random decimal in the range [min, max).
|
|
1402
|
+
* @param min - Minimum value (inclusive)
|
|
1403
|
+
* @param max - Maximum value (exclusive)
|
|
1404
|
+
* @returns A random decimal between min and max
|
|
1405
|
+
*/
|
|
1406
|
+
function randomDecimalInInterval(min, max) {
|
|
1407
|
+
return Math.random() * (max - min) + min;
|
|
1408
|
+
}
|
|
1409
|
+
const randomId = (length) => {
|
|
1410
|
+
const characters = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
|
1411
|
+
let result = '';
|
|
1412
|
+
for (let i = 0; i < length; i++) {
|
|
1413
|
+
result += characters.charAt(randomIntegerInInterval(0, characters.length - 1));
|
|
1414
|
+
}
|
|
1415
|
+
return result;
|
|
1416
|
+
};
|
|
1417
|
+
function randomPick(arr) {
|
|
1418
|
+
return first$1(randomPicks(arr, 1));
|
|
1419
|
+
}
|
|
1420
|
+
function randomPicks(arr, count) {
|
|
1421
|
+
const available = [...arr];
|
|
1422
|
+
const result = [];
|
|
1423
|
+
while (available.length > 0 && count > 0) {
|
|
1424
|
+
const randomIndex = randomIntegerInInterval(0, available.length - 1);
|
|
1425
|
+
result.push(available[randomIndex]);
|
|
1426
|
+
available.splice(randomIndex, 1);
|
|
1427
|
+
count--;
|
|
1428
|
+
}
|
|
1429
|
+
return result;
|
|
1430
|
+
}
|
|
1431
|
+
|
|
1432
|
+
function dictToEntries(obj) {
|
|
1433
|
+
return Object.entries(obj);
|
|
1434
|
+
}
|
|
1435
|
+
function entriesToDict(entries) {
|
|
1436
|
+
return Object.fromEntries(entries);
|
|
1437
|
+
}
|
|
1438
|
+
function entriesToEntries(dict, mapper) {
|
|
1439
|
+
return entriesToDict(dictToEntries(dict).map((entry) => mapper(entry)));
|
|
1440
|
+
}
|
|
1441
|
+
/** @deprecated[2025.08.01]: Compatibility layer. */
|
|
1442
|
+
const mapEntries = entriesToEntries;
|
|
1443
|
+
function entriesToList(dict, mapper) {
|
|
1444
|
+
return dictToEntries(dict).map((entry) => mapper(entry));
|
|
1445
|
+
}
|
|
1446
|
+
|
|
1447
|
+
function dictToList(obj) {
|
|
1448
|
+
return Object.keys(obj).map(key => obj[key]);
|
|
1449
|
+
}
|
|
1450
|
+
function pick(o, keys) {
|
|
1451
|
+
return keys.reduce((obj, key) => {
|
|
1452
|
+
obj[key] = o[key];
|
|
1453
|
+
return obj;
|
|
1454
|
+
}, {});
|
|
1455
|
+
}
|
|
1456
|
+
function shallowRecordEquals(a, b) {
|
|
1457
|
+
if (a === b)
|
|
1458
|
+
return true;
|
|
1459
|
+
const aKeys = Object.keys(a), bKeys = Object.keys(b);
|
|
1460
|
+
if (aKeys.length !== bKeys.length)
|
|
1461
|
+
return false;
|
|
1462
|
+
for (const key of aKeys) {
|
|
1463
|
+
if (a[key] !== b[key])
|
|
1464
|
+
return false;
|
|
1465
|
+
}
|
|
1466
|
+
return true;
|
|
1467
|
+
}
|
|
1468
|
+
|
|
1402
1469
|
/**
|
|
1403
1470
|
* Class that stores a value that is computationally/memory intensive to initialize.
|
|
1404
1471
|
* The initialization of the value is done once and only if required (lazy initialization).
|
|
@@ -3685,6 +3752,7 @@ exports.Logger = Logger;
|
|
|
3685
3752
|
exports.NEVER = NEVER;
|
|
3686
3753
|
exports.NonExhaustiveSwitchError = NonExhaustiveSwitchError;
|
|
3687
3754
|
exports.Operation = Operation;
|
|
3755
|
+
exports.OperationAggregateError = OperationAggregateError;
|
|
3688
3756
|
exports.Optional = Optional;
|
|
3689
3757
|
exports.PredicateBuilder = PredicateBuilder;
|
|
3690
3758
|
exports.RandomTimeDuration = RandomTimeDuration;
|