@valkyriestudios/utils 12.12.0 → 12.14.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/README.md +4 -0
- package/array/join.js +6 -18
- package/array/sort.d.ts +12 -5
- package/array/sort.js +52 -49
- package/date/format.js +5 -1
- package/index.d.ts +7 -7
- package/package.json +1 -1
- package/string/humanizeNumber.js +9 -6
package/README.md
CHANGED
|
@@ -404,6 +404,10 @@ Available tokens for usage in spec:
|
|
|
404
404
|
| `SSS` | Milliseconds as 3-digit | 000 001 ... 998 999 |
|
|
405
405
|
| `A` | Uppercase AM/PM | AM ... PM |
|
|
406
406
|
| `a` | Lowercase AM/PM | am ... pm |
|
|
407
|
+
| `l` | Locale-specific short Date | 15/07/2024 |
|
|
408
|
+
| `L` | Locale-Specific date | 15 jul 2024 |
|
|
409
|
+
| `t` | Locale-specific short time | 10:28 AM |
|
|
410
|
+
| `T` | Locale-specific time with seconds | 10:28:30 AM |
|
|
407
411
|
|
|
408
412
|
```typescript
|
|
409
413
|
format(new Date('2023-01-10T14:30:00Z'), '[Today is] dddd, MMMM D, YYYY [at] h:mm A', 'en', 'Europe/Brussels');
|
package/array/join.js
CHANGED
|
@@ -3,27 +3,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.join = join;
|
|
4
4
|
exports.default = join;
|
|
5
5
|
const round_1 = require("../number/round");
|
|
6
|
-
const
|
|
6
|
+
const isIntegerAboveOrEqual_1 = require("../number/isIntegerAboveOrEqual");
|
|
7
7
|
function join(val, opts) {
|
|
8
8
|
if (!Array.isArray(val) || !val.length)
|
|
9
9
|
return '';
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
if (opts && Object.prototype.toString.call(opts) === '[object Object]') {
|
|
16
|
-
if (typeof opts.delim === 'string')
|
|
17
|
-
DELIM = opts.delim;
|
|
18
|
-
if (opts.trim === false)
|
|
19
|
-
TRIM = opts.trim;
|
|
20
|
-
if (opts.valtrim === false)
|
|
21
|
-
VALTRIM = false;
|
|
22
|
-
if (opts.innertrim === true)
|
|
23
|
-
INNERTRIM = true;
|
|
24
|
-
if ((0, isInteger_1.isInteger)(opts.valround) && opts.valround >= 0)
|
|
25
|
-
VALROUND = opts.valround;
|
|
26
|
-
}
|
|
10
|
+
const DELIM = typeof opts?.delim === 'string' ? opts.delim : ' ';
|
|
11
|
+
const TRIM = opts?.trim ?? true;
|
|
12
|
+
const VALTRIM = opts?.valtrim ?? true;
|
|
13
|
+
const INNERTRIM = opts?.innertrim ?? false;
|
|
14
|
+
const VALROUND = (0, isIntegerAboveOrEqual_1.isIntegerAboveOrEqual)(opts?.valround, 0) ? opts.valround : false;
|
|
27
15
|
let result = '';
|
|
28
16
|
for (let i = 0; i < val.length; i++) {
|
|
29
17
|
const el = val[i];
|
package/array/sort.d.ts
CHANGED
|
@@ -17,7 +17,14 @@ interface sortOptions {
|
|
|
17
17
|
}
|
|
18
18
|
type sortByFunction = (el: Record<string, any>) => string;
|
|
19
19
|
/**
|
|
20
|
-
* Sort an array of objects
|
|
20
|
+
* Sort an array of objects.
|
|
21
|
+
*
|
|
22
|
+
* The internals of this function swap between insertion and quicksort depending on the use-case.
|
|
23
|
+
* Insertion sort is used for smaller arrays and quicksort is used for larger arrays.
|
|
24
|
+
*
|
|
25
|
+
* The threshold for insertion sort is 10 elements.
|
|
26
|
+
*
|
|
27
|
+
* The quicksort implementation is based on Tony Hoare's quicksort
|
|
21
28
|
* (https://cs.stanford.edu/people/eroberts/courses/soco/projects/2008-09/tony-hoare/quicksort.html)
|
|
22
29
|
*
|
|
23
30
|
* Example:
|
|
@@ -43,10 +50,10 @@ type sortByFunction = (el: Record<string, any>) => string;
|
|
|
43
50
|
* Output:
|
|
44
51
|
* [{test: 'Pony'}, {test: 'Peter'}, {test: 'JOHn'}, {test: 'Joe'}]
|
|
45
52
|
*
|
|
46
|
-
* @param val - Array to sort
|
|
47
|
-
* @param by - Either a string (key) or a function
|
|
48
|
-
* @param dir - (default='asc') Direction to sort in (asc or desc)
|
|
49
|
-
* @param opts - Sort options
|
|
53
|
+
* @param {Array} val - Array to sort
|
|
54
|
+
* @param {string|sortByFunction} by - Either a string (key) or a function
|
|
55
|
+
* @param {'desc'|'asc'} dir - (default='asc') Direction to sort in (asc or desc)
|
|
56
|
+
* @param {sortOptions} opts - Sort options
|
|
50
57
|
*
|
|
51
58
|
* @returns Sorted array
|
|
52
59
|
* @throws {Error}
|
package/array/sort.js
CHANGED
|
@@ -3,50 +3,60 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.sort = sort;
|
|
4
4
|
exports.default = sort;
|
|
5
5
|
const isNotEmpty_1 = require("../object/isNotEmpty");
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
const INSERTION_SORT_THRESHOLD = 10;
|
|
7
|
+
function partition(arr, low, high) {
|
|
8
|
+
const pivot = arr[Math.floor((low + high) / 2)][0];
|
|
9
|
+
let i = low;
|
|
10
|
+
let j = high;
|
|
11
|
+
while (i <= j) {
|
|
12
|
+
while (arr[i][0] < pivot) {
|
|
13
|
+
i++;
|
|
11
14
|
}
|
|
12
|
-
while (arr[
|
|
13
|
-
|
|
15
|
+
while (arr[j][0] > pivot) {
|
|
16
|
+
j--;
|
|
14
17
|
}
|
|
15
|
-
if (
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
start_ix++;
|
|
20
|
-
end_ix--;
|
|
18
|
+
if (i <= j) {
|
|
19
|
+
[arr[i], arr[j]] = [arr[j], arr[i]];
|
|
20
|
+
i++;
|
|
21
|
+
j--;
|
|
21
22
|
}
|
|
22
23
|
}
|
|
23
|
-
return
|
|
24
|
+
return i;
|
|
24
25
|
}
|
|
25
|
-
function quickSort(arr
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
function quickSort(arr) {
|
|
27
|
+
const stack = [{ low: 0, high: arr.length - 1 }];
|
|
28
|
+
while (stack.length) {
|
|
29
|
+
const { low, high } = stack.pop();
|
|
30
|
+
if (high - low <= INSERTION_SORT_THRESHOLD) {
|
|
31
|
+
for (let i = low + 1; i <= high; i++) {
|
|
32
|
+
const key = arr[i];
|
|
33
|
+
let j = i - 1;
|
|
34
|
+
while (j >= low && arr[j][0] > key[0]) {
|
|
35
|
+
arr[j + 1] = arr[j];
|
|
36
|
+
j--;
|
|
37
|
+
}
|
|
38
|
+
arr[j + 1] = key;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
const p = partition(arr, low, high);
|
|
43
|
+
if (p - 1 > low)
|
|
44
|
+
stack.push({ low, high: p - 1 });
|
|
45
|
+
if (p < high)
|
|
46
|
+
stack.push({ low: p, high });
|
|
47
|
+
}
|
|
30
48
|
}
|
|
31
49
|
return arr;
|
|
32
50
|
}
|
|
33
51
|
function sort(arr, by, dir = 'asc', opts) {
|
|
34
52
|
if (!Array.isArray(arr) || !arr.length)
|
|
35
53
|
return [];
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
let NOKEY_HIDE = false;
|
|
39
|
-
let NOKEY_AT_END = true;
|
|
54
|
+
const NOKEY_HIDE = opts?.nokey_hide === true;
|
|
55
|
+
const NOKEY_AT_END = opts?.nokey_atend !== false;
|
|
40
56
|
let FILTER_FN = isNotEmpty_1.isNotEmptyObject;
|
|
41
|
-
if (
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
if (opts.nokey_atend === false)
|
|
45
|
-
NOKEY_AT_END = false;
|
|
46
|
-
if (typeof opts.filter_fn === 'function') {
|
|
47
|
-
const fn = opts.filter_fn;
|
|
48
|
-
FILTER_FN = (el => (0, isNotEmpty_1.isNotEmptyObject)(el) && fn(el));
|
|
49
|
-
}
|
|
57
|
+
if (typeof opts?.filter_fn === 'function') {
|
|
58
|
+
const fn = opts.filter_fn;
|
|
59
|
+
FILTER_FN = (el => (0, isNotEmpty_1.isNotEmptyObject)(el) && fn(el));
|
|
50
60
|
}
|
|
51
61
|
const prepared_arr = [];
|
|
52
62
|
const nokey_arr = [];
|
|
@@ -54,30 +64,27 @@ function sort(arr, by, dir = 'asc', opts) {
|
|
|
54
64
|
const by_s = by.trim();
|
|
55
65
|
if (!by_s.length)
|
|
56
66
|
throw new Error('Sort by as string should contain content');
|
|
57
|
-
for (
|
|
58
|
-
const el = arr[i];
|
|
67
|
+
for (const el of arr) {
|
|
59
68
|
if (!FILTER_FN(el))
|
|
60
69
|
continue;
|
|
61
70
|
if (el?.[by_s] === undefined) {
|
|
62
71
|
nokey_arr.push(el);
|
|
63
72
|
}
|
|
64
73
|
else {
|
|
65
|
-
prepared_arr.push(
|
|
74
|
+
prepared_arr.push([el[by_s], el]);
|
|
66
75
|
}
|
|
67
76
|
}
|
|
68
77
|
}
|
|
69
78
|
else if (typeof by === 'function') {
|
|
70
|
-
|
|
71
|
-
for (let i = 0; i < arr.length; i++) {
|
|
72
|
-
const el = arr[i];
|
|
79
|
+
for (const el of arr) {
|
|
73
80
|
if (!FILTER_FN(el))
|
|
74
81
|
continue;
|
|
75
|
-
key = by(el);
|
|
82
|
+
const key = by(el);
|
|
76
83
|
if (key === undefined) {
|
|
77
84
|
nokey_arr.push(el);
|
|
78
85
|
}
|
|
79
86
|
else {
|
|
80
|
-
prepared_arr.push(
|
|
87
|
+
prepared_arr.push([key, el]);
|
|
81
88
|
}
|
|
82
89
|
}
|
|
83
90
|
}
|
|
@@ -88,15 +95,11 @@ function sort(arr, by, dir = 'asc', opts) {
|
|
|
88
95
|
if (dir === 'desc')
|
|
89
96
|
prepared_arr.reverse();
|
|
90
97
|
const rslt = [];
|
|
91
|
-
if (!NOKEY_HIDE && !NOKEY_AT_END)
|
|
92
|
-
|
|
93
|
-
rslt.push(nokey_arr[i]);
|
|
94
|
-
}
|
|
98
|
+
if (!NOKEY_HIDE && !NOKEY_AT_END)
|
|
99
|
+
rslt.push(...nokey_arr);
|
|
95
100
|
for (let i = 0; i < prepared_arr.length; i++)
|
|
96
|
-
rslt.push(prepared_arr[i]
|
|
97
|
-
if (!NOKEY_HIDE && NOKEY_AT_END)
|
|
98
|
-
|
|
99
|
-
rslt.push(nokey_arr[i]);
|
|
100
|
-
}
|
|
101
|
+
rslt.push(prepared_arr[i][1]);
|
|
102
|
+
if (!NOKEY_HIDE && NOKEY_AT_END)
|
|
103
|
+
rslt.push(...nokey_arr);
|
|
101
104
|
return rslt;
|
|
102
105
|
}
|
package/date/format.js
CHANGED
|
@@ -36,7 +36,7 @@ function toZone(date, zone) {
|
|
|
36
36
|
throw new Error(`format: Invalid zone passed - ${zone}`);
|
|
37
37
|
const offset = zone_time - client_time;
|
|
38
38
|
zone_offset_cache.set(ckey, offset);
|
|
39
|
-
return new Date(
|
|
39
|
+
return new Date(client_time + offset);
|
|
40
40
|
}
|
|
41
41
|
function runIntl(loc, token, props, val) {
|
|
42
42
|
const hash = `${loc}:${token}`;
|
|
@@ -74,6 +74,10 @@ const Tokens = [
|
|
|
74
74
|
['SSS', d => `${d.getMilliseconds()}`.padStart(3, '0')],
|
|
75
75
|
['A', d => d.getHours() < 12 ? 'AM' : 'PM'],
|
|
76
76
|
['a', d => d.getHours() < 12 ? 'am' : 'pm'],
|
|
77
|
+
['l', (d, loc) => runIntl(loc, 'l', { dateStyle: 'short' }, d)],
|
|
78
|
+
['L', (d, loc) => runIntl(loc, 'L', { dateStyle: 'medium' }, d)],
|
|
79
|
+
['t', (d, loc) => runIntl(loc, 't', { timeStyle: 'short' }, d)],
|
|
80
|
+
['T', (d, loc) => runIntl(loc, 'T', { timeStyle: 'medium' }, d)],
|
|
77
81
|
]
|
|
78
82
|
.sort((a, b) => a[0].length > b[0].length ? -1 : 1)
|
|
79
83
|
.map((el) => [el[0], new RegExp(el[0], 'g'), el[1]]);
|
package/index.d.ts
CHANGED
|
@@ -26,9 +26,9 @@ declare module "number/round" {
|
|
|
26
26
|
function round(val: number, precision?: number): number;
|
|
27
27
|
export { round, round as default };
|
|
28
28
|
}
|
|
29
|
-
declare module "number/
|
|
30
|
-
function
|
|
31
|
-
export {
|
|
29
|
+
declare module "number/isIntegerAboveOrEqual" {
|
|
30
|
+
function isIntegerAboveOrEqual(val: unknown, ref: number): val is number;
|
|
31
|
+
export { isIntegerAboveOrEqual, isIntegerAboveOrEqual as default };
|
|
32
32
|
}
|
|
33
33
|
declare module "array/join" {
|
|
34
34
|
interface joinOptions {
|
|
@@ -56,10 +56,6 @@ declare module "array/mapKey" {
|
|
|
56
56
|
function mapKey<T extends Record<string, any>>(arr: T[], key: string, opts?: mapOptions): Record<string, T>;
|
|
57
57
|
export { mapKey, mapKey as default };
|
|
58
58
|
}
|
|
59
|
-
declare module "number/isIntegerAboveOrEqual" {
|
|
60
|
-
function isIntegerAboveOrEqual(val: unknown, ref: number): val is number;
|
|
61
|
-
export { isIntegerAboveOrEqual, isIntegerAboveOrEqual as default };
|
|
62
|
-
}
|
|
63
59
|
declare module "array/mapPrimitive" {
|
|
64
60
|
interface mapOptions {
|
|
65
61
|
valtrim?: boolean;
|
|
@@ -322,6 +318,10 @@ declare module "number/isBetween" {
|
|
|
322
318
|
function isNumberBetween(val: unknown, min: number, max: number): val is number;
|
|
323
319
|
export { isNumberBetween, isNumberBetween as default };
|
|
324
320
|
}
|
|
321
|
+
declare module "number/isInteger" {
|
|
322
|
+
function isInteger(val: unknown): val is number;
|
|
323
|
+
export { isInteger, isInteger as default };
|
|
324
|
+
}
|
|
325
325
|
declare module "number/isIntegerAbove" {
|
|
326
326
|
function isIntegerAbove(val: unknown, ref: number): val is number;
|
|
327
327
|
export { isIntegerAbove, isIntegerAbove as default };
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{ "name": "@valkyriestudios/utils", "version": "12.
|
|
1
|
+
{ "name": "@valkyriestudios/utils", "version": "12.14.0", "description": "A collection of single-function utilities for common tasks", "author": { "name": "Peter Vermeulen", "url": "https://www.linkedin.com/in/petervermeulen1/" }, "keywords": [ "utility", "library", "javascript", "js", "node", "bun" ], "license": "MIT", "repository": { "type": "git", "url": "git+https://github.com/ValkyrieStudios/utils.git" }, "bugs": { "url": "https://github.com/ValkyrieStudios/utils/issues" }, "homepage": "https://github.com/ValkyrieStudios/utils#readme", "types": "index.d.ts" }
|
package/string/humanizeNumber.js
CHANGED
|
@@ -34,10 +34,13 @@ function humanizeNumber(val, options = {}) {
|
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
const humanized = `${(0, round_1.round)(normalized, PRECISION)}`.split('.', 2);
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
37
|
+
const integerPart = humanized[0];
|
|
38
|
+
let formattedIntegerPart = '';
|
|
39
|
+
for (let i = 0; i < integerPart.length; i++) {
|
|
40
|
+
if (i > 0 && (integerPart.length - i) % 3 === 0) {
|
|
41
|
+
formattedIntegerPart += DELIM;
|
|
42
|
+
}
|
|
43
|
+
formattedIntegerPart += integerPart[i];
|
|
44
|
+
}
|
|
45
|
+
return `${sign}${formattedIntegerPart}${humanized[1] ? SEPARATOR + humanized[1] : ''}${UNITS ? UNITS[unit_ix] : ''}`;
|
|
43
46
|
}
|