atomic-fns 1.1.7 → 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 +405 -60
  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 -249
  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 -642
  27. package/dist/collections/index.js +14 -716
  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 -145
  55. package/dist/decimal/index.js +10 -374
  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 -50
  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 -226
  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 +101 -58
  171. package/dist/collections/BTree.d.ts +0 -229
  172. package/dist/collections/BTree.js +0 -1165
  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 -80
  176. package/dist/collections/LRUCache.js +0 -126
  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 -141
  183. package/dist/collections/SplayTree.d.ts +0 -105
  184. package/dist/collections/SplayTree.js +0 -338
  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 -30
  191. package/dist/functools/index.d.ts +0 -130
  192. package/dist/functools/index.js +0 -235
  193. package/dist/globals/index.d.ts +0 -285
  194. package/dist/globals/index.js +0 -463
  195. package/dist/i18n/currency.d.ts +0 -24
  196. package/dist/i18n/currency.js +0 -85
  197. package/dist/i18n/date/index.d.ts +0 -203
  198. package/dist/i18n/date/index.js +0 -531
  199. package/dist/i18n/date/utils.d.ts +0 -65
  200. package/dist/i18n/date/utils.js +0 -290
  201. package/dist/i18n/duration.d.ts +0 -112
  202. package/dist/i18n/duration.js +0 -392
  203. package/dist/i18n/format.d.ts +0 -31
  204. package/dist/i18n/format.js +0 -506
  205. package/dist/i18n/index.d.ts +0 -8
  206. package/dist/i18n/index.js +0 -8
  207. package/dist/itertools/index.d.ts +0 -255
  208. package/dist/itertools/index.js +0 -437
  209. package/dist/math/index.d.ts +0 -96
  210. package/dist/math/index.js +0 -98
  211. package/dist/mod.d.ts +0 -1
  212. package/dist/mod.js +0 -1
  213. package/dist/operators/index.d.ts +0 -152
  214. package/dist/operators/index.js +0 -305
  215. package/dist/types.d.ts +0 -19
  216. package/dist/types.js +0 -1
