atomic-fns 1.2.0 → 2.0.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 (216) hide show
  1. package/README.md +397 -91
  2. package/dist/array/index.d.ts +9 -0
  3. package/dist/array/index.js +9 -0
  4. package/dist/array/list.d.ts +99 -0
  5. package/dist/array/list.js +133 -0
  6. package/dist/array/sets.d.ts +130 -0
  7. package/dist/array/sets.js +213 -0
  8. package/dist/async/index.d.ts +6 -0
  9. package/dist/async/index.js +6 -0
  10. package/dist/async/retry.d.ts +38 -0
  11. package/dist/async/retry.js +56 -0
  12. package/dist/async/sleep.d.ts +42 -0
  13. package/dist/async/sleep.js +76 -0
  14. package/dist/collections/bisect.d.ts +103 -0
  15. package/dist/collections/bisect.js +157 -0
  16. package/dist/collections/deque.d.ts +67 -97
  17. package/dist/collections/deque.js +197 -256
  18. package/dist/collections/entries.d.ts +89 -0
  19. package/dist/collections/entries.js +131 -0
  20. package/dist/collections/frozen-set.d.ts +42 -0
  21. package/dist/collections/frozen-set.js +64 -0
  22. package/dist/collections/group.d.ts +141 -0
  23. package/dist/collections/group.js +241 -0
  24. package/dist/collections/heap.d.ts +64 -0
  25. package/dist/collections/heap.js +205 -0
  26. package/dist/collections/index.d.ts +15 -623
  27. package/dist/collections/index.js +14 -844
  28. package/dist/collections/internal/arrayKeys.d.ts +19 -0
  29. package/dist/collections/internal/arrayKeys.js +83 -0
  30. package/dist/collections/internal/invariants.d.ts +4 -0
  31. package/dist/collections/internal/invariants.js +12 -0
  32. package/dist/collections/internal/iterable.d.ts +25 -0
  33. package/dist/collections/internal/iterable.js +62 -0
  34. package/dist/collections/iterate.d.ts +162 -0
  35. package/dist/collections/iterate.js +188 -0
  36. package/dist/collections/lru-cache.d.ts +58 -0
  37. package/dist/collections/lru-cache.js +164 -0
  38. package/dist/collections/order.d.ts +19 -0
  39. package/dist/collections/order.js +38 -0
  40. package/dist/collections/shape.d.ts +32 -0
  41. package/dist/collections/shape.js +86 -0
  42. package/dist/collections/sorted-map.d.ts +171 -0
  43. package/dist/collections/sorted-map.js +845 -0
  44. package/dist/collections/sorted-set.d.ts +103 -0
  45. package/dist/collections/sorted-set.js +147 -0
  46. package/dist/collections/splay-tree.d.ts +82 -0
  47. package/dist/collections/splay-tree.js +354 -0
  48. package/dist/collections/trie.d.ts +58 -0
  49. package/dist/collections/trie.js +196 -0
  50. package/dist/decimal/currency.d.ts +211 -0
  51. package/dist/decimal/currency.js +321 -0
  52. package/dist/decimal/decimal.d.ts +299 -0
  53. package/dist/decimal/decimal.js +660 -0
  54. package/dist/decimal/index.d.ts +11 -148
  55. package/dist/decimal/index.js +10 -410
  56. package/dist/decimal/internal/bits.d.ts +2 -0
  57. package/dist/decimal/internal/bits.js +7 -0
  58. package/dist/decimal/internal/echo.d.ts +4 -0
  59. package/dist/decimal/internal/echo.js +6 -0
  60. package/dist/decimal/internal/isqrt.d.ts +9 -0
  61. package/dist/decimal/internal/isqrt.js +34 -0
  62. package/dist/decimal/internal/locale.d.ts +7 -0
  63. package/dist/decimal/internal/locale.js +24 -0
  64. package/dist/decimal/internal/minor-units.d.ts +2 -0
  65. package/dist/decimal/internal/minor-units.js +33 -0
  66. package/dist/decimal/internal/pow10.d.ts +24 -0
  67. package/dist/decimal/internal/pow10.js +96 -0
  68. package/dist/encoding/base64.d.ts +39 -0
  69. package/dist/encoding/base64.js +53 -0
  70. package/dist/encoding/hex.d.ts +23 -0
  71. package/dist/encoding/hex.js +34 -0
  72. package/dist/encoding/index.d.ts +6 -0
  73. package/dist/encoding/index.js +6 -0
  74. package/dist/function/debounce.d.ts +68 -0
  75. package/dist/function/debounce.js +203 -0
  76. package/dist/function/index.d.ts +6 -0
  77. package/dist/function/index.js +6 -0
  78. package/dist/function/shared.d.ts +2 -0
  79. package/dist/function/shared.js +5 -0
  80. package/dist/function/wrap.d.ts +130 -0
  81. package/dist/function/wrap.js +113 -0
  82. package/dist/hash/digest.d.ts +18 -0
  83. package/dist/hash/digest.js +26 -0
  84. package/dist/hash/hash.d.ts +22 -0
  85. package/dist/hash/hash.js +252 -0
  86. package/dist/hash/hashString.d.ts +13 -0
  87. package/dist/hash/hashString.js +53 -0
  88. package/dist/hash/index.d.ts +8 -0
  89. package/dist/hash/index.js +8 -0
  90. package/dist/hash/stableStringify.d.ts +19 -0
  91. package/dist/hash/stableStringify.js +102 -0
  92. package/dist/id/index.d.ts +7 -0
  93. package/dist/id/index.js +7 -0
  94. package/dist/id/nanoid.d.ts +16 -0
  95. package/dist/id/nanoid.js +65 -0
  96. package/dist/id/uniqueId.d.ts +14 -0
  97. package/dist/id/uniqueId.js +20 -0
  98. package/dist/id/uuid.d.ts +25 -0
  99. package/dist/id/uuid.js +64 -0
  100. package/dist/index.d.ts +15 -8
  101. package/dist/index.js +15 -8
  102. package/dist/internal/bytes.d.ts +11 -0
  103. package/dist/internal/bytes.js +33 -0
  104. package/dist/internal/codec.d.ts +11 -0
  105. package/dist/internal/codec.js +84 -0
  106. package/dist/internal/compare.d.ts +10 -0
  107. package/dist/internal/compare.js +26 -0
  108. package/dist/internal/crypto.d.ts +5 -0
  109. package/dist/internal/crypto.js +11 -0
  110. package/dist/internal/keys.d.ts +12 -0
  111. package/dist/internal/keys.js +23 -0
  112. package/dist/internal/kind.d.ts +44 -0
  113. package/dist/internal/kind.js +139 -0
  114. package/dist/internal/sparse.d.ts +51 -0
  115. package/dist/internal/sparse.js +104 -0
  116. package/dist/internal/text.d.ts +7 -0
  117. package/dist/internal/text.js +15 -0
  118. package/dist/internal/timer.d.ts +10 -0
  119. package/dist/internal/timer.js +17 -0
  120. package/dist/internal/truncate.d.ts +10 -0
  121. package/dist/internal/truncate.js +22 -0
  122. package/dist/internal/walk.d.ts +47 -0
  123. package/dist/internal/walk.js +100 -0
  124. package/dist/is/index.d.ts +8 -0
  125. package/dist/is/index.js +8 -0
  126. package/dist/is/isArrayLike.d.ts +18 -0
  127. package/dist/is/isArrayLike.js +25 -0
  128. package/dist/is/isError.d.ts +13 -0
  129. package/dist/is/isError.js +18 -0
  130. package/dist/is/isNil.d.ts +12 -0
  131. package/dist/is/isNil.js +14 -0
  132. package/dist/is/isPlainObject.d.ts +15 -0
  133. package/dist/is/isPlainObject.js +34 -0
  134. package/dist/number/index.d.ts +7 -0
  135. package/dist/number/index.js +7 -0
  136. package/dist/number/round.d.ts +86 -0
  137. package/dist/number/round.js +130 -0
  138. package/dist/number/stats.d.ts +52 -0
  139. package/dist/number/stats.js +115 -0
  140. package/dist/object/cloneDeep.d.ts +28 -0
  141. package/dist/object/cloneDeep.js +200 -0
  142. package/dist/object/index.d.ts +14 -0
  143. package/dist/object/index.js +13 -0
  144. package/dist/object/isEqual.d.ts +64 -0
  145. package/dist/object/isEqual.js +289 -0
  146. package/dist/object/matches.d.ts +40 -0
  147. package/dist/object/matches.js +284 -0
  148. package/dist/object/merge.d.ts +66 -0
  149. package/dist/object/merge.js +272 -0
  150. package/dist/object/parsePath.d.ts +22 -0
  151. package/dist/object/parsePath.js +111 -0
  152. package/dist/object/path.d.ts +85 -0
  153. package/dist/object/path.js +208 -0
  154. package/dist/object/pick.d.ts +91 -0
  155. package/dist/object/pick.js +180 -0
  156. package/dist/object/reshape.d.ts +73 -0
  157. package/dist/object/reshape.js +144 -0
  158. package/dist/random/index.d.ts +96 -32
  159. package/dist/random/index.js +215 -53
  160. package/dist/string/case.d.ts +71 -0
  161. package/dist/string/case.js +152 -0
  162. package/dist/string/fold.d.ts +35 -0
  163. package/dist/string/fold.js +100 -0
  164. package/dist/string/index.d.ts +6 -187
  165. package/dist/string/index.js +6 -224
  166. package/dist/string/truncate.d.ts +25 -0
  167. package/dist/string/truncate.js +44 -0
  168. package/dist/string/words.d.ts +27 -0
  169. package/dist/string/words.js +241 -0
  170. package/package.json +99 -51
  171. package/dist/collections/BTree.d.ts +0 -230
  172. package/dist/collections/BTree.js +0 -1143
  173. package/dist/collections/Heap.d.ts +0 -69
  174. package/dist/collections/Heap.js +0 -181
  175. package/dist/collections/LRUCache.d.ts +0 -83
  176. package/dist/collections/LRUCache.js +0 -139
  177. package/dist/collections/SortedMap.d.ts +0 -92
  178. package/dist/collections/SortedMap.js +0 -131
  179. package/dist/collections/SortedSet.d.ts +0 -69
  180. package/dist/collections/SortedSet.js +0 -99
  181. package/dist/collections/SortedTree.d.ts +0 -103
  182. package/dist/collections/SortedTree.js +0 -142
  183. package/dist/collections/SplayTree.d.ts +0 -107
  184. package/dist/collections/SplayTree.js +0 -351
  185. package/dist/collections/Trie.d.ts +0 -42
  186. package/dist/collections/Trie.js +0 -104
  187. package/dist/collections/abc.d.ts +0 -152
  188. package/dist/collections/abc.js +0 -39
  189. package/dist/collections/frozenset.d.ts +0 -19
  190. package/dist/collections/frozenset.js +0 -33
  191. package/dist/functools/index.d.ts +0 -106
  192. package/dist/functools/index.js +0 -203
  193. package/dist/globals/index.d.ts +0 -268
  194. package/dist/globals/index.js +0 -447
  195. package/dist/i18n/currency.d.ts +0 -27
  196. package/dist/i18n/currency.js +0 -100
  197. package/dist/i18n/date/index.d.ts +0 -210
  198. package/dist/i18n/date/index.js +0 -552
  199. package/dist/i18n/date/utils.d.ts +0 -64
  200. package/dist/i18n/date/utils.js +0 -192
  201. package/dist/i18n/duration.d.ts +0 -113
  202. package/dist/i18n/duration.js +0 -398
  203. package/dist/i18n/format.d.ts +0 -34
  204. package/dist/i18n/format.js +0 -378
  205. package/dist/i18n/index.d.ts +0 -9
  206. package/dist/i18n/index.js +0 -8
  207. package/dist/itertools/index.d.ts +0 -251
  208. package/dist/itertools/index.js +0 -434
  209. package/dist/math/index.d.ts +0 -79
  210. package/dist/math/index.js +0 -81
  211. package/dist/mod.d.ts +0 -1
  212. package/dist/mod.js +0 -1
  213. package/dist/operators/index.d.ts +0 -148
  214. package/dist/operators/index.js +0 -325
  215. package/dist/types.d.ts +0 -19
  216. package/dist/types.js +0 -1
