@oscarpalmer/atoms 0.16.0 → 0.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/dist/js/array.js CHANGED
@@ -1,13 +1,65 @@
1
1
  // src/js/array.ts
2
- var _getCallback = function(value) {
3
- if (typeof value === "function") {
4
- return value;
2
+ var _getCallbacks = function(bool, key) {
3
+ if (typeof bool === "function") {
4
+ return { bool };
5
5
  }
6
- const isString = typeof value === "string";
7
- if (!isString && typeof value !== "number") {
6
+ if (typeof key === "function") {
7
+ return { key };
8
+ }
9
+ const isString = typeof key === "string";
10
+ if (!isString && typeof key !== "number" || isString && key.includes(".")) {
8
11
  return;
9
12
  }
10
- return isString && value.includes(".") ? undefined : (item) => item[value];
13
+ return {
14
+ key: (item) => item?.[key]
15
+ };
16
+ };
17
+ var _findValue = function(type, array, value, key) {
18
+ const callbacks = _getCallbacks(value, key);
19
+ if (callbacks?.bool === undefined && callbacks?.key === undefined) {
20
+ return type === "index" ? array.indexOf(value) : array.find((item) => item === value);
21
+ }
22
+ if (callbacks.bool !== undefined) {
23
+ const index2 = array.findIndex(callbacks.bool);
24
+ return type === "index" ? index2 : index2 > -1 ? array[index2] : undefined;
25
+ }
26
+ const { length } = array;
27
+ let index = 0;
28
+ for (;index < length; index += 1) {
29
+ const item = array[index];
30
+ if (callbacks.key?.(item) === value) {
31
+ return type === "index" ? index : item;
32
+ }
33
+ }
34
+ return type === "index" ? -1 : undefined;
35
+ };
36
+ var _findValues = function(type, array, value, key) {
37
+ const callbacks = _getCallbacks(value, key);
38
+ const { length } = array;
39
+ if (type === "unique" && callbacks?.key === undefined && length >= 100) {
40
+ return Array.from(new Set(array));
41
+ }
42
+ if (typeof callbacks?.bool === "function") {
43
+ return array.filter(callbacks.bool);
44
+ }
45
+ if (type === "all" && key === undefined) {
46
+ return array.filter((item) => item === value);
47
+ }
48
+ const hasCallback = typeof callbacks?.key === "function";
49
+ const result = [];
50
+ const values = hasCallback ? [] : result;
51
+ let index = 0;
52
+ for (;index < length; index += 1) {
53
+ const item = array[index];
54
+ const itemValue = hasCallback ? callbacks.key?.(item) : item;
55
+ if (type === "all" && itemValue === value || type === "unique" && values.indexOf(itemValue) === -1) {
56
+ if (values !== result) {
57
+ values.push(itemValue);
58
+ }
59
+ result.push(item);
60
+ }
61
+ }
62
+ return result;
11
63
  };
12
64
  var _insertValues = function(type, array, values, start, deleteCount) {
13
65
  const chunked = chunk(values).reverse();
@@ -37,23 +89,17 @@ function chunk(array, size) {
37
89
  return chunks;
38
90
  }
39
91
  function exists(array, value, key) {
40
- const callback = _getCallback(key);
41
- if (callback === undefined) {
42
- return array.indexOf(value) > -1;
43
- }
44
- const needle = typeof value === "object" && value !== null ? callback(value) : value;
45
- const { length } = array;
46
- let index = 0;
47
- for (;index < length; index += 1) {
48
- if (callback(array[index]) === needle) {
49
- return true;
50
- }
51
- }
52
- return false;
92
+ return _findValue("index", array, value, key) > -1;
93
+ }
94
+ function filter(array, value, key) {
95
+ return _findValues("all", array, value, key);
96
+ }
97
+ function find(array, value, key) {
98
+ return _findValue("value", array, value, key);
53
99
  }
54
100
  function groupBy(array, key) {
55
- const keyCallback = _getCallback(key);
56
- if (keyCallback === undefined) {
101
+ const callbacks = _getCallbacks(undefined, key);
102
+ if (callbacks?.key === undefined) {
57
103
  return {};
58
104
  }
59
105
  const grouped = {};
@@ -61,7 +107,7 @@ function groupBy(array, key) {
61
107
  let index = 0;
62
108
  for (;index < length; index += 1) {
63
109
  const item = array[index];
64
- const value = keyCallback(item);
110
+ const value = callbacks.key(item);
65
111
  if (value in grouped) {
66
112
  grouped[value].push(item);
67
113
  } else {
@@ -70,6 +116,9 @@ function groupBy(array, key) {
70
116
  }
71
117
  return grouped;
72
118
  }
119
+ function indexOf(array, value, key) {
120
+ return _findValue("index", array, value, key);
121
+ }
73
122
  function insert(array, index, values) {
74
123
  _insertValues("splice", array, values, index, 0);
75
124
  }
@@ -80,32 +129,17 @@ function splice(array, start, deleteCount, values) {
80
129
  return _insertValues("splice", array, values, start, deleteCount);
81
130
  }
82
131
  function unique(array, key) {
83
- const keyCallback = _getCallback(key);
84
- const { length } = array;
85
- if (keyCallback === undefined && length >= 100) {
86
- return Array.from(new Set(array));
87
- }
88
- const result = [];
89
- const values = keyCallback === undefined ? result : [];
90
- let index = 0;
91
- for (;index < length; index += 1) {
92
- const item = array[index];
93
- const value = keyCallback?.(item) ?? item;
94
- if (values.indexOf(value) === -1) {
95
- if (values !== result) {
96
- values.push(value);
97
- }
98
- result.push(item);
99
- }
100
- }
101
- return result;
132
+ return _findValues("unique", array, undefined, key);
102
133
  }
103
134
  export {
104
135
  unique,
105
136
  splice,
106
137
  push,
107
138
  insert,
139
+ indexOf,
108
140
  groupBy,
141
+ find,
142
+ filter,
109
143
  exists,
110
144
  chunk
111
145
  };
package/dist/js/array.mjs CHANGED
@@ -1,13 +1,65 @@
1
1
  // src/js/array.ts
2
- var _getCallback = function(value) {
3
- if (typeof value === "function") {
4
- return value;
2
+ var _getCallbacks = function(bool, key) {
3
+ if (typeof bool === "function") {
4
+ return { bool };
5
5
  }
6
- const isString = typeof value === "string";
7
- if (!isString && typeof value !== "number") {
6
+ if (typeof key === "function") {
7
+ return { key };
8
+ }
9
+ const isString = typeof key === "string";
10
+ if (!isString && typeof key !== "number" || isString && key.includes(".")) {
8
11
  return;
9
12
  }
10
- return isString && value.includes(".") ? undefined : (item) => item[value];
13
+ return {
14
+ key: (item) => item?.[key]
15
+ };
16
+ };
17
+ var _findValue = function(type, array, value, key) {
18
+ const callbacks = _getCallbacks(value, key);
19
+ if (callbacks?.bool === undefined && callbacks?.key === undefined) {
20
+ return type === "index" ? array.indexOf(value) : array.find((item) => item === value);
21
+ }
22
+ if (callbacks.bool !== undefined) {
23
+ const index2 = array.findIndex(callbacks.bool);
24
+ return type === "index" ? index2 : index2 > -1 ? array[index2] : undefined;
25
+ }
26
+ const { length } = array;
27
+ let index = 0;
28
+ for (;index < length; index += 1) {
29
+ const item = array[index];
30
+ if (callbacks.key?.(item) === value) {
31
+ return type === "index" ? index : item;
32
+ }
33
+ }
34
+ return type === "index" ? -1 : undefined;
35
+ };
36
+ var _findValues = function(type, array, value, key) {
37
+ const callbacks = _getCallbacks(value, key);
38
+ const { length } = array;
39
+ if (type === "unique" && callbacks?.key === undefined && length >= 100) {
40
+ return Array.from(new Set(array));
41
+ }
42
+ if (typeof callbacks?.bool === "function") {
43
+ return array.filter(callbacks.bool);
44
+ }
45
+ if (type === "all" && key === undefined) {
46
+ return array.filter((item) => item === value);
47
+ }
48
+ const hasCallback = typeof callbacks?.key === "function";
49
+ const result = [];
50
+ const values = hasCallback ? [] : result;
51
+ let index = 0;
52
+ for (;index < length; index += 1) {
53
+ const item = array[index];
54
+ const itemValue = hasCallback ? callbacks.key?.(item) : item;
55
+ if (type === "all" && itemValue === value || type === "unique" && values.indexOf(itemValue) === -1) {
56
+ if (values !== result) {
57
+ values.push(itemValue);
58
+ }
59
+ result.push(item);
60
+ }
61
+ }
62
+ return result;
11
63
  };
12
64
  var _insertValues = function(type, array, values, start, deleteCount) {
13
65
  const chunked = chunk(values).reverse();
@@ -37,23 +89,17 @@ function chunk(array, size) {
37
89
  return chunks;
38
90
  }
39
91
  function exists(array, value, key) {
40
- const callback = _getCallback(key);
41
- if (callback === undefined) {
42
- return array.indexOf(value) > -1;
43
- }
44
- const needle = typeof value === "object" && value !== null ? callback(value) : value;
45
- const { length } = array;
46
- let index = 0;
47
- for (;index < length; index += 1) {
48
- if (callback(array[index]) === needle) {
49
- return true;
50
- }
51
- }
52
- return false;
92
+ return _findValue("index", array, value, key) > -1;
93
+ }
94
+ function filter(array, value, key) {
95
+ return _findValues("all", array, value, key);
96
+ }
97
+ function find(array, value, key) {
98
+ return _findValue("value", array, value, key);
53
99
  }
54
100
  function groupBy(array, key) {
55
- const keyCallback = _getCallback(key);
56
- if (keyCallback === undefined) {
101
+ const callbacks = _getCallbacks(undefined, key);
102
+ if (callbacks?.key === undefined) {
57
103
  return {};
58
104
  }
59
105
  const grouped = {};
@@ -61,7 +107,7 @@ function groupBy(array, key) {
61
107
  let index = 0;
62
108
  for (;index < length; index += 1) {
63
109
  const item = array[index];
64
- const value = keyCallback(item);
110
+ const value = callbacks.key(item);
65
111
  if (value in grouped) {
66
112
  grouped[value].push(item);
67
113
  } else {
@@ -70,6 +116,9 @@ function groupBy(array, key) {
70
116
  }
71
117
  return grouped;
72
118
  }
119
+ function indexOf(array, value, key) {
120
+ return _findValue("index", array, value, key);
121
+ }
73
122
  function insert(array, index, values) {
74
123
  _insertValues("splice", array, values, index, 0);
75
124
  }
@@ -80,32 +129,17 @@ function splice(array, start, deleteCount, values) {
80
129
  return _insertValues("splice", array, values, start, deleteCount);
81
130
  }
82
131
  function unique(array, key) {
83
- const keyCallback = _getCallback(key);
84
- const { length } = array;
85
- if (keyCallback === undefined && length >= 100) {
86
- return Array.from(new Set(array));
87
- }
88
- const result = [];
89
- const values = keyCallback === undefined ? result : [];
90
- let index = 0;
91
- for (;index < length; index += 1) {
92
- const item = array[index];
93
- const value = keyCallback?.(item) ?? item;
94
- if (values.indexOf(value) === -1) {
95
- if (values !== result) {
96
- values.push(value);
97
- }
98
- result.push(item);
99
- }
100
- }
101
- return result;
132
+ return _findValues("unique", array, undefined, key);
102
133
  }
103
134
  export {
104
135
  unique,
105
136
  splice,
106
137
  push,
107
138
  insert,
139
+ indexOf,
108
140
  groupBy,
141
+ find,
142
+ filter,
109
143
  exists,
110
144
  chunk
111
145
  };
package/dist/js/index.js CHANGED
@@ -1,13 +1,65 @@
1
1
  // src/js/array.ts
2
- var _getCallback = function(value) {
3
- if (typeof value === "function") {
4
- return value;
2
+ var _getCallbacks = function(bool, key) {
3
+ if (typeof bool === "function") {
4
+ return { bool };
5
+ }
6
+ if (typeof key === "function") {
7
+ return { key };
5
8
  }
6
- const isString = typeof value === "string";
7
- if (!isString && typeof value !== "number") {
9
+ const isString = typeof key === "string";
10
+ if (!isString && typeof key !== "number" || isString && key.includes(".")) {
8
11
  return;
9
12
  }
10
- return isString && value.includes(".") ? undefined : (item) => item[value];
13
+ return {
14
+ key: (item) => item?.[key]
15
+ };
16
+ };
17
+ var _findValue = function(type, array, value, key) {
18
+ const callbacks = _getCallbacks(value, key);
19
+ if (callbacks?.bool === undefined && callbacks?.key === undefined) {
20
+ return type === "index" ? array.indexOf(value) : array.find((item) => item === value);
21
+ }
22
+ if (callbacks.bool !== undefined) {
23
+ const index2 = array.findIndex(callbacks.bool);
24
+ return type === "index" ? index2 : index2 > -1 ? array[index2] : undefined;
25
+ }
26
+ const { length } = array;
27
+ let index = 0;
28
+ for (;index < length; index += 1) {
29
+ const item = array[index];
30
+ if (callbacks.key?.(item) === value) {
31
+ return type === "index" ? index : item;
32
+ }
33
+ }
34
+ return type === "index" ? -1 : undefined;
35
+ };
36
+ var _findValues = function(type, array, value, key) {
37
+ const callbacks = _getCallbacks(value, key);
38
+ const { length } = array;
39
+ if (type === "unique" && callbacks?.key === undefined && length >= 100) {
40
+ return Array.from(new Set(array));
41
+ }
42
+ if (typeof callbacks?.bool === "function") {
43
+ return array.filter(callbacks.bool);
44
+ }
45
+ if (type === "all" && key === undefined) {
46
+ return array.filter((item) => item === value);
47
+ }
48
+ const hasCallback = typeof callbacks?.key === "function";
49
+ const result = [];
50
+ const values = hasCallback ? [] : result;
51
+ let index = 0;
52
+ for (;index < length; index += 1) {
53
+ const item = array[index];
54
+ const itemValue = hasCallback ? callbacks.key?.(item) : item;
55
+ if (type === "all" && itemValue === value || type === "unique" && values.indexOf(itemValue) === -1) {
56
+ if (values !== result) {
57
+ values.push(itemValue);
58
+ }
59
+ result.push(item);
60
+ }
61
+ }
62
+ return result;
11
63
  };
12
64
  var _insertValues = function(type, array, values, start, deleteCount) {
13
65
  const chunked = chunk(values).reverse();
@@ -37,23 +89,17 @@ function chunk(array, size) {
37
89
  return chunks;
38
90
  }
39
91
  function exists(array, value, key) {
40
- const callback = _getCallback(key);
41
- if (callback === undefined) {
42
- return array.indexOf(value) > -1;
43
- }
44
- const needle = typeof value === "object" && value !== null ? callback(value) : value;
45
- const { length } = array;
46
- let index = 0;
47
- for (;index < length; index += 1) {
48
- if (callback(array[index]) === needle) {
49
- return true;
50
- }
51
- }
52
- return false;
92
+ return _findValue("index", array, value, key) > -1;
93
+ }
94
+ function filter(array, value, key) {
95
+ return _findValues("all", array, value, key);
96
+ }
97
+ function find(array, value, key) {
98
+ return _findValue("value", array, value, key);
53
99
  }
54
100
  function groupBy(array, key) {
55
- const keyCallback = _getCallback(key);
56
- if (keyCallback === undefined) {
101
+ const callbacks = _getCallbacks(undefined, key);
102
+ if (callbacks?.key === undefined) {
57
103
  return {};
58
104
  }
59
105
  const grouped = {};
@@ -61,7 +107,7 @@ function groupBy(array, key) {
61
107
  let index = 0;
62
108
  for (;index < length; index += 1) {
63
109
  const item = array[index];
64
- const value = keyCallback(item);
110
+ const value = callbacks.key(item);
65
111
  if (value in grouped) {
66
112
  grouped[value].push(item);
67
113
  } else {
@@ -70,6 +116,9 @@ function groupBy(array, key) {
70
116
  }
71
117
  return grouped;
72
118
  }
119
+ function indexOf(array, value, key) {
120
+ return _findValue("index", array, value, key);
121
+ }
73
122
  function insert(array, index, values) {
74
123
  _insertValues("splice", array, values, index, 0);
75
124
  }
@@ -80,25 +129,7 @@ function splice(array, start, deleteCount, values) {
80
129
  return _insertValues("splice", array, values, start, deleteCount);
81
130
  }
82
131
  function unique(array, key) {
83
- const keyCallback = _getCallback(key);
84
- const { length } = array;
85
- if (keyCallback === undefined && length >= 100) {
86
- return Array.from(new Set(array));
87
- }
88
- const result = [];
89
- const values = keyCallback === undefined ? result : [];
90
- let index = 0;
91
- for (;index < length; index += 1) {
92
- const item = array[index];
93
- const value = keyCallback?.(item) ?? item;
94
- if (values.indexOf(value) === -1) {
95
- if (values !== result) {
96
- values.push(value);
97
- }
98
- result.push(item);
99
- }
100
- }
101
- return result;
132
+ return _findValues("unique", array, undefined, key);
102
133
  }
103
134
  // src/js/element/index.ts
104
135
  var _findElements = function(selector, context, single) {
@@ -247,6 +278,104 @@ function getString(value) {
247
278
  function isNullableOrWhitespace(value) {
248
279
  return value == null || getString(value).trim().length === 0;
249
280
  }
281
+
282
+ // src/js/value.ts
283
+ var _getValue = function(data, key) {
284
+ if (typeof data !== "object" || data === null || /^(__proto__|constructor|prototype)$/i.test(key)) {
285
+ return;
286
+ }
287
+ return data instanceof Map ? data.get(key) : data[key];
288
+ };
289
+ var _setValue = function(data, key, value) {
290
+ if (typeof data !== "object" || data === null || /^(__proto__|constructor|prototype)$/i.test(key)) {
291
+ return;
292
+ }
293
+ if (data instanceof Map) {
294
+ data.set(key, value);
295
+ } else {
296
+ data[key] = value;
297
+ }
298
+ };
299
+ function getValue(data, key) {
300
+ if (typeof data !== "object" || data === null || isNullableOrWhitespace(key)) {
301
+ return;
302
+ }
303
+ const parts = getString(key).split(".");
304
+ const { length } = parts;
305
+ let index = 0;
306
+ let value = data;
307
+ for (;index < length; index += 1) {
308
+ value = _getValue(value, parts[index]);
309
+ if (value == null) {
310
+ break;
311
+ }
312
+ }
313
+ return value;
314
+ }
315
+ function isArrayOrObject(value) {
316
+ return /^(array|object)$/i.test(value?.constructor?.name);
317
+ }
318
+ function isNullable(value) {
319
+ return value == null;
320
+ }
321
+ function isObject(value) {
322
+ return /^object$/i.test(value?.constructor?.name);
323
+ }
324
+ function setValue(data, key, value) {
325
+ if (typeof data !== "object" || data === null || isNullableOrWhitespace(key)) {
326
+ return data;
327
+ }
328
+ const parts = getString(key).split(".");
329
+ const { length } = parts;
330
+ let index = 0;
331
+ let target = data;
332
+ for (;index < length; index += 1) {
333
+ const part = parts[index];
334
+ if (parts.indexOf(part) === parts.length - 1) {
335
+ _setValue(target, part, value);
336
+ break;
337
+ }
338
+ let next = _getValue(target, part);
339
+ if (typeof next !== "object" || next === null) {
340
+ next = /^\d+$/.test(part) ? [] : {};
341
+ target[part] = next;
342
+ }
343
+ target = next;
344
+ }
345
+ return data;
346
+ }
347
+
348
+ // src/js/object.ts
349
+ function clone(value2) {
350
+ return structuredClone(value2);
351
+ }
352
+ function merge(...values) {
353
+ if (values.length === 0) {
354
+ return {};
355
+ }
356
+ const actual = values.filter(isArrayOrObject);
357
+ const result = actual.every(Array.isArray) ? [] : {};
358
+ const { length: itemsLength } = actual;
359
+ let itemIndex = 0;
360
+ for (;itemIndex < itemsLength; itemIndex += 1) {
361
+ const item = actual[itemIndex];
362
+ const isArray = Array.isArray(item);
363
+ const keys = isArray ? undefined : Object.keys(item);
364
+ const keysLength = isArray ? item.length : keys.length;
365
+ let keyIndex = 0;
366
+ for (;keyIndex < keysLength; keyIndex += 1) {
367
+ const key = keys?.[keyIndex] ?? keyIndex;
368
+ const next = item[key];
369
+ const previous = result[key];
370
+ if (isArrayOrObject(previous) && isArrayOrObject(next)) {
371
+ result[key] = merge(previous, next);
372
+ } else {
373
+ result[key] = next;
374
+ }
375
+ }
376
+ }
377
+ return result;
378
+ }
250
379
  // src/js/timer.ts
251
380
  function repeat(callback, options) {
252
381
  const count = typeof options?.count === "number" ? options.count : Infinity;
@@ -330,71 +459,6 @@ class Timer {
330
459
  return work("stop", this, this.state, this.options);
331
460
  }
332
461
  }
333
- // src/js/value.ts
334
- var _getValue = function(data, key) {
335
- if (typeof data !== "object" || data === null || /^(__proto__|constructor|prototype)$/i.test(key)) {
336
- return;
337
- }
338
- return data instanceof Map ? data.get(key) : data[key];
339
- };
340
- var _setValue = function(data, key, value) {
341
- if (typeof data !== "object" || data === null || /^(__proto__|constructor|prototype)$/i.test(key)) {
342
- return;
343
- }
344
- if (data instanceof Map) {
345
- data.set(key, value);
346
- } else {
347
- data[key] = value;
348
- }
349
- };
350
- function getValue(data, key) {
351
- if (typeof data !== "object" || data === null || isNullableOrWhitespace(key)) {
352
- return;
353
- }
354
- const parts = getString(key).split(".");
355
- const { length } = parts;
356
- let index = 0;
357
- let value = data;
358
- for (;index < length; index += 1) {
359
- value = _getValue(value, parts[index]);
360
- if (value == null) {
361
- break;
362
- }
363
- }
364
- return value;
365
- }
366
- function isArrayOrObject(value) {
367
- return /^(array|object)$/i.test(value?.constructor?.name);
368
- }
369
- function isNullable(value) {
370
- return value == null;
371
- }
372
- function isObject(value) {
373
- return /^object$/i.test(value?.constructor?.name);
374
- }
375
- function setValue(data, key, value) {
376
- if (typeof data !== "object" || data === null || isNullableOrWhitespace(key)) {
377
- return data;
378
- }
379
- const parts = getString(key).split(".");
380
- const { length } = parts;
381
- let index = 0;
382
- let target = data;
383
- for (;index < length; index += 1) {
384
- const part = parts[index];
385
- if (parts.indexOf(part) === parts.length - 1) {
386
- _setValue(target, part, value);
387
- break;
388
- }
389
- let next = _getValue(target, part);
390
- if (typeof next !== "object" || next === null) {
391
- next = /^\d+$/.test(part) ? [] : {};
392
- target[part] = next;
393
- }
394
- target = next;
395
- }
396
- return data;
397
- }
398
462
  export {
399
463
  wait,
400
464
  unique,
@@ -402,11 +466,13 @@ export {
402
466
  setValue,
403
467
  repeat,
404
468
  push,
469
+ merge,
405
470
  isObject,
406
471
  isNullableOrWhitespace,
407
472
  isNullable,
408
473
  isArrayOrObject,
409
474
  insert,
475
+ indexOf,
410
476
  groupBy,
411
477
  getValue,
412
478
  getTextDirection,
@@ -417,8 +483,11 @@ export {
417
483
  findParentElement,
418
484
  findElements,
419
485
  findElement,
486
+ find,
487
+ filter,
420
488
  exists,
421
489
  createUuid,
490
+ clone,
422
491
  clamp,
423
492
  chunk,
424
493
  between,
package/dist/js/index.mjs CHANGED
@@ -3,6 +3,7 @@ export * from "./array";
3
3
  export * from "./element";
4
4
  export * from "./event";
5
5
  export * from "./number";
6
+ export * from "./object";
6
7
  export * from "./string";
7
8
  export * from "./timer";
8
9
  export * from "./value";
@@ -0,0 +1,40 @@
1
+ // src/js/value.ts
2
+ function isArrayOrObject(value) {
3
+ return /^(array|object)$/i.test(value?.constructor?.name);
4
+ }
5
+
6
+ // src/js/object.ts
7
+ function clone(value2) {
8
+ return structuredClone(value2);
9
+ }
10
+ function merge(...values) {
11
+ if (values.length === 0) {
12
+ return {};
13
+ }
14
+ const actual = values.filter(isArrayOrObject);
15
+ const result = actual.every(Array.isArray) ? [] : {};
16
+ const { length: itemsLength } = actual;
17
+ let itemIndex = 0;
18
+ for (;itemIndex < itemsLength; itemIndex += 1) {
19
+ const item = actual[itemIndex];
20
+ const isArray = Array.isArray(item);
21
+ const keys = isArray ? undefined : Object.keys(item);
22
+ const keysLength = isArray ? item.length : keys.length;
23
+ let keyIndex = 0;
24
+ for (;keyIndex < keysLength; keyIndex += 1) {
25
+ const key = keys?.[keyIndex] ?? keyIndex;
26
+ const next = item[key];
27
+ const previous = result[key];
28
+ if (isArrayOrObject(previous) && isArrayOrObject(next)) {
29
+ result[key] = merge(previous, next);
30
+ } else {
31
+ result[key] = next;
32
+ }
33
+ }
34
+ }
35
+ return result;
36
+ }
37
+ export {
38
+ merge,
39
+ clone
40
+ };
@@ -0,0 +1,36 @@
1
+ // src/js/object.ts
2
+ import {isArrayOrObject} from "./value";
3
+ function clone(value2) {
4
+ return structuredClone(value2);
5
+ }
6
+ function merge(...values) {
7
+ if (values.length === 0) {
8
+ return {};
9
+ }
10
+ const actual = values.filter(isArrayOrObject);
11
+ const result = actual.every(Array.isArray) ? [] : {};
12
+ const { length: itemsLength } = actual;
13
+ let itemIndex = 0;
14
+ for (;itemIndex < itemsLength; itemIndex += 1) {
15
+ const item = actual[itemIndex];
16
+ const isArray = Array.isArray(item);
17
+ const keys = isArray ? undefined : Object.keys(item);
18
+ const keysLength = isArray ? item.length : keys.length;
19
+ let keyIndex = 0;
20
+ for (;keyIndex < keysLength; keyIndex += 1) {
21
+ const key = keys?.[keyIndex] ?? keyIndex;
22
+ const next = item[key];
23
+ const previous = result[key];
24
+ if (isArrayOrObject(previous) && isArrayOrObject(next)) {
25
+ result[key] = merge(previous, next);
26
+ } else {
27
+ result[key] = next;
28
+ }
29
+ }
30
+ }
31
+ return result;
32
+ }
33
+ export {
34
+ merge,
35
+ clone
36
+ };
package/package.json CHANGED
@@ -42,6 +42,12 @@
42
42
  "require": "./dist/js/number.js",
43
43
  "types": "./types/number.d.ts"
44
44
  },
45
+ "./object": {
46
+ "bun": "./src/js/object.ts",
47
+ "import": "./dist/js/object.mjs",
48
+ "require": "./dist/js/object.js",
49
+ "types": "./types/object.d.ts"
50
+ },
45
51
  "./string": {
46
52
  "bun": "./src/js/string.ts",
47
53
  "import": "./dist/js/string.mjs",
@@ -86,12 +92,12 @@
86
92
  "build": "bun run build:css && bun run build:js && bun run types",
87
93
  "build:css": "bunx sass ./src/css:./dist/css --no-source-map",
88
94
  "build:js": "bunx bun ./.bun.ts && bunx bun ./.bun.ts --mjs",
89
- "test": "bun test --preload ./test/_preload.ts --coverage",
95
+ "test": "bun test",
90
96
  "types": "bunx tsc -p ./tsconfig.json",
91
97
  "watch:css": "bunx sass ./src/css:./dist/css --no-source-map --watch",
92
98
  "watch:js": "bun build ./src/js/index.ts --outfile ./dist/js/index.js --watch"
93
99
  },
94
100
  "type": "module",
95
101
  "types": "./types/index.d.ts",
96
- "version": "0.16.0"
102
+ "version": "0.17.0"
97
103
  }
package/src/js/array.ts CHANGED
@@ -1,25 +1,126 @@
1
- import {Key} from './value';
1
+ import {GenericObject, Key} from './value';
2
2
 
3
- type KeyCallback<T> = (item: T) => Key;
3
+ type BooleanCallback<T> = (item: T, index: number, array: T[]) => boolean;
4
+
5
+ type Callbacks<T> = {
6
+ bool?: BooleanCallback<T>;
7
+ key?: KeyCallback<T>;
8
+ };
9
+
10
+ type FindType = 'index' | 'value';
4
11
 
5
12
  type InsertType = 'push' | 'splice';
6
13
 
7
- function _getCallback<T>(
8
- value: Key | KeyCallback<T> | undefined,
9
- ): KeyCallback<T> | undefined {
10
- if (typeof value === 'function') {
11
- return value;
14
+ type KeyCallback<T> = (item: T) => Key;
15
+
16
+ function _getCallbacks<T>(
17
+ bool: unknown,
18
+ key: unknown,
19
+ ): Callbacks<T> | undefined {
20
+ if (typeof bool === 'function') {
21
+ return {bool: bool as BooleanCallback<T>};
12
22
  }
13
23
 
14
- const isString = typeof value === 'string';
24
+ if (typeof key === 'function') {
25
+ return {key: key as KeyCallback<T>};
26
+ }
27
+
28
+ const isString = typeof key === 'string';
15
29
 
16
- if (!isString && typeof value !== 'number') {
30
+ if (
31
+ (!isString && typeof key !== 'number') ||
32
+ (isString && key.includes('.'))
33
+ ) {
17
34
  return;
18
35
  }
19
36
 
20
- return isString && value.includes('.')
21
- ? undefined
22
- : (item: T): Key => item[value as never];
37
+ return {
38
+ key: (item: T) => (item as GenericObject)?.[key as string] as Key,
39
+ };
40
+ }
41
+
42
+ function _findValue<T1, T2 = T1>(
43
+ type: FindType,
44
+ array: T1[],
45
+ value: T2 | BooleanCallback<T1>,
46
+ key?: Key | KeyCallback<T1>,
47
+ ): unknown {
48
+ const callbacks = _getCallbacks(value, key);
49
+
50
+ if (callbacks?.bool === undefined && callbacks?.key === undefined) {
51
+ return type === 'index'
52
+ ? array.indexOf(value as T1)
53
+ : array.find(item => item === value);
54
+ }
55
+
56
+ if (callbacks.bool !== undefined) {
57
+ const index = array.findIndex(callbacks.bool);
58
+
59
+ return type === 'index' ? index : index > -1 ? array[index] : undefined;
60
+ }
61
+
62
+ const {length} = array;
63
+
64
+ let index = 0;
65
+
66
+ for (; index < length; index += 1) {
67
+ const item = array[index];
68
+
69
+ if (callbacks.key?.(item) === value) {
70
+ return type === 'index' ? index : item;
71
+ }
72
+ }
73
+
74
+ return type === 'index' ? -1 : undefined;
75
+ }
76
+
77
+ function _findValues<T1, T2 = T1>(
78
+ type: 'all' | 'unique',
79
+ array: T1[],
80
+ value: T2 | BooleanCallback<T1>,
81
+ key?: Key | KeyCallback<T1>,
82
+ ): T1[] {
83
+ const callbacks = _getCallbacks(value, key);
84
+
85
+ const {length} = array;
86
+
87
+ if (type === 'unique' && callbacks?.key === undefined && length >= 100) {
88
+ return Array.from(new Set(array));
89
+ }
90
+
91
+ if (typeof callbacks?.bool === 'function') {
92
+ return array.filter(callbacks.bool);
93
+ }
94
+
95
+ if (type === 'all' && key === undefined) {
96
+ return array.filter(item => item === value);
97
+ }
98
+
99
+ const hasCallback = typeof callbacks?.key === 'function';
100
+
101
+ const result: T1[] = [];
102
+
103
+ const values: unknown[] = hasCallback ? [] : result;
104
+
105
+ let index = 0;
106
+
107
+ for (; index < length; index += 1) {
108
+ const item = array[index];
109
+ const itemValue = hasCallback ? callbacks.key?.(item) : item;
110
+
111
+ if (
112
+ (type === 'all' && itemValue === value) ||
113
+ (type === 'unique' && values.indexOf(itemValue) === -1)
114
+ ) {
115
+ if (values !== result) {
116
+ values.push(itemValue);
117
+ }
118
+
119
+ result.push(item);
120
+ }
121
+ }
122
+
123
+ return result;
23
124
  }
24
125
 
25
126
  function _insertValues<T>(
@@ -76,37 +177,90 @@ export function chunk<T>(array: T[], size?: number): T[][] {
76
177
  }
77
178
 
78
179
  /**
79
- * Does the value exist in the array?
80
- * - `key` is optional and can be used to specify a key or callback for finding a key for comparisons
81
- * - If `key` is not provided, the item itself is used for comparisons
180
+ * Does the value exist in array?
181
+ */
182
+ export function exists<T1, T2>(
183
+ array: T1[],
184
+ value: T2 | BooleanCallback<T1>,
185
+ ): boolean;
186
+
187
+ /**
188
+ * - Does the value exist in array?
189
+ * - Use `key` to find a comparison value to match with `value`
82
190
  */
83
191
  export function exists<T1, T2 = T1>(
84
192
  array: T1[],
85
193
  value: T2,
194
+ key: Key | KeyCallback<T1>,
195
+ ): boolean;
196
+
197
+ /**
198
+ * Does the value exist in array?
199
+ */
200
+ export function exists<T1, T2 = T1>(
201
+ array: T1[],
202
+ value: T2 | BooleanCallback<T1>,
86
203
  key?: Key | KeyCallback<T1>,
87
204
  ): boolean {
88
- const callback = _getCallback(key);
205
+ return (_findValue('index', array, value, key) as number) > -1;
206
+ }
89
207
 
90
- if (callback === undefined) {
91
- return array.indexOf(value as never) > -1;
92
- }
208
+ /**
209
+ * Returns a filtered array of items matching `value`
210
+ */
211
+ export function filter<T1, T2>(
212
+ array: T1[],
213
+ value: T2 | BooleanCallback<T1>,
214
+ ): T1[];
93
215
 
94
- const needle =
95
- typeof value === 'object' && value !== null
96
- ? callback(value as never)
97
- : value;
216
+ /**
217
+ * - Returns a filtered array of items
218
+ * - Use `key` to find a comparison value to match with `value`
219
+ */
220
+ export function filter<T1, T2 = T1>(
221
+ array: T1[],
222
+ value: T2,
223
+ key: Key | KeyCallback<T1>,
224
+ ): T1[];
98
225
 
99
- const {length} = array;
226
+ /**
227
+ * Returns a filtered array of items
228
+ */
229
+ export function filter<T1, T2 = T1>(
230
+ array: T1[],
231
+ value: T2 | BooleanCallback<T1>,
232
+ key?: Key | KeyCallback<T1>,
233
+ ): T1[] {
234
+ return _findValues('all', array, value, key);
235
+ }
100
236
 
101
- let index = 0;
237
+ /**
238
+ * Returns the first item matching `value`, or `undefined` if no match is found
239
+ */
240
+ export function find<T1, T2>(
241
+ array: T1[],
242
+ value: T2 | BooleanCallback<T1>,
243
+ ): T1 | undefined;
102
244
 
103
- for (; index < length; index += 1) {
104
- if (callback(array[index]) === needle) {
105
- return true;
106
- }
107
- }
245
+ /**
246
+ * - Returns the first matching item, or `undefined` if no match is found
247
+ * - Use `key` to find a comparison value to match with `value`
248
+ */
249
+ export function find<T1, T2 = T1>(
250
+ array: T1[],
251
+ value: T2,
252
+ key: Key | KeyCallback<T1>,
253
+ ): T1 | undefined;
108
254
 
109
- return false;
255
+ /**
256
+ * - Returns the first matching item, or `undefined` if no match is found
257
+ */
258
+ export function find<T1, T2 = T1>(
259
+ array: T1[],
260
+ value: T2 | BooleanCallback<T1>,
261
+ key?: Key | KeyCallback<T1>,
262
+ ): T1 | undefined {
263
+ return _findValue('value', array, value, key) as T1 | undefined;
110
264
  }
111
265
 
112
266
  /**
@@ -114,11 +268,11 @@ export function exists<T1, T2 = T1>(
114
268
  */
115
269
  export function groupBy<T>(
116
270
  array: T[],
117
- key: Key | ((item: T) => Key),
271
+ key: Key | KeyCallback<T>,
118
272
  ): Record<Key, T[]> {
119
- const keyCallback = _getCallback(key) as KeyCallback<T>;
273
+ const callbacks = _getCallbacks(undefined, key);
120
274
 
121
- if (keyCallback === undefined) {
275
+ if (callbacks?.key === undefined) {
122
276
  return {};
123
277
  }
124
278
 
@@ -130,7 +284,7 @@ export function groupBy<T>(
130
284
 
131
285
  for (; index < length; index += 1) {
132
286
  const item = array[index];
133
- const value = keyCallback(item);
287
+ const value = callbacks.key(item);
134
288
 
135
289
  if (value in grouped) {
136
290
  grouped[value].push(item);
@@ -142,6 +296,35 @@ export function groupBy<T>(
142
296
  return grouped;
143
297
  }
144
298
 
299
+ /**
300
+ * Returns the index for the first item matching `value`, or `-1` if no match is found
301
+ */
302
+ export function indexOf<T1, T2>(
303
+ array: T1[],
304
+ value: T2 | BooleanCallback<T1>,
305
+ ): number;
306
+
307
+ /**
308
+ * - Returns the index for the first matching item, or `-1` if no match is found
309
+ * - Use `key` to find a comparison value to match with `value`
310
+ */
311
+ export function indexOf<T1, T2 = T1>(
312
+ array: T1[],
313
+ value: T2,
314
+ key: Key | KeyCallback<T1>,
315
+ ): number;
316
+
317
+ /**
318
+ * Returns the index of the first matching item, or `-1` if no match is found
319
+ */
320
+ export function indexOf<T1, T2 = T1>(
321
+ array: T1[],
322
+ value: T2 | BooleanCallback<T1>,
323
+ key?: Key | KeyCallback<T1>,
324
+ ): number {
325
+ return _findValue('index', array, value, key) as number;
326
+ }
327
+
145
328
  /**
146
329
  * - Inserts values into an array at a specified index
147
330
  * - Uses chunking to avoid stack overflow
@@ -172,38 +355,19 @@ export function splice<T>(
172
355
  }
173
356
 
174
357
  /**
175
- * - Returns a new array with unique items
176
- * - `key` is optional and can be used to specify a key or callback for finding a key for uniqueness
177
- * - If `key` is not provided, the item itself is used for comparisons
178
- * - Inspired by Lodash :-)
358
+ * Returns an array of unique items
179
359
  */
180
- export function unique<T>(array: T[], key?: Key | ((item: T) => Key)): T[] {
181
- const keyCallback = _getCallback(key);
182
-
183
- const {length} = array;
184
-
185
- if (keyCallback === undefined && length >= 100) {
186
- return Array.from(new Set(array));
187
- }
188
-
189
- const result: T[] = [];
190
-
191
- const values: unknown[] = keyCallback === undefined ? result : [];
360
+ export function unique<T>(array: T[]): T[];
192
361
 
193
- let index = 0;
194
-
195
- for (; index < length; index += 1) {
196
- const item = array[index];
197
- const value = keyCallback?.(item) ?? item;
198
-
199
- if (values.indexOf(value) === -1) {
200
- if (values !== result) {
201
- values.push(value);
202
- }
203
-
204
- result.push(item);
205
- }
206
- }
362
+ /**
363
+ * - Returns an array of unique items
364
+ * - Use `key` to find a comparison value to match with `value`
365
+ */
366
+ export function unique<T>(array: T[], key: Key | KeyCallback<T>): T[];
207
367
 
208
- return result;
368
+ /**
369
+ * Returns an array of unique items
370
+ */
371
+ export function unique<T>(array: T[], key?: Key | KeyCallback<T>): T[] {
372
+ return _findValues('unique', array, undefined, key);
209
373
  }
package/src/js/index.ts CHANGED
@@ -2,6 +2,7 @@ export * from './array';
2
2
  export * from './element';
3
3
  export * from './event';
4
4
  export * from './number';
5
+ export * from './object';
5
6
  export * from './string';
6
7
  export * from './timer';
7
8
  export * from './value';
@@ -0,0 +1,48 @@
1
+ import {ArrayOrObject, GenericObject, isArrayOrObject} from './value';
2
+
3
+ /**
4
+ * Clones any kind of value
5
+ */
6
+ export function clone<T>(value: T): T {
7
+ return structuredClone(value);
8
+ }
9
+
10
+ /**
11
+ * Merges multiple arrays or objects into a single one
12
+ */
13
+ export function merge<T = ArrayOrObject>(...values: T[]): T {
14
+ if (values.length === 0) {
15
+ return {} as T;
16
+ }
17
+
18
+ const actual = values.filter(isArrayOrObject) as GenericObject[];
19
+ const result = (actual.every(Array.isArray) ? [] : {}) as GenericObject;
20
+
21
+ const {length: itemsLength} = actual;
22
+
23
+ let itemIndex = 0;
24
+
25
+ for (; itemIndex < itemsLength; itemIndex += 1) {
26
+ const item = actual[itemIndex];
27
+ const isArray = Array.isArray(item);
28
+ const keys = isArray ? undefined : Object.keys(item);
29
+
30
+ const keysLength = isArray ? item.length : (keys as string[]).length;
31
+
32
+ let keyIndex = 0;
33
+
34
+ for (; keyIndex < keysLength; keyIndex += 1) {
35
+ const key = keys?.[keyIndex] ?? keyIndex;
36
+ const next = item[key];
37
+ const previous = result[key];
38
+
39
+ if (isArrayOrObject(previous) && isArrayOrObject(next)) {
40
+ result[key] = merge(previous as never, next);
41
+ } else {
42
+ result[key] = next;
43
+ }
44
+ }
45
+ }
46
+
47
+ return result as T;
48
+ }
package/types/array.d.ts CHANGED
@@ -1,19 +1,50 @@
1
1
  import { Key } from './value';
2
+ type BooleanCallback<T> = (item: T, index: number, array: T[]) => boolean;
2
3
  type KeyCallback<T> = (item: T) => Key;
3
4
  /**
4
5
  * Chunks an array into smaller arrays of a specified size
5
6
  */
6
7
  export declare function chunk<T>(array: T[], size?: number): T[][];
7
8
  /**
8
- * Does the value exist in the array?
9
- * - `key` is optional and can be used to specify a key or callback for finding a key for comparisons
10
- * - If `key` is not provided, the item itself is used for comparisons
9
+ * Does the value exist in array?
11
10
  */
12
- export declare function exists<T1, T2 = T1>(array: T1[], value: T2, key?: Key | KeyCallback<T1>): boolean;
11
+ export declare function exists<T1, T2>(array: T1[], value: T2 | BooleanCallback<T1>): boolean;
12
+ /**
13
+ * - Does the value exist in array?
14
+ * - Use `key` to find a comparison value to match with `value`
15
+ */
16
+ export declare function exists<T1, T2 = T1>(array: T1[], value: T2, key: Key | KeyCallback<T1>): boolean;
17
+ /**
18
+ * Returns a filtered array of items matching `value`
19
+ */
20
+ export declare function filter<T1, T2>(array: T1[], value: T2 | BooleanCallback<T1>): T1[];
21
+ /**
22
+ * - Returns a filtered array of items
23
+ * - Use `key` to find a comparison value to match with `value`
24
+ */
25
+ export declare function filter<T1, T2 = T1>(array: T1[], value: T2, key: Key | KeyCallback<T1>): T1[];
26
+ /**
27
+ * Returns the first item matching `value`, or `undefined` if no match is found
28
+ */
29
+ export declare function find<T1, T2>(array: T1[], value: T2 | BooleanCallback<T1>): T1 | undefined;
30
+ /**
31
+ * - Returns the first matching item, or `undefined` if no match is found
32
+ * - Use `key` to find a comparison value to match with `value`
33
+ */
34
+ export declare function find<T1, T2 = T1>(array: T1[], value: T2, key: Key | KeyCallback<T1>): T1 | undefined;
13
35
  /**
14
36
  * Groups an array of items using a key or callback
15
37
  */
16
- export declare function groupBy<T>(array: T[], key: Key | ((item: T) => Key)): Record<Key, T[]>;
38
+ export declare function groupBy<T>(array: T[], key: Key | KeyCallback<T>): Record<Key, T[]>;
39
+ /**
40
+ * Returns the index for the first item matching `value`, or `-1` if no match is found
41
+ */
42
+ export declare function indexOf<T1, T2>(array: T1[], value: T2 | BooleanCallback<T1>): number;
43
+ /**
44
+ * - Returns the index for the first matching item, or `-1` if no match is found
45
+ * - Use `key` to find a comparison value to match with `value`
46
+ */
47
+ export declare function indexOf<T1, T2 = T1>(array: T1[], value: T2, key: Key | KeyCallback<T1>): number;
17
48
  /**
18
49
  * - Inserts values into an array at a specified index
19
50
  * - Uses chunking to avoid stack overflow
@@ -30,10 +61,12 @@ export declare function push<T>(array: T[], values: T[]): number;
30
61
  */
31
62
  export declare function splice<T>(array: T[], start: number, deleteCount: number, values: T[]): T[];
32
63
  /**
33
- * - Returns a new array with unique items
34
- * - `key` is optional and can be used to specify a key or callback for finding a key for uniqueness
35
- * - If `key` is not provided, the item itself is used for comparisons
36
- * - Inspired by Lodash :-)
64
+ * Returns an array of unique items
65
+ */
66
+ export declare function unique<T>(array: T[]): T[];
67
+ /**
68
+ * - Returns an array of unique items
69
+ * - Use `key` to find a comparison value to match with `value`
37
70
  */
38
- export declare function unique<T>(array: T[], key?: Key | ((item: T) => Key)): T[];
71
+ export declare function unique<T>(array: T[], key: Key | KeyCallback<T>): T[];
39
72
  export {};
package/types/index.d.ts CHANGED
@@ -2,6 +2,7 @@ export * from './array';
2
2
  export * from './element';
3
3
  export * from './event';
4
4
  export * from './number';
5
+ export * from './object';
5
6
  export * from './string';
6
7
  export * from './timer';
7
8
  export * from './value';
@@ -0,0 +1,9 @@
1
+ import { ArrayOrObject } from './value';
2
+ /**
3
+ * Clones any kind of value
4
+ */
5
+ export declare function clone<T>(value: T): T;
6
+ /**
7
+ * Merges multiple arrays or objects into a single one
8
+ */
9
+ export declare function merge<T = ArrayOrObject>(...values: T[]): T;