@evolu/common 8.0.0-next.5 → 8.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/dist/src/Array.d.ts +279 -173
- package/dist/src/Array.d.ts.map +1 -1
- package/dist/src/Array.js +105 -101
- package/dist/src/Assert.d.ts +39 -44
- package/dist/src/Assert.d.ts.map +1 -1
- package/dist/src/Assert.js +38 -31
- package/dist/src/BigInt.d.ts +6 -3
- package/dist/src/BigInt.d.ts.map +1 -1
- package/dist/src/BigInt.js +5 -2
- package/dist/src/Brand.d.ts +27 -40
- package/dist/src/Brand.d.ts.map +1 -1
- package/dist/src/Buffer.d.ts +27 -11
- package/dist/src/Buffer.d.ts.map +1 -1
- package/dist/src/Cache.d.ts +9 -4
- package/dist/src/Cache.d.ts.map +1 -1
- package/dist/src/Cache.js +8 -3
- package/dist/src/Callbacks.d.ts +30 -19
- package/dist/src/Callbacks.d.ts.map +1 -1
- package/dist/src/Console.d.ts +145 -66
- package/dist/src/Console.d.ts.map +1 -1
- package/dist/src/Console.js +91 -43
- package/dist/src/Crypto.d.ts +85 -42
- package/dist/src/Crypto.d.ts.map +1 -1
- package/dist/src/Crypto.js +44 -20
- package/dist/src/Eq.d.ts +87 -21
- package/dist/src/Eq.d.ts.map +1 -1
- package/dist/src/Eq.js +67 -19
- package/dist/src/Error.d.ts +3 -3
- package/dist/src/Error.d.ts.map +1 -1
- package/dist/src/Function.d.ts +119 -58
- package/dist/src/Function.d.ts.map +1 -1
- package/dist/src/Function.js +86 -43
- package/dist/src/Http.d.ts +394 -0
- package/dist/src/Http.d.ts.map +1 -0
- package/dist/src/Http.js +102 -0
- package/dist/src/Identicon.d.ts +16 -7
- package/dist/src/Identicon.d.ts.map +1 -1
- package/dist/src/Identicon.js +14 -5
- package/dist/src/LeakDetector.d.ts +88 -0
- package/dist/src/LeakDetector.d.ts.map +1 -0
- package/dist/src/LeakDetector.js +86 -0
- package/dist/src/LockManager.d.ts +18 -9
- package/dist/src/LockManager.d.ts.map +1 -1
- package/dist/src/LockManager.js +7 -8
- package/dist/src/Lookup.d.ts +43 -13
- package/dist/src/Lookup.d.ts.map +1 -1
- package/dist/src/Lookup.js +28 -8
- package/dist/src/Microtask.d.ts +1 -1
- package/dist/src/Microtask.d.ts.map +1 -1
- package/dist/src/Microtask.js +3 -7
- package/dist/src/Number.d.ts +49 -13
- package/dist/src/Number.d.ts.map +1 -1
- package/dist/src/Number.js +34 -5
- package/dist/src/Object.d.ts +160 -40
- package/dist/src/Object.d.ts.map +1 -1
- package/dist/src/Object.js +92 -46
- package/dist/src/Option.d.ts +10 -7
- package/dist/src/Option.d.ts.map +1 -1
- package/dist/src/Option.js +9 -6
- package/dist/src/Order.d.ts +21 -21
- package/dist/src/Order.d.ts.map +1 -1
- package/dist/src/Order.js +18 -21
- package/dist/src/Platform.d.ts +31 -0
- package/dist/src/Platform.d.ts.map +1 -1
- package/dist/src/Platform.js +98 -0
- package/dist/src/Random.d.ts +32 -17
- package/dist/src/Random.d.ts.map +1 -1
- package/dist/src/Random.js +12 -8
- package/dist/src/Redacted.d.ts +43 -29
- package/dist/src/Redacted.d.ts.map +1 -1
- package/dist/src/Redacted.js +14 -3
- package/dist/src/Ref.d.ts +11 -3
- package/dist/src/Ref.d.ts.map +1 -1
- package/dist/src/Ref.js +2 -2
- package/dist/src/RefCount.d.ts +2 -6
- package/dist/src/RefCount.d.ts.map +1 -1
- package/dist/src/RefCount.js +33 -90
- package/dist/src/Relation.d.ts +70 -5
- package/dist/src/Relation.d.ts.map +1 -1
- package/dist/src/Relation.js +77 -2
- package/dist/src/Resource.d.ts +590 -155
- package/dist/src/Resource.d.ts.map +1 -1
- package/dist/src/Resource.js +592 -343
- package/dist/src/Result.d.ts +838 -191
- package/dist/src/Result.d.ts.map +1 -1
- package/dist/src/Result.js +163 -102
- package/dist/src/Schedule.d.ts +684 -231
- package/dist/src/Schedule.d.ts.map +1 -1
- package/dist/src/Schedule.js +766 -295
- package/dist/src/Set.d.ts +89 -40
- package/dist/src/Set.d.ts.map +1 -1
- package/dist/src/Set.js +50 -29
- package/dist/src/Sqlite.d.ts +29 -72
- package/dist/src/Sqlite.d.ts.map +1 -1
- package/dist/src/Sqlite.js +39 -45
- package/dist/src/StackTrace.d.ts +40 -0
- package/dist/src/StackTrace.d.ts.map +1 -0
- package/dist/src/StackTrace.js +140 -0
- package/dist/src/Store.d.ts +5 -4
- package/dist/src/Store.d.ts.map +1 -1
- package/dist/src/Store.js +5 -4
- package/dist/src/String.d.ts +7 -1
- package/dist/src/String.d.ts.map +1 -1
- package/dist/src/String.js +20 -7
- package/dist/src/Task.d.ts +3428 -1629
- package/dist/src/Task.d.ts.map +1 -1
- package/dist/src/Task.js +1876 -1279
- package/dist/src/Test.d.ts +17 -124
- package/dist/src/Test.d.ts.map +1 -1
- package/dist/src/Test.js +17 -68
- package/dist/src/Time.d.ts +108 -49
- package/dist/src/Time.d.ts.map +1 -1
- package/dist/src/Time.js +172 -73
- package/dist/src/Type.d.ts +3542 -1926
- package/dist/src/Type.d.ts.map +1 -1
- package/dist/src/Type.js +3070 -1784
- package/dist/src/Types.d.ts +200 -100
- package/dist/src/Types.d.ts.map +1 -1
- package/dist/src/Types.js +39 -8
- package/dist/src/WebSocket.d.ts +48 -23
- package/dist/src/WebSocket.d.ts.map +1 -1
- package/dist/src/WebSocket.js +15 -6
- package/dist/src/Worker.d.ts +94 -36
- package/dist/src/Worker.d.ts.map +1 -1
- package/dist/src/Worker.js +58 -24
- package/dist/src/index.d.ts +55 -52
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +3 -1
- package/dist/src/intl/cs.d.ts +94 -0
- package/dist/src/intl/cs.d.ts.map +1 -0
- package/dist/src/intl/cs.js +220 -0
- package/dist/src/intl/index.d.ts +7 -0
- package/dist/src/intl/index.d.ts.map +1 -0
- package/dist/src/intl/index.js +6 -0
- package/dist/src/local-first/Db.d.ts +12 -8
- package/dist/src/local-first/Db.d.ts.map +1 -1
- package/dist/src/local-first/Db.js +107 -130
- package/dist/src/local-first/Error.d.ts +4 -4
- package/dist/src/local-first/Evolu.d.ts +338 -92
- package/dist/src/local-first/Evolu.d.ts.map +1 -1
- package/dist/src/local-first/Evolu.js +47 -55
- package/dist/src/local-first/LocalAuth.d.ts +4 -4
- package/dist/src/local-first/LocalAuth.d.ts.map +1 -1
- package/dist/src/local-first/Owner.d.ts +61 -24
- package/dist/src/local-first/Owner.d.ts.map +1 -1
- package/dist/src/local-first/Owner.js +45 -8
- package/dist/src/local-first/Protocol.d.ts +44 -31
- package/dist/src/local-first/Protocol.d.ts.map +1 -1
- package/dist/src/local-first/Protocol.js +36 -13
- package/dist/src/local-first/Query.d.ts +147 -62
- package/dist/src/local-first/Query.d.ts.map +1 -1
- package/dist/src/local-first/Query.js +112 -58
- package/dist/src/local-first/Relay.d.ts +44 -14
- package/dist/src/local-first/Relay.d.ts.map +1 -1
- package/dist/src/local-first/Schema.d.ts +92 -41
- package/dist/src/local-first/Schema.d.ts.map +1 -1
- package/dist/src/local-first/Schema.js +25 -8
- package/dist/src/local-first/Shared.d.ts +23 -21
- package/dist/src/local-first/Shared.d.ts.map +1 -1
- package/dist/src/local-first/Shared.js +85 -42
- package/dist/src/local-first/Storage.d.ts +53 -32
- package/dist/src/local-first/Storage.d.ts.map +1 -1
- package/dist/src/local-first/Storage.js +194 -234
- package/dist/src/local-first/Timestamp.d.ts +21 -21
- package/dist/src/local-first/Timestamp.d.ts.map +1 -1
- package/dist/src/local-first/Timestamp.js +2 -2
- package/dist/src/local-first/index.d.ts +11 -11
- package/package.json +14 -13
- package/src/Array.ts +306 -205
- package/src/Assert.ts +48 -68
- package/src/BigInt.ts +6 -3
- package/src/Brand.ts +27 -40
- package/src/Buffer.ts +28 -12
- package/src/Cache.ts +9 -4
- package/src/Callbacks.ts +30 -19
- package/src/Console.ts +156 -84
- package/src/Crypto.ts +83 -41
- package/src/Eq.ts +95 -22
- package/src/Error.ts +5 -2
- package/src/Function.ts +167 -59
- package/src/Http.ts +549 -0
- package/src/Identicon.ts +16 -7
- package/src/LeakDetector.ts +182 -0
- package/src/LockManager.ts +43 -39
- package/src/Lookup.ts +62 -28
- package/src/Microtask.ts +19 -23
- package/src/Number.ts +64 -12
- package/src/Object.ts +173 -49
- package/src/Option.ts +10 -7
- package/src/Order.ts +23 -21
- package/src/Platform.ts +136 -0
- package/src/Polyfills.ts +6 -12
- package/src/Random.ts +32 -19
- package/src/Redacted.ts +44 -30
- package/src/Ref.ts +14 -6
- package/src/RefCount.ts +38 -80
- package/src/Relation.ts +202 -10
- package/src/Resource.ts +1199 -591
- package/src/Result.ts +930 -271
- package/src/Schedule.ts +859 -343
- package/src/Set.ts +89 -40
- package/src/Sqlite.ts +142 -137
- package/src/StackTrace.ts +230 -0
- package/src/Store.ts +8 -7
- package/src/String.ts +22 -5
- package/src/Task.ts +5109 -2845
- package/src/Test.ts +20 -167
- package/src/Time.ts +293 -90
- package/src/Type.ts +10034 -4117
- package/src/Types.ts +227 -101
- package/src/WebSocket.ts +64 -36
- package/src/Worker.ts +180 -72
- package/src/index.ts +55 -52
- package/src/intl/cs.ts +388 -0
- package/src/intl/index.ts +7 -0
- package/src/local-first/Db.ts +161 -190
- package/src/local-first/Error.ts +4 -4
- package/src/local-first/Evolu.ts +495 -250
- package/src/local-first/LocalAuth.ts +6 -12
- package/src/local-first/Owner.ts +58 -21
- package/src/local-first/Protocol.ts +49 -31
- package/src/local-first/Query.ts +146 -61
- package/src/local-first/Relay.ts +51 -21
- package/src/local-first/Schema.ts +109 -51
- package/src/local-first/Shared.ts +253 -214
- package/src/local-first/Storage.ts +266 -264
- package/src/local-first/Timestamp.ts +25 -18
- package/src/local-first/index.ts +11 -11
- package/dist/src/Skiplist.d.ts +0 -28
- package/dist/src/Skiplist.d.ts.map +0 -1
- package/dist/src/Skiplist.js +0 -64
- package/dist/src/Tracer.d.ts +0 -48
- package/dist/src/Tracer.d.ts.map +0 -1
- package/dist/src/Tracer.js +0 -6
- package/src/Skiplist.ts +0 -108
- package/src/Tracer.ts +0 -54
package/dist/src/Random.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Random number generation.
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
6
|
import { Random as RandomLib } from "random";
|
|
7
|
-
import type { Brand } from "./Brand.
|
|
7
|
+
import type { Brand } from "./Brand.ts";
|
|
8
8
|
/**
|
|
9
9
|
* A random floating point number in [0, 1).
|
|
10
10
|
*
|
|
@@ -19,41 +19,56 @@ export type RandomNumber = number & Brand<"RandomNumber">;
|
|
|
19
19
|
* ### Example
|
|
20
20
|
*
|
|
21
21
|
* ```ts
|
|
22
|
-
*
|
|
22
|
+
* import {
|
|
23
|
+
* createRandom,
|
|
24
|
+
* testCreateRandom,
|
|
25
|
+
* type RandomNumber,
|
|
26
|
+
* } from "@evolu/common";
|
|
27
|
+
*
|
|
28
|
+
* // For apps, use the Math.random-backed implementation.
|
|
23
29
|
* const random = createRandom();
|
|
24
|
-
* random.next();
|
|
30
|
+
* const value = random.next();
|
|
31
|
+
* expectTypeOf(value).toEqualTypeOf<RandomNumber>();
|
|
32
|
+
* expect(value).toBeGreaterThanOrEqual(0);
|
|
33
|
+
* expect(value).toBeLessThan(1);
|
|
25
34
|
*
|
|
26
|
-
* // For tests
|
|
27
|
-
* const
|
|
28
|
-
*
|
|
35
|
+
* // For tests, use a seed.
|
|
36
|
+
* const firstTestRandom = testCreateRandom("test");
|
|
37
|
+
* const secondTestRandom = testCreateRandom("test");
|
|
38
|
+
* expect(firstTestRandom.next()).toBe(secondTestRandom.next());
|
|
29
39
|
* ```
|
|
30
40
|
*/
|
|
31
41
|
export interface Random {
|
|
32
42
|
/** Returns a floating point number in [0, 1). Just like Math.random(). */
|
|
33
|
-
next: () => RandomNumber;
|
|
43
|
+
readonly next: () => RandomNumber;
|
|
34
44
|
}
|
|
35
45
|
export interface RandomDep {
|
|
36
|
-
random: Random;
|
|
46
|
+
readonly random: Random;
|
|
37
47
|
}
|
|
38
48
|
/** Creates a {@link Random} using Math.random(). */
|
|
39
49
|
export declare const createRandom: () => Random;
|
|
40
|
-
/** Creates a seeded {@link Random} for deterministic tests. Default seed "evolu". */
|
|
41
|
-
export declare const testCreateRandom: (seed?: string) => Random;
|
|
42
50
|
/**
|
|
43
|
-
* Creates
|
|
44
|
-
*
|
|
51
|
+
* Creates a seeded {@link Random} for deterministic tests.
|
|
52
|
+
*
|
|
53
|
+
* Default seed "evolu".
|
|
45
54
|
*/
|
|
46
|
-
export declare const
|
|
55
|
+
export declare const testCreateRandom: (seed?: string) => Random;
|
|
47
56
|
/**
|
|
48
|
-
*
|
|
57
|
+
* Seedable random number generator supporting many common distributions,
|
|
58
|
+
* provided by the NPM `random` package.
|
|
49
59
|
*
|
|
50
60
|
* https://github.com/transitive-bullshit/random
|
|
51
61
|
*/
|
|
52
62
|
export interface RandomLibDep {
|
|
53
63
|
readonly randomLib: RandomLib;
|
|
54
64
|
}
|
|
55
|
-
/** Creates a
|
|
65
|
+
/** Creates a random number generator from the NPM `random` package. */
|
|
56
66
|
export declare const createRandomLib: () => RandomLib;
|
|
57
|
-
/**
|
|
67
|
+
/**
|
|
68
|
+
* Creates a seeded random number generator from the NPM `random` package for
|
|
69
|
+
* deterministic tests.
|
|
70
|
+
*
|
|
71
|
+
* Default seed "evolu".
|
|
72
|
+
*/
|
|
58
73
|
export declare const testCreateRandomLib: (seed?: string) => RandomLib;
|
|
59
74
|
//# sourceMappingURL=Random.d.ts.map
|
package/dist/src/Random.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Random.d.ts","sourceRoot":"","sources":["../../src/Random.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,IAAI,SAAS,EAAE,MAAM,QAAQ,CAAC;AAC7C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,KAAK,CAAC,cAAc,CAAC,CAAC;AAE1D
|
|
1
|
+
{"version":3,"file":"Random.d.ts","sourceRoot":"","sources":["../../src/Random.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,IAAI,SAAS,EAAE,MAAM,QAAQ,CAAC;AAC7C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,KAAK,CAAC,cAAc,CAAC,CAAC;AAE1D;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,WAAW,MAAM;IACrB,0EAA0E;IAC1E,QAAQ,CAAC,IAAI,EAAE,MAAM,YAAY,CAAC;CACnC;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,oDAAoD;AACpD,eAAO,MAAM,YAAY,QAAO,MAE9B,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,qBAAqB,MAKjD,CAAC;AAEF;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;CAC/B;AAED,uEAAuE;AACvE,eAAO,MAAM,eAAe,QAAO,SAA4B,CAAC;AAEhE;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,qBAAqB,SAChC,CAAC"}
|
package/dist/src/Random.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Random number generation.
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
@@ -8,19 +8,23 @@ import { Random as RandomLib } from "random";
|
|
|
8
8
|
export const createRandom = () => ({
|
|
9
9
|
next: () => Math.random(),
|
|
10
10
|
});
|
|
11
|
-
/** Creates a seeded {@link Random} for deterministic tests. Default seed "evolu". */
|
|
12
|
-
export const testCreateRandom = (seed = "evolu") => createRandomWithSeed(seed);
|
|
13
11
|
/**
|
|
14
|
-
* Creates
|
|
15
|
-
*
|
|
12
|
+
* Creates a seeded {@link Random} for deterministic tests.
|
|
13
|
+
*
|
|
14
|
+
* Default seed "evolu".
|
|
16
15
|
*/
|
|
17
|
-
export const
|
|
16
|
+
export const testCreateRandom = (seed = "evolu") => {
|
|
18
17
|
const random = new RandomLib(seed);
|
|
19
18
|
return {
|
|
20
19
|
next: () => random.next(),
|
|
21
20
|
};
|
|
22
21
|
};
|
|
23
|
-
/** Creates a
|
|
22
|
+
/** Creates a random number generator from the NPM `random` package. */
|
|
24
23
|
export const createRandomLib = () => new RandomLib();
|
|
25
|
-
/**
|
|
24
|
+
/**
|
|
25
|
+
* Creates a seeded random number generator from the NPM `random` package for
|
|
26
|
+
* deterministic tests.
|
|
27
|
+
*
|
|
28
|
+
* Default seed "evolu".
|
|
29
|
+
*/
|
|
26
30
|
export const testCreateRandomLib = (seed = "evolu") => new RandomLib(seed);
|
package/dist/src/Redacted.d.ts
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
|
-
import type { Brand } from "./Brand.
|
|
7
|
-
import type { Eq } from "./Eq.
|
|
6
|
+
import type { Brand } from "./Brand.ts";
|
|
7
|
+
import type { Eq } from "./Eq.ts";
|
|
8
8
|
/**
|
|
9
9
|
* A wrapper type that prevents sensitive values from being accidentally exposed
|
|
10
10
|
* through logging, serialization, or inspection.
|
|
@@ -26,35 +26,38 @@ import type { Eq } from "./Eq.js";
|
|
|
26
26
|
* ### Example
|
|
27
27
|
*
|
|
28
28
|
* ```ts
|
|
29
|
-
*
|
|
29
|
+
* import {
|
|
30
|
+
* createRedacted,
|
|
31
|
+
* revealRedacted,
|
|
32
|
+
* type Brand,
|
|
33
|
+
* type Redacted,
|
|
34
|
+
* } from "@evolu/common";
|
|
35
|
+
*
|
|
30
36
|
* type ApiKey = string & Brand<"ApiKey">;
|
|
31
37
|
* type DbPassword = string & Brand<"DbPassword">;
|
|
32
|
-
*
|
|
33
|
-
* // Wrap them with Redacted for safe passing
|
|
34
38
|
* type RedactedApiKey = Redacted<ApiKey>;
|
|
35
|
-
* type RedactedDbPassword = Redacted<DbPassword>;
|
|
36
39
|
*
|
|
37
|
-
* //
|
|
40
|
+
* // Apply brands only after validation or at another trusted boundary.
|
|
38
41
|
* const apiKey: ApiKey = "secret-123" as ApiKey;
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* fetchUser(
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
42
|
+
* using redactedKey: RedactedApiKey = createRedacted(apiKey);
|
|
43
|
+
* const fetchUser = (key: RedactedApiKey): ApiKey => revealRedacted(key);
|
|
44
|
+
*
|
|
45
|
+
* expect(redactedKey.toString()).toBe("<redacted>");
|
|
46
|
+
* expect(JSON.stringify({ apiKey: redactedKey })).toBe(
|
|
47
|
+
* '{"apiKey":"<redacted>"}',
|
|
48
|
+
* );
|
|
49
|
+
* expect(fetchUser(redactedKey)).toBe(apiKey);
|
|
50
|
+
*
|
|
51
|
+
* using password = createRedacted("password" as DbPassword);
|
|
52
|
+
* // @ts-expect-error Redacted secrets retain their distinct branded types.
|
|
53
|
+
* fetchUser(password);
|
|
54
|
+
*
|
|
55
|
+
* const disposedKey = (() => {
|
|
56
|
+
* using key = createRedacted(apiKey);
|
|
57
|
+
* return key;
|
|
58
|
+
* })();
|
|
59
|
+
* // Leaving the `using` scope removes the value from memory.
|
|
60
|
+
* expect(() => revealRedacted(disposedKey)).toThrow();
|
|
58
61
|
* ```
|
|
59
62
|
*/
|
|
60
63
|
export interface Redacted<A> extends Brand<"Redacted">, Disposable {
|
|
@@ -80,12 +83,23 @@ export declare const isRedacted: (value: unknown) => value is Redacted<unknown>;
|
|
|
80
83
|
* ### Example
|
|
81
84
|
*
|
|
82
85
|
* ```ts
|
|
86
|
+
* import {
|
|
87
|
+
* createEqRedacted,
|
|
88
|
+
* createRedacted,
|
|
89
|
+
* eqString,
|
|
90
|
+
* type Brand,
|
|
91
|
+
* } from "@evolu/common";
|
|
92
|
+
*
|
|
83
93
|
* type ApiKey = string & Brand<"ApiKey">;
|
|
84
94
|
* const eqRedactedApiKey = createEqRedacted<ApiKey>(eqString);
|
|
85
95
|
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
96
|
+
* // Apply brands only after validation or at another trusted boundary.
|
|
97
|
+
* using a = createRedacted("x" as ApiKey);
|
|
98
|
+
* using b = createRedacted("x" as ApiKey);
|
|
99
|
+
* using c = createRedacted("y" as ApiKey);
|
|
100
|
+
*
|
|
101
|
+
* expect(eqRedactedApiKey(a, b)).toBe(true);
|
|
102
|
+
* expect(eqRedactedApiKey(a, c)).toBe(false);
|
|
89
103
|
* ```
|
|
90
104
|
*/
|
|
91
105
|
export declare const createEqRedacted: <A>(eq: Eq<A>) => Eq<Redacted<A>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Redacted.d.ts","sourceRoot":"","sources":["../../src/Redacted.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAElC
|
|
1
|
+
{"version":3,"file":"Redacted.d.ts","sourceRoot":"","sources":["../../src/Redacted.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAElC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AACH,MAAM,WAAW,QAAQ,CAAC,CAAC,CAAE,SAAQ,KAAK,CAAC,UAAU,CAAC,EAAE,UAAU;IAChE,uEAAuE;IACvE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;CAClB;AAED,gEAAgE;AAChE,eAAO,MAAM,cAAc,GAAI,CAAC,SAAS,CAAC,KAAG,QAAQ,CAAC,CAAC,CAItD,CAAC;AAaF;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,GAAI,CAAC,YAAY,QAAQ,CAAC,CAAC,CAAC,KAAG,CAGzD,CAAC;AAEF,uDAAuD;AACvD,eAAO,MAAM,UAAU,UAAW,OAAO,KAAG,KAAK,IAAI,QAAQ,CAAC,OAAO,CAG7B,CAAC;AAEzC;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,gBAAgB,GAC1B,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,KAAG,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAEY,CAAC"}
|
package/dist/src/Redacted.js
CHANGED
|
@@ -42,12 +42,23 @@ export const isRedacted = (value) => typeof value === "object" &&
|
|
|
42
42
|
* ### Example
|
|
43
43
|
*
|
|
44
44
|
* ```ts
|
|
45
|
+
* import {
|
|
46
|
+
* createEqRedacted,
|
|
47
|
+
* createRedacted,
|
|
48
|
+
* eqString,
|
|
49
|
+
* type Brand,
|
|
50
|
+
* } from "@evolu/common";
|
|
51
|
+
*
|
|
45
52
|
* type ApiKey = string & Brand<"ApiKey">;
|
|
46
53
|
* const eqRedactedApiKey = createEqRedacted<ApiKey>(eqString);
|
|
47
54
|
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
55
|
+
* // Apply brands only after validation or at another trusted boundary.
|
|
56
|
+
* using a = createRedacted("x" as ApiKey);
|
|
57
|
+
* using b = createRedacted("x" as ApiKey);
|
|
58
|
+
* using c = createRedacted("y" as ApiKey);
|
|
59
|
+
*
|
|
60
|
+
* expect(eqRedactedApiKey(a, b)).toBe(true);
|
|
61
|
+
* expect(eqRedactedApiKey(a, c)).toBe(false);
|
|
51
62
|
* ```
|
|
52
63
|
*/
|
|
53
64
|
export const createEqRedacted = (eq) => (x, y) => eq(revealRedacted(x), revealRedacted(y));
|
package/dist/src/Ref.d.ts
CHANGED
|
@@ -18,18 +18,26 @@
|
|
|
18
18
|
* ### Example
|
|
19
19
|
*
|
|
20
20
|
* ```ts
|
|
21
|
+
* import { createRef } from "@evolu/common";
|
|
22
|
+
*
|
|
21
23
|
* const count = createRef(0);
|
|
22
24
|
* count.set(1);
|
|
23
25
|
* count.update((n) => n + 1);
|
|
24
|
-
*
|
|
26
|
+
* expect(count.get()).toBe(2);
|
|
25
27
|
* ```
|
|
26
28
|
*
|
|
27
|
-
* ###
|
|
29
|
+
* ### As a dependency
|
|
28
30
|
*
|
|
29
31
|
* ```ts
|
|
32
|
+
* import { createRef, type Ref } from "@evolu/common";
|
|
33
|
+
*
|
|
30
34
|
* interface CounterRefDep {
|
|
31
35
|
* readonly counterRef: Ref<number>;
|
|
32
36
|
* }
|
|
37
|
+
*
|
|
38
|
+
* const deps: CounterRefDep = { counterRef: createRef(0) };
|
|
39
|
+
* deps.counterRef.update((count) => count + 1);
|
|
40
|
+
* expect(deps.counterRef.get()).toBe(1);
|
|
33
41
|
* ```
|
|
34
42
|
*/
|
|
35
43
|
export interface Ref<T> {
|
|
@@ -48,7 +56,7 @@ export interface Ref<T> {
|
|
|
48
56
|
/** Updates the current value and returns it. */
|
|
49
57
|
readonly updateAndGet: (updater: (current: T) => T) => T;
|
|
50
58
|
/** Modifies the current value and returns a computed result. */
|
|
51
|
-
readonly modify: <R>(
|
|
59
|
+
readonly modify: <R>(modifier: (current: T) => readonly [result: R, nextValue: T]) => R;
|
|
52
60
|
}
|
|
53
61
|
/** Creates a {@link Ref} with the given initial immutable value. */
|
|
54
62
|
export declare const createRef: <T>(initialValue: T) => Ref<T>;
|
package/dist/src/Ref.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Ref.d.ts","sourceRoot":"","sources":["../../src/Ref.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH
|
|
1
|
+
{"version":3,"file":"Ref.d.ts","sourceRoot":"","sources":["../../src/Ref.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,MAAM,WAAW,GAAG,CAAC,CAAC;IACpB,iCAAiC;IACjC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAEtB,8BAA8B;IAC9B,QAAQ,CAAC,GAAG,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IAEjC,6DAA6D;IAC7D,QAAQ,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC;IAEpC,6CAA6C;IAC7C,QAAQ,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC;IAEpC,iCAAiC;IACjC,QAAQ,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC;IAEtD,gEAAgE;IAChE,QAAQ,CAAC,YAAY,EAAE,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAEzD,gDAAgD;IAChD,QAAQ,CAAC,YAAY,EAAE,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAEzD,gEAAgE;IAChE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,EACjB,QAAQ,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,KACzD,CAAC,CAAC;CACR;AAED,oEAAoE;AACpE,eAAO,MAAM,SAAS,GAAI,CAAC,gBAAgB,CAAC,KAAG,GAAG,CAAC,CAAC,CA0CnD,CAAC"}
|
package/dist/src/Ref.js
CHANGED
|
@@ -32,8 +32,8 @@ export const createRef = (initialValue) => {
|
|
|
32
32
|
currentValue = updater(currentValue);
|
|
33
33
|
return currentValue;
|
|
34
34
|
},
|
|
35
|
-
modify: (
|
|
36
|
-
const [result, nextValue] =
|
|
35
|
+
modify: (modifier) => {
|
|
36
|
+
const [result, nextValue] = modifier(currentValue);
|
|
37
37
|
currentValue = nextValue;
|
|
38
38
|
return result;
|
|
39
39
|
},
|
package/dist/src/RefCount.d.ts
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
|
-
import { type LookupOption } from "./Lookup.
|
|
7
|
-
import { NonNegativeInt, PositiveInt } from "./Type.
|
|
6
|
+
import { type LookupOption } from "./Lookup.ts";
|
|
7
|
+
import { NonNegativeInt, PositiveInt } from "./Type.ts";
|
|
8
8
|
/**
|
|
9
9
|
* Reference count for one retained value.
|
|
10
10
|
*
|
|
@@ -21,8 +21,6 @@ export interface RefCount extends Disposable {
|
|
|
21
21
|
readonly decrement: () => NonNegativeInt;
|
|
22
22
|
/** Returns the current count. */
|
|
23
23
|
readonly getCount: () => NonNegativeInt;
|
|
24
|
-
/** Disposes and invalidates the helper. Further method calls throw. */
|
|
25
|
-
readonly [Symbol.dispose]: () => void;
|
|
26
24
|
}
|
|
27
25
|
/** Creates {@link RefCount}. */
|
|
28
26
|
export declare const createRefCount: () => RefCount;
|
|
@@ -50,8 +48,6 @@ export interface RefCountByKey<TKey> extends Disposable {
|
|
|
50
48
|
readonly has: (key: TKey) => boolean;
|
|
51
49
|
/** Returns all currently tracked keys. */
|
|
52
50
|
readonly keys: () => ReadonlySet<TKey>;
|
|
53
|
-
/** Disposes and invalidates the helper. Further method calls throw. */
|
|
54
|
-
readonly [Symbol.dispose]: () => void;
|
|
55
51
|
}
|
|
56
52
|
/** Options for {@link createRefCountByKey}. */
|
|
57
53
|
export interface CreateRefCountByKeyOptions<TKey, L = TKey> extends LookupOption<TKey, L> {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RefCount.d.ts","sourceRoot":"","sources":["../../src/RefCount.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAgC,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,WAAW,EAAsB,MAAM,WAAW,CAAC;AAE5E;;;;GAIG;AACH,MAAM,WAAW,QAAS,SAAQ,UAAU;IAC1C,sDAAsD;IACtD,QAAQ,CAAC,SAAS,EAAE,MAAM,WAAW,CAAC;IAEtC;;;;OAIG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,cAAc,CAAC;IAEzC,iCAAiC;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"RefCount.d.ts","sourceRoot":"","sources":["../../src/RefCount.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAgC,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,WAAW,EAAsB,MAAM,WAAW,CAAC;AAE5E;;;;GAIG;AACH,MAAM,WAAW,QAAS,SAAQ,UAAU;IAC1C,sDAAsD;IACtD,QAAQ,CAAC,SAAS,EAAE,MAAM,WAAW,CAAC;IAEtC;;;;OAIG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,cAAc,CAAC;IAEzC,iCAAiC;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,cAAc,CAAC;CACzC;AAED,gCAAgC;AAChC,eAAO,MAAM,cAAc,QAAO,QAkBjC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,WAAW,aAAa,CAAC,IAAI,CAAE,SAAQ,UAAU;IACrD,sDAAsD;IACtD,QAAQ,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,IAAI,KAAK,WAAW,CAAC;IAE/C;;;;;OAKG;IACH,QAAQ,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,IAAI,KAAK,cAAc,CAAC;IAElD,2EAA2E;IAC3E,QAAQ,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,IAAI,KAAK,cAAc,CAAC;IAEjD,2EAA2E;IAC3E,QAAQ,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,IAAI,KAAK,OAAO,CAAC;IAErC,0CAA0C;IAC1C,QAAQ,CAAC,IAAI,EAAE,MAAM,WAAW,CAAC,IAAI,CAAC,CAAC;CACxC;AAED,+CAA+C;AAC/C,MAAM,WAAW,0BAA0B,CACzC,IAAI,EACJ,CAAC,GAAG,IAAI,CACR,SAAQ,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC;CAAG;AAElC,qCAAqC;AACrC,wBAAgB,mBAAmB,CAAC,IAAI,GAAG,OAAO,KAAK,aAAa,CAAC,IAAI,CAAC,CAAC;AAC3E,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,CAAC,EACzC,OAAO,EAAE,0BAA0B,CAAC,IAAI,EAAE,CAAC,CAAC,GAC3C,aAAa,CAAC,IAAI,CAAC,CAAC"}
|
package/dist/src/RefCount.js
CHANGED
|
@@ -55,87 +55,40 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
|
|
|
55
55
|
var e = new Error(message);
|
|
56
56
|
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
57
57
|
});
|
|
58
|
-
import { assert
|
|
59
|
-
import { identity } from "./Function.js";
|
|
58
|
+
import { assert } from "./Assert.js";
|
|
59
|
+
import { disposable, identity } from "./Function.js";
|
|
60
60
|
import { createLookupMap } from "./Lookup.js";
|
|
61
61
|
import { NonNegativeInt, PositiveInt, zeroNonNegativeInt } from "./Type.js";
|
|
62
62
|
/** Creates {@link RefCount}. */
|
|
63
63
|
export const createRefCount = () => {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
assertNotDisposed(disposables);
|
|
79
|
-
assert(count > 0, "RefCount must not be decremented below zero.");
|
|
80
|
-
count = NonNegativeInt.orThrow(count - 1);
|
|
81
|
-
return count;
|
|
82
|
-
},
|
|
83
|
-
getCount: () => {
|
|
84
|
-
assertNotDisposed(disposables);
|
|
85
|
-
return count;
|
|
86
|
-
},
|
|
87
|
-
[Symbol.dispose]: () => disposables.dispose(),
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
catch (e_1) {
|
|
91
|
-
env_1.error = e_1;
|
|
92
|
-
env_1.hasError = true;
|
|
93
|
-
}
|
|
94
|
-
finally {
|
|
95
|
-
__disposeResources(env_1);
|
|
96
|
-
}
|
|
64
|
+
let count = zeroNonNegativeInt;
|
|
65
|
+
return disposable({
|
|
66
|
+
increment: () => {
|
|
67
|
+
const nextCount = PositiveInt.orThrow(count + 1);
|
|
68
|
+
count = nextCount;
|
|
69
|
+
return nextCount;
|
|
70
|
+
},
|
|
71
|
+
decrement: () => {
|
|
72
|
+
assert(count > 0, "RefCount must not be decremented below zero.");
|
|
73
|
+
count = NonNegativeInt.orThrow(count - 1);
|
|
74
|
+
return count;
|
|
75
|
+
},
|
|
76
|
+
getCount: () => count,
|
|
77
|
+
});
|
|
97
78
|
};
|
|
98
79
|
export function createRefCountByKey({ lookup = identity, } = {}) {
|
|
99
|
-
const
|
|
80
|
+
const env_1 = { stack: [], error: void 0, hasError: false };
|
|
100
81
|
try {
|
|
101
|
-
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
try {
|
|
106
|
-
const disposer = __addDisposableResource(env_3, new DisposableStack(), false);
|
|
107
|
-
disposer.defer(() => {
|
|
108
|
-
refCountByKey.clear();
|
|
109
|
-
});
|
|
110
|
-
for (const refCount of refCountByKey.values()) {
|
|
111
|
-
disposer.use(refCount);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
catch (e_3) {
|
|
115
|
-
env_3.error = e_3;
|
|
116
|
-
env_3.hasError = true;
|
|
117
|
-
}
|
|
118
|
-
finally {
|
|
119
|
-
__disposeResources(env_3);
|
|
120
|
-
}
|
|
82
|
+
const disposer = __addDisposableResource(env_1, new DisposableStack(), false);
|
|
83
|
+
const refCountByKey = createLookupMap({ lookup });
|
|
84
|
+
disposer.defer(() => {
|
|
85
|
+
refCountByKey.clear();
|
|
121
86
|
});
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
let refCount = refCountByKey.get(key);
|
|
125
|
-
if (!refCount) {
|
|
126
|
-
refCount = createRefCount();
|
|
127
|
-
refCountByKey.set(key, refCount);
|
|
128
|
-
}
|
|
129
|
-
return refCount;
|
|
130
|
-
};
|
|
131
|
-
return {
|
|
132
|
-
increment: (key) => {
|
|
133
|
-
assertNotDisposed(disposables);
|
|
134
|
-
return getRefCount(key).increment();
|
|
135
|
-
},
|
|
87
|
+
return disposable({
|
|
88
|
+
increment: (key) => refCountByKey.getOrInsertComputed(key, createRefCount).increment(),
|
|
136
89
|
decrement: (key) => {
|
|
137
|
-
|
|
138
|
-
|
|
90
|
+
const refCount = refCountByKey.get(key);
|
|
91
|
+
assert(refCount, "RefCount must not be decremented for an untracked key.");
|
|
139
92
|
const nextCount = refCount.decrement();
|
|
140
93
|
if (nextCount === 0) {
|
|
141
94
|
refCountByKey.delete(key);
|
|
@@ -143,26 +96,16 @@ export function createRefCountByKey({ lookup = identity, } = {}) {
|
|
|
143
96
|
}
|
|
144
97
|
return nextCount;
|
|
145
98
|
},
|
|
146
|
-
getCount: (key) =>
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
has: (key) => {
|
|
151
|
-
assertNotDisposed(disposables);
|
|
152
|
-
return refCountByKey.has(key);
|
|
153
|
-
},
|
|
154
|
-
keys: () => {
|
|
155
|
-
assertNotDisposed(disposables);
|
|
156
|
-
return new Set(refCountByKey.keys());
|
|
157
|
-
},
|
|
158
|
-
[Symbol.dispose]: () => disposables.dispose(),
|
|
159
|
-
};
|
|
99
|
+
getCount: (key) => refCountByKey.get(key)?.getCount() ?? zeroNonNegativeInt,
|
|
100
|
+
has: (key) => refCountByKey.has(key),
|
|
101
|
+
keys: () => new Set(refCountByKey.keys()),
|
|
102
|
+
}, disposer);
|
|
160
103
|
}
|
|
161
|
-
catch (
|
|
162
|
-
|
|
163
|
-
|
|
104
|
+
catch (e_1) {
|
|
105
|
+
env_1.error = e_1;
|
|
106
|
+
env_1.hasError = true;
|
|
164
107
|
}
|
|
165
108
|
finally {
|
|
166
|
-
__disposeResources(
|
|
109
|
+
__disposeResources(env_1);
|
|
167
110
|
}
|
|
168
111
|
}
|
package/dist/src/Relation.d.ts
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
|
-
import { type Lookup } from "./Lookup.
|
|
6
|
+
import { type Lookup } from "./Lookup.ts";
|
|
7
|
+
import { NonNegativeInt, PositiveInt } from "./Type.ts";
|
|
7
8
|
/**
|
|
8
9
|
* Bidirectional relation between two types.
|
|
9
10
|
*
|
|
@@ -34,20 +35,33 @@ import { type Lookup } from "./Lookup.js";
|
|
|
34
35
|
* The input parameter types of `lookupA` and `lookupB` determine which values
|
|
35
36
|
* the returned relation accepts on each side.
|
|
36
37
|
*
|
|
37
|
-
* ###
|
|
38
|
+
* ### Reference identity
|
|
38
39
|
*
|
|
39
40
|
* Use the default identity semantics.
|
|
40
41
|
*
|
|
41
42
|
* ```ts
|
|
42
|
-
*
|
|
43
|
+
* import { createRelation } from "@evolu/common";
|
|
44
|
+
*
|
|
45
|
+
* interface Socket {
|
|
46
|
+
* readonly id: string;
|
|
47
|
+
* }
|
|
48
|
+
*
|
|
49
|
+
* const relation = createRelation<Socket, string>();
|
|
50
|
+
* const socket = { id: "socket-1" };
|
|
51
|
+
*
|
|
43
52
|
* relation.add(socket, "owner-1");
|
|
53
|
+
*
|
|
54
|
+
* expect(relation.has(socket, "owner-1")).toBe(true);
|
|
55
|
+
* expect(relation.has({ id: "socket-1" }, "owner-1")).toBe(false);
|
|
44
56
|
* ```
|
|
45
57
|
*
|
|
46
|
-
* ###
|
|
58
|
+
* ### Lookup-derived equality
|
|
47
59
|
*
|
|
48
60
|
* Use lookup-derived equality.
|
|
49
61
|
*
|
|
50
62
|
* ```ts
|
|
63
|
+
* import { createRelation } from "@evolu/common";
|
|
64
|
+
*
|
|
51
65
|
* interface Person {
|
|
52
66
|
* readonly id: string;
|
|
53
67
|
* readonly name: string;
|
|
@@ -59,7 +73,10 @@ import { type Lookup } from "./Lookup.js";
|
|
|
59
73
|
* });
|
|
60
74
|
*
|
|
61
75
|
* relation.add({ id: "1", name: "Ada" }, { id: "admins" });
|
|
62
|
-
*
|
|
76
|
+
*
|
|
77
|
+
* expect(relation.has({ id: "1", name: "Grace" }, { id: "admins" })).toBe(
|
|
78
|
+
* true,
|
|
79
|
+
* );
|
|
63
80
|
* ```
|
|
64
81
|
*
|
|
65
82
|
* @see {@link createRelation}
|
|
@@ -131,4 +148,52 @@ export interface CreateRelationOptions<A, B, LA = A, LB = B> {
|
|
|
131
148
|
/** Creates a {@link Relation}. */
|
|
132
149
|
export declare function createRelation<A, B>(): Relation<A, B>;
|
|
133
150
|
export declare function createRelation<A, B, LA, LB>(options: CreateRelationOptions<A, B, LA, LB>): Relation<A, B>;
|
|
151
|
+
/**
|
|
152
|
+
* Bidirectional relation with a positive retain count for every active pair.
|
|
153
|
+
*
|
|
154
|
+
* Logical equality and canonical representatives follow the same lookup rules
|
|
155
|
+
* as {@link Relation}. The first active representative on each side remains
|
|
156
|
+
* canonical until that value has no active pairs. Increment and decrement
|
|
157
|
+
* return those representatives so callers can reliably handle pair transitions
|
|
158
|
+
* without repeating lookup or canonicalization logic.
|
|
159
|
+
*
|
|
160
|
+
* Unlike {@link Relation}'s live iterators, directional and entry reads return
|
|
161
|
+
* snapshots so callers can mutate this relation while iterating. Their order
|
|
162
|
+
* follows first insertion of the current canonical representatives and pairs.
|
|
163
|
+
*/
|
|
164
|
+
export interface RefCountedRelation<A, B> {
|
|
165
|
+
/** Increments a pair count and returns its canonical values and new count. */
|
|
166
|
+
readonly increment: (a: A, b: B) => {
|
|
167
|
+
readonly a: A;
|
|
168
|
+
readonly b: B;
|
|
169
|
+
readonly count: PositiveInt;
|
|
170
|
+
};
|
|
171
|
+
/**
|
|
172
|
+
* Decrements a pair count and returns its canonical values and new count.
|
|
173
|
+
* Decrementing a missing pair is a programmer error checked with
|
|
174
|
+
* {@link assert}.
|
|
175
|
+
*/
|
|
176
|
+
readonly decrement: (a: A, b: B) => {
|
|
177
|
+
readonly a: A;
|
|
178
|
+
readonly b: B;
|
|
179
|
+
readonly count: NonNegativeInt;
|
|
180
|
+
};
|
|
181
|
+
/** Returns the pair count, or zero when the pair is absent. */
|
|
182
|
+
readonly getCount: (a: A, b: B) => NonNegativeInt;
|
|
183
|
+
/** Returns a snapshot of canonical A values related to `b`. */
|
|
184
|
+
readonly getAs: (b: B) => ReadonlyArray<A>;
|
|
185
|
+
/** Returns a snapshot of canonical B values related to `a`. */
|
|
186
|
+
readonly getBs: (a: A) => ReadonlyArray<B>;
|
|
187
|
+
/** Returns whether an A value has at least one active pair. */
|
|
188
|
+
readonly hasA: (a: A) => boolean;
|
|
189
|
+
/** Returns whether a B value has at least one active pair. */
|
|
190
|
+
readonly hasB: (b: B) => boolean;
|
|
191
|
+
/** Returns a snapshot of every canonical pair and its positive count. */
|
|
192
|
+
readonly getEntries: () => ReadonlyArray<readonly [a: A, b: B, count: PositiveInt]>;
|
|
193
|
+
/** Removes all pair counts and both directional indexes. */
|
|
194
|
+
readonly clear: () => void;
|
|
195
|
+
}
|
|
196
|
+
/** Creates a {@link RefCountedRelation}. */
|
|
197
|
+
export declare function createRefCountedRelation<A, B>(): RefCountedRelation<A, B>;
|
|
198
|
+
export declare function createRefCountedRelation<A, B, LA, LB>(options: CreateRelationOptions<A, B, LA, LB>): RefCountedRelation<A, B>;
|
|
134
199
|
//# sourceMappingURL=Relation.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Relation.d.ts","sourceRoot":"","sources":["../../src/Relation.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAGL,KAAK,MAAM,
|
|
1
|
+
{"version":3,"file":"Relation.d.ts","sourceRoot":"","sources":["../../src/Relation.ts"],"names":[],"mappings":"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"}
|