@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 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
- for (let i = 0; i < val.length; i++) {
12
- const el = val[i];
13
- const hash = (0, fnv1A_1.fnv1A)(el);
14
- if (set.has(hash))
15
- continue;
16
- set.add(hash);
17
- acc.push(el);
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
- const j = Math.floor(Math.random() * (i + 1));
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[Math.floor((low + high) / 2)][0];
8
+ const pivot = arr[(low + high) >> 1][0];
9
9
  let i = low;
10
10
  let j = high;
11
11
  while (i <= j) {
@@ -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 Math.floor((d - new Date(d.getFullYear(), 0, 0)) / 86400000);
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
@@ -3,5 +3,5 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.nowUnix = nowUnix;
4
4
  exports.default = nowUnix;
5
5
  function nowUnix() {
6
- return Math.floor(Date.now() / 1000);
6
+ return (Date.now() / 1000) | 0;
7
7
  }
package/date/nowUnixMs.js CHANGED
@@ -3,5 +3,5 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.nowUnixMs = nowUnixMs;
4
4
  exports.default = nowUnixMs;
5
5
  function nowUnixMs() {
6
- return Math.floor(Date.now());
6
+ return Date.now();
7
7
  }
package/date/toUnix.js CHANGED
@@ -6,5 +6,5 @@ const is_1 = require("./is");
6
6
  function toUnix(val) {
7
7
  if (!(0, is_1.isDate)(val))
8
8
  throw new TypeError('toUnix requires a date object');
9
- return Math.floor(val.valueOf() / 1000);
9
+ return (val.valueOf() / 1000) | 0;
10
10
  }
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
- if (typeof data === 'string') {
15
- sanitized = data;
16
- }
17
- else if (Number.isFinite(data)) {
18
- sanitized = String(data);
19
- }
20
- else if (Array.isArray(data) || Object.prototype.toString.call(data) === '[object Object]') {
21
- sanitized = JSON.stringify(data);
22
- }
23
- else if (data instanceof RegExp) {
24
- sanitized = data.toString();
25
- }
26
- else if (data instanceof Date) {
27
- sanitized = String(data.getTime());
28
- }
29
- else if (Number.isNaN(data) || data === Infinity) {
30
- sanitized = REPL_NAN;
31
- }
32
- else if (data === false) {
33
- sanitized = REPL_FALSE;
34
- }
35
- else if (data === true) {
36
- sanitized = REPL_TRUE;
37
- }
38
- else if (data === null) {
39
- sanitized = REPL_NULL;
40
- }
41
- else if (data === undefined) {
42
- sanitized = REPL_UNDEF;
43
- }
44
- else {
45
- throw new TypeError('An FNV1A Hash could not be calculated for this datatype');
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
- function dedupe<T>(val: T[]): T[];
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;
@@ -6,5 +6,5 @@ function randomIntBetween(min = 0, max = 10) {
6
6
  if (!Number.isFinite(min) ||
7
7
  !Number.isFinite(max))
8
8
  throw new TypeError('Min/Max should be numeric');
9
- return Math.floor((Math.random() * (max - min)) + min);
9
+ return ((Math.random() * (max - min)) + min) | 0;
10
10
  }
package/package.json CHANGED
@@ -1 +1 @@
1
- { "name": "@valkyriestudios/utils", "version": "12.15.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" }
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" }