@evolu/common 6.0.1-preview.2 → 6.0.1-preview.20
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/Assert.d.ts +6 -3
- package/dist/src/Assert.d.ts.map +1 -1
- package/dist/src/Assert.js +7 -4
- package/dist/src/Brand.d.ts +75 -0
- package/dist/src/Brand.d.ts.map +1 -0
- package/dist/src/Brand.js +1 -0
- package/dist/src/Buffer.d.ts +1 -1
- package/dist/src/Buffer.d.ts.map +1 -1
- package/dist/src/Buffer.js +1 -1
- package/dist/src/CallbackRegistry.d.ts +53 -0
- package/dist/src/CallbackRegistry.d.ts.map +1 -0
- package/dist/src/CallbackRegistry.js +25 -0
- package/dist/src/Console.d.ts +31 -6
- package/dist/src/Console.d.ts.map +1 -1
- package/dist/src/Console.js +72 -9
- package/dist/src/Crypto.d.ts +61 -34
- package/dist/src/Crypto.d.ts.map +1 -1
- package/dist/src/Crypto.js +29 -42
- package/dist/src/Evolu/Db.d.ts +137 -66
- package/dist/src/Evolu/Db.d.ts.map +1 -1
- package/dist/src/Evolu/Db.js +300 -705
- package/dist/src/Evolu/Diff.d.ts +3 -3
- package/dist/src/Evolu/Diff.d.ts.map +1 -1
- package/dist/src/Evolu/Diff.js +7 -5
- package/dist/src/Evolu/Evolu.d.ts +200 -115
- package/dist/src/Evolu/Evolu.d.ts.map +1 -1
- package/dist/src/Evolu/Evolu.js +287 -157
- package/dist/src/Evolu/Internal.d.ts +0 -2
- package/dist/src/Evolu/Internal.d.ts.map +1 -1
- package/dist/src/Evolu/Internal.js +0 -2
- package/dist/src/Evolu/LocalAuth.d.ts +144 -0
- package/dist/src/Evolu/LocalAuth.d.ts.map +1 -0
- package/dist/src/Evolu/LocalAuth.js +171 -0
- package/dist/src/Evolu/Owner.d.ts +152 -127
- package/dist/src/Evolu/Owner.d.ts.map +1 -1
- package/dist/src/Evolu/Owner.js +88 -107
- package/dist/src/Evolu/Platform.d.ts +9 -7
- package/dist/src/Evolu/Platform.d.ts.map +1 -1
- package/dist/src/Evolu/Protocol.d.ts +170 -186
- package/dist/src/Evolu/Protocol.d.ts.map +1 -1
- package/dist/src/Evolu/Protocol.js +487 -343
- package/dist/src/Evolu/Public.d.ts +6 -8
- package/dist/src/Evolu/Public.d.ts.map +1 -1
- package/dist/src/Evolu/Public.js +2 -3
- package/dist/src/Evolu/PublicKysely.js +3 -3
- package/dist/src/Evolu/Query.d.ts +2 -1
- package/dist/src/Evolu/Query.d.ts.map +1 -1
- package/dist/src/Evolu/Relay.d.ts +4 -3
- package/dist/src/Evolu/Relay.d.ts.map +1 -1
- package/dist/src/Evolu/Relay.js +50 -12
- package/dist/src/Evolu/Schema.d.ts +129 -73
- package/dist/src/Evolu/Schema.d.ts.map +1 -1
- package/dist/src/Evolu/Schema.js +169 -89
- package/dist/src/Evolu/Storage.d.ts +159 -14
- package/dist/src/Evolu/Storage.d.ts.map +1 -1
- package/dist/src/Evolu/Storage.js +42 -32
- package/dist/src/Evolu/Sync.d.ts +77 -13
- package/dist/src/Evolu/Sync.d.ts.map +1 -1
- package/dist/src/Evolu/Sync.js +453 -20
- package/dist/src/Evolu/Timestamp.d.ts +35 -27
- package/dist/src/Evolu/Timestamp.d.ts.map +1 -1
- package/dist/src/Evolu/Timestamp.js +27 -18
- package/dist/src/ManyToManyMap.d.ts +74 -10
- package/dist/src/ManyToManyMap.d.ts.map +1 -1
- package/dist/src/ManyToManyMap.js +41 -6
- package/dist/src/Number.d.ts +2 -1
- package/dist/src/Number.d.ts.map +1 -1
- package/dist/src/Random.d.ts +3 -2
- package/dist/src/Random.d.ts.map +1 -1
- package/dist/src/RefCountedResourceManager.d.ts +119 -0
- package/dist/src/RefCountedResourceManager.d.ts.map +1 -0
- package/dist/src/RefCountedResourceManager.js +197 -0
- package/dist/src/Result.d.ts +147 -51
- package/dist/src/Result.d.ts.map +1 -1
- package/dist/src/Result.js +7 -241
- package/dist/src/Sqlite.d.ts +21 -4
- package/dist/src/Sqlite.d.ts.map +1 -1
- package/dist/src/Sqlite.js +50 -8
- package/dist/src/Task.d.ts +511 -0
- package/dist/src/Task.d.ts.map +1 -0
- package/dist/src/Task.js +410 -0
- package/dist/src/Time.d.ts +59 -0
- package/dist/src/Time.d.ts.map +1 -1
- package/dist/src/Time.js +87 -4
- package/dist/src/Type.d.ts +462 -327
- package/dist/src/Type.d.ts.map +1 -1
- package/dist/src/Type.js +490 -436
- package/dist/src/Types.d.ts +0 -74
- package/dist/src/Types.d.ts.map +1 -1
- package/dist/src/WebSocket.d.ts +5 -2
- package/dist/src/WebSocket.d.ts.map +1 -1
- package/dist/src/WebSocket.js +12 -13
- package/dist/src/Worker.d.ts +39 -11
- package/dist/src/Worker.d.ts.map +1 -1
- package/dist/src/Worker.js +22 -4
- package/dist/src/index.d.ts +3 -3
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +3 -3
- package/package.json +14 -13
- package/src/Assert.ts +8 -7
- package/src/Brand.ts +75 -0
- package/src/Buffer.ts +1 -1
- package/src/CallbackRegistry.ts +84 -0
- package/src/Console.ts +91 -11
- package/src/Crypto.ts +94 -79
- package/src/Evolu/Db.ts +505 -1027
- package/src/Evolu/Diff.ts +7 -5
- package/src/Evolu/Evolu.ts +682 -329
- package/src/Evolu/Internal.ts +0 -2
- package/src/Evolu/LocalAuth.ts +422 -0
- package/src/Evolu/Owner.ts +221 -235
- package/src/Evolu/Platform.ts +9 -9
- package/src/Evolu/Protocol.ts +681 -614
- package/src/Evolu/Public.ts +7 -14
- package/src/Evolu/PublicKysely.ts +3 -3
- package/src/Evolu/Query.ts +2 -1
- package/src/Evolu/Relay.ts +62 -16
- package/src/Evolu/Schema.ts +391 -191
- package/src/Evolu/Storage.ts +275 -55
- package/src/Evolu/Sync.ts +758 -37
- package/src/Evolu/Timestamp.ts +38 -35
- package/src/ManyToManyMap.ts +127 -24
- package/src/Number.ts +2 -6
- package/src/Random.ts +3 -2
- package/src/RefCountedResourceManager.ts +368 -0
- package/src/Result.ts +152 -53
- package/src/Sqlite.ts +59 -23
- package/src/Task.ts +779 -0
- package/src/Time.ts +168 -4
- package/src/Type.ts +696 -660
- package/src/Types.ts +0 -76
- package/src/WebSocket.ts +23 -17
- package/src/Worker.ts +72 -23
- package/src/index.ts +3 -3
- package/dist/src/Callbacks.d.ts +0 -20
- package/dist/src/Callbacks.d.ts.map +0 -1
- package/dist/src/Callbacks.js +0 -18
- package/dist/src/Evolu/Config.d.ts +0 -69
- package/dist/src/Evolu/Config.d.ts.map +0 -1
- package/dist/src/Evolu/Config.js +0 -9
- package/dist/src/Evolu/Kysely.d.ts +0 -6
- package/dist/src/Evolu/Kysely.d.ts.map +0 -1
- package/dist/src/Evolu/Kysely.js +0 -21
- package/dist/src/NanoId.d.ts +0 -27
- package/dist/src/NanoId.d.ts.map +0 -1
- package/dist/src/NanoId.js +0 -6
- package/dist/src/Promise.d.ts +0 -180
- package/dist/src/Promise.d.ts.map +0 -1
- package/dist/src/Promise.js +0 -176
- package/src/Callbacks.ts +0 -43
- package/src/Evolu/Config.ts +0 -83
- package/src/Evolu/Kysely.ts +0 -38
- package/src/NanoId.ts +0 -39
- package/src/Promise.ts +0 -295
|
@@ -3,33 +3,54 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Evolu Protocol is a local-first, end-to-end encrypted binary synchronization
|
|
5
5
|
* protocol optimized for minimal size and maximum speed. It enables data sync
|
|
6
|
-
* between a client and a relay
|
|
7
|
-
*
|
|
6
|
+
* between a client and a relay. In the future, direct peer-to-peer (P2P) sync
|
|
7
|
+
* between clients will be possible without a relay.
|
|
8
|
+
*
|
|
9
|
+
* Relays don't need to sync with each other—clients using those relays will
|
|
10
|
+
* sync them eventually. If a relay is offline (e.g., for maintenance), it will
|
|
11
|
+
* sync automatically later via client sync logic. For relay backup using
|
|
12
|
+
* SQLite, see https://sqlite.org/rsync.html (uses a similar algorithm to Evolu
|
|
13
|
+
* RBSR).
|
|
8
14
|
*
|
|
9
15
|
* Evolu Protocol is designed for SQLite but can be extended to any database. It
|
|
10
16
|
* implements [Range-Based Set
|
|
11
17
|
* Reconciliation](https://arxiv.org/abs/2212.13567). To learn how RBSR works,
|
|
12
18
|
* check [Negentropy](https://logperiodic.com/rbsr.html). Evolu Protocol is
|
|
13
19
|
* similar to Negentropy but uses different encoding and also provides data
|
|
14
|
-
* transfer and
|
|
20
|
+
* transfer, ownership, real-time broadcasting, request-response semantics, and
|
|
21
|
+
* error handling.
|
|
15
22
|
*
|
|
16
23
|
* ### Message Structure
|
|
17
24
|
*
|
|
18
|
-
* | Field | Notes
|
|
19
|
-
* | :----------------------------- |
|
|
20
|
-
* | **Header** |
|
|
21
|
-
* | - {@link protocolVersion} |
|
|
22
|
-
* | - {@link OwnerId} |
|
|
23
|
-
* | - {@link
|
|
24
|
-
* | **
|
|
25
|
-
* | -
|
|
26
|
-
* | - {@link
|
|
27
|
-
* | - {@link
|
|
28
|
-
* | **
|
|
29
|
-
* | - {@link
|
|
30
|
-
* |
|
|
31
|
-
*
|
|
32
|
-
*
|
|
25
|
+
* | Field | Notes |
|
|
26
|
+
* | :----------------------------- | :------------------------ |
|
|
27
|
+
* | **Header** | |
|
|
28
|
+
* | - {@link protocolVersion} | |
|
|
29
|
+
* | - {@link OwnerId} | {@link Owner} |
|
|
30
|
+
* | - messageType | {@link MessageType} |
|
|
31
|
+
* | **Request (messageType=0)** | |
|
|
32
|
+
* | - hasWriteKey | 0 = no, 1 = yes |
|
|
33
|
+
* | - {@link OwnerWriteKey} | If hasWriteKey = 1 |
|
|
34
|
+
* | - subscriptionFlag | {@link SubscriptionFlags} |
|
|
35
|
+
* | **Response (messageType=1)** | |
|
|
36
|
+
* | - {@link ProtocolErrorCode} | |
|
|
37
|
+
* | **Broadcast (messageType=2)** | |
|
|
38
|
+
* | - (no additional fields) | |
|
|
39
|
+
* | **Messages** | |
|
|
40
|
+
* | - {@link NonNegativeInt} | A number of messages. |
|
|
41
|
+
* | - {@link EncryptedCrdtMessage} | |
|
|
42
|
+
* | **Ranges** | |
|
|
43
|
+
* | - {@link NonNegativeInt} | Number of ranges. |
|
|
44
|
+
* | - {@link Range} | |
|
|
45
|
+
*
|
|
46
|
+
* ### WriteKey Validation
|
|
47
|
+
*
|
|
48
|
+
* The initiator sends a hasWriteKey flag and optionally a WriteKey. The
|
|
49
|
+
* WriteKey is required when sending messages as a secure token proving the
|
|
50
|
+
* initiator can write changes. It's ok to not send a WriteKey if the initiator
|
|
51
|
+
* is only syncing (read-only) and not sending messages. The non-initiator
|
|
52
|
+
* validates the WriteKey immediately after parsing the initiator header, before
|
|
53
|
+
* processing any messages or ranges.
|
|
33
54
|
*
|
|
34
55
|
* ### Synchronization
|
|
35
56
|
*
|
|
@@ -43,16 +64,20 @@
|
|
|
43
64
|
* if further sync is needed or possible, continuing until both sides are
|
|
44
65
|
* synchronized.
|
|
45
66
|
*
|
|
67
|
+
* The **non-initiator always responds** to provide sync completion feedback,
|
|
68
|
+
* even with empty messages containing only the header and no error. This allows
|
|
69
|
+
* the initiator to detect when synchronization is complete.
|
|
70
|
+
*
|
|
46
71
|
* Both **Messages** and **Ranges** are optional, allowing each side to send,
|
|
47
72
|
* sync, or only subscribe data as needed.
|
|
48
73
|
*
|
|
49
|
-
* When the initiator sends data, the {@link
|
|
50
|
-
*
|
|
51
|
-
* responds without a {@link
|
|
52
|
-
* signals it wants data. If the non-initiator detects an issue, it
|
|
53
|
-
* error code via the `Error` field in the header back to the
|
|
54
|
-
* relay-to-relay or P2P sync, both sides may require the
|
|
55
|
-
* depending on who is the initiator.
|
|
74
|
+
* When the initiator sends data, the {@link OwnerWriteKey} is required as a
|
|
75
|
+
* secure token proving the initiator can write changes. The non-initiator
|
|
76
|
+
* responds without a {@link OwnerWriteKey}, since the initiator’s request
|
|
77
|
+
* already signals it wants data. If the non-initiator detects an issue, it
|
|
78
|
+
* sends an error code via the `Error` field in the header back to the
|
|
79
|
+
* initiator. In relay-to-relay or P2P sync, both sides may require the
|
|
80
|
+
* {@link OwnerWriteKey} depending on who is the initiator.
|
|
56
81
|
*
|
|
57
82
|
* ### Protocol Errors
|
|
58
83
|
*
|
|
@@ -66,15 +91,21 @@
|
|
|
66
91
|
* - {@link ProtocolUnsupportedVersionError}: Protocol version mismatch.
|
|
67
92
|
* - {@link ProtocolInvalidDataError}: The message is malformed or corrupted.
|
|
68
93
|
*
|
|
69
|
-
* All protocol errors except `ProtocolInvalidDataError` include the `
|
|
94
|
+
* All protocol errors except `ProtocolInvalidDataError` include the `OwnerId`
|
|
70
95
|
* to allow clients to associate errors with the correct owner.
|
|
71
96
|
*
|
|
72
97
|
* ### Message Size Limit
|
|
73
98
|
*
|
|
74
99
|
* The protocol enforces a strict maximum size for all messages, defined by
|
|
75
100
|
* {@link maxProtocolMessageSize}. This ensures every {@link ProtocolMessage} is
|
|
76
|
-
* less than or equal to this limit,
|
|
77
|
-
*
|
|
101
|
+
* less than or equal to this limit, enabling stateless transports, simplified
|
|
102
|
+
* relay implementation, and predictable memory usage. When all messages don't
|
|
103
|
+
* fit within the limit, the protocol automatically continues synchronization in
|
|
104
|
+
* subsequent rounds using range-based reconciliation.
|
|
105
|
+
*
|
|
106
|
+
* Individual database mutations are limited to `maxMutationSize` (640KB), which
|
|
107
|
+
* is smaller than the protocol message limit to ensure efficient sync with
|
|
108
|
+
* {@link maxProtocolMessageRangesSize}.
|
|
78
109
|
*
|
|
79
110
|
* ### Why Binary?
|
|
80
111
|
*
|
|
@@ -82,13 +113,12 @@
|
|
|
82
113
|
*
|
|
83
114
|
* - Encrypted data doesn’t compress well, unlike plain JSON.
|
|
84
115
|
* - Message size must be controlled during creation.
|
|
85
|
-
* - Sequential byte reading is faster than parsing and
|
|
116
|
+
* - Sequential byte reading is faster than parsing and avoids conversions.
|
|
86
117
|
*
|
|
87
118
|
* It uses structure-aware encoding, significantly outperforming generic binary
|
|
88
119
|
* serialization formats with the following optimizations:
|
|
89
120
|
*
|
|
90
121
|
* - **NonNegativeInt:** Up to 33% smaller than MessagePack.
|
|
91
|
-
* - **Base64Url Strings:** Up to 25% size reduction.
|
|
92
122
|
* - **DateIso:** Up to 75% smaller.
|
|
93
123
|
* - **Timestamp Encoding:** Delta encoding for milliseconds and run-length
|
|
94
124
|
* encoding (RLE) for counters and NodeIds.
|
|
@@ -121,15 +151,15 @@
|
|
|
121
151
|
* @module
|
|
122
152
|
*/
|
|
123
153
|
import { NonEmptyReadonlyArray } from "../Array.js";
|
|
154
|
+
import { Brand } from "../Brand.js";
|
|
124
155
|
import { Buffer } from "../Buffer.js";
|
|
125
|
-
import {
|
|
126
|
-
import { ReadonlyRecord } from "../Object.js";
|
|
156
|
+
import { EncryptionKey, RandomBytesDep, SymmetricCryptoDecryptError, SymmetricCryptoDep } from "../Crypto.js";
|
|
127
157
|
import { Result } from "../Result.js";
|
|
128
158
|
import { SqliteValue } from "../Sqlite.js";
|
|
129
|
-
import {
|
|
130
|
-
import {
|
|
131
|
-
import {
|
|
132
|
-
import {
|
|
159
|
+
import { NonNegativeInt, PositiveInt } from "../Type.js";
|
|
160
|
+
import { Owner, OwnerId, OwnerWriteKey } from "./Owner.js";
|
|
161
|
+
import { BaseRange, CrdtMessage, DbChange, EncryptedCrdtMessage, EncryptedDbChange, FingerprintRange, RangeType, SkipRange, StorageDep } from "./Storage.js";
|
|
162
|
+
import { NodeId, Timestamp } from "./Timestamp.js";
|
|
133
163
|
/** Maximum size of the entire protocol message in bytes. */
|
|
134
164
|
export declare const maxProtocolMessageSize: PositiveInt;
|
|
135
165
|
/** Maximum size of the ranges in bytes. */
|
|
@@ -138,6 +168,24 @@ export declare const maxProtocolMessageRangesSize: PositiveInt;
|
|
|
138
168
|
export type ProtocolMessage = Uint8Array & Brand<"ProtocolMessage">;
|
|
139
169
|
/** Evolu Protocol version. */
|
|
140
170
|
export declare const protocolVersion: NonNegativeInt;
|
|
171
|
+
export declare const MessageType: {
|
|
172
|
+
/** Request message from initiator (client) to non-initiator (relay). */
|
|
173
|
+
readonly Request: 0;
|
|
174
|
+
/** Response message from non-initiator (relay) to initiator (client). */
|
|
175
|
+
readonly Response: 1;
|
|
176
|
+
/** Broadcast message from non-initiator (relay) to subscribed clients. */
|
|
177
|
+
readonly Broadcast: 2;
|
|
178
|
+
};
|
|
179
|
+
export type MessageType = (typeof MessageType)[keyof typeof MessageType];
|
|
180
|
+
export declare const SubscriptionFlags: {
|
|
181
|
+
/** No subscription changes for this owner. */
|
|
182
|
+
readonly None: 0;
|
|
183
|
+
/** Subscribe to updates for this owner. */
|
|
184
|
+
readonly Subscribe: 1;
|
|
185
|
+
/** Unsubscribe from updates for this owner. */
|
|
186
|
+
readonly Unsubscribe: 2;
|
|
187
|
+
};
|
|
188
|
+
export type SubscriptionFlag = (typeof SubscriptionFlags)[keyof typeof SubscriptionFlags];
|
|
141
189
|
export declare const ProtocolErrorCode: {
|
|
142
190
|
readonly NoError: 0;
|
|
143
191
|
/** A code for {@link ProtocolWriteKeyError}. */
|
|
@@ -148,110 +196,7 @@ export declare const ProtocolErrorCode: {
|
|
|
148
196
|
readonly SyncError: 3;
|
|
149
197
|
};
|
|
150
198
|
type ProtocolErrorCode = (typeof ProtocolErrorCode)[keyof typeof ProtocolErrorCode];
|
|
151
|
-
|
|
152
|
-
* Evolu Protocol Storage
|
|
153
|
-
*
|
|
154
|
-
* The protocol is agnostic to storage implementation details—any storage can be
|
|
155
|
-
* plugged in, as long as it implements this interface. Implementations must
|
|
156
|
-
* handle their own errors; return values only indicates overall success or
|
|
157
|
-
* failure.
|
|
158
|
-
*/
|
|
159
|
-
export interface Storage {
|
|
160
|
-
readonly getSize: (ownerId: BinaryOwnerId) => NonNegativeInt | null;
|
|
161
|
-
readonly fingerprint: (ownerId: BinaryOwnerId, begin: NonNegativeInt, end: NonNegativeInt) => Fingerprint | null;
|
|
162
|
-
/**
|
|
163
|
-
* Computes fingerprints with their upper bounds in one call.
|
|
164
|
-
*
|
|
165
|
-
* This function can be replaced with many fingerprint/findLowerBound calls,
|
|
166
|
-
* but implementations can leverage it for batching and more efficient
|
|
167
|
-
* fingerprint computation.
|
|
168
|
-
*/
|
|
169
|
-
readonly fingerprintRanges: (ownerId: BinaryOwnerId, buckets: ReadonlyArray<NonNegativeInt>, upperBound?: RangeUpperBound) => ReadonlyArray<FingerprintRange> | null;
|
|
170
|
-
readonly findLowerBound: (ownerId: BinaryOwnerId, begin: NonNegativeInt, end: NonNegativeInt, upperBound: RangeUpperBound) => NonNegativeInt | null;
|
|
171
|
-
readonly iterate: (ownerId: BinaryOwnerId, begin: NonNegativeInt, end: NonNegativeInt, callback: (timestamp: BinaryTimestamp, index: NonNegativeInt) => boolean) => void;
|
|
172
|
-
/**
|
|
173
|
-
* Authorizes the initiator's {@link WriteKey} for the given
|
|
174
|
-
* {@link BinaryOwnerId}.
|
|
175
|
-
*
|
|
176
|
-
* For a client that does not expect foreign writes, return `false`.
|
|
177
|
-
*/
|
|
178
|
-
readonly validateWriteKey: (ownerId: BinaryOwnerId, writeKey: WriteKey) => boolean;
|
|
179
|
-
/** Write encrypted {@link CrdtMessage}s to storage. */
|
|
180
|
-
readonly writeMessages: (ownerId: BinaryOwnerId, messages: NonEmptyReadonlyArray<EncryptedCrdtMessage>) => boolean;
|
|
181
|
-
/** Read encrypted {@link DbChange}s from storage. */
|
|
182
|
-
readonly readDbChange: (ownerId: BinaryOwnerId, timestamp: BinaryTimestamp) => EncryptedDbChange | null;
|
|
183
|
-
}
|
|
184
|
-
export interface StorageDep {
|
|
185
|
-
readonly storage: Storage;
|
|
186
|
-
}
|
|
187
|
-
/** An encrypted {@link CrdtMessage}. */
|
|
188
|
-
export interface EncryptedCrdtMessage {
|
|
189
|
-
readonly timestamp: Timestamp;
|
|
190
|
-
readonly change: EncryptedDbChange;
|
|
191
|
-
}
|
|
192
|
-
/** Encrypted DbChange */
|
|
193
|
-
export type EncryptedDbChange = Uint8Array & Brand<"EncryptedDbChange">;
|
|
194
|
-
/**
|
|
195
|
-
* A CRDT message that combines a unique {@link Timestamp} with a
|
|
196
|
-
* {@link DbChange}.
|
|
197
|
-
*/
|
|
198
|
-
export interface CrdtMessage {
|
|
199
|
-
readonly timestamp: Timestamp;
|
|
200
|
-
readonly change: DbChange;
|
|
201
|
-
}
|
|
202
|
-
/**
|
|
203
|
-
* A DbChange is a change to a table row. Together with a unique
|
|
204
|
-
* {@link Timestamp}, it forms a {@link CrdtMessage}.
|
|
205
|
-
*/
|
|
206
|
-
export interface DbChange {
|
|
207
|
-
readonly table: Base64Url256;
|
|
208
|
-
readonly id: Id;
|
|
209
|
-
readonly values: ReadonlyRecord<Base64Url256, SqliteValue>;
|
|
210
|
-
}
|
|
211
|
-
export declare const RangeType: {
|
|
212
|
-
readonly Fingerprint: 1;
|
|
213
|
-
readonly Skip: 0;
|
|
214
|
-
readonly Timestamps: 2;
|
|
215
|
-
};
|
|
216
|
-
export type RangeType = (typeof RangeType)[keyof typeof RangeType];
|
|
217
|
-
export declare const InfiniteUpperBound: unique symbol;
|
|
218
|
-
export type InfiniteUpperBound = typeof InfiniteUpperBound;
|
|
219
|
-
/**
|
|
220
|
-
* Union type for Range's upperBound: either a {@link BinaryTimestamp} or
|
|
221
|
-
* {@link InfiniteUpperBound}.
|
|
222
|
-
*/
|
|
223
|
-
export type RangeUpperBound = BinaryTimestamp | InfiniteUpperBound;
|
|
224
|
-
interface BaseRange {
|
|
225
|
-
readonly upperBound: RangeUpperBound;
|
|
226
|
-
}
|
|
227
|
-
export interface SkipRange extends BaseRange {
|
|
228
|
-
readonly type: typeof RangeType.Skip;
|
|
229
|
-
}
|
|
230
|
-
export interface FingerprintRange extends BaseRange {
|
|
231
|
-
readonly type: typeof RangeType.Fingerprint;
|
|
232
|
-
readonly fingerprint: Fingerprint;
|
|
233
|
-
}
|
|
234
|
-
/**
|
|
235
|
-
* A cryptographic hash used for efficiently comparing collections of
|
|
236
|
-
* {@link BinaryTimestamp}s.
|
|
237
|
-
*
|
|
238
|
-
* It consists of the first {@link fingerprintSize} bytes of the SHA-256 hash of
|
|
239
|
-
* one or more timestamps.
|
|
240
|
-
*/
|
|
241
|
-
export type Fingerprint = Uint8Array & Brand<"Fingerprint">;
|
|
242
|
-
export declare const fingerprintSize: NonNegativeInt;
|
|
243
|
-
/** A fingerprint of an empty range. */
|
|
244
|
-
export declare const zeroFingerprint: Fingerprint;
|
|
245
|
-
export interface TimestampsRange extends BaseRange {
|
|
246
|
-
readonly type: typeof RangeType.Timestamps;
|
|
247
|
-
readonly timestamps: ReadonlyArray<BinaryTimestamp>;
|
|
248
|
-
}
|
|
249
|
-
export interface TimestampsRangeWithTimestampsBuffer extends BaseRange {
|
|
250
|
-
readonly type: typeof RangeType.Timestamps;
|
|
251
|
-
readonly timestamps: TimestampsBuffer;
|
|
252
|
-
}
|
|
253
|
-
export type Range = SkipRange | FingerprintRange | TimestampsRange;
|
|
254
|
-
export type ProtocolError = ProtocolUnsupportedVersionError | ProtocolInvalidDataError | ProtocolWriteKeyError | ProtocolWriteError | ProtocolSyncError;
|
|
199
|
+
export type ProtocolError = ProtocolUnsupportedVersionError | ProtocolInvalidDataError | ProtocolWriteKeyError | ProtocolWriteError | ProtocolSyncError | ProtocolTimestampMismatchError;
|
|
255
200
|
/** Base interface for all protocol errors. */
|
|
256
201
|
export interface ProtocolErrorBase {
|
|
257
202
|
readonly ownerId: OwnerId;
|
|
@@ -272,7 +217,7 @@ export interface ProtocolInvalidDataError {
|
|
|
272
217
|
readonly data: globalThis.Uint8Array;
|
|
273
218
|
readonly error: unknown;
|
|
274
219
|
}
|
|
275
|
-
/** Error when a {@link
|
|
220
|
+
/** Error when a {@link OwnerWriteKey} is invalid, missing, or fails validation. */
|
|
276
221
|
export interface ProtocolWriteKeyError extends ProtocolErrorBase {
|
|
277
222
|
readonly type: "ProtocolWriteKeyError";
|
|
278
223
|
}
|
|
@@ -290,6 +235,16 @@ export interface ProtocolWriteError extends ProtocolErrorBase {
|
|
|
290
235
|
export interface ProtocolSyncError extends ProtocolErrorBase {
|
|
291
236
|
readonly type: "ProtocolSyncError";
|
|
292
237
|
}
|
|
238
|
+
/**
|
|
239
|
+
* Error when embedded timestamp doesn't match expected timestamp in
|
|
240
|
+
* EncryptedDbChange. Indicates potential tampering or corruption of CRDT
|
|
241
|
+
* messages.
|
|
242
|
+
*/
|
|
243
|
+
export interface ProtocolTimestampMismatchError {
|
|
244
|
+
readonly type: "ProtocolTimestampMismatchError";
|
|
245
|
+
readonly expected: Timestamp;
|
|
246
|
+
readonly embedded: Timestamp;
|
|
247
|
+
}
|
|
293
248
|
/**
|
|
294
249
|
* Creates a {@link ProtocolMessage} from CRDT messages.
|
|
295
250
|
*
|
|
@@ -297,9 +252,10 @@ export interface ProtocolSyncError extends ProtocolErrorBase {
|
|
|
297
252
|
* ensures all messages will be sent in the next round(s) even over
|
|
298
253
|
* unidirectional and stateless transports.
|
|
299
254
|
*/
|
|
300
|
-
export declare const createProtocolMessageFromCrdtMessages: (deps:
|
|
255
|
+
export declare const createProtocolMessageFromCrdtMessages: (deps: RandomBytesDep & SymmetricCryptoDep) => (owner: Owner, messages: NonEmptyReadonlyArray<CrdtMessage>, maxSize?: PositiveInt) => ProtocolMessage;
|
|
301
256
|
/** Creates a {@link ProtocolMessage} for sync. */
|
|
302
|
-
export declare const createProtocolMessageForSync: (deps: StorageDep) => (ownerId: OwnerId) => ProtocolMessage | null;
|
|
257
|
+
export declare const createProtocolMessageForSync: (deps: StorageDep) => (ownerId: OwnerId, subscriptionFlag?: SubscriptionFlag) => ProtocolMessage | null;
|
|
258
|
+
export declare const createProtocolMessageForUnsubscribe: (ownerId: OwnerId) => ProtocolMessage;
|
|
303
259
|
/**
|
|
304
260
|
* Mutable builder for constructing {@link ProtocolMessage} respecting size
|
|
305
261
|
* limits.
|
|
@@ -313,13 +269,24 @@ export interface ProtocolMessageBuffer {
|
|
|
313
269
|
readonly unwrap: () => ProtocolMessage;
|
|
314
270
|
readonly getSize: () => PositiveInt;
|
|
315
271
|
}
|
|
316
|
-
export declare const createProtocolMessageBuffer: (ownerId: OwnerId, options
|
|
317
|
-
readonly errorCode?: ProtocolErrorCode;
|
|
318
|
-
readonly writeKey?: WriteKey;
|
|
272
|
+
export declare const createProtocolMessageBuffer: (ownerId: OwnerId, options: {
|
|
319
273
|
readonly totalMaxSize?: PositiveInt | undefined;
|
|
320
274
|
readonly rangesMaxSize?: PositiveInt | undefined;
|
|
321
275
|
readonly version?: NonNegativeInt;
|
|
322
|
-
}
|
|
276
|
+
} & ({
|
|
277
|
+
readonly messageType: typeof MessageType.Request;
|
|
278
|
+
readonly writeKey?: OwnerWriteKey;
|
|
279
|
+
readonly subscriptionFlag?: SubscriptionFlag;
|
|
280
|
+
} | {
|
|
281
|
+
readonly messageType: typeof MessageType.Response;
|
|
282
|
+
readonly errorCode: ProtocolErrorCode;
|
|
283
|
+
} | {
|
|
284
|
+
readonly messageType: typeof MessageType.Broadcast;
|
|
285
|
+
})) => ProtocolMessageBuffer;
|
|
286
|
+
export interface TimestampsRangeWithTimestampsBuffer extends BaseRange {
|
|
287
|
+
readonly type: typeof RangeType.Timestamps;
|
|
288
|
+
readonly timestamps: TimestampsBuffer;
|
|
289
|
+
}
|
|
323
290
|
export interface TimestampsBuffer {
|
|
324
291
|
readonly add: (timestamp: Timestamp) => void;
|
|
325
292
|
readonly addInfinite: () => void;
|
|
@@ -329,67 +296,72 @@ export interface TimestampsBuffer {
|
|
|
329
296
|
}
|
|
330
297
|
export declare const createTimestampsBuffer: () => TimestampsBuffer;
|
|
331
298
|
export interface ApplyProtocolMessageAsClientOptions {
|
|
332
|
-
getWriteKey?: (ownerId: OwnerId) =>
|
|
299
|
+
getWriteKey?: (ownerId: OwnerId) => OwnerWriteKey | null;
|
|
333
300
|
/** For testing purposes only; should not be used in production. */
|
|
334
301
|
version?: NonNegativeInt;
|
|
335
302
|
totalMaxSize?: PositiveInt;
|
|
336
303
|
rangesMaxSize?: PositiveInt;
|
|
337
304
|
}
|
|
338
|
-
|
|
305
|
+
/**
|
|
306
|
+
* Result type for {@link applyProtocolMessageAsClient} that distinguishes
|
|
307
|
+
* between responses to client requests and broadcast messages.
|
|
308
|
+
*/
|
|
309
|
+
export type ApplyProtocolMessageAsClientResult = {
|
|
310
|
+
readonly type: "response";
|
|
311
|
+
readonly message: ProtocolMessage;
|
|
312
|
+
} | {
|
|
313
|
+
readonly type: "no-response";
|
|
314
|
+
} | {
|
|
315
|
+
readonly type: "broadcast";
|
|
316
|
+
};
|
|
317
|
+
export declare const applyProtocolMessageAsClient: (deps: StorageDep) => (inputMessage: Uint8Array, options?: ApplyProtocolMessageAsClientOptions) => Promise<Result<ApplyProtocolMessageAsClientResult, ProtocolInvalidDataError | ProtocolSyncError | ProtocolUnsupportedVersionError | ProtocolWriteError | ProtocolWriteKeyError>>;
|
|
339
318
|
export interface ApplyProtocolMessageAsRelayOptions {
|
|
340
319
|
/** To subscribe an owner for broadcasting. */
|
|
341
320
|
subscribe?: (ownerId: OwnerId) => void;
|
|
321
|
+
/** To unsubscribe an owner from broadcasting. */
|
|
322
|
+
unsubscribe?: (ownerId: OwnerId) => void;
|
|
342
323
|
/** To broadcast a protocol message to all subscribers. */
|
|
343
324
|
broadcast?: (ownerId: OwnerId, message: ProtocolMessage) => void;
|
|
344
325
|
totalMaxSize?: PositiveInt;
|
|
345
326
|
rangesMaxSize?: PositiveInt;
|
|
346
327
|
}
|
|
347
|
-
export declare const applyProtocolMessageAsRelay: (deps: StorageDep) => (inputMessage: Uint8Array, { subscribe, broadcast, totalMaxSize, rangesMaxSize, }?: ApplyProtocolMessageAsRelayOptions,
|
|
348
|
-
/** For testing purposes only; should not be used in production. */
|
|
349
|
-
version?: number & Brand<"Int"> & Brand<"NonNegative">) => Result<ProtocolMessage | null, ProtocolInvalidDataError>;
|
|
350
|
-
/** Binary representation of {@link Id}. */
|
|
351
|
-
export type BinaryId = Uint8Array & Brand<"BinaryId">;
|
|
352
|
-
export declare const binaryIdLength: NonNegativeInt;
|
|
353
|
-
export declare const idToBinaryId: (id: Id) => BinaryId;
|
|
354
|
-
export declare const binaryIdToId: (binaryId: BinaryId) => Id;
|
|
355
|
-
/** Binary representation of {@link OwnerId}. */
|
|
356
|
-
export type BinaryOwnerId = Uint8Array & Brand<"BinaryOwnerId">;
|
|
357
|
-
export declare const ownerIdToBinaryOwnerId: (ownerId: OwnerId) => BinaryOwnerId;
|
|
358
|
-
export declare const binaryOwnerIdToOwnerId: (binaryOwnerId: BinaryOwnerId) => OwnerId;
|
|
359
328
|
/**
|
|
360
|
-
*
|
|
361
|
-
*
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
*
|
|
367
|
-
* these types use Base64Url alphabet and are < 256 characters.
|
|
368
|
-
*/
|
|
369
|
-
export type Base64Url256Variant = Base64Url256 | Id | NanoId | OwnerId;
|
|
370
|
-
/**
|
|
371
|
-
* Converts a Base64Url string to a Uint8Array for binary storage. This encoding
|
|
372
|
-
* is more space-efficient than UTF-8 for Base64Url strings.
|
|
329
|
+
* Result type for {@link applyProtocolMessageAsRelay}.
|
|
330
|
+
*
|
|
331
|
+
* Unlike {@link ApplyProtocolMessageAsClientResult}, relays always respond with
|
|
332
|
+
* a message to provide sync completion feedback. This ensures the initiator can
|
|
333
|
+
* reliably detect when synchronization is complete, even when there's nothing
|
|
334
|
+
* to sync. Clients may choose not to respond in certain cases (like when they
|
|
335
|
+
* receive broadcast messages or when they lack a write key for syncing).
|
|
373
336
|
*/
|
|
374
|
-
export
|
|
375
|
-
|
|
337
|
+
export interface ApplyProtocolMessageAsRelayResult {
|
|
338
|
+
readonly type: "response";
|
|
339
|
+
readonly message: ProtocolMessage;
|
|
340
|
+
}
|
|
341
|
+
export declare const applyProtocolMessageAsRelay: (deps: StorageDep) => (inputMessage: Uint8Array, options?: ApplyProtocolMessageAsRelayOptions,
|
|
342
|
+
/** For testing purposes only; should not be used in production. */
|
|
343
|
+
version?: number & Brand<"Int"> & Brand<"NonNegative">) => Promise<Result<ApplyProtocolMessageAsRelayResult, ProtocolInvalidDataError>>;
|
|
376
344
|
/**
|
|
377
345
|
* Evolu uses MessagePack to handle all number variants except for
|
|
378
346
|
* NonNegativeInt. For NonNegativeInt, Evolu provides more efficient encoding.
|
|
379
347
|
*/
|
|
380
348
|
export declare const encodeNumber: (buffer: Buffer, number: number) => void;
|
|
381
349
|
export declare const decodeNumber: (buffer: Buffer) => number;
|
|
382
|
-
export declare const binaryTimestampToFingerprint: (timestamp: BinaryTimestamp) => Fingerprint;
|
|
383
350
|
/**
|
|
384
351
|
* Encodes and encrypts a {@link DbChange} using the provided owner's encryption
|
|
385
352
|
* key. Returns an encrypted binary representation as {@link EncryptedDbChange}.
|
|
353
|
+
*
|
|
354
|
+
* The format includes the protocol version for backward compatibility and the
|
|
355
|
+
* timestamp for tamper-proof verification that the timestamp matches the change
|
|
356
|
+
* data.
|
|
386
357
|
*/
|
|
387
|
-
export declare const encodeAndEncryptDbChange: (deps: SymmetricCryptoDep) => (
|
|
358
|
+
export declare const encodeAndEncryptDbChange: (deps: SymmetricCryptoDep) => (message: CrdtMessage, key: EncryptionKey) => EncryptedDbChange;
|
|
388
359
|
/**
|
|
389
|
-
* Decrypts and decodes an {@link
|
|
390
|
-
* encryption key.
|
|
360
|
+
* Decrypts and decodes an {@link EncryptedCrdtMessage} using the provided
|
|
361
|
+
* owner's encryption key. Verifies that the embedded timestamp matches the
|
|
362
|
+
* expected timestamp to ensure message integrity.
|
|
391
363
|
*/
|
|
392
|
-
export declare const decryptAndDecodeDbChange: (deps: SymmetricCryptoDep) => (
|
|
364
|
+
export declare const decryptAndDecodeDbChange: (deps: SymmetricCryptoDep) => (message: EncryptedCrdtMessage, key: EncryptionKey) => Result<DbChange, SymmetricCryptoDecryptError | ProtocolInvalidDataError | ProtocolTimestampMismatchError>;
|
|
393
365
|
/**
|
|
394
366
|
* Encodes a non-negative integer into a variable-length integer format. It's
|
|
395
367
|
* more efficient than encoding via {@link encodeNumber}.
|
|
@@ -409,21 +381,33 @@ export declare const encodeString: (buffer: Buffer, value: string) => void;
|
|
|
409
381
|
export declare const decodeString: (buffer: Buffer) => string;
|
|
410
382
|
export declare const encodeNodeId: (buffer: Buffer, nodeId: NodeId) => void;
|
|
411
383
|
export declare const decodeNodeId: (buffer: Buffer) => NodeId;
|
|
412
|
-
export declare const encodeBase64Url256: (buffer: Buffer, string: Base64Url256Variant) => void;
|
|
413
|
-
export declare const decodeBase64Url256WithLength: (buffer: Buffer) => Base64Url256;
|
|
414
384
|
export declare const ProtocolValueType: {
|
|
415
385
|
readonly String: NonNegativeInt;
|
|
416
386
|
readonly Number: NonNegativeInt;
|
|
417
387
|
readonly Null: NonNegativeInt;
|
|
418
|
-
readonly
|
|
419
|
-
readonly Id: NonNegativeInt;
|
|
420
|
-
readonly Base64Url256: NonNegativeInt;
|
|
388
|
+
readonly Bytes: NonNegativeInt;
|
|
421
389
|
readonly NonNegativeInt: NonNegativeInt;
|
|
390
|
+
readonly EmptyString: NonNegativeInt;
|
|
391
|
+
readonly Base64Url: NonNegativeInt;
|
|
392
|
+
readonly Id: NonNegativeInt;
|
|
422
393
|
readonly Json: NonNegativeInt;
|
|
423
394
|
readonly DateIsoWithNonNegativeTime: NonNegativeInt;
|
|
424
395
|
readonly DateIsoWithNegativeTime: NonNegativeInt;
|
|
425
396
|
};
|
|
426
397
|
export declare const encodeSqliteValue: (buffer: Buffer, value: SqliteValue) => void;
|
|
427
398
|
export declare const decodeSqliteValue: (buffer: Buffer) => SqliteValue;
|
|
399
|
+
/**
|
|
400
|
+
* Decodes a ProtocolMessage into a readable JSON object for debugging.
|
|
401
|
+
*
|
|
402
|
+
* Note: This is a stub for future implementation. It should use:
|
|
403
|
+
*
|
|
404
|
+
* - DecodeVersionAndOwner
|
|
405
|
+
* - DecodeError or decodeWriteKeys (depending on context)
|
|
406
|
+
* - DecodeMessages
|
|
407
|
+
* - DecodeRanges
|
|
408
|
+
*
|
|
409
|
+
* If you want to help, please contribute to this function.
|
|
410
|
+
*/
|
|
411
|
+
export declare const decodeProtocolMessageToJson: (_protocolMessage: ProtocolMessage, _isInitiator: boolean) => unknown;
|
|
428
412
|
export {};
|
|
429
413
|
//# sourceMappingURL=Protocol.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Protocol.d.ts","sourceRoot":"","sources":["../../../src/Evolu/Protocol.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Protocol.d.ts","sourceRoot":"","sources":["../../../src/Evolu/Protocol.ts"],"names":[],"mappings":"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"}
|