@@ -1,847 +1,17 @@
1
1
  /**
2
- * This module includes classes and functions to work with Container types.
3
- *
2
+ * Iteration over objects, arrays, strings, maps, sets and other iterables.
3
+ * Sorted containers, trees, heaps, deques, caches, tries and bisect.
4
4
  * @module collections
5
5
  */
6
- import { call, get, isArrayLike, isDate, isEmpty, isFunction, isIterable, isNull, isObject, isRegExp } from '../globals/index.js';
7
- import { enumerate } from '../itertools/index.js';
8
- import { compare, eq, identity } from '../operators/index.js';
9
- export * from './abc.js';
10
- export * from './BTree.js';
11
- export * from './deque.js';
12
- export * from './frozenset.js';
13
- export * from './Heap.js';
14
- export * from './LRUCache.js';
15
- export * from './SortedMap.js';
16
- export * from './SortedSet.js';
17
- export * from './SortedTree.js';
18
- export * from './SplayTree.js';
19
- export * from './Trie.js';
20
- /** Assigns `key`, defining it where a plain write would set the prototype instead. */
21
- function setOwn(obj, key, value) {
22
- if (typeof key === 'string' && key !== '__proto__') {
23
- obj[key] = value;
24
- }
25
- else {
26
- Object.defineProperty(obj, key, { value, enumerable: true, writable: true, configurable: true });
27
- }
28
- }
29
- /** `isEmpty` counts declared parameters and keys, which says nothing about these values. */
30
- function isBlank(x) {
31
- if (isPlainObject(x))
32
- return Object.keys(x).length === 0;
33
- return isEmpty(x) && typeof x !== 'function' && !isDate(x) && !isRegExp(x);
34
- }
35
- export function compact(arr) {
36
- if (!arr)
37
- return;
38
- if (Array.isArray(arr))
39
- return arr.filter((x) => !isBlank(x));
40
- const result = {};
41
- for (const key of Object.keys(arr)) {
42
- if (!isBlank(arr[key])) {
43
- setOwn(result, key, arr[key]);
44
- }
45
- }
46
- return result;
47
- }
48
- export function count(obj, func) {
49
- const counters = {};
50
- forEach(obj, (value, key) => {
51
- const result = func(value, key);
52
- setOwn(counters, result, Object.hasOwn(counters, result) ? counters[result] + 1 : 1);
53
- });
54
- return counters;
55
- }
56
- export function filter(arr, fn = isNull) {
57
- if (!arr)
58
- return;
59
- const predicate = isFunction(fn) ? fn : isObject(fn) ? matches(fn) : (obj) => get(fn, obj);
60
- const results = [];
61
- forEach(arr, (value, key) => {
62
- if (predicate(value, key, arr))
63
- results.push(value);
64
- });
65
- return results;
66
- }
67
- export function find(arr, fn) {
68
- const it = isFunction(fn) ? fn : isObject(fn) ? matches(fn) : (obj) => get(fn, obj);
69
- if (Array.isArray(arr)) {
70
- return arr.find(it);
71
- }
72
- else if (isIterable(arr)) {
73
- for (const [index, value] of enumerate(arr)) {
74
- if (it(value, index, arr))
75
- return value;
76
- }
77
- }
78
- else if (isObject(arr)) {
79
- for (const key of Object.keys(arr)) {
80
- if (it(arr[key], key, arr)) {
81
- return arr[key];
82
- }
83
- }
84
- }
85
- }
86
- /**
87
- * Performs an efficient array insert operation in the given array. If the index or the array is invalid, it just returns the given array.
88
- *
89
- * **Note:** Uses the same behavior as `Array.splice`.
90
- *
91
- * @param {Array<*>} arr The given array to insert into
92
- * @param {number} index The index of the array insert operation.
93
- * @param {*} value The value to insert in the array at the given `index`.
94
- * @returns {Array<*>} The given array.
95
- */
96
- export function insert(arr, index, value) {
97
- if (!arr || index < 0)
98
- return arr;
99
- arr.splice(index, 0, value);
100
- return arr;
101
- }
102
- /**
103
- * Creates a function that performs a partial deep comparison between a given object and `shape`, returning `true` if the given object has equivalent property values, else `false`.
104
- * @example
105
- ```js
106
- let objects = [
107
- { a: 1, b: 2, c: 3 },
108
- { a: 4, b: 5, c: 6 }
109
- ]
110
-
111
- filter(objects, matches({ a: 4, c: 6 }))
112
- // [{ a: 4, b: 5, c: 6 }]
113
- ```
114
- * @param shape
115
- * @returns
116
- */
117
- export function matches(shape) {
118
- return (obj) => {
119
- if (!shape || !obj)
120
- return false;
121
- const seen = new Map();
122
- for (const key in shape) {
123
- if (!isPartialMatch(shape[key], obj[key], seen))
124
- return false;
125
- }
126
- return true;
127
- };
128
- }
129
- function isPartialMatch(shape, value, seen) {
130
- if (shape === value)
131
- return true;
132
- const isList = Array.isArray(shape);
133
- if (!isList && !isPlainObject(shape))
134
- return false;
135
- if (value === null || typeof value !== 'object' || isList !== Array.isArray(value))
136
- return false;
137
- const visited = seen.get(shape) ?? new Set();
138
- if (visited.has(value))
139
- return true;
140
- seen.set(shape, visited.add(value));
141
- return Object.keys(shape).every((key) => isPartialMatch(shape[key], value[key], seen));
142
- }
143
- export function forEach(collection, fn) {
144
- if (collection == null)
145
- return;
146
- if (Array.isArray(collection)) {
147
- for (let i = 0; i < collection.length; i++) {
148
- const res = fn(collection[i], i, collection);
149
- if (res === false)
150
- return;
151
- }
152
- }
153
- else if (isIterable(collection)) {
154
- for (const [index, value] of enumerate(collection)) {
155
- const res = fn(value, index, collection);
156
- if (res === false)
157
- return;
158
- }
159
- }
160
- else {
161
- for (const key of Object.keys(collection)) {
162
- const res = fn(collection[key], key, collection);
163
- if (res === false)
164
- return;
165
- }
166
- }
167
- }
168
- export function findLast(arr, fn) {
169
- let result;
170
- const it = isFunction(fn) ? fn : isObject(fn) ? matches(fn) : (obj) => get(fn, obj);
171
- forEachRight(arr, (val, key) => {
172
- if (it(val, key, arr)) {
173
- result = val;
174
- return false;
175
- }
176
- });
177
- return result;
178
- }
179
- export function forEachRight(collection, fn) {
180
- if (Array.isArray(collection)) {
181
- for (let i = collection.length - 1; i >= 0; i--) {
182
- const value = collection[i];
183
- const res = fn(value, i, collection);
184
- if (res === false)
185
- return;
186
- }
187
- }
188
- else if (isIterable(collection)) {
189
- const items = Array.from(collection);
190
- for (let i = items.length - 1; i >= 0; i--) {
191
- const res = fn(items[i], i, collection);
192
- if (res === false)
193
- return;
194
- }
195
- }
196
- else if (isObject(collection)) {
197
- const keys = Object.keys(collection);
198
- for (let i = keys.length - 1; i >= 0; i--) {
199
- const key = keys[i];
200
- const value = collection[key];
201
- const res = fn(value, key, collection);
202
- if (res === false)
203
- return;
204
- }
205
- }
206
- }
207
- export function flatten(arr, depth = 1) {
208
- if (!depth)
209
- return arr;
210
- if (Array.isArray(arr))
211
- return flattenArray(arr, depth, []);
212
- if (isFlattenable(arr))
213
- return flattenObj(arr);
214
- return arr;
215
- }
216
- function flattenArray(arr, depth = 1, result = []) {
217
- for (const value of arr) {
218
- if (depth && Array.isArray(value)) {
219
- flattenArray(value, typeof depth === 'number' ? depth - 1 : depth, result);
220
- }
221
- else {
222
- result.push(value);
223
- }
224
- }
225
- return result;
226
- }
227
- /** A `Date` or `RegExp` has no keys to walk, so `flatten` keeps it as a leaf. */
228
- function isFlattenable(x) {
229
- return Array.isArray(x) || (isObject(x) && !isDate(x) && !isRegExp(x));
230
- }
231
- function flattenObj(obj, prefix = '', result = {}, keepNull = false) {
232
- if (isNull(obj) ? keepNull : !isFlattenable(obj)) {
233
- setOwn(result, prefix, obj);
234
- return result;
235
- }
236
- if (Array.isArray(obj) || isObject(obj)) {
237
- for (const i of Object.keys(obj)) {
238
- let pref = prefix;
239
- if (Array.isArray(obj)) {
240
- pref = `${pref}[${i}]`;
241
- }
242
- else {
243
- if (prefix) {
244
- pref = `${prefix}.${i}`;
245
- }
246
- else {
247
- pref = i;
248
- }
249
- }
250
- flattenObj(obj[i], pref, result, keepNull);
251
- }
252
- return result;
253
- }
254
- return result;
255
- }
256
- export function map(arr, fn) {
257
- const it = isFunction(fn) ? fn : (obj) => get(fn, obj);
258
- if (Array.isArray(arr)) {
259
- return arr.map((x, i) => it(x, i, arr));
260
- }
261
- if (isIterable(arr)) {
262
- return Array.from(arr, (x, i) => it(x, i, arr));
263
- }
264
- if (isObject(arr)) {
265
- return Object.keys(arr).map((key) => it(arr[key], key, arr));
266
- }
267
- }
268
- export function pick(obj, paths) {
269
- if (!obj)
270
- return {};
271
- const result = {};
272
- if (isFunction(paths)) {
273
- for (const key of Object.keys(obj)) {
274
- if (paths(obj[key], key)) {
275
- setOwn(result, key, obj[key]);
276
- }
277
- }
278
- return result;
279
- }
280
- for (const path of paths) {
281
- const key = typeof path === 'symbol' ? path : String(path);
282
- const value = get(path, obj);
283
- if (key !== '__proto__' && (value !== undefined || key in Object(obj)))
284
- result[key] = value;
285
- }
286
- return result;
287
- }
288
- export function omit(obj, paths) {
289
- if (!obj)
290
- return {};
291
- const result = {};
292
- if (isFunction(paths)) {
293
- for (const key of Object.keys(obj)) {
294
- if (!paths(obj[key], key)) {
295
- setOwn(result, key, obj[key]);
296
- }
297
- }
298
- return result;
299
- }
300
- const kept = { ...obj };
301
- for (const key of paths) {
302
- delete kept[key];
303
- }
304
- return kept;
305
- }
306
- export function findIndex(obj, fn, start = 0) {
307
- if (!obj)
308
- return -1;
309
- const length = obj.length;
310
- if (length && start < 0) {
311
- start = Math.max(start + length, 0);
312
- }
313
- if (!length || start >= length)
314
- return -1;
315
- const it = isFunction(fn) ? fn : isObject(fn) ? matches(fn) : (obj) => get(fn, obj);
316
- for (; start < length; start++) {
317
- if (it(obj[start], start, obj))
318
- return start;
319
- }
320
- return -1;
321
- }
322
- /**
323
- * This method is like {@link findIndex} except that it searches for a given value directly, instead of using a predicate function.
324
- * @param {Array} obj The array to inspect.
325
- * @param {*} value The value to find
326
- * @param {number} [start=0] The index to search from.
327
- * @returns {number} The index of the found value, else -1
328
- * @example
329
- ```js
330
- indexOf([1, 2, 1, 2], 2)
331
- // 1
332
-
333
- // Search from a `start` index.
334
- indexOf([1, 2, 1, 2], 2, 2)
335
- // 3
336
- ```
337
- * @see {@link findIndex}
338
- * @see {@link lastIndexOf}
339
- */
340
- export function indexOf(obj, value, start = 0) {
341
- if (!obj)
342
- return -1;
343
- const op = call(obj, 'indexOf', value, start);
344
- if (op != null)
345
- return op;
346
- const length = obj.length;
347
- if (length && start < 0) {
348
- start = Math.max(start + length, 0);
349
- }
350
- if (!length || start >= length)
351
- return -1;
352
- for (; start < length; start++) {
353
- if (eq(value, obj[start]))
354
- return start;
355
- }
356
- return -1;
357
- }
358
- export function findLastIndex(arr, fn, start) {
359
- if (arr == null)
360
- return -1;
361
- const length = arr.length;
362
- start = Math.min(start ?? length - 1, length - 1);
363
- if (!length || start < 0)
364
- return -1;
365
- const it = isFunction(fn) ? fn : isObject(fn) ? matches(fn) : (obj) => get(fn, obj);
366
- for (; start >= 0; start--) {
367
- if (it(arr[start], start, arr))
368
- return start;
369
- }
370
- return -1;
371
- }
372
- /**
373
- * This method is like {@link indexOf} except that it iterates the collection from right to left.
374
- * @param {Array} obj The array to inspect.
375
- * @param {*} value The value to find
376
- * @param {number} [start] The index to search from.
377
- * @returns {number} The index of the found value, else -1
378
- * @example
379
- ```js
380
- lastIndexOf([1, 2, 1, 2], 2)
381
- // 3
382
-
383
- // Search from the `fromIndex`.
384
- lastIndexOf([1, 2, 1, 2], 2, 2)
385
- // 1
386
- ```
387
- * @see {@link findLastIndex}
388
- * @see {@link indexOf}
389
- */
390
- export function lastIndexOf(obj, value, start) {
391
- if (obj == null)
392
- return -1;
393
- const op = call(obj, 'lastIndexOf', ...(start === undefined ? [value] : [value, start]));
394
- if (op != null)
395
- return op;
396
- const length = obj.length;
397
- start = Math.min(start ?? length - 1, length - 1);
398
- if (!length || start < 0)
399
- return -1;
400
- for (; start >= 0; start--) {
401
- if (eq(value, obj[start]))
402
- return start;
403
- }
404
- return -1;
405
- }
406
- export function clone(value, deep = false) {
407
- return cloneValue(value, deep, new Map());
408
- }
409
- function cloneValue(value, deep, copies) {
410
- if (copies.has(value))
411
- return copies.get(value);
412
- if (value instanceof ArrayBuffer)
413
- return value.slice(0);
414
- if (ArrayBuffer.isView(value)) {
415
- return cloneTypedArray(value, deep);
416
- }
417
- if (isObject(value) && isFunction(value.clone)) {
418
- return value.clone();
419
- }
420
- if (Array.isArray(value) || hasElements(value)) {
421
- return cloneArray(value, deep, copies);
422
- }
423
- if (value?.constructor === Map) {
424
- const map = new Map();
425
- copies.set(value, map);
426
- for (const [key, item] of value)
427
- map.set(key, deep ? cloneValue(item, deep, copies) : item);
428
- return map;
429
- }
430
- if (value?.constructor === Set) {
431
- const set = new Set();
432
- copies.set(value, set);
433
- for (const item of value)
434
- set.add(deep ? cloneValue(item, deep, copies) : item);
435
- return set;
436
- }
437
- if (isObject(value)) {
438
- if (isDate(value))
439
- return new Date(value.getTime());
440
- if (isRegExp(value)) {
441
- const regex = new RegExp(value.source, value.flags);
442
- regex.lastIndex = value.lastIndex;
443
- return regex;
444
- }
445
- const copy = {};
446
- copies.set(value, copy);
447
- for (const key in value) {
448
- if (deep) {
449
- setOwn(copy, key, cloneValue(value[key], deep, copies));
450
- }
451
- else {
452
- setOwn(copy, key, value[key]);
453
- }
454
- }
455
- return copy;
456
- }
457
- return value;
458
- }
459
- /** `isArrayLike` accepts any numeric `length`, so this also looks for the elements. */
460
- function hasElements(x) {
461
- return isArrayLike(x) && (isIterable(x) || x.length - 1 in x);
462
- }
463
- /**
464
- * Clones an array. If `deep` is `false` (default) the clone will be shallow. Otherwise {@link https://developer.mozilla.org/en-US/docs/Web/API/structuredClone structuredClone} is used.
465
- * @param arr The array to clone
466
- * @param [deep=false] Creates a deep clone using `structuredClone` if true.
467
- * @returns The new array
468
- * @see {@link clone}
469
- */
470
- function cloneArray(arr, deep, copies) {
471
- if (!deep)
472
- return Array.from(arr);
473
- try {
474
- return structuredClone(arr);
475
- }
476
- catch {
477
- const copy = Array.from(arr);
478
- copies.set(arr, copy);
479
- copy.forEach((item, index) => {
480
- copy[index] = cloneValue(item, deep, copies);
481
- });
482
- return copy;
483
- }
484
- }
485
- /**
486
- * Clones a typed array. If `deep` is `false` (default) the clone will be shallow. Otherwise {@link https://developer.mozilla.org/en-US/docs/Web/API/structuredClone structuredClone} is used.
487
- * @param arr The array to clone
488
- * @param [deep=false] Creates a deep clone using `structuredClone` if true.
489
- * @returns The new array
490
- * @see {@link clone}
491
- */
492
- function cloneTypedArray(typedArray, isDeep = false) {
493
- if (typedArray instanceof DataView) {
494
- const viewed = isDeep ? typedArray.buffer.slice(0) : typedArray.buffer;
495
- return new DataView(viewed, typedArray.byteOffset, typedArray.byteLength);
496
- }
497
- const buffer = isDeep ? structuredClone(typedArray) : typedArray.buffer;
498
- return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
499
- }
500
- export function uniq(arr, fn = identity) {
501
- const keys = new Set();
502
- const results = [];
503
- const it = isFunction(fn) ? fn : (x) => get(fn, x);
504
- for (const x of arr ?? []) {
505
- const key = it(x);
506
- if (keys.has(key))
507
- continue;
508
- keys.add(key);
509
- results.push(Object.is(x, -0) ? 0 : x);
510
- }
511
- return results;
512
- }
513
- export function sortedUniq(arr, fn = identity) {
514
- const it = isFunction(fn) ? fn : (x) => get(fn, x);
515
- return uniq(arr, it).sort((x, y) => compare(it(x), it(y)));
516
- }
517
- /** True for an object made by `{}`, `JSON.parse` or `Object.create(null)`, in any realm. */
518
- function isPlainObject(x) {
519
- if (Object.prototype.toString.call(x) !== '[object Object]')
520
- return false;
521
- const proto = Object.getPrototypeOf(x);
522
- return proto === null || Object.getPrototypeOf(proto) === null;
523
- }
524
- function baseMergeDeep(obj, source, key, stack, copies, merged) {
525
- const objValue = obj[key];
526
- const srcValue = source[key];
527
- const stacked = stack.get(srcValue);
528
- if (stacked) {
529
- obj[key] = stacked;
530
- return;
531
- }
532
- let newValue;
533
- let isCommon = newValue === undefined;
534
- let isCopy = false;
535
- const isArray = Array.isArray(srcValue);
536
- const isTyped = ArrayBuffer.isView(srcValue);
537
- if (isArray || isTyped) {
538
- if (Array.isArray(objValue)) {
539
- newValue = objValue;
540
- }
541
- else if (hasElements(objValue)) {
542
- newValue = Array.from(objValue);
543
- }
544
- else if (isTyped) {
545
- isCommon = false;
546
- newValue = cloneTypedArray(srcValue, true);
547
- }
548
- else {
549
- newValue = [];
550
- isCopy = true;
551
- }
552
- }
553
- else if (isPlainObject(srcValue)) {
554
- isCopy = !isObject(objValue);
555
- newValue = isCopy ? {} : objValue;
556
- }
557
- else {
558
- isCommon = false;
559
- newValue = srcValue;
560
- }
561
- if (isCopy && copies.has(srcValue)) {
562
- obj[key] = copies.get(srcValue);
563
- return;
564
- }
565
- const targets = merged.get(srcValue) ?? new WeakSet();
566
- if (isCommon && !targets.has(newValue)) {
567
- merged.set(srcValue, targets.add(newValue));
568
- stack.set(srcValue, newValue);
569
- baseMerge(newValue, srcValue, stack, copies, merged);
570
- stack.delete(srcValue);
571
- }
572
- if (isCopy)
573
- copies.set(srcValue, newValue);
574
- obj[key] = newValue;
575
- }
576
- function baseMerge(obj, source, stack, copies, merged) {
577
- if (obj === source)
578
- return obj;
579
- for (const key of Object.keys(source)) {
580
- if (key === '__proto__')
581
- continue;
582
- const srcValue = source[key];
583
- const objValue = obj[key];
584
- if (typeof srcValue === 'object' && srcValue !== null) {
585
- baseMergeDeep(obj, source, key, stack, copies, merged);
586
- }
587
- else {
588
- if (srcValue !== undefined && objValue !== srcValue) {
589
- obj[key] = srcValue;
590
- }
591
- }
592
- }
593
- }
594
- /**
595
- * Recursively merges own enumerable string keyed properties of source objects into the destination object. Source properties that resolve to `undefined` are skipped if a destination value exists. Array and plain object properties are merged recursively. Other objects and value types are overridden by assignment. Source objects are applied from left to right. Subsequent sources overwrite property assignments of previous sources.
596
- *
597
- * Note: this method mutates `object`
598
- *
599
- *
600
- * @param {Object} object The destination object.
601
- * @param {...Object} sources The source objects.
602
- * @returns Returns `object`.
603
- *
604
- * @example
605
- ```js
606
- let object = {
607
- 'a': [{ 'b': 2 }, { 'd': 4 }]
608
- }
609
-
610
- let other = {
611
- 'a': [{ 'c': 3 }, { 'e': 5 }]
612
- }
613
-
614
- merge(object, other)
615
- // { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }
616
- ```
617
- */
618
- export function merge(object, ...sources) {
619
- for (const source of sources) {
620
- if (source != null)
621
- baseMerge(object, source, new WeakMap(), new WeakMap(), new WeakMap());
622
- }
623
- return object;
624
- }
625
- /**
626
- * Assigns own and inherited enumerable string keyed properties of source objects to the destination object for all destination properties that resolve to `undefined`. Source objects are applied from left to right. Once a property is set, additional values of the same property are ignored.
627
- * **Note:** This method mutates `object`.
628
-
629
- * @param {Object} object The destination object.
630
- * @param {...Object} [sources] The source objects.
631
- * @returns Returns `object`.
632
- * @example
633
- ```js
634
- defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 })
635
- // { 'a': 1, 'b': 2 }
636
- ```
637
- */
638
- export function defaults(object, ...sources) {
639
- for (const source of sources) {
640
- for (const key in source) {
641
- if (object[key] === undefined) {
642
- object[key] = source[key];
643
- }
644
- }
645
- }
646
- return object;
647
- }
648
- /**
649
- * Returns a generator of array values not included in the other given arrays using a `Set` for equality comparisons. The order and references of result values are not guaranteed.
650
- * @param args The initial arrays
651
- * @example
652
- ```js
653
- [...difference([2, 1], [2, 3])]
654
- // [1]
655
- ```
656
- * @see {@link union}
657
- * @see {@link intersection}
658
- */
659
- export function* difference(...args) {
660
- const sets = args.map((arr) => new Set(arr));
661
- const setA = sets[0] ?? new Set();
662
- for (let i = 1; i < sets.length; i++) {
663
- for (const x of sets[i].values()) {
664
- setA.delete(x);
665
- }
666
- }
667
- for (const x of setA.values()) {
668
- yield x;
669
- }
670
- }
671
- /**
672
- * Creates a generator of unique values that are included in all given arrays.
673
- * @param args The arrays to inspect
674
- * @example
675
- ```js
676
- [...intersection([2, 1], [2, 3])]
677
- // [2]
678
- ```
679
- * @see {@link difference}
680
- * @see {@link union}
681
- */
682
- export function* intersection(...args) {
683
- const sets = args.map((arr) => new Set(arr));
684
- // build a counter map to find items in all
685
- const results = new Map();
686
- const total = sets.length;
687
- for (let i = 0; i < total; i++) {
688
- for (const x of sets[i].values()) {
689
- const count = results.get(x) || 0;
690
- results.set(x, count + 1);
691
- }
692
- }
693
- for (const [key, value] of results.entries()) {
694
- if (value === total)
695
- yield key;
696
- }
697
- }
698
- /**
699
- * Creates a generator of unique values from all given arrays using `Set` for equality comparisons.
700
- * @param args The arrays to perform union on.
701
- * @example
702
- ```js
703
- [...union([2], [1, 2])]
704
- // [2, 1]
705
- ```
706
- * @see {@link difference}
707
- * @see {@link intersection}
708
- */
709
- export function* union(...args) {
710
- const results = new Set();
711
- for (const arr of args) {
712
- for (const item of arr ?? []) {
713
- results.add(item);
714
- }
715
- }
716
- for (const item of results.values()) {
717
- yield item;
718
- }
719
- }
720
- export function groupBy(arr, func = identity) {
721
- const useKey = isFunction(func) ? func : (obj) => get(func, obj);
722
- const results = {};
723
- forEach(arr, (value) => {
724
- const groupKey = useKey(value);
725
- if (!Object.hasOwn(results, groupKey))
726
- setOwn(results, groupKey, []);
727
- results[groupKey].push(value);
728
- });
729
- return results;
730
- }
731
- export function groupByMap(arr, func = identity) {
732
- const results = new Map();
733
- const useKey = isFunction(func) ? func : (obj) => get(func, obj);
734
- forEach(arr, (value) => {
735
- const groupKey = useKey(value);
736
- const values = results.get(groupKey) || [];
737
- values.push(value);
738
- results.set(groupKey, values);
739
- });
740
- return results;
741
- }
742
- export function remove(arr, func) {
743
- const it = isFunction(func)
744
- ? func
745
- : Array.isArray(func)
746
- ? (x) => func.includes(x)
747
- : (x) => func === x;
748
- return arr.filter((x, i) => !it(x, i, arr));
749
- }
750
- /**
751
- * Returns the index of `x` in a **sorted** array if found, in `O(log n)` using binary search.
752
- * If the element is not found, returns `-n - 1`, where `n` is the index to insert `x` at.
753
- * @param arr The sorted array
754
- * @param x The element to find
755
- * @param lo The starting index
756
- * @param hi The end index to search within
757
- * @param comp The compare function to check for `x`
758
- * @returns {number} The index if the element is found or a negative integer.
759
- */
760
- export function binarySearch(arr, x, lo = 0, hi, comp = compare) {
761
- hi ??= arr.length - 1;
762
- while (lo < hi) {
763
- const mid = (lo + hi) >> 1;
764
- const check = comp(x, arr[mid]);
765
- if (check === 0)
766
- return mid;
767
- if (check > 0)
768
- lo = mid + 1;
769
- else
770
- hi = mid - 1;
771
- }
772
- const check = lo <= hi ? comp(x, arr[lo]) : -1;
773
- if (check === 0)
774
- return lo;
775
- // Returns (-n - 1) where n is the insertion point for new element in the range
776
- return check > 0 ? -lo - 2 : -lo - 1;
777
- }
778
- /**
779
- * Returns an insertion index which comes after any existing entries of `x` in a **sorted** array, using binary search.
780
- * @param arr The sorted array
781
- * @param x The element to find
782
- * @param lo The starting index
783
- * @param hi The end index to search within
784
- * @param comp The compare function to check for `x`
785
- * @returns {number}
786
- */
787
- export function bisect(arr, x, lo = 0, hi, comp = compare) {
788
- hi ??= arr.length;
789
- while (lo < hi) {
790
- const mid = (lo + hi) >> 1;
791
- const check = comp(x, arr[mid]);
792
- if (check >= 0)
793
- lo = mid + 1;
794
- else
795
- hi = mid;
796
- }
797
- return lo;
798
- }
799
- /**
800
- * Returns an insertion index which comes before any existing entries of `x` in a **sorted** array, using binary search.
801
- * @param arr The sorted array
802
- * @param x The element to find
803
- * @param lo The starting index
804
- * @param hi The end index to search within
805
- * @param comp The compare function to check for `x`
806
- * @returns {number}
807
- */
808
- export function bisectLeft(arr, x, lo = 0, hi, comp = compare) {
809
- hi ??= arr.length;
810
- while (lo < hi) {
811
- const mid = (lo + hi) >> 1;
812
- const check = comp(x, arr[mid]);
813
- if (check <= 0)
814
- hi = mid;
815
- else
816
- lo = mid + 1;
817
- }
818
- return lo;
819
- }
820
- /**
821
- * Runs {@link bisect} first to locate an insertion point, and inserts the value `x` in the sorted array after any existing entries of `x` to maintain sort order.
822
- * Please note this method is `O(n)` because insertion resizes the array.
823
- * @param arr The array to insert into
824
- * @param x The element to insert
825
- * @param lo The starting index
826
- * @param hi The end index to search within
827
- * @param comp The compare function to check for `x`
828
- * @returns {Array}
829
- */
830
- export function insort(arr, x, lo = 0, hi, comp = compare) {
831
- const index = bisect(arr, x, lo, hi, comp);
832
- return insert(arr, index, x);
833
- }
834
- /**
835
- * Runs {@link bisectLeft} first to locate an insertion point, and inserts the value `x` in the sorted array before any existing entries of `x` to maintain sort order.
836
- * Please note this method is `O(n)` because insertion resizes the array.
837
- * @param arr The array to insert into
838
- * @param x The element to insert
839
- * @param lo The starting index
840
- * @param hi The end index to search within
841
- * @param comp The compare function to check for `x`
842
- * @returns {Array}
843
- */
844
- export function insortLeft(arr, x, lo = 0, hi, comp = compare) {
845
- const index = bisectLeft(arr, x, lo, hi, comp);
846
- return insert(arr, index, x);
847
- }
6
+ export { entries, includes, isEmpty, keys, size, values } from './entries.js';
7
+ export { countBy, groupBy, keyBy, maxBy, meanBy, minBy, orderBy, partition, sortBy, sumBy } from './group.js';
8
+ export { every, filter, find, findLast, flatMap, forEach, forEachRight, map, reduce, reduceRight, reject, some } from './iterate.js';
9
+ export { binarySearch, bisect, bisectLeft, bisectRight, insort, insortLeft } from './bisect.js';
10
+ export { Deque } from './deque.js';
11
+ export { FrozenSet } from './frozen-set.js';
12
+ export { Heap } from './heap.js';
13
+ export { LRUCache } from './lru-cache.js';
14
+ export { SortedMap } from './sorted-map.js';
15
+ export { SortedSet } from './sorted-set.js';
16
+ export { SplayTree } from './splay-tree.js';
17
+ export { Trie } from './trie.js';