@@ -0,0 +1,19 @@
1
+ import { type ArrayWalkEvent } from '../../internal/sparse.js';
2
+ /**
3
+ * Walk `arr` without expanding huge hole runs index-by-index.
4
+ * Dense indices use `i in arr`. Once holes pass {@link HOLE_STREAK_BEFORE_KEYS} plus the elements
5
+ * seen so far, take `Object.keys` once and continue over remaining canonical indices only, so
6
+ * cost stays proportional to the elements however they are spaced.
7
+ * Holes are reported as a single `holeRun` event (`end` exclusive).
8
+ * Return `false` from `visit` to stop.
9
+ */
10
+ export declare function walkArray(arr: unknown[], visit: (event: ArrayWalkEvent) => unknown): void;
11
+ /**
12
+ * True when `arr.length` is above {@link HUGE_SPARSE_MIN_LENGTH} and also exceeds
13
+ * `2 * visitedIndexCount + 1024`, so a dense `0..length` walk would spend most of its time on holes.
14
+ * Below {@link HUGE_SPARSE_MIN_LENGTH}, consumers walk with their existing hole semantics.
15
+ * Counts the values visited by {@link walkArray}; dense arrays exit early once they cannot qualify.
16
+ */
17
+ export declare function isHugeSparse(arr: unknown[]): boolean;
18
+ /** Throw when `arr` is a huge sparse array that must not be expanded per-index. */
19
+ export declare function assertNotHugeSparse(arr: unknown[]): void;
@@ -0,0 +1,83 @@
1
+ import { arrayIndicesFrom, HOLE_STREAK_BEFORE_KEYS, HUGE_SPARSE_MIN_LENGTH } from '../../internal/sparse.js';
2
+ /**
3
+ * Walk `arr` without expanding huge hole runs index-by-index.
4
+ * Dense indices use `i in arr`. Once holes pass {@link HOLE_STREAK_BEFORE_KEYS} plus the elements
5
+ * seen so far, take `Object.keys` once and continue over remaining canonical indices only, so
6
+ * cost stays proportional to the elements however they are spaced.
7
+ * Holes are reported as a single `holeRun` event (`end` exclusive).
8
+ * Return `false` from `visit` to stop.
9
+ */
10
+ export function walkArray(arr, visit) {
11
+ const len = arr.length;
12
+ let i = 0;
13
+ let elements = 0;
14
+ let holes = 0;
15
+ while (i < len) {
16
+ if (i in arr) {
17
+ if (visit({ kind: 'value', index: i, value: arr[i] }) === false)
18
+ return;
19
+ i++;
20
+ elements++;
21
+ continue;
22
+ }
23
+ const holeStart = i;
24
+ while (i < len && !(i in arr) && holes < HOLE_STREAK_BEFORE_KEYS + elements) {
25
+ i++;
26
+ holes++;
27
+ }
28
+ if (holes >= HOLE_STREAK_BEFORE_KEYS + elements && i < len) {
29
+ const rest = arrayIndicesFrom(arr, i);
30
+ const holeEnd = rest.length > 0 ? rest[0] : len;
31
+ if (visit({ kind: 'holeRun', start: holeStart, end: holeEnd }) === false)
32
+ return;
33
+ for (let k = 0; k < rest.length; k++) {
34
+ const idx = rest[k];
35
+ if (k > 0) {
36
+ const prev = rest[k - 1];
37
+ if (idx > prev + 1) {
38
+ if (visit({ kind: 'holeRun', start: prev + 1, end: idx }) === false)
39
+ return;
40
+ }
41
+ }
42
+ if (visit({ kind: 'value', index: idx, value: arr[idx] }) === false)
43
+ return;
44
+ }
45
+ if (rest.length > 0) {
46
+ const last = rest[rest.length - 1];
47
+ if (last + 1 < len) {
48
+ if (visit({ kind: 'holeRun', start: last + 1, end: len }) === false)
49
+ return;
50
+ }
51
+ }
52
+ return;
53
+ }
54
+ if (visit({ kind: 'holeRun', start: holeStart, end: i }) === false)
55
+ return;
56
+ }
57
+ }
58
+ /**
59
+ * True when `arr.length` is above {@link HUGE_SPARSE_MIN_LENGTH} and also exceeds
60
+ * `2 * visitedIndexCount + 1024`, so a dense `0..length` walk would spend most of its time on holes.
61
+ * Below {@link HUGE_SPARSE_MIN_LENGTH}, consumers walk with their existing hole semantics.
62
+ * Counts the values visited by {@link walkArray}; dense arrays exit early once they cannot qualify.
63
+ */
64
+ export function isHugeSparse(arr) {
65
+ const len = arr.length;
66
+ if (len <= HUGE_SPARSE_MIN_LENGTH)
67
+ return false;
68
+ let own = 0;
69
+ walkArray(arr, (event) => {
70
+ if (event.kind !== 'value')
71
+ return;
72
+ own++;
73
+ if (len <= 2 * own + 1024)
74
+ return false;
75
+ });
76
+ return len > 2 * own + 1024;
77
+ }
78
+ /** Throw when `arr` is a huge sparse array that must not be expanded per-index. */
79
+ export function assertNotHugeSparse(arr) {
80
+ if (isHugeSparse(arr)) {
81
+ throw new RangeError('sparse array too large');
82
+ }
83
+ }
@@ -0,0 +1,4 @@
1
+ /** Called once by `SortedMap`'s static block with access to its private structure check. */
2
+ export declare function registerSortedMapCheck(fn: (map: object) => void): void;
3
+ /** Throws when a `SortedMap`'s B+ tree breaks an invariant. For tests. */
4
+ export declare function checkSortedMap(map: object): void;
@@ -0,0 +1,12 @@
1
+ let check;
2
+ /** Called once by `SortedMap`'s static block with access to its private structure check. */
3
+ export function registerSortedMapCheck(fn) {
4
+ check = fn;
5
+ }
6
+ /** Throws when a `SortedMap`'s B+ tree breaks an invariant. For tests. */
7
+ export function checkSortedMap(map) {
8
+ if (check === undefined) {
9
+ throw new Error('no SortedMap from this module graph has registered its invariant check');
10
+ }
11
+ check(map);
12
+ }
@@ -0,0 +1,25 @@
1
+ /** Return `value` typed as an iterable; throw `TypeError` before allocating when it is not one. */
2
+ export declare function requireIterable<T>(value: unknown): Iterable<T>;
3
+ /**
4
+ * True when `value` is an array that iterates with the built-in array iterator, so iterating it
5
+ * visits every index up to `length`, holes included. An array with its own or a subclass's
6
+ * `[Symbol.iterator]` iterates however that method says and is treated as any other iterable.
7
+ */
8
+ export declare function iteratesAsArray(value: unknown): value is unknown[];
9
+ /**
10
+ * Copy an iterable into a new plain array, as iterating it yields the values (holes read as
11
+ * `undefined`). The copy never goes through `slice`, so an Array subclass's `Symbol.species`
12
+ * cannot choose its class. Non-iterables throw `TypeError` and huge sparse arrays throw
13
+ * `RangeError`, both before allocating.
14
+ */
15
+ export declare function arrayFromIterable<T>(value: unknown): T[];
16
+ /**
17
+ * Map an iterable into a new array; non-iterables throw `TypeError` and huge sparse arrays throw
18
+ * `RangeError`, both before allocating.
19
+ */
20
+ export declare function arrayFromIterableMap<U>(value: unknown, mapFn: (item: unknown, index: number) => U): U[];
21
+ /**
22
+ * Visit array elements in own-element time: each own value, and each hole run once as
23
+ * `undefined` at the run's start index. Return `false` from `visit` to stop.
24
+ */
25
+ export declare function forEachArrayElement<T>(arr: T[], visit: (value: T, index: number) => boolean | undefined): void;
@@ -0,0 +1,62 @@
1
+ import { assertNotHugeSparse, walkArray } from './arrayKeys.js';
2
+ function isIterable(x) {
3
+ if (x == null)
4
+ return false;
5
+ return typeof x[Symbol.iterator] === 'function';
6
+ }
7
+ /** Return `value` typed as an iterable; throw `TypeError` before allocating when it is not one. */
8
+ export function requireIterable(value) {
9
+ if (!isIterable(value))
10
+ throw new TypeError('expected an iterable');
11
+ return value;
12
+ }
13
+ /**
14
+ * True when `value` is an array that iterates with the built-in array iterator, so iterating it
15
+ * visits every index up to `length`, holes included. An array with its own or a subclass's
16
+ * `[Symbol.iterator]` iterates however that method says and is treated as any other iterable.
17
+ */
18
+ export function iteratesAsArray(value) {
19
+ return Array.isArray(value) && value[Symbol.iterator] === Array.prototype.values;
20
+ }
21
+ /**
22
+ * Copy an iterable into a new plain array, as iterating it yields the values (holes read as
23
+ * `undefined`). The copy never goes through `slice`, so an Array subclass's `Symbol.species`
24
+ * cannot choose its class. Non-iterables throw `TypeError` and huge sparse arrays throw
25
+ * `RangeError`, both before allocating.
26
+ */
27
+ export function arrayFromIterable(value) {
28
+ const it = requireIterable(value);
29
+ if (iteratesAsArray(it))
30
+ assertNotHugeSparse(it);
31
+ const out = [];
32
+ for (const x of it)
33
+ out.push(x);
34
+ return out;
35
+ }
36
+ /**
37
+ * Map an iterable into a new array; non-iterables throw `TypeError` and huge sparse arrays throw
38
+ * `RangeError`, both before allocating.
39
+ */
40
+ export function arrayFromIterableMap(value, mapFn) {
41
+ const it = requireIterable(value);
42
+ if (iteratesAsArray(it))
43
+ assertNotHugeSparse(it);
44
+ const out = [];
45
+ let i = 0;
46
+ for (const x of it) {
47
+ out.push(mapFn(x, i));
48
+ i++;
49
+ }
50
+ return out;
51
+ }
52
+ /**
53
+ * Visit array elements in own-element time: each own value, and each hole run once as
54
+ * `undefined` at the run's start index. Return `false` from `visit` to stop.
55
+ */
56
+ export function forEachArrayElement(arr, visit) {
57
+ walkArray(arr, (ev) => {
58
+ if (ev.kind === 'value')
59
+ return visit(ev.value, ev.index);
60
+ return visit(undefined, ev.start);
61
+ });
62
+ }
@@ -0,0 +1,162 @@
1
+ /**
2
+ * Iteration over every shape: `forEach`, `map`, `filter`, `find`, `some`, `reduce` and friends.
3
+ */
4
+ import { type Collection, type CollectionCallback, type CollectionKey, type CollectionValue } from './shape.js';
5
+ /**
6
+ * Call `callback` with `(value, key, collection)` for every entry of `collection`, in order. Like
7
+ * the native `forEach`, it visits every entry and ignores what the callback returns; use
8
+ * {@link some}, {@link every} or `for...of` to stop early.
9
+ * @param collection The collection to walk.
10
+ * @param callback Called once per entry.
11
+ * @example
12
+ * ```ts
13
+ * forEach({ a: 1, b: 2 }, (value, key) => console.log(key, value))
14
+ * // a 1
15
+ * // b 2
16
+ * ```
17
+ */
18
+ export declare function forEach<C extends Collection>(collection: C, callback: CollectionCallback<C, unknown>): void;
19
+ /**
20
+ * {@link forEach} from the last entry to the first.
21
+ * @param collection The collection to walk.
22
+ * @param callback Called once per entry.
23
+ * @example
24
+ * ```ts
25
+ * forEachRight([1, 2], (value) => console.log(value))
26
+ * // 2
27
+ * // 1
28
+ * ```
29
+ */
30
+ export declare function forEachRight<C extends Collection>(collection: C, callback: CollectionCallback<C, unknown>): void;
31
+ /**
32
+ * The results of `callback` for every entry of `collection`, as an array.
33
+ * @param collection The collection to walk.
34
+ * @param callback Maps one entry.
35
+ * @returns A new array with one result per entry.
36
+ * @example
37
+ * ```ts
38
+ * map({ a: 1, b: 2 }, (value) => value * 2) // [2, 4]
39
+ * map(new Map([['x', 1]]), (value, key) => `${key}=${value}`) // ['x=1']
40
+ * ```
41
+ */
42
+ export declare function map<C extends Collection, R>(collection: C, callback: CollectionCallback<C, R>): R[];
43
+ /**
44
+ * {@link map}, then one level of flattening, as `Array.prototype.flatMap` does: an array result
45
+ * is spread, anything else is kept as one element.
46
+ * @param collection The collection to walk.
47
+ * @param callback Maps one entry to an array or a value.
48
+ * @returns A new flat array.
49
+ * @example
50
+ * ```ts
51
+ * flatMap({ a: 1, b: 2 }, (value, key) => [key, value]) // ['a', 1, 'b', 2]
52
+ * ```
53
+ */
54
+ export declare function flatMap<C extends Collection, R>(collection: C, callback: CollectionCallback<C, R | readonly R[]>): R[];
55
+ /**
56
+ * The values of `collection` for which `predicate` is truthy, in order.
57
+ * @param collection The collection to walk.
58
+ * @param predicate Tests one entry.
59
+ * @returns A new array of values.
60
+ * @example
61
+ * ```ts
62
+ * filter({ a: 1, b: 2, c: 3 }, (value) => value % 2 === 1) // [1, 3]
63
+ * filter(new Set(['x', 'yy']), (value) => value.length > 1) // ['yy']
64
+ * ```
65
+ */
66
+ export declare function filter<C extends Collection, S extends CollectionValue<C>>(collection: C, predicate: (value: CollectionValue<C>, key: CollectionKey<C>, collection: C) => value is S): S[];
67
+ /** {@link filter} with a predicate that is not a type guard. */
68
+ export declare function filter<C extends Collection>(collection: C, predicate: CollectionCallback<C, unknown>): CollectionValue<C>[];
69
+ /**
70
+ * The values of `collection` for which `predicate` is falsy: the complement of {@link filter}.
71
+ * @param collection The collection to walk.
72
+ * @param predicate Tests one entry.
73
+ * @returns A new array of values.
74
+ * @example
75
+ * ```ts
76
+ * reject([1, 2, 3], (value) => value > 1) // [1]
77
+ * ```
78
+ */
79
+ export declare function reject<C extends Collection>(collection: C, predicate: CollectionCallback<C, unknown>): CollectionValue<C>[];
80
+ /**
81
+ * The first value of `collection` for which `predicate` is truthy, or `undefined`. It stops at
82
+ * that entry, so it works on an endless iterable that has a match.
83
+ * @param collection The collection to search.
84
+ * @param predicate Tests one entry.
85
+ * @returns The value found, or `undefined`.
86
+ * @example
87
+ * ```ts
88
+ * find({ a: 1, b: 2 }, (value) => value > 1) // 2
89
+ * ```
90
+ */
91
+ export declare function find<C extends Collection, S extends CollectionValue<C>>(collection: C, predicate: (value: CollectionValue<C>, key: CollectionKey<C>, collection: C) => value is S): S | undefined;
92
+ /** {@link find} with a predicate that is not a type guard. */
93
+ export declare function find<C extends Collection>(collection: C, predicate: CollectionCallback<C, unknown>): CollectionValue<C> | undefined;
94
+ /**
95
+ * {@link find} from the last entry to the first.
96
+ * @param collection The collection to search.
97
+ * @param predicate Tests one entry.
98
+ * @returns The value found, or `undefined`.
99
+ * @example
100
+ * ```ts
101
+ * findLast([1, 2, 3], (value) => value < 3) // 2
102
+ * ```
103
+ */
104
+ export declare function findLast<C extends Collection, S extends CollectionValue<C>>(collection: C, predicate: (value: CollectionValue<C>, key: CollectionKey<C>, collection: C) => value is S): S | undefined;
105
+ /** {@link findLast} with a predicate that is not a type guard. */
106
+ export declare function findLast<C extends Collection>(collection: C, predicate: CollectionCallback<C, unknown>): CollectionValue<C> | undefined;
107
+ /**
108
+ * True when `predicate` is truthy for some entry; stops at the first one.
109
+ * @param collection The collection to test.
110
+ * @param predicate Tests one entry.
111
+ * @returns Whether any entry passes. `false` for an empty collection.
112
+ * @example
113
+ * ```ts
114
+ * some({ a: 1, b: -1 }, (value) => value < 0) // true
115
+ * ```
116
+ */
117
+ export declare function some<C extends Collection>(collection: C, predicate: CollectionCallback<C, unknown>): boolean;
118
+ /**
119
+ * True when `predicate` is truthy for every entry; stops at the first that fails.
120
+ * @param collection The collection to test.
121
+ * @param predicate Tests one entry.
122
+ * @returns Whether every entry passes. `true` for an empty collection.
123
+ * @example
124
+ * ```ts
125
+ * every(new Set([2, 4]), (value) => value % 2 === 0) // true
126
+ * ```
127
+ */
128
+ export declare function every<C extends Collection>(collection: C, predicate: CollectionCallback<C, unknown>): boolean;
129
+ /** `(accumulator, value, key, collection)`, as `Array.prototype.reduce` passes them plus the key. */
130
+ export type CollectionReducer<C, A> = (accumulator: A, value: CollectionValue<C>, key: CollectionKey<C>, collection: C) => A;
131
+ /**
132
+ * Fold the entries of `collection` into one value, as `Array.prototype.reduce` does. Without
133
+ * `initial`, the first value starts the fold.
134
+ * @param collection The collection to fold.
135
+ * @param reducer Combines the accumulator with one entry.
136
+ * @param initial The starting accumulator.
137
+ * @returns The final accumulator.
138
+ * @throws {TypeError} when `collection` is empty and no `initial` is given, as the native method does.
139
+ * @example
140
+ * ```ts
141
+ * reduce({ a: 1, b: 2 }, (sum, value) => sum + value, 0) // 3
142
+ * reduce(new Map([['x', 1]]), (out, value, key) => `${out}${key}${value}`, '') // 'x1'
143
+ * ```
144
+ */
145
+ export declare function reduce<C extends Collection, A>(collection: C, reducer: CollectionReducer<C, A>, initial: A): A;
146
+ /** {@link reduce} without `initial`: the first value starts the fold. */
147
+ export declare function reduce<C extends Collection>(collection: C, reducer: CollectionReducer<C, CollectionValue<C>>): CollectionValue<C>;
148
+ /**
149
+ * {@link reduce} from the last entry to the first, as `Array.prototype.reduceRight` does.
150
+ * @param collection The collection to fold.
151
+ * @param reducer Combines the accumulator with one entry.
152
+ * @param initial The starting accumulator.
153
+ * @returns The final accumulator.
154
+ * @throws {TypeError} when `collection` is empty and no `initial` is given.
155
+ * @example
156
+ * ```ts
157
+ * reduceRight(['a', 'b', 'c'], (out, value) => out + value, '') // 'cba'
158
+ * ```
159
+ */
160
+ export declare function reduceRight<C extends Collection, A>(collection: C, reducer: CollectionReducer<C, A>, initial: A): A;
161
+ /** {@link reduceRight} without `initial`: the last value starts the fold. */
162
+ export declare function reduceRight<C extends Collection>(collection: C, reducer: CollectionReducer<C, CollectionValue<C>>): CollectionValue<C>;
@@ -0,0 +1,188 @@
1
+ /**
2
+ * Iteration over every shape: `forEach`, `map`, `filter`, `find`, `some`, `reduce` and friends.
3
+ */
4
+ import { eachEntry, eachIndex, entryList } from './shape.js';
5
+ /**
6
+ * Call `callback` with `(value, key, collection)` for every entry of `collection`, in order. Like
7
+ * the native `forEach`, it visits every entry and ignores what the callback returns; use
8
+ * {@link some}, {@link every} or `for...of` to stop early.
9
+ * @param collection The collection to walk.
10
+ * @param callback Called once per entry.
11
+ * @example
12
+ * ```ts
13
+ * forEach({ a: 1, b: 2 }, (value, key) => console.log(key, value))
14
+ * // a 1
15
+ * // b 2
16
+ * ```
17
+ */
18
+ export function forEach(collection, callback) {
19
+ const fn = callback;
20
+ eachEntry(collection, (value, key) => {
21
+ fn(value, key, collection);
22
+ });
23
+ }
24
+ /**
25
+ * {@link forEach} from the last entry to the first.
26
+ * @param collection The collection to walk.
27
+ * @param callback Called once per entry.
28
+ * @example
29
+ * ```ts
30
+ * forEachRight([1, 2], (value) => console.log(value))
31
+ * // 2
32
+ * // 1
33
+ * ```
34
+ */
35
+ export function forEachRight(collection, callback) {
36
+ const fn = callback;
37
+ const list = entryList(collection);
38
+ for (let i = list.length - 1; i >= 0; i--)
39
+ fn(list[i][1], list[i][0], collection);
40
+ }
41
+ /**
42
+ * The results of `callback` for every entry of `collection`, as an array.
43
+ * @param collection The collection to walk.
44
+ * @param callback Maps one entry.
45
+ * @returns A new array with one result per entry.
46
+ * @example
47
+ * ```ts
48
+ * map({ a: 1, b: 2 }, (value) => value * 2) // [2, 4]
49
+ * map(new Map([['x', 1]]), (value, key) => `${key}=${value}`) // ['x=1']
50
+ * ```
51
+ */
52
+ export function map(collection, callback) {
53
+ const fn = callback;
54
+ const out = [];
55
+ eachEntry(collection, (value, key) => {
56
+ out.push(fn(value, key, collection));
57
+ });
58
+ return out;
59
+ }
60
+ /**
61
+ * {@link map}, then one level of flattening, as `Array.prototype.flatMap` does: an array result
62
+ * is spread, anything else is kept as one element.
63
+ * @param collection The collection to walk.
64
+ * @param callback Maps one entry to an array or a value.
65
+ * @returns A new flat array.
66
+ * @example
67
+ * ```ts
68
+ * flatMap({ a: 1, b: 2 }, (value, key) => [key, value]) // ['a', 1, 'b', 2]
69
+ * ```
70
+ */
71
+ export function flatMap(collection, callback) {
72
+ const fn = callback;
73
+ const out = [];
74
+ eachEntry(collection, (value, key) => {
75
+ const result = fn(value, key, collection);
76
+ if (Array.isArray(result)) {
77
+ eachIndex(result, (item) => {
78
+ out.push(item);
79
+ });
80
+ }
81
+ else {
82
+ out.push(result);
83
+ }
84
+ });
85
+ return out;
86
+ }
87
+ export function filter(collection, predicate) {
88
+ const fn = predicate;
89
+ const out = [];
90
+ eachEntry(collection, (value, key) => {
91
+ if (fn(value, key, collection))
92
+ out.push(value);
93
+ });
94
+ return out;
95
+ }
96
+ /**
97
+ * The values of `collection` for which `predicate` is falsy: the complement of {@link filter}.
98
+ * @param collection The collection to walk.
99
+ * @param predicate Tests one entry.
100
+ * @returns A new array of values.
101
+ * @example
102
+ * ```ts
103
+ * reject([1, 2, 3], (value) => value > 1) // [1]
104
+ * ```
105
+ */
106
+ export function reject(collection, predicate) {
107
+ return filter(collection, (value, key, c) => !predicate(value, key, c));
108
+ }
109
+ export function find(collection, predicate) {
110
+ const fn = predicate;
111
+ let found;
112
+ eachEntry(collection, (value, key) => {
113
+ if (!fn(value, key, collection))
114
+ return false;
115
+ found = value;
116
+ return true;
117
+ });
118
+ return found;
119
+ }
120
+ export function findLast(collection, predicate) {
121
+ const fn = predicate;
122
+ const list = entryList(collection);
123
+ for (let i = list.length - 1; i >= 0; i--) {
124
+ if (fn(list[i][1], list[i][0], collection))
125
+ return list[i][1];
126
+ }
127
+ return undefined;
128
+ }
129
+ /**
130
+ * True when `predicate` is truthy for some entry; stops at the first one.
131
+ * @param collection The collection to test.
132
+ * @param predicate Tests one entry.
133
+ * @returns Whether any entry passes. `false` for an empty collection.
134
+ * @example
135
+ * ```ts
136
+ * some({ a: 1, b: -1 }, (value) => value < 0) // true
137
+ * ```
138
+ */
139
+ export function some(collection, predicate) {
140
+ const fn = predicate;
141
+ return eachEntry(collection, (value, key) => Boolean(fn(value, key, collection)));
142
+ }
143
+ /**
144
+ * True when `predicate` is truthy for every entry; stops at the first that fails.
145
+ * @param collection The collection to test.
146
+ * @param predicate Tests one entry.
147
+ * @returns Whether every entry passes. `true` for an empty collection.
148
+ * @example
149
+ * ```ts
150
+ * every(new Set([2, 4]), (value) => value % 2 === 0) // true
151
+ * ```
152
+ */
153
+ export function every(collection, predicate) {
154
+ const fn = predicate;
155
+ return !eachEntry(collection, (value, key) => !fn(value, key, collection));
156
+ }
157
+ function emptyReduceError() {
158
+ return new TypeError('reduce of an empty collection with no initial value');
159
+ }
160
+ export function reduce(collection, reducer, ...initial) {
161
+ const fn = reducer;
162
+ let hasAcc = initial.length > 0;
163
+ let acc = initial[0];
164
+ eachEntry(collection, (value, key) => {
165
+ if (hasAcc) {
166
+ acc = fn(acc, value, key, collection);
167
+ }
168
+ else {
169
+ acc = value;
170
+ hasAcc = true;
171
+ }
172
+ });
173
+ if (!hasAcc)
174
+ throw emptyReduceError();
175
+ return acc;
176
+ }
177
+ export function reduceRight(collection, reducer, ...initial) {
178
+ const fn = reducer;
179
+ const list = entryList(collection);
180
+ const hasInitial = initial.length > 0;
181
+ if (!hasInitial && list.length === 0)
182
+ throw emptyReduceError();
183
+ let i = list.length - 1;
184
+ let acc = hasInitial ? initial[0] : list[i--][1];
185
+ for (; i >= 0; i--)
186
+ acc = fn(acc, list[i][1], list[i][0], collection);
187
+ return acc;
188
+ }
@@ -0,0 +1,58 @@
1
+ /**
2
+ * A fixed-capacity least-recently-used cache with `Map`'s method names. `get` refreshes recency;
3
+ * `has` does not. Keys compare with SameValueZero, as in `Map`. Iterators and `forEach` walk a
4
+ * snapshot taken when they start, so `get` and `set` inside a loop are safe.
5
+ *
6
+ * @example
7
+ * ```ts
8
+ * const cache = new LRUCache<string, number>(2)
9
+ * cache.set('a', 1).set('b', 2)
10
+ * cache.get('a') // 1, so 'b' is now the least recent
11
+ * cache.set('c', 3)
12
+ * cache.has('b') // false
13
+ * ```
14
+ */
15
+ export declare class LRUCache<K = unknown, V = unknown> {
16
+ private readonly state;
17
+ /**
18
+ * Create an empty cache.
19
+ * @param capacity Maximum number of entries; must be an integer >= 1. Defaults to 1024.
20
+ * @throws {TypeError} when capacity is not a number.
21
+ * @throws {RangeError} when capacity is not an integer >= 1.
22
+ */
23
+ constructor(capacity?: number);
24
+ /**
25
+ * Set `key` to `value`. Setting an existing key updates its value and makes it the most recent,
26
+ * without evicting. Inserting a new key at capacity evicts the least recently used entry.
27
+ */
28
+ set(key: K, value: V): this;
29
+ /** Whether `key` is cached. Does not refresh its recency. */
30
+ has(key: K): boolean;
31
+ /**
32
+ * Return the value for `key`, refreshing its recency. Missing keys return `undefined`.
33
+ */
34
+ get(key: K): V | undefined;
35
+ /** Remove every entry. */
36
+ clear(): void;
37
+ /**
38
+ * Remove `key`.
39
+ * @returns Whether it was present.
40
+ */
41
+ delete(key: K): boolean;
42
+ /** The number of entries. */
43
+ get size(): number;
44
+ /** Maximum number of entries. */
45
+ get capacity(): number;
46
+ /** `'LRUCache'`, for `Object.prototype.toString`. */
47
+ get [Symbol.toStringTag](): string;
48
+ /** The keys, least to most recently used. */
49
+ keys(): IteratorObject<K>;
50
+ /** The values, least to most recently used. */
51
+ values(): IteratorObject<V>;
52
+ /** `[key, value]` pairs, least to most recently used. */
53
+ entries(): IteratorObject<[K, V]>;
54
+ /** Call `callback(value, key, cache)` for each entry, least to most recently used. */
55
+ forEach(callback: (value: V, key: K, cache: this) => void, thisArg?: unknown): void;
56
+ /** `[key, value]` pairs, least to most recently used. */
57
+ [Symbol.iterator](): IteratorObject<[K, V]>;
58
+ }