@oscarpalmer/atoms 0.75.0 → 0.76.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.
Files changed (215) hide show
  1. package/dist/js/array/chunk.cjs +2 -1
  2. package/dist/js/array/chunk.js +2 -1
  3. package/dist/js/array/count.cjs +10 -3
  4. package/dist/js/array/count.js +10 -3
  5. package/dist/js/array/exists.cjs +10 -3
  6. package/dist/js/array/exists.js +10 -3
  7. package/dist/js/array/filter.cjs +10 -3
  8. package/dist/js/array/filter.js +10 -3
  9. package/dist/js/array/find.cjs +10 -3
  10. package/dist/js/array/find.js +10 -3
  11. package/dist/js/array/group-by.cjs +18 -16
  12. package/dist/js/array/group-by.js +18 -16
  13. package/dist/js/array/index-of.cjs +10 -3
  14. package/dist/js/array/index-of.js +10 -3
  15. package/dist/js/array/index.cjs +2 -2
  16. package/dist/js/array/index.js +2 -2
  17. package/dist/js/array/insert.cjs +10 -4
  18. package/dist/js/array/insert.js +10 -4
  19. package/dist/js/array/splice.cjs +4 -4
  20. package/dist/js/array/splice.js +4 -4
  21. package/dist/js/array/to-map.cjs +11 -11
  22. package/dist/js/array/to-map.js +11 -11
  23. package/dist/js/array/to-record.cjs +3 -3
  24. package/dist/js/array/to-record.js +3 -3
  25. package/dist/js/array/unique.cjs +2 -2
  26. package/dist/js/array/unique.js +2 -2
  27. package/dist/js/colour/base.cjs +1 -1
  28. package/dist/js/colour/base.js +1 -1
  29. package/dist/js/colour/hex.cjs +2 -2
  30. package/dist/js/colour/hex.js +2 -2
  31. package/dist/js/colour/hsl.cjs +13 -7
  32. package/dist/js/colour/hsl.js +13 -7
  33. package/dist/js/colour/rgb.cjs +12 -6
  34. package/dist/js/colour/rgb.js +12 -6
  35. package/dist/js/emitter.cjs +8 -5
  36. package/dist/js/emitter.js +8 -5
  37. package/dist/js/function.cjs +6 -6
  38. package/dist/js/function.js +6 -6
  39. package/dist/js/index.cjs +0 -1
  40. package/dist/js/index.js +1 -2
  41. package/dist/js/internal/array/callbacks.cjs +23 -0
  42. package/dist/js/internal/array/callbacks.js +23 -0
  43. package/dist/js/internal/{array-find.cjs → array/find.cjs} +11 -12
  44. package/dist/js/internal/{array-find.js → array/find.js} +11 -12
  45. package/dist/js/logger.cjs +13 -13
  46. package/dist/js/logger.js +13 -13
  47. package/dist/js/query.cjs +0 -3
  48. package/dist/js/query.js +1 -4
  49. package/dist/js/random.cjs +0 -6
  50. package/dist/js/random.js +0 -6
  51. package/dist/js/sized.cjs +1 -1
  52. package/dist/js/sized.js +1 -1
  53. package/dist/js/string/index.cjs +7 -1
  54. package/dist/js/string/index.js +7 -1
  55. package/dist/js/value/compare.cjs +0 -1
  56. package/dist/js/value/compare.js +0 -1
  57. package/dist/js/value/get.cjs +3 -3
  58. package/dist/js/value/get.js +2 -2
  59. package/dist/js/value/set.cjs +4 -4
  60. package/dist/js/value/set.js +2 -2
  61. package/package.json +3 -2
  62. package/src/js/array/chunk.ts +6 -5
  63. package/src/js/array/compact.ts +8 -10
  64. package/src/js/array/count.ts +39 -19
  65. package/src/js/array/exists.ts +40 -16
  66. package/src/js/array/filter.ts +42 -20
  67. package/src/js/array/find.ts +45 -20
  68. package/src/js/array/group-by.ts +158 -27
  69. package/src/js/array/index-of.ts +40 -18
  70. package/src/js/array/index.ts +10 -9
  71. package/src/js/array/insert.ts +28 -14
  72. package/src/js/array/models.ts +18 -15
  73. package/src/js/array/shuffle.ts +3 -3
  74. package/src/js/array/sort.ts +28 -34
  75. package/src/js/array/splice.ts +22 -26
  76. package/src/js/array/to-map.ts +133 -45
  77. package/src/js/array/to-record.ts +137 -39
  78. package/src/js/array/unique.ts +20 -15
  79. package/src/js/colour/base.ts +3 -3
  80. package/src/js/colour/functions.ts +4 -6
  81. package/src/js/colour/hex.ts +5 -5
  82. package/src/js/colour/hsl.ts +18 -12
  83. package/src/js/colour/index.ts +1 -1
  84. package/src/js/colour/is.ts +3 -3
  85. package/src/js/colour/rgb.ts +17 -11
  86. package/src/js/emitter.ts +12 -9
  87. package/src/js/function.ts +12 -12
  88. package/src/js/index.ts +16 -16
  89. package/src/js/internal/array/callbacks.ts +33 -0
  90. package/src/js/internal/{array-find.ts → array/find.ts} +23 -24
  91. package/src/js/internal/{value-handle.ts → value/handle.ts} +1 -1
  92. package/src/js/is.ts +2 -2
  93. package/src/js/logger.ts +14 -14
  94. package/src/js/math.ts +1 -1
  95. package/src/js/models.ts +5 -5
  96. package/src/js/number.ts +2 -2
  97. package/src/js/query.ts +6 -10
  98. package/src/js/queue.ts +1 -1
  99. package/src/js/random.ts +9 -19
  100. package/src/js/sized.ts +145 -145
  101. package/src/js/string/case.ts +1 -1
  102. package/src/js/string/index.ts +13 -7
  103. package/src/js/string/template.ts +6 -3
  104. package/src/js/value/clone.ts +3 -7
  105. package/src/js/value/compare.ts +3 -5
  106. package/src/js/value/diff.ts +4 -4
  107. package/src/js/value/equal.ts +2 -2
  108. package/src/js/value/get.ts +3 -3
  109. package/src/js/value/index.ts +2 -2
  110. package/src/js/value/merge.ts +3 -3
  111. package/src/js/value/set.ts +3 -4
  112. package/src/js/value/smush.ts +4 -4
  113. package/src/js/value/unsmush.ts +4 -4
  114. package/types/array/chunk.d.cts +2 -2
  115. package/types/array/chunk.d.ts +2 -2
  116. package/types/array/compact.d.cts +4 -4
  117. package/types/array/compact.d.ts +4 -4
  118. package/types/array/count.d.cts +15 -8
  119. package/types/array/count.d.ts +13 -7
  120. package/types/array/exists.d.cts +14 -5
  121. package/types/array/exists.d.ts +12 -4
  122. package/types/array/filter.d.cts +16 -7
  123. package/types/array/filter.d.ts +14 -6
  124. package/types/array/find.d.cts +16 -7
  125. package/types/array/find.d.ts +14 -6
  126. package/types/array/group-by.d.cts +51 -5
  127. package/types/array/group-by.d.ts +49 -5
  128. package/types/array/index-of.d.cts +16 -7
  129. package/types/array/index-of.d.ts +14 -6
  130. package/types/array/index.d.cts +239 -95
  131. package/types/array/index.d.ts +7 -6
  132. package/types/array/insert.d.cts +9 -4
  133. package/types/array/insert.d.ts +10 -5
  134. package/types/array/models.d.cts +14 -11
  135. package/types/array/models.d.ts +14 -12
  136. package/types/array/shuffle.d.cts +2 -2
  137. package/types/array/shuffle.d.ts +2 -2
  138. package/types/array/sort.d.cts +11 -11
  139. package/types/array/sort.d.ts +10 -10
  140. package/types/array/splice.d.cts +4 -4
  141. package/types/array/splice.d.ts +4 -4
  142. package/types/array/to-map.d.cts +44 -20
  143. package/types/array/to-map.d.ts +42 -20
  144. package/types/array/to-record.d.cts +44 -20
  145. package/types/array/to-record.d.ts +42 -20
  146. package/types/array/unique.d.cts +11 -6
  147. package/types/array/unique.d.ts +10 -6
  148. package/types/colour/base.d.cts +28 -16
  149. package/types/colour/base.d.ts +2 -2
  150. package/types/colour/functions.d.cts +28 -16
  151. package/types/colour/functions.d.ts +3 -3
  152. package/types/colour/hex.d.cts +28 -16
  153. package/types/colour/hex.d.ts +4 -4
  154. package/types/colour/hsl.d.cts +28 -16
  155. package/types/colour/hsl.d.ts +16 -10
  156. package/types/colour/index.d.cts +28 -16
  157. package/types/colour/index.d.ts +1 -1
  158. package/types/colour/is.d.cts +28 -16
  159. package/types/colour/is.d.ts +3 -3
  160. package/types/colour/rgb.d.cts +28 -16
  161. package/types/colour/rgb.d.ts +15 -9
  162. package/types/emitter.d.cts +11 -8
  163. package/types/emitter.d.ts +11 -8
  164. package/types/function.d.cts +10 -10
  165. package/types/function.d.ts +11 -11
  166. package/types/index.d.cts +1061 -669
  167. package/types/index.d.ts +16 -16
  168. package/types/internal/array/callbacks.d.cts +11 -0
  169. package/types/internal/array/callbacks.d.ts +2 -0
  170. package/types/internal/array/find.d.cts +7 -0
  171. package/types/internal/array/find.d.ts +3 -0
  172. package/types/internal/{value-handle.d.ts → value/handle.d.ts} +1 -1
  173. package/types/is.d.ts +1 -1
  174. package/types/logger.d.cts +13 -13
  175. package/types/logger.d.ts +13 -13
  176. package/types/math.d.cts +1 -1
  177. package/types/math.d.ts +1 -1
  178. package/types/models.d.cts +4 -4
  179. package/types/models.d.ts +1 -4
  180. package/types/number.d.cts +2 -2
  181. package/types/number.d.ts +2 -2
  182. package/types/query.d.cts +2 -2
  183. package/types/query.d.ts +3 -3
  184. package/types/queue.d.cts +1 -1
  185. package/types/queue.d.ts +1 -1
  186. package/types/random.d.cts +8 -12
  187. package/types/random.d.ts +8 -12
  188. package/types/sized.d.cts +6 -6
  189. package/types/sized.d.ts +6 -6
  190. package/types/string/index.d.cts +6 -3
  191. package/types/string/index.d.ts +3 -3
  192. package/types/string/template.d.cts +3 -0
  193. package/types/string/template.d.ts +4 -1
  194. package/types/value/clone.d.cts +4 -2
  195. package/types/value/clone.d.ts +4 -2
  196. package/types/value/get.d.ts +1 -1
  197. package/types/value/index.d.cts +8 -6
  198. package/types/value/index.d.ts +2 -2
  199. package/types/value/merge.d.cts +1 -1
  200. package/types/value/merge.d.ts +2 -2
  201. package/types/value/set.d.ts +1 -1
  202. package/types/value/smush.d.cts +1 -1
  203. package/types/value/smush.d.ts +2 -2
  204. package/types/value/unsmush.d.cts +1 -1
  205. package/types/value/unsmush.d.ts +2 -2
  206. package/dist/js/internal/array-callbacks.cjs +0 -18
  207. package/dist/js/internal/array-callbacks.js +0 -18
  208. package/src/js/internal/array-callbacks.ts +0 -28
  209. package/types/internal/array-callbacks.d.cts +0 -13
  210. package/types/internal/array-callbacks.d.ts +0 -2
  211. package/types/internal/array-find.d.cts +0 -11
  212. package/types/internal/array-find.d.ts +0 -4
  213. /package/dist/js/internal/{value-handle.cjs → value/handle.cjs} +0 -0
  214. /package/dist/js/internal/{value-handle.js → value/handle.js} +0 -0
  215. /package/types/internal/{value-handle.d.cts → value/handle.d.cts} +0 -0
