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.
- package/README.md +405 -60
- package/dist/array/index.d.ts +9 -0
- package/dist/array/index.js +9 -0
- package/dist/array/list.d.ts +99 -0
- package/dist/array/list.js +133 -0
- package/dist/array/sets.d.ts +130 -0
- package/dist/array/sets.js +213 -0
- package/dist/async/index.d.ts +6 -0
- package/dist/async/index.js +6 -0
- package/dist/async/retry.d.ts +38 -0
- package/dist/async/retry.js +56 -0
- package/dist/async/sleep.d.ts +42 -0
- package/dist/async/sleep.js +76 -0
- package/dist/collections/bisect.d.ts +103 -0
- package/dist/collections/bisect.js +157 -0
- package/dist/collections/deque.d.ts +67 -97
- package/dist/collections/deque.js +197 -249
- package/dist/collections/entries.d.ts +89 -0
- package/dist/collections/entries.js +131 -0
- package/dist/collections/frozen-set.d.ts +42 -0
- package/dist/collections/frozen-set.js +64 -0
- package/dist/collections/group.d.ts +141 -0
- package/dist/collections/group.js +241 -0
- package/dist/collections/heap.d.ts +64 -0
- package/dist/collections/heap.js +205 -0
- package/dist/collections/index.d.ts +15 -642
- package/dist/collections/index.js +14 -716
- package/dist/collections/internal/arrayKeys.d.ts +19 -0
- package/dist/collections/internal/arrayKeys.js +83 -0
- package/dist/collections/internal/invariants.d.ts +4 -0
- package/dist/collections/internal/invariants.js +12 -0
- package/dist/collections/internal/iterable.d.ts +25 -0
- package/dist/collections/internal/iterable.js +62 -0
- package/dist/collections/iterate.d.ts +162 -0
- package/dist/collections/iterate.js +188 -0
- package/dist/collections/lru-cache.d.ts +58 -0
- package/dist/collections/lru-cache.js +164 -0
- package/dist/collections/order.d.ts +19 -0
- package/dist/collections/order.js +38 -0
- package/dist/collections/shape.d.ts +32 -0
- package/dist/collections/shape.js +86 -0
- package/dist/collections/sorted-map.d.ts +171 -0
- package/dist/collections/sorted-map.js +845 -0
- package/dist/collections/sorted-set.d.ts +103 -0
- package/dist/collections/sorted-set.js +147 -0
- package/dist/collections/splay-tree.d.ts +82 -0
- package/dist/collections/splay-tree.js +354 -0
- package/dist/collections/trie.d.ts +58 -0
- package/dist/collections/trie.js +196 -0
- package/dist/decimal/currency.d.ts +211 -0
- package/dist/decimal/currency.js +321 -0
- package/dist/decimal/decimal.d.ts +299 -0
- package/dist/decimal/decimal.js +660 -0
- package/dist/decimal/index.d.ts +11 -145
- package/dist/decimal/index.js +10 -374
- package/dist/decimal/internal/bits.d.ts +2 -0
- package/dist/decimal/internal/bits.js +7 -0
- package/dist/decimal/internal/echo.d.ts +4 -0
- package/dist/decimal/internal/echo.js +6 -0
- package/dist/decimal/internal/isqrt.d.ts +9 -0
- package/dist/decimal/internal/isqrt.js +34 -0
- package/dist/decimal/internal/locale.d.ts +7 -0
- package/dist/decimal/internal/locale.js +24 -0
- package/dist/decimal/internal/minor-units.d.ts +2 -0
- package/dist/decimal/internal/minor-units.js +33 -0
- package/dist/decimal/internal/pow10.d.ts +24 -0
- package/dist/decimal/internal/pow10.js +96 -0
- package/dist/encoding/base64.d.ts +39 -0
- package/dist/encoding/base64.js +53 -0
- package/dist/encoding/hex.d.ts +23 -0
- package/dist/encoding/hex.js +34 -0
- package/dist/encoding/index.d.ts +6 -0
- package/dist/encoding/index.js +6 -0
- package/dist/function/debounce.d.ts +68 -0
- package/dist/function/debounce.js +203 -0
- package/dist/function/index.d.ts +6 -0
- package/dist/function/index.js +6 -0
- package/dist/function/shared.d.ts +2 -0
- package/dist/function/shared.js +5 -0
- package/dist/function/wrap.d.ts +130 -0
- package/dist/function/wrap.js +113 -0
- package/dist/hash/digest.d.ts +18 -0
- package/dist/hash/digest.js +26 -0
- package/dist/hash/hash.d.ts +22 -0
- package/dist/hash/hash.js +252 -0
- package/dist/hash/hashString.d.ts +13 -0
- package/dist/hash/hashString.js +53 -0
- package/dist/hash/index.d.ts +8 -0
- package/dist/hash/index.js +8 -0
- package/dist/hash/stableStringify.d.ts +19 -0
- package/dist/hash/stableStringify.js +102 -0
- package/dist/id/index.d.ts +7 -0
- package/dist/id/index.js +7 -0
- package/dist/id/nanoid.d.ts +16 -0
- package/dist/id/nanoid.js +65 -0
- package/dist/id/uniqueId.d.ts +14 -0
- package/dist/id/uniqueId.js +20 -0
- package/dist/id/uuid.d.ts +25 -0
- package/dist/id/uuid.js +64 -0
- package/dist/index.d.ts +15 -8
- package/dist/index.js +15 -8
- package/dist/internal/bytes.d.ts +11 -0
- package/dist/internal/bytes.js +33 -0
- package/dist/internal/codec.d.ts +11 -0
- package/dist/internal/codec.js +84 -0
- package/dist/internal/compare.d.ts +10 -0
- package/dist/internal/compare.js +26 -0
- package/dist/internal/crypto.d.ts +5 -0
- package/dist/internal/crypto.js +11 -0
- package/dist/internal/keys.d.ts +12 -0
- package/dist/internal/keys.js +23 -0
- package/dist/internal/kind.d.ts +44 -0
- package/dist/internal/kind.js +139 -0
- package/dist/internal/sparse.d.ts +51 -0
- package/dist/internal/sparse.js +104 -0
- package/dist/internal/text.d.ts +7 -0
- package/dist/internal/text.js +15 -0
- package/dist/internal/timer.d.ts +10 -0
- package/dist/internal/timer.js +17 -0
- package/dist/internal/truncate.d.ts +10 -0
- package/dist/internal/truncate.js +22 -0
- package/dist/internal/walk.d.ts +47 -0
- package/dist/internal/walk.js +100 -0
- package/dist/is/index.d.ts +8 -0
- package/dist/is/index.js +8 -0
- package/dist/is/isArrayLike.d.ts +18 -0
- package/dist/is/isArrayLike.js +25 -0
- package/dist/is/isError.d.ts +13 -0
- package/dist/is/isError.js +18 -0
- package/dist/is/isNil.d.ts +12 -0
- package/dist/is/isNil.js +14 -0
- package/dist/is/isPlainObject.d.ts +15 -0
- package/dist/is/isPlainObject.js +34 -0
- package/dist/number/index.d.ts +7 -0
- package/dist/number/index.js +7 -0
- package/dist/number/round.d.ts +86 -0
- package/dist/number/round.js +130 -0
- package/dist/number/stats.d.ts +52 -0
- package/dist/number/stats.js +115 -0
- package/dist/object/cloneDeep.d.ts +28 -0
- package/dist/object/cloneDeep.js +200 -0
- package/dist/object/index.d.ts +14 -0
- package/dist/object/index.js +13 -0
- package/dist/object/isEqual.d.ts +64 -0
- package/dist/object/isEqual.js +289 -0
- package/dist/object/matches.d.ts +40 -0
- package/dist/object/matches.js +284 -0
- package/dist/object/merge.d.ts +66 -0
- package/dist/object/merge.js +272 -0
- package/dist/object/parsePath.d.ts +22 -0
- package/dist/object/parsePath.js +111 -0
- package/dist/object/path.d.ts +85 -0
- package/dist/object/path.js +208 -0
- package/dist/object/pick.d.ts +91 -0
- package/dist/object/pick.js +180 -0
- package/dist/object/reshape.d.ts +73 -0
- package/dist/object/reshape.js +144 -0
- package/dist/random/index.d.ts +96 -32
- package/dist/random/index.js +215 -50
- package/dist/string/case.d.ts +71 -0
- package/dist/string/case.js +152 -0
- package/dist/string/fold.d.ts +35 -0
- package/dist/string/fold.js +100 -0
- package/dist/string/index.d.ts +6 -187
- package/dist/string/index.js +6 -226
- package/dist/string/truncate.d.ts +25 -0
- package/dist/string/truncate.js +44 -0
- package/dist/string/words.d.ts +27 -0
- package/dist/string/words.js +241 -0
- package/package.json +101 -58
- package/dist/collections/BTree.d.ts +0 -229
- package/dist/collections/BTree.js +0 -1165
- package/dist/collections/Heap.d.ts +0 -69
- package/dist/collections/Heap.js +0 -181
- package/dist/collections/LRUCache.d.ts +0 -80
- package/dist/collections/LRUCache.js +0 -126
- package/dist/collections/SortedMap.d.ts +0 -92
- package/dist/collections/SortedMap.js +0 -131
- package/dist/collections/SortedSet.d.ts +0 -69
- package/dist/collections/SortedSet.js +0 -99
- package/dist/collections/SortedTree.d.ts +0 -103
- package/dist/collections/SortedTree.js +0 -141
- package/dist/collections/SplayTree.d.ts +0 -105
- package/dist/collections/SplayTree.js +0 -338
- package/dist/collections/Trie.d.ts +0 -42
- package/dist/collections/Trie.js +0 -104
- package/dist/collections/abc.d.ts +0 -152
- package/dist/collections/abc.js +0 -39
- package/dist/collections/frozenset.d.ts +0 -19
- package/dist/collections/frozenset.js +0 -30
- package/dist/functools/index.d.ts +0 -130
- package/dist/functools/index.js +0 -235
- package/dist/globals/index.d.ts +0 -285
- package/dist/globals/index.js +0 -463
- package/dist/i18n/currency.d.ts +0 -24
- package/dist/i18n/currency.js +0 -85
- package/dist/i18n/date/index.d.ts +0 -203
- package/dist/i18n/date/index.js +0 -531
- package/dist/i18n/date/utils.d.ts +0 -65
- package/dist/i18n/date/utils.js +0 -290
- package/dist/i18n/duration.d.ts +0 -112
- package/dist/i18n/duration.js +0 -392
- package/dist/i18n/format.d.ts +0 -31
- package/dist/i18n/format.js +0 -506
- package/dist/i18n/index.d.ts +0 -8
- package/dist/i18n/index.js +0 -8
- package/dist/itertools/index.d.ts +0 -255
- package/dist/itertools/index.js +0 -437
- package/dist/math/index.d.ts +0 -96
- package/dist/math/index.js +0 -98
- package/dist/mod.d.ts +0 -1
- package/dist/mod.js +0 -1
- package/dist/operators/index.d.ts +0 -152
- package/dist/operators/index.js +0 -305
- package/dist/types.d.ts +0 -19
- package/dist/types.js +0 -1
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
function refresh(state, entry) {
|
|
2
|
+
if (entry === state.newest)
|
|
3
|
+
return;
|
|
4
|
+
unlink(state, entry);
|
|
5
|
+
append(state, entry);
|
|
6
|
+
}
|
|
7
|
+
function unlink(state, entry) {
|
|
8
|
+
const { older, newer } = entry;
|
|
9
|
+
if (older === undefined)
|
|
10
|
+
state.oldest = newer;
|
|
11
|
+
else
|
|
12
|
+
older.newer = newer;
|
|
13
|
+
if (newer === undefined)
|
|
14
|
+
state.newest = older;
|
|
15
|
+
else
|
|
16
|
+
newer.older = older;
|
|
17
|
+
entry.older = undefined;
|
|
18
|
+
entry.newer = undefined;
|
|
19
|
+
}
|
|
20
|
+
function append(state, entry) {
|
|
21
|
+
entry.older = state.newest;
|
|
22
|
+
if (state.newest === undefined)
|
|
23
|
+
state.oldest = entry;
|
|
24
|
+
else
|
|
25
|
+
state.newest.newer = entry;
|
|
26
|
+
state.newest = entry;
|
|
27
|
+
}
|
|
28
|
+
function snapshot(state) {
|
|
29
|
+
const entries = [];
|
|
30
|
+
for (let entry = state.oldest; entry !== undefined; entry = entry.newer)
|
|
31
|
+
entries.push(entry);
|
|
32
|
+
return entries;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* A fixed-capacity least-recently-used cache with `Map`'s method names. `get` refreshes recency;
|
|
36
|
+
* `has` does not. Keys compare with SameValueZero, as in `Map`. Iterators and `forEach` walk a
|
|
37
|
+
* snapshot taken when they start, so `get` and `set` inside a loop are safe.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```ts
|
|
41
|
+
* const cache = new LRUCache<string, number>(2)
|
|
42
|
+
* cache.set('a', 1).set('b', 2)
|
|
43
|
+
* cache.get('a') // 1, so 'b' is now the least recent
|
|
44
|
+
* cache.set('c', 3)
|
|
45
|
+
* cache.has('b') // false
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export class LRUCache {
|
|
49
|
+
/**
|
|
50
|
+
* Create an empty cache.
|
|
51
|
+
* @param capacity Maximum number of entries; must be an integer >= 1. Defaults to 1024.
|
|
52
|
+
* @throws {TypeError} when capacity is not a number.
|
|
53
|
+
* @throws {RangeError} when capacity is not an integer >= 1.
|
|
54
|
+
*/
|
|
55
|
+
constructor(capacity = 1024) {
|
|
56
|
+
if (typeof capacity !== 'number')
|
|
57
|
+
throw new TypeError('capacity must be a number');
|
|
58
|
+
if (!Number.isInteger(capacity) || capacity < 1) {
|
|
59
|
+
throw new RangeError('capacity must be an integer >= 1');
|
|
60
|
+
}
|
|
61
|
+
const state = {
|
|
62
|
+
items: new Map(),
|
|
63
|
+
capacity,
|
|
64
|
+
oldest: undefined,
|
|
65
|
+
newest: undefined
|
|
66
|
+
};
|
|
67
|
+
Object.defineProperty(this, 'state', { value: state });
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Set `key` to `value`. Setting an existing key updates its value and makes it the most recent,
|
|
71
|
+
* without evicting. Inserting a new key at capacity evicts the least recently used entry.
|
|
72
|
+
*/
|
|
73
|
+
set(key, value) {
|
|
74
|
+
const { state } = this;
|
|
75
|
+
const entry = state.items.get(key);
|
|
76
|
+
if (entry !== undefined) {
|
|
77
|
+
entry.value = value;
|
|
78
|
+
refresh(state, entry);
|
|
79
|
+
return this;
|
|
80
|
+
}
|
|
81
|
+
const oldest = state.oldest;
|
|
82
|
+
if (oldest !== undefined && state.items.size >= state.capacity) {
|
|
83
|
+
unlink(state, oldest);
|
|
84
|
+
state.items.delete(oldest.key);
|
|
85
|
+
}
|
|
86
|
+
const added = { key, value, older: undefined, newer: undefined };
|
|
87
|
+
state.items.set(key, added);
|
|
88
|
+
append(state, added);
|
|
89
|
+
return this;
|
|
90
|
+
}
|
|
91
|
+
/** Whether `key` is cached. Does not refresh its recency. */
|
|
92
|
+
has(key) {
|
|
93
|
+
return this.state.items.has(key);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Return the value for `key`, refreshing its recency. Missing keys return `undefined`.
|
|
97
|
+
*/
|
|
98
|
+
get(key) {
|
|
99
|
+
const { state } = this;
|
|
100
|
+
const entry = state.items.get(key);
|
|
101
|
+
if (entry === undefined)
|
|
102
|
+
return undefined;
|
|
103
|
+
refresh(state, entry);
|
|
104
|
+
return entry.value;
|
|
105
|
+
}
|
|
106
|
+
/** Remove every entry. */
|
|
107
|
+
clear() {
|
|
108
|
+
const { state } = this;
|
|
109
|
+
state.items.clear();
|
|
110
|
+
state.oldest = undefined;
|
|
111
|
+
state.newest = undefined;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Remove `key`.
|
|
115
|
+
* @returns Whether it was present.
|
|
116
|
+
*/
|
|
117
|
+
delete(key) {
|
|
118
|
+
const { state } = this;
|
|
119
|
+
const entry = state.items.get(key);
|
|
120
|
+
if (entry === undefined)
|
|
121
|
+
return false;
|
|
122
|
+
unlink(state, entry);
|
|
123
|
+
return state.items.delete(key);
|
|
124
|
+
}
|
|
125
|
+
/** The number of entries. */
|
|
126
|
+
get size() {
|
|
127
|
+
return this.state.items.size;
|
|
128
|
+
}
|
|
129
|
+
/** Maximum number of entries. */
|
|
130
|
+
get capacity() {
|
|
131
|
+
return this.state.capacity;
|
|
132
|
+
}
|
|
133
|
+
/** `'LRUCache'`, for `Object.prototype.toString`. */
|
|
134
|
+
get [Symbol.toStringTag]() {
|
|
135
|
+
return 'LRUCache';
|
|
136
|
+
}
|
|
137
|
+
/** The keys, least to most recently used. */
|
|
138
|
+
keys() {
|
|
139
|
+
return snapshot(this.state)
|
|
140
|
+
.map((entry) => entry.key)
|
|
141
|
+
.values();
|
|
142
|
+
}
|
|
143
|
+
/** The values, least to most recently used. */
|
|
144
|
+
values() {
|
|
145
|
+
return snapshot(this.state)
|
|
146
|
+
.map((entry) => entry.value)
|
|
147
|
+
.values();
|
|
148
|
+
}
|
|
149
|
+
/** `[key, value]` pairs, least to most recently used. */
|
|
150
|
+
entries() {
|
|
151
|
+
return snapshot(this.state)
|
|
152
|
+
.map((entry) => [entry.key, entry.value])
|
|
153
|
+
.values();
|
|
154
|
+
}
|
|
155
|
+
/** Call `callback(value, key, cache)` for each entry, least to most recently used. */
|
|
156
|
+
forEach(callback, thisArg) {
|
|
157
|
+
for (const [k, v] of this.entries())
|
|
158
|
+
Reflect.apply(callback, thisArg, [v, k, this]);
|
|
159
|
+
}
|
|
160
|
+
/** `[key, value]` pairs, least to most recently used. */
|
|
161
|
+
[Symbol.iterator]() {
|
|
162
|
+
return this.entries();
|
|
163
|
+
}
|
|
164
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The default key order of the key helpers.
|
|
3
|
+
*/
|
|
4
|
+
/** The two families of keys the default order compares: numbers with bigints, and strings. */
|
|
5
|
+
export type KeyKind = 'number' | 'string';
|
|
6
|
+
/**
|
|
7
|
+
* The family of a non-nil key.
|
|
8
|
+
* @throws {RangeError} for `NaN`.
|
|
9
|
+
* @throws {TypeError} for anything but a number, a bigint or a string.
|
|
10
|
+
*/
|
|
11
|
+
export declare function keyKind(x: unknown): KeyKind;
|
|
12
|
+
/**
|
|
13
|
+
* Order two keys in `direction` (`1` ascending, `-1` descending): numbers and bigints by value
|
|
14
|
+
* (`<` is exact across the two), strings by UTF-16 code units as `<` does, and `null` /
|
|
15
|
+
* `undefined` after everything else in either direction.
|
|
16
|
+
* @throws {RangeError} for `NaN`.
|
|
17
|
+
* @throws {TypeError} for any other type, or a number against a string.
|
|
18
|
+
*/
|
|
19
|
+
export declare function compareKeys(a: unknown, b: unknown, direction?: 1 | -1): number;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The default key order of the key helpers.
|
|
3
|
+
*/
|
|
4
|
+
import { isNil } from '../is/isNil.js';
|
|
5
|
+
/**
|
|
6
|
+
* The family of a non-nil key.
|
|
7
|
+
* @throws {RangeError} for `NaN`.
|
|
8
|
+
* @throws {TypeError} for anything but a number, a bigint or a string.
|
|
9
|
+
*/
|
|
10
|
+
export function keyKind(x) {
|
|
11
|
+
if (typeof x === 'number') {
|
|
12
|
+
if (Number.isNaN(x))
|
|
13
|
+
throw new RangeError('NaN has no order; return another key');
|
|
14
|
+
return 'number';
|
|
15
|
+
}
|
|
16
|
+
if (typeof x === 'bigint')
|
|
17
|
+
return 'number';
|
|
18
|
+
if (typeof x === 'string')
|
|
19
|
+
return 'string';
|
|
20
|
+
throw new TypeError(`cannot order a ${typeof x} key; return a number, bigint or string`);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Order two keys in `direction` (`1` ascending, `-1` descending): numbers and bigints by value
|
|
24
|
+
* (`<` is exact across the two), strings by UTF-16 code units as `<` does, and `null` /
|
|
25
|
+
* `undefined` after everything else in either direction.
|
|
26
|
+
* @throws {RangeError} for `NaN`.
|
|
27
|
+
* @throws {TypeError} for any other type, or a number against a string.
|
|
28
|
+
*/
|
|
29
|
+
export function compareKeys(a, b, direction = 1) {
|
|
30
|
+
const aNil = isNil(a);
|
|
31
|
+
const bNil = isNil(b);
|
|
32
|
+
if (aNil || bNil)
|
|
33
|
+
return aNil === bNil ? 0 : aNil ? 1 : -1;
|
|
34
|
+
if (keyKind(a) !== keyKind(b))
|
|
35
|
+
throw new TypeError('cannot order a string key against a number key');
|
|
36
|
+
const ascending = a < b ? -1 : a > b ? 1 : 0;
|
|
37
|
+
return ascending * direction;
|
|
38
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/** Any value the collection helpers accept: an object, a string, or `null` / `undefined` as empty. */
|
|
2
|
+
export type Collection = object | string | null | undefined;
|
|
3
|
+
/**
|
|
4
|
+
* The key a collection helper passes for `C`: an index for arrays, typed arrays, strings and other
|
|
5
|
+
* iterables, the map key for a `Map`, the value for a `Set`, and an own string key otherwise.
|
|
6
|
+
*/
|
|
7
|
+
export type CollectionKey<C> = C extends string ? number : C extends ReadonlyMap<infer K, unknown> ? K : C extends ReadonlySet<infer V> ? V : C extends Iterable<unknown> ? number : C extends object ? string : never;
|
|
8
|
+
/**
|
|
9
|
+
* The value a collection helper passes for `C`: an element, a code point, a map value, a set
|
|
10
|
+
* member, or an own property value.
|
|
11
|
+
*/
|
|
12
|
+
export type CollectionValue<C> = C extends string ? string : C extends ReadonlyMap<unknown, infer V> ? V : C extends Iterable<infer V> ? V : C extends object ? [keyof C] extends [never] ? unknown : C[keyof C] : never;
|
|
13
|
+
/** `(value, key, collection)`, as `Map.prototype.forEach` passes them. */
|
|
14
|
+
export type CollectionCallback<C, R> = (value: CollectionValue<C>, key: CollectionKey<C>, collection: C) => R;
|
|
15
|
+
/** A visitor of `(value, key)`; returning `true` stops the walk. */
|
|
16
|
+
export type Visit = (value: unknown, key: unknown) => boolean | undefined | void;
|
|
17
|
+
/**
|
|
18
|
+
* Visit the present elements of `arr` in index order until `visit` returns `true`; the cost
|
|
19
|
+
* follows the elements, not `length`. Returns whether it stopped early.
|
|
20
|
+
*/
|
|
21
|
+
export declare function eachIndex(arr: readonly unknown[], visit: Visit): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Visit the entries of `collection` as `(value, key)`, by the shape rules of `fns/collection`,
|
|
24
|
+
* until `visit` returns `true`. Returns whether it stopped early. A number, boolean, bigint or
|
|
25
|
+
* symbol has no entries, as `Object.keys(5)` has none.
|
|
26
|
+
*/
|
|
27
|
+
export declare function eachEntry(collection: unknown, visit: Visit): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Every `[key, value]` of `collection` in order, as `entries` lists them, for the helpers that
|
|
30
|
+
* walk from the end.
|
|
31
|
+
*/
|
|
32
|
+
export declare function entryList(collection: unknown): [key: unknown, value: unknown][];
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { isMap, isSet, typedArrayLength } from '../internal/kind.js';
|
|
2
|
+
import { walkArray } from '../internal/sparse.js';
|
|
3
|
+
const mapEntries = Map.prototype.entries;
|
|
4
|
+
const setValues = Set.prototype.values;
|
|
5
|
+
function isIterable(x) {
|
|
6
|
+
return typeof x[Symbol.iterator] === 'function';
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Visit the present elements of `arr` in index order until `visit` returns `true`; the cost
|
|
10
|
+
* follows the elements, not `length`. Returns whether it stopped early.
|
|
11
|
+
*/
|
|
12
|
+
export function eachIndex(arr, visit) {
|
|
13
|
+
let stopped = false;
|
|
14
|
+
walkArray(arr, (event) => {
|
|
15
|
+
if (event.kind === 'value' && visit(event.value, event.index) === true) {
|
|
16
|
+
stopped = true;
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
return stopped;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Visit the entries of `collection` as `(value, key)`, by the shape rules of `fns/collection`,
|
|
24
|
+
* until `visit` returns `true`. Returns whether it stopped early. A number, boolean, bigint or
|
|
25
|
+
* symbol has no entries, as `Object.keys(5)` has none.
|
|
26
|
+
*/
|
|
27
|
+
export function eachEntry(collection, visit) {
|
|
28
|
+
if (collection === null || collection === undefined)
|
|
29
|
+
return false;
|
|
30
|
+
if (typeof collection === 'string') {
|
|
31
|
+
let i = 0;
|
|
32
|
+
for (const ch of collection)
|
|
33
|
+
if (visit(ch, i++) === true)
|
|
34
|
+
return true;
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
if (typeof collection !== 'object' && typeof collection !== 'function')
|
|
38
|
+
return false;
|
|
39
|
+
if (Array.isArray(collection))
|
|
40
|
+
return eachIndex(collection, visit);
|
|
41
|
+
const length = typedArrayLength(collection);
|
|
42
|
+
if (length !== undefined) {
|
|
43
|
+
const view = collection;
|
|
44
|
+
for (let i = 0; i < length; i++)
|
|
45
|
+
if (visit(view[i], i) === true)
|
|
46
|
+
return true;
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
if (isMap(collection)) {
|
|
50
|
+
for (const [key, value] of mapEntries.call(collection)) {
|
|
51
|
+
if (visit(value, key) === true)
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
if (isSet(collection)) {
|
|
57
|
+
for (const value of setValues.call(collection)) {
|
|
58
|
+
if (visit(value, value) === true)
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
if (isIterable(collection)) {
|
|
64
|
+
let i = 0;
|
|
65
|
+
for (const value of collection)
|
|
66
|
+
if (visit(value, i++) === true)
|
|
67
|
+
return true;
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
const record = collection;
|
|
71
|
+
for (const key of Object.keys(record))
|
|
72
|
+
if (visit(record[key], key) === true)
|
|
73
|
+
return true;
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Every `[key, value]` of `collection` in order, as `entries` lists them, for the helpers that
|
|
78
|
+
* walk from the end.
|
|
79
|
+
*/
|
|
80
|
+
export function entryList(collection) {
|
|
81
|
+
const out = [];
|
|
82
|
+
eachEntry(collection, (value, key) => {
|
|
83
|
+
out.push([key, value]);
|
|
84
|
+
});
|
|
85
|
+
return out;
|
|
86
|
+
}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { type Comparator } from '../internal/compare.js';
|
|
2
|
+
export declare let createSetMap: <T>(values?: Iterable<T> | null, compareFn?: Comparator<T> | null) => SortedMap<T, true>;
|
|
3
|
+
export declare let insertIfAbsent: <K, V>(map: SortedMap<K, V>, key: K, value: V) => boolean;
|
|
4
|
+
/**
|
|
5
|
+
* A map whose keys stay sorted, on a copy-on-write B+ tree with subtree counts. It has `Map`'s
|
|
6
|
+
* method names and iterates in key order, adds order queries (`firstKey`, `lastKey`, `lower`,
|
|
7
|
+
* `higher`, `floor`, `ceiling`), position queries (`at`, `rank`) and range operations
|
|
8
|
+
* (`entriesBetween`, `updateRange`, `removeRange`), and clones in O(1): a clone shares nodes with
|
|
9
|
+
* its source until either one writes. Keys the comparator calls equal are the
|
|
10
|
+
* same key, and a `-0` key is stored as `+0`, as `Map` does. With the default comparator, keys are
|
|
11
|
+
* numbers, bigints or strings: `NaN` throws `RangeError`, and `null`, `undefined` and other values
|
|
12
|
+
* throw `TypeError`; pass a comparator to order them.
|
|
13
|
+
*
|
|
14
|
+
* The comparator must be pure, return a finite number for every pair, and return 0 for a key
|
|
15
|
+
* compared with itself; every new key is checked, and a comparator that breaks these rules throws
|
|
16
|
+
* `TypeError` and leaves the map unchanged. Subtracting numbers fails for `Infinity` and `NaN`
|
|
17
|
+
* keys (`Infinity - x` is not finite); the default comparator handles every number but `NaN`.
|
|
18
|
+
*
|
|
19
|
+
* Under a strict total order, changing the map while iterating it never repeats a key: after a
|
|
20
|
+
* structural change the cursor re-seeks to the key after the last one it yielded. The walk ends
|
|
21
|
+
* unless the loop keeps inserting keys ahead of the cursor, as with `Map`.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```ts
|
|
25
|
+
* const scores = new SortedMap([
|
|
26
|
+
* ['carol', 7],
|
|
27
|
+
* ['alice', 9]
|
|
28
|
+
* ])
|
|
29
|
+
* scores.set('bob', 8)
|
|
30
|
+
* ;[...scores.keys()] // ['alice', 'bob', 'carol']
|
|
31
|
+
* scores.at(-1) // ['carol', 7]
|
|
32
|
+
* scores.rank('bob') // 1
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export declare class SortedMap<K = unknown, V = unknown> {
|
|
36
|
+
#private;
|
|
37
|
+
/**
|
|
38
|
+
* Create a map holding `entries`. Sorted input loads in linear time; when keys repeat, the last
|
|
39
|
+
* entry wins, as for `Map`.
|
|
40
|
+
* @param entries Initial `[key, value]` pairs. `null` means none, as for `Map`.
|
|
41
|
+
* @param compareFn Key comparator. Defaults to the primitive order (numbers, bigints and strings).
|
|
42
|
+
* @throws {TypeError} when `entries` is not iterable or holds something that is not an entry,
|
|
43
|
+
* or the comparator cannot order a key.
|
|
44
|
+
*/
|
|
45
|
+
constructor(entries?: Iterable<readonly [K, V]> | null, compareFn?: ((a: K, b: K) => number) | null);
|
|
46
|
+
/** The number of entries. */
|
|
47
|
+
get size(): number;
|
|
48
|
+
/** `'SortedMap'`, for `Object.prototype.toString`. */
|
|
49
|
+
get [Symbol.toStringTag](): string;
|
|
50
|
+
/** Remove every entry. */
|
|
51
|
+
clear(): void;
|
|
52
|
+
/** The value for `key`, or `undefined` when it is absent. O(log n). */
|
|
53
|
+
get(key: K): V | undefined;
|
|
54
|
+
/**
|
|
55
|
+
* Insert or replace `key`. Replacing also stores the new key object. O(log n).
|
|
56
|
+
* @returns `this`
|
|
57
|
+
* @throws {TypeError} when the comparator cannot order `key`; the map is unchanged.
|
|
58
|
+
*/
|
|
59
|
+
set(key: K, value: V): this;
|
|
60
|
+
/** Whether `key` is present. O(log n). */
|
|
61
|
+
has(key: K): boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Remove `key`. O(log n).
|
|
64
|
+
* @returns Whether it was present.
|
|
65
|
+
*/
|
|
66
|
+
delete(key: K): boolean;
|
|
67
|
+
/**
|
|
68
|
+
* The entry at `index` in key order, with `Array.prototype.at` rules (negative counts from the
|
|
69
|
+
* end), or `undefined` out of range. O(log n), with no comparator calls.
|
|
70
|
+
*/
|
|
71
|
+
at(index: number): [K, V] | undefined;
|
|
72
|
+
/**
|
|
73
|
+
* `[key, value]` pairs in ascending key order.
|
|
74
|
+
* @param lowestKey Start at the first key not below it. Omitted (or `undefined`) means the first
|
|
75
|
+
* key.
|
|
76
|
+
*/
|
|
77
|
+
entries(lowestKey?: K): IteratorObject<[K, V]>;
|
|
78
|
+
/**
|
|
79
|
+
* `[key, value]` pairs in descending key order.
|
|
80
|
+
* @param highestKey Start at the last key not above it. Omitted (or `undefined`) means the last
|
|
81
|
+
* key.
|
|
82
|
+
*/
|
|
83
|
+
entriesDescending(highestKey?: K): IteratorObject<[K, V]>;
|
|
84
|
+
/** The keys, in order. */
|
|
85
|
+
keys(): IteratorObject<K>;
|
|
86
|
+
/** The values, in key order. */
|
|
87
|
+
values(): IteratorObject<V>;
|
|
88
|
+
/** Call `callback(value, key, map)` for each entry, in key order. */
|
|
89
|
+
forEach(callback: (value: V, key: K, map: this) => void, thisArg?: unknown): void;
|
|
90
|
+
/** `[key, value]` pairs, in key order. */
|
|
91
|
+
[Symbol.iterator](): IteratorObject<[K, V]>;
|
|
92
|
+
/**
|
|
93
|
+
* How many keys sort before `key`: its index when present, else where it would go. O(log n).
|
|
94
|
+
* @throws {TypeError} when the comparator cannot order `key`.
|
|
95
|
+
*/
|
|
96
|
+
rank(key: K): number;
|
|
97
|
+
/** The smallest key, or `undefined` when empty. */
|
|
98
|
+
firstKey(): K | undefined;
|
|
99
|
+
/** The largest key, or `undefined` when empty. */
|
|
100
|
+
lastKey(): K | undefined;
|
|
101
|
+
/** The entry with the least key above `key`, or `undefined`. */
|
|
102
|
+
higher(key: K): [K, V] | undefined;
|
|
103
|
+
/** The entry with the greatest key below `key`, or `undefined`. */
|
|
104
|
+
lower(key: K): [K, V] | undefined;
|
|
105
|
+
/** The entry with the least key at or above `key`, or `undefined`. */
|
|
106
|
+
ceiling(key: K): [K, V] | undefined;
|
|
107
|
+
/** The entry with the greatest key at or below `key`, or `undefined`. */
|
|
108
|
+
floor(key: K): [K, V] | undefined;
|
|
109
|
+
/**
|
|
110
|
+
* The entries whose keys lie in `[from, to)`, or `[from, to]` with `inclusiveEnd`, in key order.
|
|
111
|
+
* @param options `inclusiveEnd` includes `to` (default false); `limit` caps how many entries are
|
|
112
|
+
* collected (a non-negative integer or `Infinity`, the default).
|
|
113
|
+
* @throws {TypeError} when `limit` is not a number.
|
|
114
|
+
* @throws {RangeError} when `limit` is negative or not an integer.
|
|
115
|
+
* @example
|
|
116
|
+
* ```ts
|
|
117
|
+
* new SortedMap([[1, 'a'], [2, 'b'], [3, 'c']]).entriesBetween(1, 3) // [[1, 'a'], [2, 'b']]
|
|
118
|
+
* ```
|
|
119
|
+
*/
|
|
120
|
+
entriesBetween(from: K, to: K, options?: {
|
|
121
|
+
inclusiveEnd?: boolean;
|
|
122
|
+
limit?: number;
|
|
123
|
+
}): [K, V][];
|
|
124
|
+
/**
|
|
125
|
+
* Visit the entries whose keys lie in `[from, to)`, or `[from, to]` with `inclusiveEnd`, in key
|
|
126
|
+
* order, and change them in one atomic step: if `update` or the comparator throws, the map is
|
|
127
|
+
* left as it was. `update(value, key, map)` returns `{ replace: value }`, `{ remove: true }`,
|
|
128
|
+
* either with `stop: true` to end after this entry, `{ stop: true }`, or `null`/`undefined` to
|
|
129
|
+
* leave the entry alone.
|
|
130
|
+
* @returns The number of entries visited.
|
|
131
|
+
* @throws {TypeError} when `update` returns a primitive, an object with none of `replace`,
|
|
132
|
+
* `remove` and `stop`, or both `replace` and a truthy `remove`.
|
|
133
|
+
* @example
|
|
134
|
+
* ```ts
|
|
135
|
+
* const stock = new SortedMap([['apple', 3], ['pear', 0]])
|
|
136
|
+
* stock.updateRange('a', 'z', (n) => (n === 0 ? { remove: true } : { replace: n - 1 }))
|
|
137
|
+
* ;[...stock] // [['apple', 2]]
|
|
138
|
+
* ```
|
|
139
|
+
*/
|
|
140
|
+
updateRange(from: K, to: K, update: (value: V, key: K, map: this) => {
|
|
141
|
+
replace: V;
|
|
142
|
+
stop?: true;
|
|
143
|
+
} | {
|
|
144
|
+
remove: true;
|
|
145
|
+
stop?: true;
|
|
146
|
+
} | {
|
|
147
|
+
stop: true;
|
|
148
|
+
} | null | undefined, options?: {
|
|
149
|
+
inclusiveEnd?: boolean;
|
|
150
|
+
}): number;
|
|
151
|
+
/**
|
|
152
|
+
* Remove the entries whose keys lie in `[from, to)`, or `[from, to]` with `inclusiveEnd`, in one
|
|
153
|
+
* atomic step: a comparator that throws leaves the map unchanged.
|
|
154
|
+
* @returns The number of entries removed.
|
|
155
|
+
* @example
|
|
156
|
+
* ```ts
|
|
157
|
+
* const log = new SortedMap([[1, 'a'], [5, 'b'], [9, 'c']])
|
|
158
|
+
* log.removeRange(0, 5, { inclusiveEnd: true }) // 2
|
|
159
|
+
* ```
|
|
160
|
+
*/
|
|
161
|
+
removeRange(from: K, to: K, options?: {
|
|
162
|
+
inclusiveEnd?: boolean;
|
|
163
|
+
}): number;
|
|
164
|
+
/**
|
|
165
|
+
* A copy in O(1): the two maps share nodes until either one writes, which copies only the path
|
|
166
|
+
* it changes. The copy keeps the class and comparator.
|
|
167
|
+
* @throws {TypeError} when a subclass constructor does not pass `(entries, compareFn)`
|
|
168
|
+
* on to `SortedMap`.
|
|
169
|
+
*/
|
|
170
|
+
clone(): this;
|
|
171
|
+
}
|