@evolu/common 6.0.1-preview.28 β 6.0.1-preview.29
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 +58 -5
- package/dist/src/Array.d.ts.map +1 -1
- package/dist/src/Array.js +53 -5
- package/dist/src/Evolu/Evolu.d.ts +3 -3
- package/dist/src/Evolu/Evolu.d.ts.map +1 -1
- package/dist/src/Evolu/Evolu.js +3 -3
- package/dist/src/Evolu/Owner.d.ts +48 -19
- package/dist/src/Evolu/Owner.d.ts.map +1 -1
- package/dist/src/Evolu/Owner.js +11 -2
- package/dist/src/Evolu/Protocol.d.ts +31 -31
- package/dist/src/Evolu/Protocol.d.ts.map +1 -1
- package/dist/src/Evolu/Protocol.js +51 -28
- package/dist/src/Evolu/Relay.d.ts +40 -25
- package/dist/src/Evolu/Relay.d.ts.map +1 -1
- package/dist/src/Evolu/Relay.js +106 -49
- package/dist/src/Evolu/Storage.d.ts +59 -12
- package/dist/src/Evolu/Storage.d.ts.map +1 -1
- package/dist/src/Evolu/Storage.js +77 -50
- package/dist/src/Evolu/Sync.d.ts.map +1 -1
- package/dist/src/Evolu/Sync.js +14 -5
- package/dist/src/Evolu/Timestamp.d.ts +25 -0
- package/dist/src/Evolu/Timestamp.d.ts.map +1 -1
- package/dist/src/Evolu/Timestamp.js +25 -0
- package/dist/src/Instances.d.ts +34 -0
- package/dist/src/Instances.d.ts.map +1 -0
- package/dist/src/{Multiton.js β Instances.js} +20 -9
- package/dist/src/Sqlite.d.ts +6 -0
- package/dist/src/Sqlite.d.ts.map +1 -1
- package/dist/src/Sqlite.js +6 -0
- package/dist/src/Task.d.ts +75 -0
- package/dist/src/Task.d.ts.map +1 -1
- package/dist/src/Task.js +29 -6
- package/dist/src/Time.d.ts +7 -1
- package/dist/src/Time.d.ts.map +1 -1
- package/dist/src/Time.js +13 -2
- package/dist/src/Type.d.ts +56 -9
- package/dist/src/Type.d.ts.map +1 -1
- package/dist/src/Type.js +40 -8
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -1
- package/package.json +1 -1
- package/src/Array.ts +76 -11
- package/src/Evolu/Evolu.ts +4 -5
- package/src/Evolu/Owner.ts +75 -26
- package/src/Evolu/Protocol.ts +90 -61
- package/src/Evolu/Relay.ts +182 -77
- package/src/Evolu/Storage.ts +157 -67
- package/src/Evolu/Sync.ts +18 -6
- package/src/Evolu/Timestamp.ts +25 -0
- package/src/Instances.ts +90 -0
- package/src/Sqlite.ts +6 -0
- package/src/Task.ts +88 -7
- package/src/Time.ts +13 -2
- package/src/Type.ts +56 -9
- package/src/index.ts +1 -1
- package/dist/src/Multiton.d.ts +0 -50
- package/dist/src/Multiton.d.ts.map +0 -1
- package/src/Multiton.ts +0 -98
package/dist/src/Array.d.ts
CHANGED
|
@@ -1,3 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* π Immutable, type-safe array operations
|
|
3
|
+
*
|
|
4
|
+
* Helpers that preserve immutability through the type system. Native array
|
|
5
|
+
* methods return mutable arrays even when called on readonly arrays. These
|
|
6
|
+
* helpers ensure transformations return readonly types.
|
|
7
|
+
*
|
|
8
|
+
* {@link NonEmptyArray} and {@link NonEmptyReadonlyArray} types represent arrays
|
|
9
|
+
* with at least one element, eliminating runtime length checks and making
|
|
10
|
+
* function requirements explicit.
|
|
11
|
+
*
|
|
12
|
+
* ### Example
|
|
13
|
+
*
|
|
14
|
+
* ```ts
|
|
15
|
+
* // β Native methods return mutable arrays
|
|
16
|
+
* const readonly: ReadonlyArray<number> = [1, 2, 3];
|
|
17
|
+
* const mapped = readonly.map((x) => x * 2); // Array<number> (mutable!)
|
|
18
|
+
*
|
|
19
|
+
* // β
Helpers preserve immutability
|
|
20
|
+
* const filtered = filterArray(readonly, (x) => x > 1); // ReadonlyArray<number>
|
|
21
|
+
*
|
|
22
|
+
* // β
NonEmptyArray enforces non-emptiness
|
|
23
|
+
* const first = (items: NonEmptyReadonlyArray<string>) => items[0];
|
|
24
|
+
* first([]); // β Compiler error
|
|
25
|
+
* first(["a"]); // β
Works
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* @module
|
|
29
|
+
*/
|
|
1
30
|
/** An array with at least one element. */
|
|
2
31
|
export type NonEmptyArray<T> = [T, ...Array<T>];
|
|
3
32
|
/** Checks if an array is non-empty. */
|
|
@@ -6,12 +35,36 @@ export declare const isNonEmptyArray: <T>(array: Array<T>) => array is NonEmptyA
|
|
|
6
35
|
export type NonEmptyReadonlyArray<T> = readonly [T, ...ReadonlyArray<T>];
|
|
7
36
|
/** Checks if an array is non-empty. */
|
|
8
37
|
export declare const isNonEmptyReadonlyArray: <T>(array: ReadonlyArray<T>) => array is NonEmptyReadonlyArray<T>;
|
|
9
|
-
/**
|
|
38
|
+
/**
|
|
39
|
+
* Appends an item to an array, returning a new non-empty readonly array.
|
|
40
|
+
*
|
|
41
|
+
* Accepts both mutable and readonly arrays. Does not mutate the original array.
|
|
42
|
+
*/
|
|
10
43
|
export declare const appendToArray: <T>(item: T, array: ReadonlyArray<T>) => NonEmptyReadonlyArray<T>;
|
|
11
|
-
/**
|
|
44
|
+
/**
|
|
45
|
+
* Prepends an item to an array, returning a new non-empty readonly array.
|
|
46
|
+
*
|
|
47
|
+
* Accepts both mutable and readonly arrays. Does not mutate the original array.
|
|
48
|
+
*/
|
|
12
49
|
export declare const prependToArray: <T>(item: T, array: ReadonlyArray<T>) => NonEmptyReadonlyArray<T>;
|
|
13
|
-
/**
|
|
14
|
-
|
|
15
|
-
|
|
50
|
+
/**
|
|
51
|
+
* Maps an array using a mapper function, preserving non-emptiness when
|
|
52
|
+
* applicable.
|
|
53
|
+
*
|
|
54
|
+
* Accepts both mutable and readonly arrays. Does not mutate the original array.
|
|
55
|
+
*/
|
|
56
|
+
export declare function mapArray<T, U>(array: NonEmptyReadonlyArray<T> | NonEmptyArray<T>, mapper: (item: T, index: number) => U): NonEmptyReadonlyArray<U>;
|
|
57
|
+
export declare function mapArray<T, U>(array: ReadonlyArray<T> | Array<T>, mapper: (item: T, index: number) => U): ReadonlyArray<U>;
|
|
58
|
+
/**
|
|
59
|
+
* Filters an array using a predicate function, returning a new readonly array.
|
|
60
|
+
*
|
|
61
|
+
* Accepts both mutable and readonly arrays. Does not mutate the original array.
|
|
62
|
+
*/
|
|
63
|
+
export declare const filterArray: <T>(array: ReadonlyArray<T>, predicate: (item: T, index: number) => boolean) => ReadonlyArray<T>;
|
|
64
|
+
/**
|
|
65
|
+
* Shifts an item from a non-empty mutable array, guaranteed to return T.
|
|
66
|
+
*
|
|
67
|
+
* **Mutates** the original array. Use only with mutable arrays.
|
|
68
|
+
*/
|
|
16
69
|
export declare const shiftArray: <T>(array: NonEmptyArray<T>) => T;
|
|
17
70
|
//# sourceMappingURL=Array.d.ts.map
|
package/dist/src/Array.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Array.d.ts","sourceRoot":"","sources":["../../src/Array.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAC1C,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAEhD,uCAAuC;AACvC,eAAO,MAAM,eAAe,GAAI,CAAC,EAC/B,OAAO,KAAK,CAAC,CAAC,CAAC,KACd,KAAK,IAAI,aAAa,CAAC,CAAC,CAAqB,CAAC;AAEjD,kDAAkD;AAClD,MAAM,MAAM,qBAAqB,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,EAAE,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;AAEzE,uCAAuC;AACvC,eAAO,MAAM,uBAAuB,GAAI,CAAC,EACvC,OAAO,aAAa,CAAC,CAAC,CAAC,KACtB,KAAK,IAAI,qBAAqB,CAAC,CAAC,CAAqB,CAAC;AAEzD
|
|
1
|
+
{"version":3,"file":"Array.d.ts","sourceRoot":"","sources":["../../src/Array.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,0CAA0C;AAC1C,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAEhD,uCAAuC;AACvC,eAAO,MAAM,eAAe,GAAI,CAAC,EAC/B,OAAO,KAAK,CAAC,CAAC,CAAC,KACd,KAAK,IAAI,aAAa,CAAC,CAAC,CAAqB,CAAC;AAEjD,kDAAkD;AAClD,MAAM,MAAM,qBAAqB,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,EAAE,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;AAEzE,uCAAuC;AACvC,eAAO,MAAM,uBAAuB,GAAI,CAAC,EACvC,OAAO,aAAa,CAAC,CAAC,CAAC,KACtB,KAAK,IAAI,qBAAqB,CAAC,CAAC,CAAqB,CAAC;AAEzD;;;;GAIG;AACH,eAAO,MAAM,aAAa,GAAI,CAAC,EAC7B,MAAM,CAAC,EACP,OAAO,aAAa,CAAC,CAAC,CAAC,KACtB,qBAAqB,CAAC,CAAC,CACwC,CAAC;AAEnE;;;;GAIG;AACH,eAAO,MAAM,cAAc,GAAI,CAAC,EAC9B,MAAM,CAAC,EACP,OAAO,aAAa,CAAC,CAAC,CAAC,KACtB,qBAAqB,CAAC,CAAC,CAAiD,CAAC;AAE5E;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,CAAC,EAC3B,KAAK,EAAE,qBAAqB,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,EAClD,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,CAAC,GACpC,qBAAqB,CAAC,CAAC,CAAC,CAAC;AAC5B,wBAAgB,QAAQ,CAAC,CAAC,EAAE,CAAC,EAC3B,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,EAClC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,CAAC,GACpC,aAAa,CAAC,CAAC,CAAC,CAAC;AAQpB;;;;GAIG;AACH,eAAO,MAAM,WAAW,GAAI,CAAC,EAC3B,OAAO,aAAa,CAAC,CAAC,CAAC,EACvB,WAAW,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,KAC7C,aAAa,CAAC,CAAC,CAAgD,CAAC;AAEnE;;;;GAIG;AACH,eAAO,MAAM,UAAU,GAAI,CAAC,EAAE,OAAO,aAAa,CAAC,CAAC,CAAC,KAAG,CAAuB,CAAC"}
|
package/dist/src/Array.js
CHANGED
|
@@ -1,12 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* π Immutable, type-safe array operations
|
|
3
|
+
*
|
|
4
|
+
* Helpers that preserve immutability through the type system. Native array
|
|
5
|
+
* methods return mutable arrays even when called on readonly arrays. These
|
|
6
|
+
* helpers ensure transformations return readonly types.
|
|
7
|
+
*
|
|
8
|
+
* {@link NonEmptyArray} and {@link NonEmptyReadonlyArray} types represent arrays
|
|
9
|
+
* with at least one element, eliminating runtime length checks and making
|
|
10
|
+
* function requirements explicit.
|
|
11
|
+
*
|
|
12
|
+
* ### Example
|
|
13
|
+
*
|
|
14
|
+
* ```ts
|
|
15
|
+
* // β Native methods return mutable arrays
|
|
16
|
+
* const readonly: ReadonlyArray<number> = [1, 2, 3];
|
|
17
|
+
* const mapped = readonly.map((x) => x * 2); // Array<number> (mutable!)
|
|
18
|
+
*
|
|
19
|
+
* // β
Helpers preserve immutability
|
|
20
|
+
* const filtered = filterArray(readonly, (x) => x > 1); // ReadonlyArray<number>
|
|
21
|
+
*
|
|
22
|
+
* // β
NonEmptyArray enforces non-emptiness
|
|
23
|
+
* const first = (items: NonEmptyReadonlyArray<string>) => items[0];
|
|
24
|
+
* first([]); // β Compiler error
|
|
25
|
+
* first(["a"]); // β
Works
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* @module
|
|
29
|
+
*/
|
|
1
30
|
/** Checks if an array is non-empty. */
|
|
2
31
|
export const isNonEmptyArray = (array) => array.length > 0;
|
|
3
32
|
/** Checks if an array is non-empty. */
|
|
4
33
|
export const isNonEmptyReadonlyArray = (array) => array.length > 0;
|
|
5
|
-
/**
|
|
34
|
+
/**
|
|
35
|
+
* Appends an item to an array, returning a new non-empty readonly array.
|
|
36
|
+
*
|
|
37
|
+
* Accepts both mutable and readonly arrays. Does not mutate the original array.
|
|
38
|
+
*/
|
|
6
39
|
export const appendToArray = (item, array) => [...array, item];
|
|
7
|
-
/**
|
|
40
|
+
/**
|
|
41
|
+
* Prepends an item to an array, returning a new non-empty readonly array.
|
|
42
|
+
*
|
|
43
|
+
* Accepts both mutable and readonly arrays. Does not mutate the original array.
|
|
44
|
+
*/
|
|
8
45
|
export const prependToArray = (item, array) => [item, ...array];
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
46
|
+
export function mapArray(array, mapper) {
|
|
47
|
+
return array.map(mapper);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Filters an array using a predicate function, returning a new readonly array.
|
|
51
|
+
*
|
|
52
|
+
* Accepts both mutable and readonly arrays. Does not mutate the original array.
|
|
53
|
+
*/
|
|
54
|
+
export const filterArray = (array, predicate) => array.filter(predicate);
|
|
55
|
+
/**
|
|
56
|
+
* Shifts an item from a non-empty mutable array, guaranteed to return T.
|
|
57
|
+
*
|
|
58
|
+
* **Mutates** the original array. Use only with mutable arrays.
|
|
59
|
+
*/
|
|
12
60
|
export const shiftArray = (array) => array.shift();
|
|
@@ -8,7 +8,7 @@ import { Mnemonic } from "../Type.js";
|
|
|
8
8
|
import { CreateDbWorkerDep, DbConfig } from "./Db.js";
|
|
9
9
|
import { AppOwner } from "./Owner.js";
|
|
10
10
|
import { FlushSyncDep, ReloadAppDep } from "./Platform.js";
|
|
11
|
-
import { ProtocolError
|
|
11
|
+
import { ProtocolError } from "./Protocol.js";
|
|
12
12
|
import { Queries, QueriesToQueryRowsPromises, Query, QueryRows, Row } from "./Query.js";
|
|
13
13
|
import { CreateQuery, EvoluSchema, IndexesConfig, Mutation, ValidateSchema } from "./Schema.js";
|
|
14
14
|
import { SyncOwner } from "./Sync.js";
|
|
@@ -362,7 +362,7 @@ export interface Evolu<S extends EvoluSchema = EvoluSchema> extends Disposable {
|
|
|
362
362
|
readonly useOwner: (owner: SyncOwner) => () => void;
|
|
363
363
|
}
|
|
364
364
|
/** Represents errors that can occur in Evolu. */
|
|
365
|
-
export type EvoluError = ProtocolError |
|
|
365
|
+
export type EvoluError = ProtocolError | SqliteError | SymmetricCryptoDecryptError | TimestampError | TransferableError;
|
|
366
366
|
export type EvoluDeps = ConsoleDep & CreateDbWorkerDep & Partial<FlushSyncDep> & RandomBytesDep & ReloadAppDep & TimeDep;
|
|
367
367
|
/**
|
|
368
368
|
* Creates an {@link Evolu} instance for a platform configured with the specified
|
|
@@ -399,7 +399,7 @@ export type EvoluDeps = ConsoleDep & CreateDbWorkerDep & Partial<FlushSyncDep> &
|
|
|
399
399
|
*
|
|
400
400
|
* ### Instance Caching
|
|
401
401
|
*
|
|
402
|
-
* `createEvolu` caches instances using {@link
|
|
402
|
+
* `createEvolu` caches instances using {@link Instances} by {@link EvoluConfig}
|
|
403
403
|
* name to enable hot reloading and prevent database corruption from multiple
|
|
404
404
|
* connections. For testing, use unique instance names to ensure proper
|
|
405
405
|
* isolation.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Evolu.d.ts","sourceRoot":"","sources":["../../../src/Evolu/Evolu.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,2BAA2B,EAAE,MAAM,cAAc,CAAC;AAE3E,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAIhD,OAAO,EAA0B,WAAW,EAAe,MAAM,cAAc,CAAC;AAChF,OAAO,EAAe,cAAc,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAML,QAAQ,EAKT,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAmB,MAAM,SAAS,CAAC;AAEvE,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE
|
|
1
|
+
{"version":3,"file":"Evolu.d.ts","sourceRoot":"","sources":["../../../src/Evolu/Evolu.ts"],"names":[],"mappings":"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"}
|
package/dist/src/Evolu/Evolu.js
CHANGED
|
@@ -4,7 +4,7 @@ import { assert, assertNonEmptyArray } from "../Assert.js";
|
|
|
4
4
|
import { createCallbackRegistry } from "../CallbackRegistry.js";
|
|
5
5
|
import { eqArrayNumber } from "../Eq.js";
|
|
6
6
|
import { exhaustiveCheck } from "../Function.js";
|
|
7
|
-
import {
|
|
7
|
+
import { createInstances } from "../Instances.js";
|
|
8
8
|
import { err, ok } from "../Result.js";
|
|
9
9
|
import { isSqlMutation } from "../Sqlite.js";
|
|
10
10
|
import { createStore } from "../Store.js";
|
|
@@ -15,7 +15,7 @@ import { createSubscribedQueries, emptyRows, serializeQuery, } from "./Query.js"
|
|
|
15
15
|
import { evoluSchemaToDbSchema, insertable, kysely, updateable, upsertable, } from "./Schema.js";
|
|
16
16
|
import { DbChange } from "./Storage.js";
|
|
17
17
|
import { initialSyncState } from "./Sync.js";
|
|
18
|
-
const evoluInstances =
|
|
18
|
+
const evoluInstances = createInstances();
|
|
19
19
|
/**
|
|
20
20
|
* Unique identifier for the current browser tab or app instance, lazily
|
|
21
21
|
* initialized on first use to distinguish between multiple tabs.
|
|
@@ -56,7 +56,7 @@ let tabId = null;
|
|
|
56
56
|
*
|
|
57
57
|
* ### Instance Caching
|
|
58
58
|
*
|
|
59
|
-
* `createEvolu` caches instances using {@link
|
|
59
|
+
* `createEvolu` caches instances using {@link Instances} by {@link EvoluConfig}
|
|
60
60
|
* name to enable hot reloading and prevent database corruption from multiple
|
|
61
61
|
* connections. For testing, use unique instance names to ensure proper
|
|
62
62
|
* isolation.
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { NonEmptyReadonlyArray } from "../Array.js";
|
|
2
2
|
import { EncryptionKey, RandomBytesDep } from "../Crypto.js";
|
|
3
|
-
import { Mnemonic, NonNegativeInt
|
|
4
|
-
import { TimestampBytes } from "./Timestamp.js";
|
|
3
|
+
import { Mnemonic, NonNegativeInt } from "../Type.js";
|
|
5
4
|
/**
|
|
6
5
|
* The Owner represents ownership of data in Evolu. Every database change is
|
|
7
6
|
* assigned to an owner, enabling sync functionality and access control.
|
|
@@ -104,6 +103,17 @@ export declare const createOwner: (secret: OwnerSecret) => Owner;
|
|
|
104
103
|
* preserved because it coordinates deletion information across devices. Other
|
|
105
104
|
* devices need to sync the information that an owner was deleted so they can
|
|
106
105
|
* delete their local data as well.
|
|
106
|
+
*
|
|
107
|
+
* ### Privacy Considerations
|
|
108
|
+
*
|
|
109
|
+
* AppOwner must never be shared with anyone, except for its {@link OwnerId},
|
|
110
|
+
* which can be used for authorization with
|
|
111
|
+
* {@link createOwnerWebSocketTransport}. It's safe because OwnerId is
|
|
112
|
+
* pseudonymous (it can't be assigned to a specific person).
|
|
113
|
+
*
|
|
114
|
+
* For data sharing scenarios, use {@link SharedOwner} and
|
|
115
|
+
* {@link SharedReadonlyOwner} instead, which are designed specifically for
|
|
116
|
+
* collaborative access.
|
|
107
117
|
*/
|
|
108
118
|
export interface AppOwner extends Owner {
|
|
109
119
|
readonly type: "AppOwner";
|
|
@@ -187,7 +197,17 @@ export type OwnerTransport = OwnerWebSocketTransport;
|
|
|
187
197
|
/**
|
|
188
198
|
* WebSocket transport configuration.
|
|
189
199
|
*
|
|
190
|
-
* ### Authentication
|
|
200
|
+
* ### Authentication via URL
|
|
201
|
+
*
|
|
202
|
+
* The {@link OwnerId} is passed as a URL query parameter. While this approach is
|
|
203
|
+
* generally discouraged for authentication tokens (they get logged), it's safe
|
|
204
|
+
* here because OwnerId is pseudonymous and used only for access verification -
|
|
205
|
+
* it provides no ability to read encrypted data or write changes.
|
|
206
|
+
*
|
|
207
|
+
* See: [HTTP headers in Websockets client
|
|
208
|
+
* API](https://stackoverflow.com/questions/4361173/http-headers-in-websockets-client-api/74564827#74564827)
|
|
209
|
+
*
|
|
210
|
+
* ### Error Handling
|
|
191
211
|
*
|
|
192
212
|
* When a relay rejects a connection (invalid OwnerId, unauthorized owner, or
|
|
193
213
|
* server error), the browser WebSocket API does not expose the specific HTTP
|
|
@@ -209,14 +229,23 @@ export interface OwnerWebSocketTransport {
|
|
|
209
229
|
* Creates an {@link OwnerWebSocketTransport} for the given relay URL and
|
|
210
230
|
* {@link OwnerId}.
|
|
211
231
|
*
|
|
232
|
+
* The URL must be a WebSocket base URL without query parameters or fragments
|
|
233
|
+
* (e.g., `wss://relay.evolu.dev`, not `wss://relay.evolu.dev?foo=bar`). The
|
|
234
|
+
* function appends the `ownerId` as a query parameter.
|
|
235
|
+
*
|
|
212
236
|
* ### Example
|
|
213
237
|
*
|
|
214
238
|
* ```ts
|
|
239
|
+
* // Create transport "wss://relay.evolu.dev?ownerId=..."
|
|
215
240
|
* const transport = createOwnerWebSocketTransport({
|
|
216
241
|
* url: "wss://relay.evolu.dev",
|
|
217
242
|
* ownerId: owner.id,
|
|
218
243
|
* });
|
|
219
|
-
*
|
|
244
|
+
*
|
|
245
|
+
* // Use with createEvolu
|
|
246
|
+
* const evolu = createEvolu(deps)(Schema, {
|
|
247
|
+
* transports: [transport],
|
|
248
|
+
* });
|
|
220
249
|
* ```
|
|
221
250
|
*/
|
|
222
251
|
export declare const createOwnerWebSocketTransport: (config: {
|
|
@@ -240,6 +269,10 @@ export declare const createOwnerWebSocketTransport: (config: {
|
|
|
240
269
|
* ```
|
|
241
270
|
*/
|
|
242
271
|
export declare const parseOwnerIdFromOwnerWebSocketTransportUrl: (url: string) => OwnerId | null;
|
|
272
|
+
/** Base interface for all owner errors. */
|
|
273
|
+
export interface BaseOwnerError {
|
|
274
|
+
readonly ownerId: OwnerId;
|
|
275
|
+
}
|
|
243
276
|
/**
|
|
244
277
|
* Usage data for an {@link OwnerId}.
|
|
245
278
|
*
|
|
@@ -252,24 +285,20 @@ export declare const parseOwnerIdFromOwnerWebSocketTransportUrl: (url: string) =
|
|
|
252
285
|
export interface OwnerUsage {
|
|
253
286
|
/** The {@link Owner} this usage data belongs to. */
|
|
254
287
|
readonly ownerId: OwnerIdBytes;
|
|
255
|
-
/** Total bytes stored in the database. */
|
|
256
|
-
readonly storedBytes: PositiveInt;
|
|
257
|
-
/** Total bytes received. */
|
|
258
|
-
readonly receivedBytes: number;
|
|
259
|
-
/** Total bytes sent. */
|
|
260
|
-
readonly sentBytes: number;
|
|
261
288
|
/**
|
|
262
|
-
*
|
|
289
|
+
* Total logical data bytes stored.
|
|
263
290
|
*
|
|
264
|
-
*
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
/**
|
|
268
|
-
* The maximum {@link Timestamp}.
|
|
291
|
+
* Measures the size of {@link EncryptedDbChange}s only, excluding
|
|
292
|
+
* {@link Storage} implementation overhead (with SqliteStorage: indexes,
|
|
293
|
+
* skiplist columns, etc.). This provides:
|
|
269
294
|
*
|
|
270
|
-
*
|
|
271
|
-
*
|
|
295
|
+
* - **Predictable measurement** - same data = same byte count across all
|
|
296
|
+
* instances
|
|
297
|
+
* - **Quota enforcement** - consistent billing/limits independent of storage
|
|
298
|
+
* implementation
|
|
299
|
+
* - **Overhead tracking** - actual Storage size can be compared against this to
|
|
300
|
+
* monitor efficiency
|
|
272
301
|
*/
|
|
273
|
-
readonly
|
|
302
|
+
readonly storedBytes: NonNegativeInt;
|
|
274
303
|
}
|
|
275
304
|
//# sourceMappingURL=Owner.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Owner.d.ts","sourceRoot":"","sources":["../../../src/Evolu/Owner.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAEL,aAAa,EAGb,cAAc,EACf,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"Owner.d.ts","sourceRoot":"","sources":["../../../src/Evolu/Owner.ts"],"names":[],"mappings":"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"}
|
package/dist/src/Evolu/Owner.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as bip39 from "@scure/bip39";
|
|
2
2
|
import { wordlist } from "@scure/bip39/wordlists/english.js";
|
|
3
3
|
import { createSlip21, EncryptionKey, Entropy16, Entropy32, } from "../Crypto.js";
|
|
4
|
-
import { brand, Id, IdBytes, idBytesToId, idToIdBytes, } from "../Type.js";
|
|
5
4
|
import { getOrNull } from "../Result.js";
|
|
5
|
+
import { brand, Id, IdBytes, idBytesToId, idToIdBytes, } from "../Type.js";
|
|
6
6
|
/**
|
|
7
7
|
* OwnerId is a branded {@link Id} that uniquely identifies an {@link Owner}.
|
|
8
8
|
* Branded from {@link Id} to leverage existing helpers like {@link idToIdBytes}.
|
|
@@ -115,14 +115,23 @@ export const createSharedReadonlyOwner = (sharedOwner) => ({
|
|
|
115
115
|
* Creates an {@link OwnerWebSocketTransport} for the given relay URL and
|
|
116
116
|
* {@link OwnerId}.
|
|
117
117
|
*
|
|
118
|
+
* The URL must be a WebSocket base URL without query parameters or fragments
|
|
119
|
+
* (e.g., `wss://relay.evolu.dev`, not `wss://relay.evolu.dev?foo=bar`). The
|
|
120
|
+
* function appends the `ownerId` as a query parameter.
|
|
121
|
+
*
|
|
118
122
|
* ### Example
|
|
119
123
|
*
|
|
120
124
|
* ```ts
|
|
125
|
+
* // Create transport "wss://relay.evolu.dev?ownerId=..."
|
|
121
126
|
* const transport = createOwnerWebSocketTransport({
|
|
122
127
|
* url: "wss://relay.evolu.dev",
|
|
123
128
|
* ownerId: owner.id,
|
|
124
129
|
* });
|
|
125
|
-
*
|
|
130
|
+
*
|
|
131
|
+
* // Use with createEvolu
|
|
132
|
+
* const evolu = createEvolu(deps)(Schema, {
|
|
133
|
+
* transports: [transport],
|
|
134
|
+
* });
|
|
126
135
|
* ```
|
|
127
136
|
*/
|
|
128
137
|
export const createOwnerWebSocketTransport = (config) => ({
|
|
@@ -85,10 +85,10 @@
|
|
|
85
85
|
*
|
|
86
86
|
* - {@link ProtocolWriteKeyError}: The provided WriteKey is invalid or missing.
|
|
87
87
|
* - {@link ProtocolWriteError}: A serious relay-side write failure occurred.
|
|
88
|
+
* - {@link ProtocolQuotaError}: Storage or billing quota exceeded.
|
|
88
89
|
* - {@link ProtocolSyncError}: A serious relay-side synchronization failure
|
|
89
90
|
* occurred.
|
|
90
|
-
* - {@link
|
|
91
|
-
* - {@link ProtocolUnsupportedVersionError}: Protocol version mismatch.
|
|
91
|
+
* - {@link ProtocolVersionError}: Protocol version mismatch.
|
|
92
92
|
* - {@link ProtocolInvalidDataError}: The message is malformed or corrupted.
|
|
93
93
|
*
|
|
94
94
|
* All protocol errors except `ProtocolInvalidDataError` include the `OwnerId`
|
|
@@ -166,7 +166,7 @@ import { EncryptionKey, RandomBytesDep, SymmetricCryptoDecryptError, SymmetricCr
|
|
|
166
166
|
import { Result } from "../Result.js";
|
|
167
167
|
import { SqliteValue } from "../Sqlite.js";
|
|
168
168
|
import { NonNegativeInt, PositiveInt } from "../Type.js";
|
|
169
|
-
import { Owner, OwnerId, OwnerWriteKey } from "./Owner.js";
|
|
169
|
+
import { BaseOwnerError, Owner, OwnerId, OwnerWriteKey } from "./Owner.js";
|
|
170
170
|
import { BaseRange, CrdtMessage, DbChange, EncryptedCrdtMessage, EncryptedDbChange, FingerprintRange, RangeType, SkipRange, StorageDep } from "./Storage.js";
|
|
171
171
|
import { NodeId, Timestamp } from "./Timestamp.js";
|
|
172
172
|
/**
|
|
@@ -242,24 +242,20 @@ export declare const ProtocolErrorCode: {
|
|
|
242
242
|
readonly WriteKeyError: 1;
|
|
243
243
|
/** A code for {@link ProtocolWriteError}. */
|
|
244
244
|
readonly WriteError: 2;
|
|
245
|
+
/** A code for {@link ProtocolQuotaError}. */
|
|
246
|
+
readonly QuotaError: 3;
|
|
245
247
|
/** A code for {@link ProtocolSyncError}. */
|
|
246
|
-
readonly SyncError:
|
|
247
|
-
/** A code for {@link ProtocolQuotaExceededError}. */
|
|
248
|
-
readonly QuotaExceededError: 4;
|
|
248
|
+
readonly SyncError: 4;
|
|
249
249
|
};
|
|
250
250
|
type ProtocolErrorCode = (typeof ProtocolErrorCode)[keyof typeof ProtocolErrorCode];
|
|
251
|
-
export type ProtocolError =
|
|
252
|
-
/** Base interface for all protocol errors. */
|
|
253
|
-
export interface ProtocolErrorBase {
|
|
254
|
-
readonly ownerId: OwnerId;
|
|
255
|
-
}
|
|
251
|
+
export type ProtocolError = ProtocolVersionError | ProtocolInvalidDataError | ProtocolWriteKeyError | ProtocolWriteError | ProtocolSyncError | ProtocolQuotaError | ProtocolTimestampMismatchError;
|
|
256
252
|
/**
|
|
257
253
|
* Represents a version mismatch in the Evolu Protocol. Occurs when the
|
|
258
254
|
* initiator and non-initiator are using incompatible protocol versions.
|
|
259
255
|
*/
|
|
260
|
-
export interface
|
|
261
|
-
readonly type: "
|
|
262
|
-
readonly
|
|
256
|
+
export interface ProtocolVersionError extends BaseOwnerError {
|
|
257
|
+
readonly type: "ProtocolVersionError";
|
|
258
|
+
readonly version: NonNegativeInt;
|
|
263
259
|
/** Indicates which side is obsolete and should update. */
|
|
264
260
|
readonly isInitiator: boolean;
|
|
265
261
|
}
|
|
@@ -270,32 +266,36 @@ export interface ProtocolInvalidDataError {
|
|
|
270
266
|
readonly error: unknown;
|
|
271
267
|
}
|
|
272
268
|
/** Error when a {@link OwnerWriteKey} is invalid, missing, or fails validation. */
|
|
273
|
-
export interface ProtocolWriteKeyError extends
|
|
269
|
+
export interface ProtocolWriteKeyError extends BaseOwnerError {
|
|
274
270
|
readonly type: "ProtocolWriteKeyError";
|
|
275
271
|
}
|
|
276
272
|
/**
|
|
277
273
|
* Error indicating a serious relay-side write failure. Clients should log this
|
|
278
274
|
* error and show a generic sync error to the user.
|
|
279
275
|
*/
|
|
280
|
-
export interface ProtocolWriteError extends
|
|
276
|
+
export interface ProtocolWriteError extends BaseOwnerError {
|
|
281
277
|
readonly type: "ProtocolWriteError";
|
|
282
278
|
}
|
|
283
279
|
/**
|
|
284
|
-
* Error
|
|
285
|
-
*
|
|
280
|
+
* Error when storage or billing quota is exceeded.
|
|
281
|
+
*
|
|
282
|
+
* When relay rejects writes due to quota, the affected device stops syncing
|
|
283
|
+
* because RBSR requires both sides to convergeβif the relay won't accept the
|
|
284
|
+
* client's data, they can never reach the same state. Only the device with
|
|
285
|
+
* excess local data is affected. Other devices that haven't exceeded quota can
|
|
286
|
+
* still sync normally.
|
|
287
|
+
*
|
|
288
|
+
* Clients should prompt the user to upgrade their plan.
|
|
286
289
|
*/
|
|
287
|
-
export interface
|
|
288
|
-
readonly type: "
|
|
290
|
+
export interface ProtocolQuotaError extends BaseOwnerError {
|
|
291
|
+
readonly type: "ProtocolQuotaError";
|
|
289
292
|
}
|
|
290
293
|
/**
|
|
291
|
-
* Error
|
|
292
|
-
*
|
|
293
|
-
*
|
|
294
|
-
* TODO: Add callback to relay config to check quota and return this error when
|
|
295
|
-
* limits are reached.
|
|
294
|
+
* Error indicating a serious relay-side synchronization failure. Clients should
|
|
295
|
+
* log this error and show a generic sync error to the user.
|
|
296
296
|
*/
|
|
297
|
-
export interface
|
|
298
|
-
readonly type: "
|
|
297
|
+
export interface ProtocolSyncError extends BaseOwnerError {
|
|
298
|
+
readonly type: "ProtocolSyncError";
|
|
299
299
|
}
|
|
300
300
|
/**
|
|
301
301
|
* Error when embedded timestamp doesn't match expected timestamp in
|
|
@@ -359,9 +359,9 @@ export interface TimestampsBuffer {
|
|
|
359
359
|
export declare const createTimestampsBuffer: () => TimestampsBuffer;
|
|
360
360
|
export interface ApplyProtocolMessageAsClientOptions {
|
|
361
361
|
getWriteKey?: (ownerId: OwnerId) => OwnerWriteKey | null;
|
|
362
|
-
/** For testing purposes only; should not be used in production. */
|
|
363
|
-
version?: NonNegativeInt;
|
|
364
362
|
rangesMaxSize?: ProtocolMessageRangesMaxSize;
|
|
363
|
+
/** For tests only. */
|
|
364
|
+
version?: NonNegativeInt;
|
|
365
365
|
}
|
|
366
366
|
/**
|
|
367
367
|
* Result type for {@link applyProtocolMessageAsClient} that distinguishes
|
|
@@ -375,7 +375,7 @@ export type ApplyProtocolMessageAsClientResult = {
|
|
|
375
375
|
} | {
|
|
376
376
|
readonly type: "broadcast";
|
|
377
377
|
};
|
|
378
|
-
export declare const applyProtocolMessageAsClient: (deps: StorageDep) => (inputMessage: Uint8Array, options?: ApplyProtocolMessageAsClientOptions) => Promise<Result<ApplyProtocolMessageAsClientResult, ProtocolInvalidDataError | ProtocolSyncError |
|
|
378
|
+
export declare const applyProtocolMessageAsClient: (deps: StorageDep) => (inputMessage: Uint8Array, options?: ApplyProtocolMessageAsClientOptions) => Promise<Result<ApplyProtocolMessageAsClientResult, ProtocolInvalidDataError | ProtocolSyncError | ProtocolVersionError | ProtocolWriteError | ProtocolWriteKeyError | ProtocolQuotaError>>;
|
|
379
379
|
export interface ApplyProtocolMessageAsRelayOptions {
|
|
380
380
|
/** To subscribe an owner for broadcasting. */
|
|
381
381
|
subscribe?: (ownerId: OwnerId) => void;
|
|
@@ -400,7 +400,7 @@ export interface ApplyProtocolMessageAsRelayResult {
|
|
|
400
400
|
readonly message: ProtocolMessage;
|
|
401
401
|
}
|
|
402
402
|
export declare const applyProtocolMessageAsRelay: (deps: StorageDep) => (inputMessage: Uint8Array, options?: ApplyProtocolMessageAsRelayOptions,
|
|
403
|
-
/** For
|
|
403
|
+
/** For tests only. */
|
|
404
404
|
version?: number & Brand<"Int"> & Brand<"NonNegative">) => Promise<Result<ApplyProtocolMessageAsRelayResult, ProtocolInvalidDataError>>;
|
|
405
405
|
/**
|
|
406
406
|
* Evolu uses MessagePack to handle all number variants except for
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Protocol.d.ts","sourceRoot":"","sources":["../../../src/Evolu/Protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgKG;
|
|
1
|
+
{"version":3,"file":"Protocol.d.ts","sourceRoot":"","sources":["../../../src/Evolu/Protocol.ts"],"names":[],"mappings":"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"}
|