package/src/js/query.ts CHANGED
@@ -1,10 +1,10 @@
1
- import {isNullableOrWhitespace, isPlainObject} from '@/is';
2
- import type {ArrayOrPlainObject, PlainObject} from '@/models';
3
- import {join} from '@/string';
4
- import {setValue} from '@/value';
1
+ import {isPlainObject} from '~/is';
2
+ import type {ArrayOrPlainObject, PlainObject} from '~/models';
3
+ import {join} from '~/string';
4
+ import {setValue} from '~/value';
5
5
 
6
6
  /**
7
- * Converts a query string to a plain _(nested)_ object
7
+ * Convert a query string to a plain _(nested)_ object
8
8
  */
9
9
  export function fromQuery(query: string): PlainObject {
10
10
  const parts = query.split('&');
@@ -15,10 +15,6 @@ export function fromQuery(query: string): PlainObject {
15
15
  for (let index = 0; index < length; index += 1) {
16
16
  const [key, value] = parts[index].split('=').map(decodeURIComponent);
17
17
 
18
- if (isNullableOrWhitespace(key)) {
19
- continue;
20
- }
21
-
22
18
  if (key.includes('.')) {
23
19
  setValue(parameters, key, getValue(value));
24
20
  } else {
@@ -86,7 +82,7 @@ function isDecodable(value: unknown): value is boolean | number | string {
86
82
  }
87
83
 
88
84
  /**
89
- * Converts a plain _(nested)_ object to a query string
85
+ * Convert a plain _(nested)_ object to a query string
90
86
  */
91
87
  export function toQuery(parameters: PlainObject): string {
92
88
  return getParts(parameters, false)
package/src/js/queue.ts CHANGED
@@ -13,7 +13,7 @@ if (globalThis._atomic_queued == null) {
13
13
  }
14
14
 
15
15
  /**
16
- * Queues a callback to be executed at the next best time
16
+ * Queue a callback to be executed at the next best time
17
17
  */
18
18
  export function queue(callback: () => void): void {
19
19
  _atomic_queued.add(callback);
package/src/js/random.ts CHANGED
@@ -1,14 +1,14 @@
1
- import {shuffle} from '@/array/shuffle';
1
+ import {shuffle} from '~/array/shuffle';
2
2
 
3
3
  /**
4
- * Returns a random boolean
4
+ * Get a random boolean
5
5
  */
6
6
  export function getRandomBoolean(): boolean {
7
7
  return Math.random() > 0.5;
8
8
  }
9
9
 
10
10
  /**
11
- * Returns a random string of characters with a specified length
11
+ * Get a random string of characters with a specified length
12
12
  * - `selection` defaults to all lowercase letters in the English alphabet
13
13
  */
14
14
  export function getRandomCharacters(
@@ -34,24 +34,14 @@ export function getRandomCharacters(
34
34
  }
35
35
 
36
36
  /**
37
- * Returns a random hexadecimal colour
37
+ * Get a random hexadecimal colour
38
38
  */
39
39
  export function getRandomColour(): string {
40
40
  return `#${Array.from({length: 6}, getRandomHex).join('')}`;
41
41
  }
42
42
 
43
43
  /**
44
- * Returns a random date
45
- */
46
- export function getRandomDate(earliest?: Date, latest?: Date): Date {
47
- const earliestTime = earliest?.getTime() ?? -8_640_000_000_000_000;
48
- const latestTime = latest?.getTime() ?? 8_640_000_000_000_000;
49
-
50
- return new Date(getRandomInteger(earliestTime, latestTime));
51
- }
52
-
53
- /**
54
- * Returns a random floating-point number
44
+ * Get a random floating-point number
55
45
  */
56
46
  export function getRandomFloat(min?: number, max?: number): number {
57
47
  const minimum = min ?? Number.MIN_SAFE_INTEGER;
@@ -60,28 +50,28 @@ export function getRandomFloat(min?: number, max?: number): number {
60
50
  }
61
51
 
62
52
  /**
63
- * Returns a random hexadecimal character
53
+ * Get a random hexadecimal character
64
54
  */
65
55
  export function getRandomHex(): string {
66
56
  return '0123456789ABCDEF'[getRandomInteger(0, 16)];
67
57
  }
68
58
 
69
59
  /**
70
- * Returns a random integer
60
+ * Get a random integer
71
61
  */
72
62
  export function getRandomInteger(min?: number, max?: number): number {
73
63
  return Math.floor(getRandomFloat(min, max));
74
64
  }
75
65
 
76
66
  /**
77
- * Returns a random item from an array
67
+ * Get a random item from an array
78
68
  */
79
69
  export function getRandomItem<Value>(array: Value[]): Value {
80
70
  return array[getRandomInteger(0, array.length)];
81
71
  }
82
72
 
83
73
  /**
84
- * - Returns an amount of random items from an array
74
+ * - Get an amount of random items from an array
85
75
  * - If `amount` is not specified, a shuffled array will be returned instead
86
76
  */
87
77
  export function getRandomItems<Value>(
package/src/js/sized.ts CHANGED
@@ -1,4 +1,4 @@
1
- import {clamp} from '@/number';
1
+ import {clamp} from '~/number';
2
2
 
3
3
  /**
4
4
  * A Map with a maximum size
@@ -6,85 +6,85 @@ import {clamp} from '@/number';
6
6
  * - Behaviour is similar to a _LRU_-cache, where the least recently used entries are removed
7
7
  */
8
8
  export class SizedMap<Key = unknown, Value = unknown> extends Map<Key, Value> {
9
- private readonly maximumSize: number;
9
+ private readonly maximumSize: number;
10
10
 
11
- /**
12
- * Is the Map full?
13
- */
14
- get full() {
15
- return this.size >= this.maximumSize;
16
- }
17
-
18
- /**
19
- * The maximum size of the Map
20
- */
21
- get maximum() {
22
- return this.maximumSize;
23
- }
11
+ /**
12
+ * Is the Map full?
13
+ */
14
+ get full() {
15
+ return this.size >= this.maximumSize;
16
+ }
24
17
 
25
- /**
26
- * Creates a new Map with entries and a maximum size _(2^20)_
27
- */
28
- constructor(entries: Array<[Key, Value]>);
29
-
30
- /**
31
- * Creates a new Map with a maximum size _(but clamped at 2^24)_
32
- */
33
- constructor(maximum: number);
34
-
35
- /**
36
- * Creates a new Map with _(optional)_ entries and a maximum size _(defaults to 2^20; clamped at 2^24)_
37
- */
38
- constructor(entries?: Array<[Key, Value]>, maximum?: number);
39
-
40
- constructor(entries?: Array<[Key, Value]> | number, maximum?: number) {
41
- const maximumSize = getMaximum(
42
- typeof entries === 'number'
43
- ? entries
44
- : typeof maximum === 'number'
45
- ? maximum
46
- : undefined,
47
- );
18
+ /**
19
+ * The maximum size of the Map
20
+ */
21
+ get maximum() {
22
+ return this.maximumSize;
23
+ }
48
24
 
49
- super(Array.isArray(entries) ? entries.slice(0, maximumSize) : undefined);
25
+ /**
26
+ * Create a new Map with entries and a maximum size _(2^20)_
27
+ */
28
+ constructor(entries: Array<[Key, Value]>);
29
+
30
+ /**
31
+ * Create a new Map with a maximum size _(but clamped at 2^24)_
32
+ */
33
+ constructor(maximum: number);
34
+
35
+ /**
36
+ * Create a new Map with _(optional)_ entries and a maximum size _(defaults to 2^20; clamped at 2^24)_
37
+ */
38
+ constructor(entries?: Array<[Key, Value]>, maximum?: number);
39
+
40
+ constructor(entries?: Array<[Key, Value]> | number, maximum?: number) {
41
+ const maximumSize = getMaximum(
42
+ typeof entries === 'number'
43
+ ? entries
44
+ : typeof maximum === 'number'
45
+ ? maximum
46
+ : undefined,
47
+ );
48
+
49
+ super(Array.isArray(entries) ? entries.slice(0, maximumSize) : undefined);
50
+
51
+ this.maximumSize = maximumSize;
52
+
53
+ if (Array.isArray(entries) && entries.length > maximumSize) {
54
+ for (let index = 0; index < maximumSize; index += 1) {
55
+ this.set(...entries[entries.length - maximumSize + index]);
56
+ }
57
+ }
58
+ }
50
59
 
51
- this.maximumSize = maximumSize;
60
+ /**
61
+ * @inheritdoc
62
+ */
63
+ get(key: Key): Value | undefined {
64
+ const value = super.get(key);
52
65
 
53
- if (Array.isArray(entries) && entries.length > maximumSize) {
54
- for (let index = 0; index < maximumSize; index += 1) {
55
- this.set(...entries[entries.length - maximumSize + index]);
66
+ if (value == null && !this.has(key)) {
67
+ return;
56
68
  }
57
- }
58
- }
59
69
 
60
- /**
61
- * @inheritdoc
62
- */
63
- get(key: Key): Value | undefined {
64
- const value = super.get(key);
70
+ this.set(key, value as Value);
65
71
 
66
- if (value === undefined && !this.has(key)) {
67
- return;
72
+ return value;
68
73
  }
69
74
 
70
- this.set(key, value as Value);
71
-
72
- return value;
73
- }
75
+ /**
76
+ * @inheritdoc
77
+ */
78
+ set(key: Key, value: Value): this {
79
+ if (this.has(key)) {
80
+ this.delete(key);
81
+ } else if (this.size >= this.maximumSize) {
82
+ this.delete(this.keys().next().value as Key);
83
+ }
74
84
 
75
- /**
76
- * @inheritdoc
77
- */
78
- set(key: Key, value: Value): this {
79
- if (this.has(key)) {
80
- this.delete(key);
81
- } else if (this.size >= this.maximumSize) {
82
- this.delete(this.keys().next().value as Key);
85
+ return super.set(key, value);
83
86
  }
84
-
85
- return super.set(key, value);
86
87
  }
87
- }
88
88
 
89
89
  /**
90
90
  * A Set with a maximum size
@@ -92,104 +92,104 @@ export class SizedMap<Key = unknown, Value = unknown> extends Map<Key, Value> {
92
92
  * - Behaviour is similar to a _LRU_-cache, where the oldest values are removed
93
93
  */
94
94
  export class SizedSet<Value = unknown> extends Set<Value> {
95
- private readonly maximumSize: number;
95
+ private readonly maximumSize: number;
96
96
 
97
- /**
98
- * Is the Set full?
99
- */
100
- get full() {
101
- return this.size >= this.maximumSize;
102
- }
97
+ /**
98
+ * Is the Set full?
99
+ */
100
+ get full() {
101
+ return this.size >= this.maximumSize;
102
+ }
103
103
 
104
- /**
105
- * The maximum size of the Set
106
- */
107
- get maximum() {
108
- return this.maximumSize;
109
- }
104
+ /**
105
+ * The maximum size of the Set
106
+ */
107
+ get maximum() {
108
+ return this.maximumSize;
109
+ }
110
110
 
111
- /**
112
- * Creates a new Set with values and a maximum size _(2^20)_
113
- */
114
- constructor(values: Value[]);
115
-
116
- /**
117
- * Creates a new Set with a maximum size _(but clamped at 2^24)_
118
- */
119
- constructor(maximum: number);
120
-
121
- /**
122
- * Creates a new Set with _(optional)_ values and a maximum size _(defaults to 2^20; clamped at 2^24)_
123
- */
124
- constructor(values?: Value[], maximum?: number);
125
-
126
- constructor(values?: Value[] | number, maximum?: number) {
127
- const maximumSize = getMaximum(
128
- typeof values === 'number'
129
- ? values
130
- : typeof maximum === 'number'
131
- ? maximum
111
+ /**
112
+ * Create a new Set with values and a maximum size _(2^20)_
113
+ */
114
+ constructor(values: Value[]);
115
+
116
+ /**
117
+ * Create a new Set with a maximum size _(but clamped at 2^24)_
118
+ */
119
+ constructor(maximum: number);
120
+
121
+ /**
122
+ * Create a new Set with _(optional)_ values and a maximum size _(defaults to 2^20; clamped at 2^24)_
123
+ */
124
+ constructor(values?: Value[], maximum?: number);
125
+
126
+ constructor(values?: Value[] | number, maximum?: number) {
127
+ const maximumSize = getMaximum(
128
+ typeof values === 'number'
129
+ ? values
130
+ : typeof maximum === 'number'
131
+ ? maximum
132
+ : undefined,
133
+ );
134
+
135
+ super(
136
+ Array.isArray(values) && values.length <= maximumSize
137
+ ? values
132
138
  : undefined,
133
- );
139
+ );
134
140
 
135
- super(
136
- Array.isArray(values) && values.length <= maximumSize
137
- ? values
138
- : undefined,
139
- );
141
+ this.maximumSize = maximumSize;
140
142
 
141
- this.maximumSize = maximumSize;
142
-
143
- if (Array.isArray(values) && values.length > maximumSize) {
144
- for (let index = 0; index < maximumSize; index += 1) {
145
- this.add(values[values.length - maximumSize + index]);
143
+ if (Array.isArray(values) && values.length > maximumSize) {
144
+ for (let index = 0; index < maximumSize; index += 1) {
145
+ this.add(values[values.length - maximumSize + index]);
146
+ }
146
147
  }
147
148
  }
148
- }
149
-
150
- /**
151
- * @inheritdoc
152
- */
153
- add(value: Value): this {
154
- if (this.has(value)) {
155
- this.delete(value);
156
- } else if (this.size >= this.maximumSize) {
157
- this.delete(this.values().next().value as Value);
158
- }
159
149
 
160
- return super.add(value);
161
- }
150
+ /**
151
+ * @inheritdoc
152
+ */
153
+ add(value: Value): this {
154
+ if (this.has(value)) {
155
+ this.delete(value);
156
+ } else if (this.size >= this.maximumSize) {
157
+ this.delete(this.values().next().value as Value);
158
+ }
162
159
 
163
- /**
164
- * Get a value from an index in the Set, if it exists
165
- * - Negative indices are counted from the end
166
- * - Optionally move the value to the end with `update`
167
- */
168
- at(index: number, update?: boolean): Value | undefined {
169
- const value = [...this.values()][index < 0 ? this.size + index : index];
170
-
171
- if ((update ?? false) && this.has(value)) {
172
- this.delete(value);
173
- this.add(value);
160
+ return super.add(value);
174
161
  }
175
162
 
176
- return value;
177
- }
163
+ /**
164
+ * Get a value from an index in the Set, if it exists
165
+ * - Negative indices are counted from the end
166
+ * - Optionally move the value to the end with `update`
167
+ */
168
+ at(index: number, update?: boolean): Value | undefined {
169
+ const value = [...this.values()][index < 0 ? this.size + index : index];
178
170
 
179
- /**
180
- * Get a value from the Set, if it exists _(and move it to the end)_
181
- */
182
- get(value: Value, update?: boolean): Value | undefined {
183
- if (this.has(value)) {
184
- if (update ?? false) {
171
+ if ((update ?? false) && this.has(value)) {
185
172
  this.delete(value);
186
173
  this.add(value);
187
174
  }
188
175
 
189
176
  return value;
190
177
  }
178
+
179
+ /**
180
+ * Get a value from the Set, if it exists _(and move it to the end)_
181
+ */
182
+ get(value: Value, update?: boolean): Value | undefined {
183
+ if (this.has(value)) {
184
+ if (update ?? false) {
185
+ this.delete(value);
186
+ this.add(value);
187
+ }
188
+
189
+ return value;
190
+ }
191
+ }
191
192
  }
192
- }
193
193
 
194
194
  function getMaximum(first?: unknown, second?: unknown): number {
195
195
  const actual =
@@ -1,4 +1,4 @@
1
- import {words} from '@/string/index';
1
+ import {words} from '~/string/index';
2
2
 
3
3
  /**
4
4
  * Convert a string to camel case _(thisIsCamelCase)_
@@ -1,4 +1,4 @@
1
- import {compact} from '@/array';
1
+ import {compact} from '~/array';
2
2
 
3
3
  /**
4
4
  * Create a new UUID
@@ -34,7 +34,7 @@ export function getString(value: unknown): string {
34
34
  }
35
35
 
36
36
  /**
37
- * Joins an array into a string while ignoring empty values _(with an optional delimiter)_
37
+ * Join an array into a string while ignoring empty values _(with an optional delimiter)_
38
38
  */
39
39
  export function join(value: unknown[], delimiter?: string): string {
40
40
  return compact(value)
@@ -44,7 +44,7 @@ export function join(value: unknown[], delimiter?: string): string {
44
44
  }
45
45
 
46
46
  /**
47
- * Parses a JSON string into its proper value _(or `undefined` if it fails)_
47
+ * Parse a JSON string into its proper value _(or `undefined` if it fails)_
48
48
  */
49
49
  export function parse(
50
50
  value: string,
@@ -58,7 +58,7 @@ export function parse(
58
58
  }
59
59
 
60
60
  /**
61
- * Truncates a string to a specified length, when possible
61
+ * Truncate a string to a specified length, when possible
62
62
  * - Returned as-is if the string is already short enough
63
63
  * - A suffix may be appended to the truncated string, e.g., an ellipsis
64
64
  */
@@ -67,12 +67,18 @@ export function truncate(
67
67
  length: number,
68
68
  suffix?: string,
69
69
  ): string {
70
+ if (length <= 0) {
71
+ return '';
72
+ }
73
+
74
+ if (length >= value.length) {
75
+ return value;
76
+ }
77
+
70
78
  const suffixLength = suffix?.length ?? 0;
71
79
  const truncatedLength = length - suffixLength;
72
80
 
73
- return value.length <= length
74
- ? value
75
- : `${value.slice(0, truncatedLength)}${suffix ?? ''}`;
81
+ return `${value.slice(0, truncatedLength)}${suffix ?? ''}`;
76
82
  }
77
83
 
78
84
  /**
@@ -1,6 +1,6 @@
1
- import type {PlainObject} from '@/models';
2
- import {getString} from '@/string/index';
3
- import {getValue} from '@/value/get';
1
+ import type {PlainObject} from '~/models';
2
+ import {getString} from '~/string/index';
3
+ import {getValue} from '~/value/get';
4
4
 
5
5
  type Options = {
6
6
  /**
@@ -13,6 +13,9 @@ type Options = {
13
13
  pattern?: RegExp;
14
14
  };
15
15
 
16
+ /**
17
+ * Render a string from a template with variables
18
+ */
16
19
  export function template(
17
20
  value: string,
18
21
  variables: PlainObject,
@@ -1,12 +1,8 @@
1
- import {isArrayOrPlainObject} from '@/is';
2
- import type {ArrayOrPlainObject, PlainObject} from '@/models';
3
-
4
- export function clone(fn: (...args: unknown[]) => unknown): null;
5
-
6
- export function clone<Value>(value: Value): Value;
1
+ import {isArrayOrPlainObject} from '~/is';
2
+ import type {ArrayOrPlainObject, GenericCallback, PlainObject} from '~/models';
7
3
 
8
4
  /**
9
- * Clones any kind of value _(deeply, if needed)_
5
+ * Clone any kind of value _(deeply, if needed)_
10
6
  */
11
7
  export function clone(value: unknown) {
12
8
  switch (true) {
@@ -1,6 +1,6 @@
1
- import {max} from '@/math';
2
- import {getNumber} from '@/number';
3
- import {words, getString, join} from '@/string';
1
+ import {max} from '~/math';
2
+ import {getNumber} from '~/number';
3
+ import {words, getString, join} from '~/string';
4
4
 
5
5
  /**
6
6
  * Compare two values _(for sorting purposes)_
@@ -62,8 +62,6 @@ export function compare(first: unknown, second: unknown): number {
62
62
  // Same value on last part? let's not fall through to string comparison
63
63
  return 0;
64
64
  }
65
-
66
- continue;
67
65
  }
68
66
 
69
67
  return firstNumber - secondNumber;
@@ -1,7 +1,7 @@
1
- import {isArrayOrPlainObject} from '@/is';
2
- import type {ArrayOrPlainObject, Key, PlainObject} from '@/models';
3
- import {join} from '@/string/index';
4
- import {equal} from '@/value/equal';
1
+ import {isArrayOrPlainObject} from '~/is';
2
+ import type {ArrayOrPlainObject, Key, PlainObject} from '~/models';
3
+ import {join} from '~/string/index';
4
+ import {equal} from '~/value/equal';
5
5
 
6
6
  export type DiffType = 'full' | 'none' | 'partial';
7
7
 
@@ -1,5 +1,5 @@
1
- import {isPlainObject} from '@/is';
2
- import type {ArrayOrPlainObject, PlainObject} from '@/models';
1
+ import {isPlainObject} from '~/is';
2
+ import type {ArrayOrPlainObject, PlainObject} from '~/models';
3
3
 
4
4
  /**
5
5
  * Are two strings equal? _(Case-sensitive by default)_
@@ -1,6 +1,6 @@
1
- import {handleValue} from '@/internal/value-handle';
2
- import type {Get, Paths, PlainObject} from '@/models';
3
1
  import type {ToString} from 'type-fest/source/internal/string';
2
+ import {handleValue} from '~/internal/value/handle';
3
+ import type {Get, Paths, PlainObject} from '~/models';
4
4
 
5
5
  /**
6
6
  * - Get the value from an object using a known path
@@ -34,7 +34,7 @@ export function getValue(
34
34
  const {length} = parts;
35
35
 
36
36
  let index = 0;
37
- let value = typeof data === 'object' ? (data ?? {}) : {};
37
+ let value: PlainObject = data;
38
38
 
39
39
  while (index < length && value != null) {
40
40
  value = handleValue(
@@ -1,7 +1,7 @@
1
- import type {PlainObject} from '@/models';
1
+ import type {PlainObject} from '~/models';
2
2
 
3
3
  /**
4
- * Creates a new object with only the specified keys
4
+ * Create a new object with only the specified keys
5
5
  */
6
6
  export function partial<Value extends PlainObject, Key extends keyof Value>(
7
7
  value: Value,
@@ -1,5 +1,5 @@
1
- import {isArrayOrPlainObject} from '@/is';
2
- import type {ArrayOrPlainObject, PlainObject} from '@/models';
1
+ import {isArrayOrPlainObject} from '~/is';
2
+ import type {ArrayOrPlainObject, PlainObject} from '~/models';
3
3
 
4
4
  type MergeOptions = {
5
5
  /**
@@ -10,7 +10,7 @@ type MergeOptions = {
10
10
  };
11
11
 
12
12
  /**
13
- * Merges multiple arrays or objects into a single one
13
+ * Merge multiple arrays or objects into a single one
14
14
  */
15
15
  export function merge<Model extends ArrayOrPlainObject>(
16
16
  values: Model[],
@@ -1,5 +1,5 @@
1
- import {handleValue} from '@/internal/value-handle';
2
- import type {Paths, PlainObject} from '@/models';
1
+ import {handleValue} from '~/internal/value/handle';
2
+ import type {Paths, PlainObject} from '~/models';
3
3
 
4
4
  /**
5
5
  * - Set the value in an object using a known path
@@ -38,8 +38,7 @@ export function setValue<Data extends PlainObject>(
38
38
  const {length} = parts;
39
39
  const lastIndex = length - 1;
40
40
 
41
- let target: PlainObject =
42
- typeof data === 'object' && data !== null ? data : {};
41
+ let target: PlainObject = data;
43
42
 
44
43
  for (let index = 0; index < length; index += 1) {
45
44
  const part = parts[index];