@evolu/common 7.4.1 → 8.0.0-next.1
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 +4 -61
- package/dist/src/Array.d.ts +343 -102
- package/dist/src/Array.d.ts.map +1 -1
- package/dist/src/Array.js +181 -85
- package/dist/src/Assert.d.ts +57 -11
- package/dist/src/Assert.d.ts.map +1 -1
- package/dist/src/Assert.js +47 -11
- package/dist/src/BigInt.d.ts +6 -1
- package/dist/src/BigInt.d.ts.map +1 -1
- package/dist/src/BigInt.js +5 -0
- package/dist/src/Brand.d.ts +40 -12
- package/dist/src/Brand.d.ts.map +1 -1
- package/dist/src/Brand.js +5 -0
- package/dist/src/Buffer.d.ts +6 -1
- package/dist/src/Buffer.d.ts.map +1 -1
- package/dist/src/Buffer.js +7 -2
- package/dist/src/Cache.d.ts +10 -2
- package/dist/src/Cache.d.ts.map +1 -1
- package/dist/src/Cache.js +6 -0
- package/dist/src/Callbacks.d.ts +10 -7
- package/dist/src/Callbacks.d.ts.map +1 -1
- package/dist/src/Callbacks.js +23 -13
- package/dist/src/Console.d.ts +361 -69
- package/dist/src/Console.d.ts.map +1 -1
- package/dist/src/Console.js +217 -117
- package/dist/src/Crypto.d.ts +70 -21
- package/dist/src/Crypto.d.ts.map +1 -1
- package/dist/src/Crypto.js +72 -27
- package/dist/src/Eq.d.ts +22 -2
- package/dist/src/Eq.d.ts.map +1 -1
- package/dist/src/Eq.js +21 -1
- package/dist/src/Error.d.ts +23 -12
- package/dist/src/Error.d.ts.map +1 -1
- package/dist/src/Error.js +27 -11
- package/dist/src/Function.d.ts +128 -56
- package/dist/src/Function.d.ts.map +1 -1
- package/dist/src/Function.js +118 -14
- package/dist/src/Identicon.d.ts +5 -0
- package/dist/src/Identicon.d.ts.map +1 -1
- package/dist/src/Identicon.js +6 -1
- package/dist/src/Lookup.d.ts +162 -0
- package/dist/src/Lookup.d.ts.map +1 -0
- package/dist/src/Lookup.js +200 -0
- package/dist/src/Microtask.d.ts +21 -0
- package/dist/src/Microtask.d.ts.map +1 -0
- package/dist/src/Microtask.js +37 -0
- package/dist/src/Number.d.ts +18 -4
- package/dist/src/Number.d.ts.map +1 -1
- package/dist/src/Number.js +23 -1
- package/dist/src/Object.d.ts +110 -5
- package/dist/src/Object.d.ts.map +1 -1
- package/dist/src/Object.js +108 -5
- package/dist/src/Option.d.ts +58 -0
- package/dist/src/Option.d.ts.map +1 -0
- package/dist/src/Option.js +43 -0
- package/dist/src/Order.d.ts +5 -0
- package/dist/src/Order.d.ts.map +1 -1
- package/dist/src/Order.js +8 -3
- package/dist/src/Platform.d.ts +36 -2
- package/dist/src/Platform.d.ts.map +1 -1
- package/dist/src/Platform.js +10 -6
- package/dist/src/Polyfills.d.ts +29 -0
- package/dist/src/Polyfills.d.ts.map +1 -0
- package/dist/src/Polyfills.js +329 -0
- package/dist/src/Random.d.ts +18 -7
- package/dist/src/Random.d.ts.map +1 -1
- package/dist/src/Random.js +9 -7
- package/dist/src/Redacted.d.ts +7 -4
- package/dist/src/Redacted.d.ts.map +1 -1
- package/dist/src/Redacted.js +5 -0
- package/dist/src/Ref.d.ts +31 -16
- package/dist/src/Ref.d.ts.map +1 -1
- package/dist/src/Ref.js +35 -7
- package/dist/src/RefCount.d.ts +62 -0
- package/dist/src/RefCount.d.ts.map +1 -0
- package/dist/src/RefCount.js +83 -0
- package/dist/src/Relation.d.ts +84 -29
- package/dist/src/Relation.d.ts.map +1 -1
- package/dist/src/Relation.js +83 -105
- package/dist/src/Resource.d.ts +263 -0
- package/dist/src/Resource.d.ts.map +1 -0
- package/dist/src/Resource.js +389 -0
- package/dist/src/Result.d.ts +390 -374
- package/dist/src/Result.d.ts.map +1 -1
- package/dist/src/Result.js +142 -70
- package/dist/src/Schedule.d.ts +953 -0
- package/dist/src/Schedule.d.ts.map +1 -0
- package/dist/src/Schedule.js +1199 -0
- package/dist/src/Set.d.ts +181 -0
- package/dist/src/Set.d.ts.map +1 -0
- package/dist/src/Set.js +137 -0
- package/dist/src/Skiplist.d.ts +6 -1
- package/dist/src/Skiplist.d.ts.map +1 -1
- package/dist/src/Skiplist.js +5 -0
- package/dist/src/Sqlite.d.ts +160 -60
- package/dist/src/Sqlite.d.ts.map +1 -1
- package/dist/src/Sqlite.js +290 -190
- package/dist/src/Store.d.ts +36 -28
- package/dist/src/Store.d.ts.map +1 -1
- package/dist/src/Store.js +55 -15
- package/dist/src/String.d.ts +5 -0
- package/dist/src/String.d.ts.map +1 -1
- package/dist/src/String.js +5 -0
- package/dist/src/Task.d.ts +2274 -423
- package/dist/src/Task.d.ts.map +1 -1
- package/dist/src/Task.js +1499 -348
- package/dist/src/Test.d.ts +150 -0
- package/dist/src/Test.d.ts.map +1 -0
- package/dist/src/Test.js +97 -0
- package/dist/src/Time.d.ts +202 -48
- package/dist/src/Time.d.ts.map +1 -1
- package/dist/src/Time.js +199 -88
- package/dist/src/Tracer.d.ts +48 -0
- package/dist/src/Tracer.d.ts.map +1 -0
- package/dist/src/Tracer.js +6 -0
- package/dist/src/Type.d.ts +587 -209
- package/dist/src/Type.d.ts.map +1 -1
- package/dist/src/Type.js +370 -240
- package/dist/src/Types.d.ts +160 -6
- package/dist/src/Types.d.ts.map +1 -1
- package/dist/src/Types.js +22 -2
- package/dist/src/WebSocket.d.ts +130 -58
- package/dist/src/WebSocket.d.ts.map +1 -1
- package/dist/src/WebSocket.js +274 -113
- package/dist/src/Worker.d.ts +245 -60
- package/dist/src/Worker.d.ts.map +1 -1
- package/dist/src/Worker.js +220 -64
- package/dist/src/index.d.ts +25 -3
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +19 -3
- package/dist/src/local-first/Db.d.ts +24 -213
- package/dist/src/local-first/Db.d.ts.map +1 -1
- package/dist/src/local-first/Db.js +621 -293
- package/dist/src/local-first/Error.d.ts +12 -0
- package/dist/src/local-first/Error.d.ts.map +1 -0
- package/dist/src/local-first/Error.js +6 -0
- package/dist/src/local-first/Evolu.d.ts +330 -285
- package/dist/src/local-first/Evolu.d.ts.map +1 -1
- package/dist/src/local-first/Evolu.js +472 -402
- package/dist/src/local-first/LocalAuth.d.ts +10 -10
- package/dist/src/local-first/LocalAuth.d.ts.map +1 -1
- package/dist/src/local-first/LocalAuth.js +6 -1
- package/dist/src/local-first/Owner.d.ts +70 -27
- package/dist/src/local-first/Owner.d.ts.map +1 -1
- package/dist/src/local-first/Owner.js +27 -14
- package/dist/src/local-first/Protocol.d.ts +58 -50
- package/dist/src/local-first/Protocol.d.ts.map +1 -1
- package/dist/src/local-first/Protocol.js +253 -155
- package/dist/src/local-first/Query.d.ts +133 -43
- package/dist/src/local-first/Query.d.ts.map +1 -1
- package/dist/src/local-first/Query.js +139 -90
- package/dist/src/local-first/Relay.d.ts +34 -49
- package/dist/src/local-first/Relay.d.ts.map +1 -1
- package/dist/src/local-first/Relay.js +59 -177
- package/dist/src/local-first/Schema.d.ts +139 -144
- package/dist/src/local-first/Schema.d.ts.map +1 -1
- package/dist/src/local-first/Schema.js +78 -163
- package/dist/src/local-first/Shared.d.ts +125 -0
- package/dist/src/local-first/Shared.d.ts.map +1 -0
- package/dist/src/local-first/Shared.js +569 -0
- package/dist/src/local-first/Storage.d.ts +54 -58
- package/dist/src/local-first/Storage.d.ts.map +1 -1
- package/dist/src/local-first/Storage.js +127 -179
- package/dist/src/local-first/Timestamp.d.ts +28 -35
- package/dist/src/local-first/Timestamp.d.ts.map +1 -1
- package/dist/src/local-first/Timestamp.js +24 -25
- package/dist/src/local-first/index.d.ts +2 -15
- package/dist/src/local-first/index.d.ts.map +1 -1
- package/dist/src/local-first/index.js +2 -15
- package/package.json +37 -24
- package/src/Array.ts +467 -106
- package/src/Assert.ts +87 -12
- package/src/BigInt.ts +7 -1
- package/src/Brand.ts +41 -12
- package/src/Buffer.ts +10 -4
- package/src/Cache.ts +11 -2
- package/src/Callbacks.ts +33 -23
- package/src/Console.ts +567 -178
- package/src/Crypto.ts +111 -62
- package/src/Eq.ts +30 -3
- package/src/Error.ts +50 -34
- package/src/Function.ts +140 -68
- package/src/Identicon.ts +7 -1
- package/src/Lookup.ts +429 -0
- package/src/Microtask.ts +58 -0
- package/src/Number.ts +40 -7
- package/src/Object.ts +155 -16
- package/src/Option.ts +74 -0
- package/src/Order.ts +11 -3
- package/src/Platform.ts +43 -7
- package/src/Polyfills.ts +520 -0
- package/src/Random.ts +25 -11
- package/src/Redacted.ts +8 -4
- package/src/Ref.ts +72 -21
- package/src/RefCount.ts +170 -0
- package/src/Relation.ts +188 -136
- package/src/Resource.ts +864 -0
- package/src/Result.ts +548 -381
- package/src/Schedule.ts +1471 -0
- package/src/Set.ts +247 -0
- package/src/Skiplist.ts +7 -1
- package/src/Sqlite.ts +409 -304
- package/src/Store.ts +94 -48
- package/src/String.ts +6 -0
- package/src/Task.ts +3696 -740
- package/src/Test.ts +202 -0
- package/src/Time.ts +357 -147
- package/src/Tracer.ts +54 -0
- package/src/Type.ts +866 -430
- package/src/Types.ts +202 -7
- package/src/WebSocket.ts +404 -167
- package/src/Worker.ts +527 -147
- package/src/index.ts +74 -3
- package/src/local-first/Db.ts +867 -597
- package/src/local-first/Error.ts +17 -0
- package/src/local-first/Evolu.ts +884 -824
- package/src/local-first/LocalAuth.ts +10 -10
- package/src/local-first/Owner.ts +94 -42
- package/src/local-first/Protocol.ts +441 -307
- package/src/local-first/Query.ts +243 -194
- package/src/local-first/Relay.ts +119 -273
- package/src/local-first/Schema.ts +284 -394
- package/src/local-first/Shared.ts +932 -0
- package/src/local-first/Storage.ts +211 -283
- package/src/local-first/Timestamp.ts +38 -45
- package/src/local-first/index.ts +2 -16
- package/dist/src/Instances.d.ts +0 -34
- package/dist/src/Instances.d.ts.map +0 -1
- package/dist/src/Instances.js +0 -44
- package/dist/src/Resources.d.ts +0 -118
- package/dist/src/Resources.d.ts.map +0 -1
- package/dist/src/Resources.js +0 -197
- package/dist/src/local-first/Platform.d.ts +0 -25
- package/dist/src/local-first/Platform.d.ts.map +0 -1
- package/dist/src/local-first/Platform.js +0 -1
- package/dist/src/local-first/Public.d.ts +0 -22
- package/dist/src/local-first/Public.d.ts.map +0 -1
- package/dist/src/local-first/Public.js +0 -15
- package/dist/src/local-first/PublicKysely.d.ts +0 -148
- package/dist/src/local-first/PublicKysely.d.ts.map +0 -1
- package/dist/src/local-first/PublicKysely.js +0 -184
- package/dist/src/local-first/Sync.d.ts +0 -112
- package/dist/src/local-first/Sync.d.ts.map +0 -1
- package/dist/src/local-first/Sync.js +0 -526
- package/src/Instances.ts +0 -92
- package/src/Resources.ts +0 -367
- package/src/local-first/Platform.ts +0 -27
- package/src/local-first/Public.ts +0 -42
- package/src/local-first/PublicKysely.ts +0 -239
- package/src/local-first/Sync.ts +0 -949
package/src/Ref.ts
CHANGED
|
@@ -1,23 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mutable reference to an immutable value.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
|
|
1
7
|
import type { Store } from "./Store.js";
|
|
2
8
|
|
|
3
9
|
/**
|
|
4
|
-
*
|
|
5
|
-
* functional programming or React. It exposes methods to get, set, and modify
|
|
6
|
-
* the current state.
|
|
10
|
+
* Mutable reference to an immutable value.
|
|
7
11
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
12
|
+
* `Ref` holds the current value and exposes explicit `get`, `set`, `update`,
|
|
13
|
+
* and `modify` operations. The reference is mutable, but the value inside it
|
|
14
|
+
* must be immutable and replaced with a new value rather than mutated in place.
|
|
15
|
+
* Storing a mutable value in `Ref` does not make sense, because callers could
|
|
16
|
+
* mutate that value directly and pass it around without `Ref`.
|
|
11
17
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
18
|
+
* Use it when mutable ownership of a value needs to be passed around as a
|
|
19
|
+
* value. For reactive state with subscriptions, see {@link Store}.
|
|
14
20
|
*
|
|
15
21
|
* ### Example
|
|
16
22
|
*
|
|
17
23
|
* ```ts
|
|
18
24
|
* const count = createRef(0);
|
|
19
25
|
* count.set(1);
|
|
20
|
-
* count.
|
|
26
|
+
* count.update((n) => n + 1);
|
|
21
27
|
* console.log(count.get()); // 2
|
|
22
28
|
* ```
|
|
23
29
|
*
|
|
@@ -30,29 +36,74 @@ import type { Store } from "./Store.js";
|
|
|
30
36
|
* ```
|
|
31
37
|
*/
|
|
32
38
|
export interface Ref<T> {
|
|
33
|
-
/** Returns the current
|
|
39
|
+
/** Returns the current value. */
|
|
34
40
|
readonly get: () => T;
|
|
35
41
|
|
|
36
|
-
/** Sets the
|
|
37
|
-
readonly set: (
|
|
42
|
+
/** Sets the current value. */
|
|
43
|
+
readonly set: (value: T) => void;
|
|
44
|
+
|
|
45
|
+
/** Sets the current value and returns the previous value. */
|
|
46
|
+
readonly getAndSet: (value: T) => T;
|
|
38
47
|
|
|
39
|
-
/**
|
|
40
|
-
readonly
|
|
48
|
+
/** Sets the current value and returns it. */
|
|
49
|
+
readonly setAndGet: (value: T) => T;
|
|
50
|
+
|
|
51
|
+
/** Updates the current value. */
|
|
52
|
+
readonly update: (updater: (current: T) => T) => void;
|
|
53
|
+
|
|
54
|
+
/** Updates the current value and returns the previous value. */
|
|
55
|
+
readonly getAndUpdate: (updater: (current: T) => T) => T;
|
|
56
|
+
|
|
57
|
+
/** Updates the current value and returns it. */
|
|
58
|
+
readonly updateAndGet: (updater: (current: T) => T) => T;
|
|
59
|
+
|
|
60
|
+
/** Modifies the current value and returns a computed result. */
|
|
61
|
+
readonly modify: <R>(
|
|
62
|
+
updater: (current: T) => readonly [result: R, nextValue: T],
|
|
63
|
+
) => R;
|
|
41
64
|
}
|
|
42
65
|
|
|
43
|
-
/** Creates a {@link Ref} with the given initial
|
|
44
|
-
export const createRef = <T>(
|
|
45
|
-
let
|
|
66
|
+
/** Creates a {@link Ref} with the given initial immutable value. */
|
|
67
|
+
export const createRef = <T>(initialValue: T): Ref<T> => {
|
|
68
|
+
let currentValue = initialValue;
|
|
46
69
|
|
|
47
70
|
return {
|
|
48
|
-
get: () =>
|
|
71
|
+
get: () => currentValue,
|
|
72
|
+
|
|
73
|
+
set: (value) => {
|
|
74
|
+
currentValue = value;
|
|
75
|
+
},
|
|
76
|
+
|
|
77
|
+
getAndSet: (value) => {
|
|
78
|
+
const previousValue = currentValue;
|
|
79
|
+
currentValue = value;
|
|
80
|
+
return previousValue;
|
|
81
|
+
},
|
|
82
|
+
|
|
83
|
+
setAndGet: (value) => {
|
|
84
|
+
currentValue = value;
|
|
85
|
+
return currentValue;
|
|
86
|
+
},
|
|
87
|
+
|
|
88
|
+
update: (updater) => {
|
|
89
|
+
currentValue = updater(currentValue);
|
|
90
|
+
},
|
|
91
|
+
|
|
92
|
+
getAndUpdate: (updater) => {
|
|
93
|
+
const previousValue = currentValue;
|
|
94
|
+
currentValue = updater(currentValue);
|
|
95
|
+
return previousValue;
|
|
96
|
+
},
|
|
49
97
|
|
|
50
|
-
|
|
51
|
-
|
|
98
|
+
updateAndGet: (updater) => {
|
|
99
|
+
currentValue = updater(currentValue);
|
|
100
|
+
return currentValue;
|
|
52
101
|
},
|
|
53
102
|
|
|
54
103
|
modify: (updater) => {
|
|
55
|
-
|
|
104
|
+
const [result, nextValue] = updater(currentValue);
|
|
105
|
+
currentValue = nextValue;
|
|
106
|
+
return result;
|
|
56
107
|
},
|
|
57
108
|
};
|
|
58
109
|
};
|
package/src/RefCount.ts
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reference counting helpers.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { assert, assertNotDisposed } from "./Assert.js";
|
|
8
|
+
import { identity } from "./Function.js";
|
|
9
|
+
import { createLookupMap, type Lookup, type LookupOption } from "./Lookup.js";
|
|
10
|
+
import { NonNegativeInt, PositiveInt, zeroNonNegativeInt } from "./Type.js";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Reference count for one retained value.
|
|
14
|
+
*
|
|
15
|
+
* Decrementing below zero is a programmer error checked with {@link assert}.
|
|
16
|
+
*/
|
|
17
|
+
export interface RefCount extends Disposable {
|
|
18
|
+
/** Increments the count and returns the new count. */
|
|
19
|
+
readonly increment: () => PositiveInt;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Decrements the count and returns the new count.
|
|
23
|
+
*
|
|
24
|
+
* Decrementing below zero is a programmer error checked with {@link assert}.
|
|
25
|
+
*/
|
|
26
|
+
readonly decrement: () => NonNegativeInt;
|
|
27
|
+
|
|
28
|
+
/** Returns the current count. */
|
|
29
|
+
readonly getCount: () => NonNegativeInt;
|
|
30
|
+
|
|
31
|
+
/** Disposes and invalidates the helper. Further method calls throw. */
|
|
32
|
+
readonly [Symbol.dispose]: () => void;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** Creates {@link RefCount}. */
|
|
36
|
+
export const createRefCount = (): RefCount => {
|
|
37
|
+
let count = zeroNonNegativeInt;
|
|
38
|
+
const stack = new DisposableStack();
|
|
39
|
+
stack.defer(() => {
|
|
40
|
+
count = zeroNonNegativeInt;
|
|
41
|
+
});
|
|
42
|
+
const moved = stack.move();
|
|
43
|
+
|
|
44
|
+
return {
|
|
45
|
+
increment: () => {
|
|
46
|
+
assertNotDisposed(moved);
|
|
47
|
+
const nextCount = PositiveInt.orThrow(count + 1);
|
|
48
|
+
count = nextCount;
|
|
49
|
+
return nextCount;
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
decrement: () => {
|
|
53
|
+
assertNotDisposed(moved);
|
|
54
|
+
assert(count > 0, "RefCount must not be decremented below zero.");
|
|
55
|
+
count = NonNegativeInt.orThrow(count - 1);
|
|
56
|
+
return count;
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
getCount: () => {
|
|
60
|
+
assertNotDisposed(moved);
|
|
61
|
+
return count;
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
[Symbol.dispose]: () => moved.dispose(),
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Reference counts keyed by logical identity.
|
|
70
|
+
*
|
|
71
|
+
* By default, {@link createRefCountByKey} uses reference identity, the same as
|
|
72
|
+
* `Map` keys. Callers may instead provide a {@link Lookup lookup} so logical
|
|
73
|
+
* equality is based on a derived stable key. Decrementing a missing key is a
|
|
74
|
+
* programmer error checked with {@link assert}.
|
|
75
|
+
*/
|
|
76
|
+
export interface RefCountByKey<TKey> extends Disposable {
|
|
77
|
+
/** Increments key count and returns the new count. */
|
|
78
|
+
readonly increment: (key: TKey) => PositiveInt;
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Decrements key count and returns the new count.
|
|
82
|
+
*
|
|
83
|
+
* Decrementing a missing key is a programmer error checked with
|
|
84
|
+
* {@link assert}.
|
|
85
|
+
*/
|
|
86
|
+
readonly decrement: (key: TKey) => NonNegativeInt;
|
|
87
|
+
|
|
88
|
+
/** Gets current count for key. Returns `0` when the key is not tracked. */
|
|
89
|
+
readonly getCount: (key: TKey) => NonNegativeInt;
|
|
90
|
+
|
|
91
|
+
/** Returns `true` when the key is tracked with count greater than zero. */
|
|
92
|
+
readonly has: (key: TKey) => boolean;
|
|
93
|
+
|
|
94
|
+
/** Returns all currently tracked keys. */
|
|
95
|
+
readonly keys: () => ReadonlySet<TKey>;
|
|
96
|
+
|
|
97
|
+
/** Disposes and invalidates the helper. Further method calls throw. */
|
|
98
|
+
readonly [Symbol.dispose]: () => void;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/** Options for {@link createRefCountByKey}. */
|
|
102
|
+
export interface CreateRefCountByKeyOptions<
|
|
103
|
+
TKey,
|
|
104
|
+
L = TKey,
|
|
105
|
+
> extends LookupOption<TKey, L> {}
|
|
106
|
+
|
|
107
|
+
/** Creates {@link RefCountByKey}. */
|
|
108
|
+
export function createRefCountByKey<TKey = unknown>(): RefCountByKey<TKey>;
|
|
109
|
+
export function createRefCountByKey<TKey, L>(
|
|
110
|
+
options: CreateRefCountByKeyOptions<TKey, L>,
|
|
111
|
+
): RefCountByKey<TKey>;
|
|
112
|
+
export function createRefCountByKey<TKey, L = TKey>({
|
|
113
|
+
lookup = identity as Lookup<TKey, L>,
|
|
114
|
+
}: CreateRefCountByKeyOptions<TKey, L> = {}): RefCountByKey<TKey> {
|
|
115
|
+
const stack = new DisposableStack();
|
|
116
|
+
|
|
117
|
+
const refCountByKey = stack.adopt(
|
|
118
|
+
createLookupMap<TKey, RefCount, L>({ lookup }),
|
|
119
|
+
(refCountByKey) => {
|
|
120
|
+
for (const refCount of refCountByKey.values()) refCount[Symbol.dispose]();
|
|
121
|
+
refCountByKey.clear();
|
|
122
|
+
},
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
const moved = stack.move();
|
|
126
|
+
|
|
127
|
+
const getRefCount = (key: TKey): RefCount => {
|
|
128
|
+
let refCount = refCountByKey.get(key);
|
|
129
|
+
if (!refCount) {
|
|
130
|
+
refCount = createRefCount();
|
|
131
|
+
refCountByKey.set(key, refCount);
|
|
132
|
+
}
|
|
133
|
+
return refCount;
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
return {
|
|
137
|
+
increment: (key) => {
|
|
138
|
+
assertNotDisposed(moved);
|
|
139
|
+
return getRefCount(key).increment();
|
|
140
|
+
},
|
|
141
|
+
|
|
142
|
+
decrement: (key) => {
|
|
143
|
+
assertNotDisposed(moved);
|
|
144
|
+
const refCount = getRefCount(key);
|
|
145
|
+
const nextCount = refCount.decrement();
|
|
146
|
+
if (nextCount === 0) {
|
|
147
|
+
refCount[Symbol.dispose]();
|
|
148
|
+
refCountByKey.delete(key);
|
|
149
|
+
}
|
|
150
|
+
return nextCount;
|
|
151
|
+
},
|
|
152
|
+
|
|
153
|
+
getCount: (key) => {
|
|
154
|
+
assertNotDisposed(moved);
|
|
155
|
+
return refCountByKey.get(key)?.getCount() ?? zeroNonNegativeInt;
|
|
156
|
+
},
|
|
157
|
+
|
|
158
|
+
has: (key) => {
|
|
159
|
+
assertNotDisposed(moved);
|
|
160
|
+
return refCountByKey.has(key);
|
|
161
|
+
},
|
|
162
|
+
|
|
163
|
+
keys: () => {
|
|
164
|
+
assertNotDisposed(moved);
|
|
165
|
+
return new Set(refCountByKey.keys());
|
|
166
|
+
},
|
|
167
|
+
|
|
168
|
+
[Symbol.dispose]: () => moved.dispose(),
|
|
169
|
+
};
|
|
170
|
+
}
|