@valkyriestudios/utils 12.15.0 → 12.17.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 +13 -1
- package/array/dedupe.d.ts +6 -2
- package/array/dedupe.js +25 -8
- package/array/index.d.ts +2 -1
- package/array/index.js +3 -1
- package/array/shuffle.js +2 -1
- package/array/sort.js +1 -1
- package/array/split.d.ts +19 -0
- package/array/split.js +37 -0
- package/date/format.js +1 -1
- package/date/nowUnix.js +1 -1
- package/date/nowUnixMs.js +1 -1
- package/date/toUnix.js +1 -1
- package/hash/fnv1A.js +32 -32
- package/index.d.ts +13 -2
- package/number/randomIntBetween.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -184,7 +184,7 @@ const group = groupBy([
|
|
|
184
184
|
**Take note**: any object without the key will be added to a fallback group called '_'
|
|
185
185
|
|
|
186
186
|
|
|
187
|
-
- **dedupe(val:Array)**
|
|
187
|
+
- **dedupe(val:Array, opts?:{filter_fn})**
|
|
188
188
|
Remove all duplicates from an array, behind the scenes it uses the fnv 1A hash algorithm to performantly do comparisons.
|
|
189
189
|
```typescript
|
|
190
190
|
dedupe(['a','a','b','c','c']); // ['a', 'b', 'c']
|
|
@@ -192,8 +192,11 @@ dedupe(['1',1,'2',2]); // ['1','2']
|
|
|
192
192
|
dedupe([new RegExp(/ab+c/, 'i'), new RegExp(/ab+c/, 'i')]); // [new RegExp(/ab+c/, 'i')]
|
|
193
193
|
dedupe([new Date('2012-02-02'), new Date('2012-02-02')]); // [new Date('2012-02-02')]
|
|
194
194
|
dedupe(['hello', 'hello', 'world']); // ['hello', 'world']
|
|
195
|
+
dedupe(['hello', 'hello', 'world', false, 'world'], {filter_fn: el => isNotEmptyString(el)}); // ['hello', 'world']
|
|
195
196
|
```
|
|
196
197
|
|
|
198
|
+
Take Note: The filtering is applied while deduping, ensuring O(n) performance, as such this is faster than dedupe(arr.filter(...))
|
|
199
|
+
|
|
197
200
|
- **join(val:Array, opts:object={delim:' ',trim:true,valtrim:true,innertrim:true,valround:false})**
|
|
198
201
|
Concatenate the values within an array into a string, behind the scenes this will automatically filter out any value that is not a string or numerical value. For strings it will automatically trim (and remove if empty after trimming) before joining.
|
|
199
202
|
|
|
@@ -312,6 +315,15 @@ const out = sort(arr, el => el.test.toLowerCase(), 'desc', {nokey_hide: true});
|
|
|
312
315
|
// [{test: 'Pony'}, {test: 'Peter'}, {test: 'JOHn'}, {test: 'Jack'}]
|
|
313
316
|
```
|
|
314
317
|
|
|
318
|
+
- **split(val:any[], size:number, opts?:{filter_fn})**
|
|
319
|
+
Splits an array into subarray of provided size with optional filter
|
|
320
|
+
```typescript
|
|
321
|
+
split([1,2,3,4,5], 2); // [[1,2],[3,4],[5]]
|
|
322
|
+
split([1, 2, false, 4, 5], 2, {filter_fn: isInteger}); // [[1,2],[4,5]]
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
Take Note: The filtering is applied while splitting, ensuring O(n) performance, as such this is faster than split(arr.filter(...), ...)
|
|
326
|
+
|
|
315
327
|
### boolean
|
|
316
328
|
- **isBoolean(val:any)**
|
|
317
329
|
Check if a variable is of type Boolean
|
package/array/dedupe.d.ts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
|
+
type DedupeOptions<T> = {
|
|
2
|
+
filter_fn?: (el: T) => boolean;
|
|
3
|
+
};
|
|
1
4
|
/**
|
|
2
5
|
* Dedupes the provided array
|
|
3
6
|
*
|
|
4
|
-
* @param val - Array to dedupe
|
|
7
|
+
* @param {Array} val - Array to dedupe
|
|
8
|
+
* @param {DedupeOptions?} opts - Dedupe options
|
|
5
9
|
*
|
|
6
10
|
* @returns Deduped array
|
|
7
11
|
*/
|
|
8
|
-
declare function dedupe<T>(val: T[]): T[];
|
|
12
|
+
declare function dedupe<T>(val: T[], opts?: DedupeOptions<T>): T[];
|
|
9
13
|
export { dedupe, dedupe as default };
|
package/array/dedupe.js
CHANGED
|
@@ -3,18 +3,35 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.dedupe = dedupe;
|
|
4
4
|
exports.default = dedupe;
|
|
5
5
|
const fnv1A_1 = require("../hash/fnv1A");
|
|
6
|
-
function dedupe(val) {
|
|
6
|
+
function dedupe(val, opts) {
|
|
7
7
|
if (!Array.isArray(val))
|
|
8
8
|
return [];
|
|
9
|
+
const FILTER_FN = typeof opts?.filter_fn === 'function' ? opts?.filter_fn : false;
|
|
9
10
|
const set = new Set();
|
|
10
11
|
const acc = [];
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
let hash;
|
|
13
|
+
const len = val.length;
|
|
14
|
+
if (FILTER_FN) {
|
|
15
|
+
for (let i = 0; i < len; i++) {
|
|
16
|
+
const el = val[i];
|
|
17
|
+
if (FILTER_FN && !FILTER_FN(el))
|
|
18
|
+
continue;
|
|
19
|
+
hash = (0, fnv1A_1.fnv1A)(el);
|
|
20
|
+
if (!set.has(hash)) {
|
|
21
|
+
set.add(hash);
|
|
22
|
+
acc.push(el);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
for (let i = 0; i < len; i++) {
|
|
28
|
+
const el = val[i];
|
|
29
|
+
hash = (0, fnv1A_1.fnv1A)(el);
|
|
30
|
+
if (!set.has(hash)) {
|
|
31
|
+
set.add(hash);
|
|
32
|
+
acc.push(el);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
18
35
|
}
|
|
19
36
|
return acc;
|
|
20
37
|
}
|
package/array/index.d.ts
CHANGED
|
@@ -7,5 +7,6 @@ import { mapKey } from './mapKey';
|
|
|
7
7
|
import { mapPrimitive } from './mapPrimitive';
|
|
8
8
|
import { groupBy } from './groupBy';
|
|
9
9
|
import { shuffle } from './shuffle';
|
|
10
|
+
import { split } from './split';
|
|
10
11
|
import { sort } from './sort';
|
|
11
|
-
export { dedupe, isArray, isArray as is, isNotEmptyArray, isNotEmptyArray as isNotEmpty, isNotEmptyArray as isNeArray, isNotEmptyArray as isNe, join, mapFn, mapKey, mapPrimitive, groupBy, shuffle, sort };
|
|
12
|
+
export { dedupe, isArray, isArray as is, isNotEmptyArray, isNotEmptyArray as isNotEmpty, isNotEmptyArray as isNeArray, isNotEmptyArray as isNe, join, mapFn, mapKey, mapPrimitive, groupBy, shuffle, split, sort };
|
package/array/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.sort = exports.shuffle = exports.groupBy = exports.mapPrimitive = exports.mapKey = exports.mapFn = exports.join = exports.isNe = exports.isNeArray = exports.isNotEmpty = exports.isNotEmptyArray = exports.is = exports.isArray = exports.dedupe = void 0;
|
|
3
|
+
exports.sort = exports.split = exports.shuffle = exports.groupBy = exports.mapPrimitive = exports.mapKey = exports.mapFn = exports.join = exports.isNe = exports.isNeArray = exports.isNotEmpty = exports.isNotEmptyArray = exports.is = exports.isArray = exports.dedupe = void 0;
|
|
4
4
|
const dedupe_1 = require("./dedupe");
|
|
5
5
|
Object.defineProperty(exports, "dedupe", { enumerable: true, get: function () { return dedupe_1.dedupe; } });
|
|
6
6
|
const is_1 = require("./is");
|
|
@@ -23,5 +23,7 @@ const groupBy_1 = require("./groupBy");
|
|
|
23
23
|
Object.defineProperty(exports, "groupBy", { enumerable: true, get: function () { return groupBy_1.groupBy; } });
|
|
24
24
|
const shuffle_1 = require("./shuffle");
|
|
25
25
|
Object.defineProperty(exports, "shuffle", { enumerable: true, get: function () { return shuffle_1.shuffle; } });
|
|
26
|
+
const split_1 = require("./split");
|
|
27
|
+
Object.defineProperty(exports, "split", { enumerable: true, get: function () { return split_1.split; } });
|
|
26
28
|
const sort_1 = require("./sort");
|
|
27
29
|
Object.defineProperty(exports, "sort", { enumerable: true, get: function () { return sort_1.sort; } });
|
package/array/shuffle.js
CHANGED
|
@@ -5,8 +5,9 @@ exports.default = shuffle;
|
|
|
5
5
|
function shuffle(arr) {
|
|
6
6
|
if (!Array.isArray(arr))
|
|
7
7
|
return;
|
|
8
|
+
let j;
|
|
8
9
|
for (let i = arr.length - 1; i > 0; i--) {
|
|
9
|
-
|
|
10
|
+
j = (Math.random() * (i + 1)) | 0;
|
|
10
11
|
[arr[i], arr[j]] = [arr[j], arr[i]];
|
|
11
12
|
}
|
|
12
13
|
}
|
package/array/sort.js
CHANGED
|
@@ -5,7 +5,7 @@ exports.default = sort;
|
|
|
5
5
|
const isNotEmpty_1 = require("../object/isNotEmpty");
|
|
6
6
|
const INSERTION_SORT_THRESHOLD = 10;
|
|
7
7
|
function partition(arr, low, high) {
|
|
8
|
-
const pivot = arr[
|
|
8
|
+
const pivot = arr[(low + high) >> 1][0];
|
|
9
9
|
let i = low;
|
|
10
10
|
let j = high;
|
|
11
11
|
while (i <= j) {
|
package/array/split.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
type SplitOptions<T> = {
|
|
2
|
+
filter_fn?: (el: T) => boolean;
|
|
3
|
+
};
|
|
4
|
+
/**
|
|
5
|
+
* Splits the provided array in a set of batches according to the provided size
|
|
6
|
+
* For Example:
|
|
7
|
+
* split([1, 2, 3, 4, 5], 2) -> [[1,2],[3,4],[5]]
|
|
8
|
+
*
|
|
9
|
+
* For Example w/ filter
|
|
10
|
+
* split([1, false, 3, 4, 5], 2, {filter_fn: el => isInteger(el)}) -> [[1, 3], [4, 5]]
|
|
11
|
+
*
|
|
12
|
+
* @param {Array} val - Array to split
|
|
13
|
+
* @param {number} size - Size of batches
|
|
14
|
+
* @param {SplitOptions?} opts - Split options
|
|
15
|
+
*
|
|
16
|
+
* @returns Split batches
|
|
17
|
+
*/
|
|
18
|
+
declare function split<T>(arr: T[], size: number, opts?: SplitOptions<T>): T[][];
|
|
19
|
+
export { split, split as default };
|
package/array/split.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.split = split;
|
|
4
|
+
exports.default = split;
|
|
5
|
+
function split(arr, size, opts) {
|
|
6
|
+
if (!Array.isArray(arr) ||
|
|
7
|
+
!Number.isInteger(size) ||
|
|
8
|
+
size <= 0)
|
|
9
|
+
throw new Error('split requires an array and positive integer size');
|
|
10
|
+
const FILTER_FN = typeof opts?.filter_fn === 'function' ? opts?.filter_fn : false;
|
|
11
|
+
const result = [];
|
|
12
|
+
let cursor = [];
|
|
13
|
+
let ticker = 0;
|
|
14
|
+
const len = arr.length;
|
|
15
|
+
if (FILTER_FN) {
|
|
16
|
+
for (let i = 0; i < len; i++) {
|
|
17
|
+
const el = arr[i];
|
|
18
|
+
if (FILTER_FN && !FILTER_FN(el))
|
|
19
|
+
continue;
|
|
20
|
+
ticker++;
|
|
21
|
+
cursor.push(el);
|
|
22
|
+
if (ticker === size) {
|
|
23
|
+
result.push(cursor);
|
|
24
|
+
cursor = [];
|
|
25
|
+
ticker = 0;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
if (ticker)
|
|
29
|
+
result.push(cursor);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
for (let i = 0; i < arr.length; i += size) {
|
|
33
|
+
result.push(arr.slice(i, i + size));
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return result;
|
|
37
|
+
}
|
package/date/format.js
CHANGED
|
@@ -19,7 +19,7 @@ const intl_formatters = new Map();
|
|
|
19
19
|
const spec_cache = new Map();
|
|
20
20
|
const zone_offset_cache = new Map();
|
|
21
21
|
function DOY(d) {
|
|
22
|
-
return
|
|
22
|
+
return ((d - new Date(d.getFullYear(), 0, 0)) / 86400000) | 0;
|
|
23
23
|
}
|
|
24
24
|
function toZone(date, zone) {
|
|
25
25
|
const ckey = `${zone}:${date.getUTCFullYear()}${DOY(date)}`;
|
package/date/nowUnix.js
CHANGED
package/date/nowUnixMs.js
CHANGED
package/date/toUnix.js
CHANGED
package/hash/fnv1A.js
CHANGED
|
@@ -11,38 +11,38 @@ const REPL_NULL = 'null';
|
|
|
11
11
|
function fnv1A(data, offset = FNV_32) {
|
|
12
12
|
let hash = offset;
|
|
13
13
|
let sanitized;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
14
|
+
switch (typeof data) {
|
|
15
|
+
case 'string':
|
|
16
|
+
sanitized = data;
|
|
17
|
+
break;
|
|
18
|
+
case 'number':
|
|
19
|
+
sanitized = Number.isNaN(data) || !Number.isFinite(data) ? REPL_NAN : String(data);
|
|
20
|
+
break;
|
|
21
|
+
case 'boolean':
|
|
22
|
+
sanitized = data ? REPL_TRUE : REPL_FALSE;
|
|
23
|
+
break;
|
|
24
|
+
case 'undefined':
|
|
25
|
+
sanitized = REPL_UNDEF;
|
|
26
|
+
break;
|
|
27
|
+
case 'object':
|
|
28
|
+
if (data === null) {
|
|
29
|
+
sanitized = REPL_NULL;
|
|
30
|
+
}
|
|
31
|
+
else if (Array.isArray(data) || data.toString() === '[object Object]') {
|
|
32
|
+
sanitized = JSON.stringify(data);
|
|
33
|
+
}
|
|
34
|
+
else if (data instanceof RegExp) {
|
|
35
|
+
sanitized = data.toString();
|
|
36
|
+
}
|
|
37
|
+
else if (data instanceof Date) {
|
|
38
|
+
sanitized = String(data.getTime());
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
throw new TypeError('An FNV1A Hash could not be calculated for this datatype');
|
|
42
|
+
}
|
|
43
|
+
break;
|
|
44
|
+
default:
|
|
45
|
+
throw new TypeError('An FNV1A Hash could not be calculated for this datatype');
|
|
46
46
|
}
|
|
47
47
|
const len = sanitized.length;
|
|
48
48
|
for (let i = 0; i < len; i++) {
|
package/index.d.ts
CHANGED
|
@@ -11,7 +11,10 @@ declare module "hash/fnv1A" {
|
|
|
11
11
|
export { fnv1A, fnv1A as default };
|
|
12
12
|
}
|
|
13
13
|
declare module "array/dedupe" {
|
|
14
|
-
|
|
14
|
+
type DedupeOptions<T> = {
|
|
15
|
+
filter_fn?: (el: T) => boolean;
|
|
16
|
+
};
|
|
17
|
+
function dedupe<T>(val: T[], opts?: DedupeOptions<T>): T[];
|
|
15
18
|
export { dedupe, dedupe as default };
|
|
16
19
|
}
|
|
17
20
|
declare module "array/is" {
|
|
@@ -81,6 +84,13 @@ declare module "array/shuffle" {
|
|
|
81
84
|
function shuffle(arr: unknown[]): void;
|
|
82
85
|
export { shuffle, shuffle as default };
|
|
83
86
|
}
|
|
87
|
+
declare module "array/split" {
|
|
88
|
+
type SplitOptions<T> = {
|
|
89
|
+
filter_fn?: (el: T) => boolean;
|
|
90
|
+
};
|
|
91
|
+
function split<T>(arr: T[], size: number, opts?: SplitOptions<T>): T[][];
|
|
92
|
+
export { split, split as default };
|
|
93
|
+
}
|
|
84
94
|
declare module "array/sort" {
|
|
85
95
|
type sortOptions<T> = {
|
|
86
96
|
filter_fn?: (el: T) => boolean;
|
|
@@ -103,8 +113,9 @@ declare module "array/index" {
|
|
|
103
113
|
import { mapPrimitive } from "array/mapPrimitive";
|
|
104
114
|
import { groupBy } from "array/groupBy";
|
|
105
115
|
import { shuffle } from "array/shuffle";
|
|
116
|
+
import { split } from "array/split";
|
|
106
117
|
import { sort } from "array/sort";
|
|
107
|
-
export { dedupe, isArray, isArray as is, isNotEmptyArray, isNotEmptyArray as isNotEmpty, isNotEmptyArray as isNeArray, isNotEmptyArray as isNe, join, mapFn, mapKey, mapPrimitive, groupBy, shuffle, sort };
|
|
118
|
+
export { dedupe, isArray, isArray as is, isNotEmptyArray, isNotEmptyArray as isNotEmpty, isNotEmptyArray as isNeArray, isNotEmptyArray as isNe, join, mapFn, mapKey, mapPrimitive, groupBy, shuffle, split, sort };
|
|
108
119
|
}
|
|
109
120
|
declare module "boolean/is" {
|
|
110
121
|
function isBoolean(val: unknown): val is boolean;
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{ "name": "@valkyriestudios/utils", "version": "12.
|
|
1
|
+
{ "name": "@valkyriestudios/utils", "version": "12.17.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" }
|