@evolu/common 8.2.0 → 8.3.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/Function.d.ts +1 -0
- package/dist/src/Function.d.ts.map +1 -1
- package/dist/src/Http.d.ts +9 -0
- package/dist/src/Http.d.ts.map +1 -1
- package/dist/src/Object.d.ts +1 -0
- package/dist/src/Object.d.ts.map +1 -1
- package/dist/src/RefCount.d.ts +1 -0
- package/dist/src/RefCount.d.ts.map +1 -1
- package/dist/src/Relation.d.ts +2 -0
- package/dist/src/Relation.d.ts.map +1 -1
- package/dist/src/Resource.d.ts +1 -0
- package/dist/src/Resource.d.ts.map +1 -1
- package/dist/src/Result.d.ts +383 -548
- package/dist/src/Result.d.ts.map +1 -1
- package/dist/src/Result.js +296 -46
- package/dist/src/StackTrace.d.ts +1 -0
- package/dist/src/StackTrace.d.ts.map +1 -1
- package/dist/src/Task.d.ts +985 -1069
- package/dist/src/Task.d.ts.map +1 -1
- package/dist/src/Task.js +1007 -156
- package/dist/src/Time.d.ts +1 -0
- package/dist/src/Time.d.ts.map +1 -1
- package/dist/src/Type.d.ts +1285 -734
- package/dist/src/Type.d.ts.map +1 -1
- package/dist/src/Type.js +1057 -193
- package/dist/src/intl/_en.d.ts +126 -0
- package/dist/src/intl/_en.d.ts.map +1 -0
- package/dist/src/intl/_en.js +267 -0
- package/dist/src/intl/ar.d.ts +117 -0
- package/dist/src/intl/ar.d.ts.map +1 -0
- package/dist/src/intl/ar.js +245 -0
- package/dist/src/intl/bn.d.ts +117 -0
- package/dist/src/intl/bn.d.ts.map +1 -0
- package/dist/src/intl/bn.js +258 -0
- package/dist/src/intl/ca.d.ts +117 -0
- package/dist/src/intl/ca.d.ts.map +1 -0
- package/dist/src/intl/ca.js +258 -0
- package/dist/src/intl/cs.d.ts +20 -7
- package/dist/src/intl/cs.d.ts.map +1 -1
- package/dist/src/intl/cs.js +54 -27
- package/dist/src/intl/da.d.ts +117 -0
- package/dist/src/intl/da.d.ts.map +1 -0
- package/dist/src/intl/da.js +258 -0
- package/dist/src/intl/de.d.ts +117 -0
- package/dist/src/intl/de.d.ts.map +1 -0
- package/dist/src/intl/de.js +258 -0
- package/dist/src/intl/el.d.ts +117 -0
- package/dist/src/intl/el.d.ts.map +1 -0
- package/dist/src/intl/el.js +265 -0
- package/dist/src/intl/es.d.ts +117 -0
- package/dist/src/intl/es.d.ts.map +1 -0
- package/dist/src/intl/es.js +258 -0
- package/dist/src/intl/fa.d.ts +117 -0
- package/dist/src/intl/fa.d.ts.map +1 -0
- package/dist/src/intl/fa.js +258 -0
- package/dist/src/intl/fi.d.ts +117 -0
- package/dist/src/intl/fi.d.ts.map +1 -0
- package/dist/src/intl/fi.js +258 -0
- package/dist/src/intl/fil.d.ts +117 -0
- package/dist/src/intl/fil.d.ts.map +1 -0
- package/dist/src/intl/fil.js +258 -0
- package/dist/src/intl/fr.d.ts +117 -0
- package/dist/src/intl/fr.d.ts.map +1 -0
- package/dist/src/intl/fr.js +258 -0
- package/dist/src/intl/he.d.ts +117 -0
- package/dist/src/intl/he.d.ts.map +1 -0
- package/dist/src/intl/he.js +258 -0
- package/dist/src/intl/hi.d.ts +117 -0
- package/dist/src/intl/hi.d.ts.map +1 -0
- package/dist/src/intl/hi.js +258 -0
- package/dist/src/intl/hr.d.ts +117 -0
- package/dist/src/intl/hr.d.ts.map +1 -0
- package/dist/src/intl/hr.js +265 -0
- package/dist/src/intl/hu.d.ts +63 -0
- package/dist/src/intl/hu.d.ts.map +1 -0
- package/dist/src/intl/hu.js +204 -0
- package/dist/src/intl/id.d.ts +117 -0
- package/dist/src/intl/id.d.ts.map +1 -0
- package/dist/src/intl/id.js +258 -0
- package/dist/src/intl/index.d.ts +42 -0
- package/dist/src/intl/index.d.ts.map +1 -1
- package/dist/src/intl/index.js +42 -0
- package/dist/src/intl/it.d.ts +117 -0
- package/dist/src/intl/it.d.ts.map +1 -0
- package/dist/src/intl/it.js +258 -0
- package/dist/src/intl/ja.d.ts +117 -0
- package/dist/src/intl/ja.d.ts.map +1 -0
- package/dist/src/intl/ja.js +258 -0
- package/dist/src/intl/ko.d.ts +117 -0
- package/dist/src/intl/ko.d.ts.map +1 -0
- package/dist/src/intl/ko.js +258 -0
- package/dist/src/intl/ml.d.ts +117 -0
- package/dist/src/intl/ml.d.ts.map +1 -0
- package/dist/src/intl/ml.js +258 -0
- package/dist/src/intl/mr.d.ts +117 -0
- package/dist/src/intl/mr.d.ts.map +1 -0
- package/dist/src/intl/mr.js +258 -0
- package/dist/src/intl/ms.d.ts +117 -0
- package/dist/src/intl/ms.d.ts.map +1 -0
- package/dist/src/intl/ms.js +245 -0
- package/dist/src/intl/nb.d.ts +63 -0
- package/dist/src/intl/nb.d.ts.map +1 -0
- package/dist/src/intl/nb.js +191 -0
- package/dist/src/intl/nl.d.ts +117 -0
- package/dist/src/intl/nl.d.ts.map +1 -0
- package/dist/src/intl/nl.js +258 -0
- package/dist/src/intl/pa.d.ts +117 -0
- package/dist/src/intl/pa.d.ts.map +1 -0
- package/dist/src/intl/pa.js +258 -0
- package/dist/src/intl/pl.d.ts +117 -0
- package/dist/src/intl/pl.d.ts.map +1 -0
- package/dist/src/intl/pl.js +242 -0
- package/dist/src/intl/pt-BR.d.ts +117 -0
- package/dist/src/intl/pt-BR.d.ts.map +1 -0
- package/dist/src/intl/pt-BR.js +258 -0
- package/dist/src/intl/pt.d.ts +117 -0
- package/dist/src/intl/pt.d.ts.map +1 -0
- package/dist/src/intl/pt.js +246 -0
- package/dist/src/intl/ro.d.ts +117 -0
- package/dist/src/intl/ro.d.ts.map +1 -0
- package/dist/src/intl/ro.js +258 -0
- package/dist/src/intl/sk.d.ts +117 -0
- package/dist/src/intl/sk.d.ts.map +1 -0
- package/dist/src/intl/sk.js +244 -0
- package/dist/src/intl/sl.d.ts +117 -0
- package/dist/src/intl/sl.d.ts.map +1 -0
- package/dist/src/intl/sl.js +258 -0
- package/dist/src/intl/sv.d.ts +117 -0
- package/dist/src/intl/sv.d.ts.map +1 -0
- package/dist/src/intl/sv.js +258 -0
- package/dist/src/intl/sw.d.ts +63 -0
- package/dist/src/intl/sw.d.ts.map +1 -0
- package/dist/src/intl/sw.js +191 -0
- package/dist/src/intl/ta.d.ts +117 -0
- package/dist/src/intl/ta.d.ts.map +1 -0
- package/dist/src/intl/ta.js +258 -0
- package/dist/src/intl/te.d.ts +117 -0
- package/dist/src/intl/te.d.ts.map +1 -0
- package/dist/src/intl/te.js +258 -0
- package/dist/src/intl/th.d.ts +117 -0
- package/dist/src/intl/th.d.ts.map +1 -0
- package/dist/src/intl/th.js +258 -0
- package/dist/src/intl/tr.d.ts +117 -0
- package/dist/src/intl/tr.d.ts.map +1 -0
- package/dist/src/intl/tr.js +255 -0
- package/dist/src/intl/uk.d.ts +117 -0
- package/dist/src/intl/uk.d.ts.map +1 -0
- package/dist/src/intl/uk.js +258 -0
- package/dist/src/intl/ur.d.ts +117 -0
- package/dist/src/intl/ur.d.ts.map +1 -0
- package/dist/src/intl/ur.js +245 -0
- package/dist/src/intl/vi.d.ts +117 -0
- package/dist/src/intl/vi.d.ts.map +1 -0
- package/dist/src/intl/vi.js +255 -0
- package/dist/src/intl/zh-CN.d.ts +117 -0
- package/dist/src/intl/zh-CN.d.ts.map +1 -0
- package/dist/src/intl/zh-CN.js +258 -0
- package/dist/src/intl/zh-TW.d.ts +117 -0
- package/dist/src/intl/zh-TW.d.ts.map +1 -0
- package/dist/src/intl/zh-TW.js +258 -0
- package/dist/src/local-first/Owner.d.ts +156 -62
- package/dist/src/local-first/Owner.d.ts.map +1 -1
- package/dist/src/local-first/Owner.js +119 -20
- package/package.json +1 -1
- package/src/Function.ts +2 -0
- package/src/Http.ts +9 -0
- package/src/Object.ts +2 -0
- package/src/RefCount.ts +2 -0
- package/src/Relation.ts +4 -0
- package/src/Resource.ts +2 -0
- package/src/Result.ts +397 -560
- package/src/StackTrace.ts +2 -0
- package/src/Task.ts +1143 -1222
- package/src/Time.ts +2 -0
- package/src/Type.ts +1598 -712
- package/src/intl/_en.ts +497 -0
- package/src/intl/ar.ts +417 -0
- package/src/intl/bn.ts +486 -0
- package/src/intl/ca.ts +488 -0
- package/src/intl/cs.ts +95 -31
- package/src/intl/da.ts +488 -0
- package/src/intl/de.ts +488 -0
- package/src/intl/el.ts +494 -0
- package/src/intl/es.ts +488 -0
- package/src/intl/fa.ts +487 -0
- package/src/intl/fi.ts +487 -0
- package/src/intl/fil.ts +488 -0
- package/src/intl/fr.ts +488 -0
- package/src/intl/he.ts +486 -0
- package/src/intl/hi.ts +487 -0
- package/src/intl/hr.ts +494 -0
- package/src/intl/hu.ts +387 -0
- package/src/intl/id.ts +487 -0
- package/src/intl/index.ts +42 -0
- package/src/intl/it.ts +488 -0
- package/src/intl/ja.ts +488 -0
- package/src/intl/ko.ts +487 -0
- package/src/intl/ml.ts +487 -0
- package/src/intl/mr.ts +487 -0
- package/src/intl/ms.ts +410 -0
- package/src/intl/nb.ts +364 -0
- package/src/intl/nl.ts +488 -0
- package/src/intl/pa.ts +487 -0
- package/src/intl/pl.ts +450 -0
- package/src/intl/pt-BR.ts +487 -0
- package/src/intl/pt.ts +424 -0
- package/src/intl/ro.ts +488 -0
- package/src/intl/sk.ts +412 -0
- package/src/intl/sl.ts +487 -0
- package/src/intl/sv.ts +488 -0
- package/src/intl/sw.ts +324 -0
- package/src/intl/ta.ts +487 -0
- package/src/intl/te.ts +487 -0
- package/src/intl/th.ts +484 -0
- package/src/intl/tr.ts +487 -0
- package/src/intl/uk.ts +488 -0
- package/src/intl/ur.ts +410 -0
- package/src/intl/vi.ts +435 -0
- package/src/intl/zh-CN.ts +482 -0
- package/src/intl/zh-TW.ts +482 -0
- package/src/local-first/Owner.ts +156 -62
package/src/local-first/Owner.ts
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* ## Intro
|
|
3
|
+
*
|
|
4
|
+
* Cryptographic identities that define ownership, encryption, sync, and
|
|
5
|
+
* deletion boundaries for Evolu data.
|
|
6
|
+
*
|
|
7
|
+
* Every database change belongs to an {@link Owner} and is encrypted with its
|
|
8
|
+
* {@link OwnerEncryptionKey}. Owners also make sync selective: only the
|
|
9
|
+
* {@link AppOwner} is synced by default, while other owners can be synced when
|
|
10
|
+
* needed.
|
|
11
|
+
*
|
|
12
|
+
* Individual changes in an append-only local-first history can only be marked
|
|
13
|
+
* as deleted. An entire owner, however, can be removed from devices and relays
|
|
14
|
+
* together with all of its data. The AppOwner must remain because it coordinates
|
|
15
|
+
* the deletion of other owners across devices.
|
|
16
|
+
*
|
|
17
|
+
* Choose an owner by how its data should live and be shared:
|
|
18
|
+
*
|
|
19
|
+
* - {@link AppOwner} coordinates sync and persists for the lifetime of the app
|
|
20
|
+
* identity.
|
|
21
|
+
* - {@link ShardOwner} partitions application data so it can be synced and
|
|
22
|
+
* deleted independently.
|
|
23
|
+
* - {@link SharedOwner} grants collaborative read and write access.
|
|
24
|
+
* - {@link SharedReadonlyOwner} grants read-only access to shared data.
|
|
25
|
+
*
|
|
26
|
+
* An {@link OwnerSecret} deterministically derives three independent values
|
|
27
|
+
* using SLIP-21:
|
|
28
|
+
*
|
|
29
|
+
* - {@link OwnerId}: the public identifier.
|
|
30
|
+
* - {@link OwnerEncryptionKey}: the symmetric key that protects the data.
|
|
31
|
+
* - {@link OwnerWriteKey}: the rotatable token that authorizes writes.
|
|
3
32
|
*
|
|
4
33
|
* @module
|
|
5
34
|
*/
|
|
@@ -34,6 +63,7 @@ import { TimestampBytes } from "./Timestamp.ts";
|
|
|
34
63
|
* {@link Owner} without a {@link OwnerWriteKey}.
|
|
35
64
|
*
|
|
36
65
|
* @see {@link createSharedReadonlyOwner}
|
|
66
|
+
* @group Core
|
|
37
67
|
*/
|
|
38
68
|
export interface ReadonlyOwner {
|
|
39
69
|
readonly id: OwnerId;
|
|
@@ -42,35 +72,11 @@ export interface ReadonlyOwner {
|
|
|
42
72
|
}
|
|
43
73
|
|
|
44
74
|
/**
|
|
45
|
-
*
|
|
46
|
-
* assigned to an owner and encrypted with its {@link OwnerEncryptionKey}. Owners
|
|
47
|
-
* allow partial sync, only the {@link AppOwner} is synced by default.
|
|
48
|
-
*
|
|
49
|
-
* Owners can also provide real data deletion, while individual changes in
|
|
50
|
-
* local-first/distributed systems can only be soft deleted, entire owners can
|
|
51
|
-
* be completely deleted from both relays and devices (except for
|
|
52
|
-
* {@link AppOwner}, which must be preserved for sync coordination).
|
|
53
|
-
*
|
|
54
|
-
* Evolu provides different owner types depending on their use case:
|
|
55
|
-
*
|
|
56
|
-
* - **Coordination**: {@link AppOwner} for sync coordination and long-term
|
|
57
|
-
* persistence
|
|
58
|
-
* - **Data partitioning**: {@link ShardOwner} for partitioning application data
|
|
59
|
-
* - **Collaboration**: {@link SharedOwner} for collaborative write access
|
|
60
|
-
* - **Data sharing**: {@link SharedReadonlyOwner} for read-only access to shared
|
|
61
|
-
* data
|
|
75
|
+
* An {@link ReadonlyOwner} with an {@link OwnerWriteKey} for authorizing writes.
|
|
62
76
|
*
|
|
63
|
-
*
|
|
64
|
-
* SLIP-21, ensuring secure and deterministic key generation:
|
|
77
|
+
* See the {@link @evolu/common!"local-first/Owner" | Owners overview}.
|
|
65
78
|
*
|
|
66
|
-
*
|
|
67
|
-
* - {@link OwnerEncryptionKey}: Symmetric encryption key for data protection
|
|
68
|
-
* - {@link OwnerWriteKey}: Authentication token for write operations (rotatable)
|
|
69
|
-
*
|
|
70
|
-
* @see {@link createAppOwner}
|
|
71
|
-
* @see {@link createShardOwner}
|
|
72
|
-
* @see {@link createSharedOwner}
|
|
73
|
-
* @see {@link createSharedReadonlyOwner}
|
|
79
|
+
* @group Core
|
|
74
80
|
*/
|
|
75
81
|
export interface Owner extends ReadonlyOwner {
|
|
76
82
|
/** TODO: Wrap with `Redacted` in the next major version. */
|
|
@@ -80,31 +86,58 @@ export interface Owner extends ReadonlyOwner {
|
|
|
80
86
|
/**
|
|
81
87
|
* An {@link ReadonlyOwner} or {@link Owner} with non-empty {@link OwnerTransport}s
|
|
82
88
|
* so it can be synced.
|
|
89
|
+
*
|
|
90
|
+
* @group Transport
|
|
83
91
|
*/
|
|
84
92
|
export interface SyncOwner {
|
|
85
93
|
readonly owner: ReadonlyOwner | Owner;
|
|
86
94
|
readonly transports: NonEmptyReadonlyArray<OwnerTransport>;
|
|
87
95
|
}
|
|
88
96
|
|
|
89
|
-
/**
|
|
97
|
+
/**
|
|
98
|
+
* A branded {@link Id} that uniquely identifies an {@link Owner}.
|
|
99
|
+
*
|
|
100
|
+
* @group Core
|
|
101
|
+
*/
|
|
90
102
|
export const OwnerId = /*#__PURE__*/ brand("OwnerId", Id);
|
|
91
103
|
export type OwnerId = typeof OwnerId.Output;
|
|
92
104
|
|
|
93
|
-
/**
|
|
105
|
+
/**
|
|
106
|
+
* Binary representation of {@link OwnerId}.
|
|
107
|
+
*
|
|
108
|
+
* @group Core
|
|
109
|
+
*/
|
|
94
110
|
export const OwnerIdBytes = /*#__PURE__*/ brand("OwnerIdBytes", IdBytes);
|
|
95
111
|
export type OwnerIdBytes = typeof OwnerIdBytes.Output;
|
|
96
112
|
|
|
97
|
-
/**
|
|
113
|
+
/**
|
|
114
|
+
* Converts {@link OwnerId} to {@link OwnerIdBytes}.
|
|
115
|
+
*
|
|
116
|
+
* @group Core
|
|
117
|
+
*/
|
|
98
118
|
export const ownerIdToOwnerIdBytes = (ownerId: OwnerId): OwnerIdBytes =>
|
|
99
119
|
idToIdBytes(ownerId) as OwnerIdBytes;
|
|
100
120
|
|
|
101
|
-
/**
|
|
121
|
+
/**
|
|
122
|
+
* Converts {@link OwnerIdBytes} to {@link OwnerId}.
|
|
123
|
+
*
|
|
124
|
+
* @group Core
|
|
125
|
+
*/
|
|
102
126
|
export const ownerIdBytesToOwnerId = (ownerIdBytes: OwnerIdBytes): OwnerId =>
|
|
103
127
|
idBytesToId(ownerIdBytes) as OwnerId;
|
|
104
128
|
|
|
129
|
+
/**
|
|
130
|
+
* Length of an {@link OwnerWriteKey} in bytes.
|
|
131
|
+
*
|
|
132
|
+
* @group Core
|
|
133
|
+
*/
|
|
105
134
|
export const ownerWriteKeyLength = /*#__PURE__*/ NonNegativeInt.orThrow(16);
|
|
106
135
|
|
|
107
|
-
/**
|
|
136
|
+
/**
|
|
137
|
+
* Symmetric encryption key for {@link Owner} data protection.
|
|
138
|
+
*
|
|
139
|
+
* @group Core
|
|
140
|
+
*/
|
|
108
141
|
export const OwnerEncryptionKey = /*#__PURE__*/ brand(
|
|
109
142
|
"OwnerEncryptionKey",
|
|
110
143
|
EncryptionKey,
|
|
@@ -112,18 +145,21 @@ export const OwnerEncryptionKey = /*#__PURE__*/ brand(
|
|
|
112
145
|
export type OwnerEncryptionKey = typeof OwnerEncryptionKey.Output;
|
|
113
146
|
|
|
114
147
|
/**
|
|
115
|
-
* A
|
|
116
|
-
*
|
|
148
|
+
* A token that authorizes write operations for an {@link Owner}.
|
|
149
|
+
*
|
|
150
|
+
* The initial key is derived from {@link OwnerSecret}. Replace it with a random
|
|
151
|
+
* key from {@link createOwnerWriteKey} to rotate write access without changing
|
|
152
|
+
* the owner identity or encryption key.
|
|
153
|
+
*
|
|
154
|
+
* @group Core
|
|
117
155
|
*/
|
|
118
156
|
export const OwnerWriteKey = /*#__PURE__*/ brand("OwnerWriteKey", Entropy16);
|
|
119
157
|
export type OwnerWriteKey = typeof OwnerWriteKey.Output;
|
|
120
158
|
|
|
121
159
|
/**
|
|
122
|
-
* Creates a
|
|
160
|
+
* Creates a random {@link OwnerWriteKey} for rotating write access.
|
|
123
161
|
*
|
|
124
|
-
*
|
|
125
|
-
* {@link OwnerSecret}. Use `createOwnerWriteKey` to rotate (replace) the write
|
|
126
|
-
* key without changing the owner identity.
|
|
162
|
+
* @group Core
|
|
127
163
|
*/
|
|
128
164
|
export const createOwnerWriteKey = (deps: RandomBytesDep): OwnerWriteKey =>
|
|
129
165
|
deps.randomBytes.create(16) as OwnerWriteKey;
|
|
@@ -133,26 +169,44 @@ export const createOwnerWriteKey = (deps: RandomBytesDep): OwnerWriteKey =>
|
|
|
133
169
|
*
|
|
134
170
|
* Can be created using {@link createOwnerSecret} or converted from a
|
|
135
171
|
* {@link Mnemonic} using {@link mnemonicToOwnerSecret}.
|
|
172
|
+
*
|
|
173
|
+
* @group Core
|
|
136
174
|
*/
|
|
137
175
|
export const OwnerSecret = /*#__PURE__*/ brand("OwnerSecret", Entropy32);
|
|
138
176
|
export type OwnerSecret = typeof OwnerSecret.Output;
|
|
139
177
|
|
|
140
|
-
/**
|
|
178
|
+
/**
|
|
179
|
+
* Creates a cryptographically random {@link OwnerSecret}.
|
|
180
|
+
*
|
|
181
|
+
* @group Core
|
|
182
|
+
*/
|
|
141
183
|
export const createOwnerSecret = (deps: RandomBytesDep): OwnerSecret =>
|
|
142
184
|
deps.randomBytes.create(32) as OwnerSecret;
|
|
143
185
|
|
|
144
|
-
/**
|
|
186
|
+
/**
|
|
187
|
+
* Deterministic {@link OwnerSecret} for tests.
|
|
188
|
+
*
|
|
189
|
+
* @group Testing
|
|
190
|
+
*/
|
|
145
191
|
export const testOwnerSecret = /*#__PURE__*/ createOwnerSecret({
|
|
146
192
|
randomBytes: /*#__PURE__*/ testCreateRandomBytes({
|
|
147
193
|
randomLib: /*#__PURE__*/ testCreateRandomLib(),
|
|
148
194
|
}),
|
|
149
195
|
});
|
|
150
196
|
|
|
151
|
-
/**
|
|
197
|
+
/**
|
|
198
|
+
* Converts an {@link OwnerSecret} to a {@link Mnemonic}.
|
|
199
|
+
*
|
|
200
|
+
* @group Core
|
|
201
|
+
*/
|
|
152
202
|
export const ownerSecretToMnemonic = (secret: OwnerSecret): Mnemonic =>
|
|
153
203
|
bip39.entropyToMnemonic(secret, wordlist) as Mnemonic;
|
|
154
204
|
|
|
155
|
-
/**
|
|
205
|
+
/**
|
|
206
|
+
* Converts a {@link Mnemonic} to an {@link OwnerSecret}.
|
|
207
|
+
*
|
|
208
|
+
* @group Core
|
|
209
|
+
*/
|
|
156
210
|
export const mnemonicToOwnerSecret = (mnemonic: Mnemonic): OwnerSecret =>
|
|
157
211
|
bip39.mnemonicToEntropy(mnemonic, wordlist) as OwnerSecret;
|
|
158
212
|
|
|
@@ -207,6 +261,8 @@ const createOwner = (secret: OwnerSecret): Owner => ({
|
|
|
207
261
|
* For data sharing scenarios, use {@link SharedOwner} and
|
|
208
262
|
* {@link SharedReadonlyOwner} to make intent explicit and distinguish
|
|
209
263
|
* collaborative usage from {@link AppOwner} coordination.
|
|
264
|
+
*
|
|
265
|
+
* @group Variants
|
|
210
266
|
*/
|
|
211
267
|
export interface AppOwner extends Owner, Typed<"AppOwner"> {
|
|
212
268
|
/**
|
|
@@ -219,14 +275,22 @@ export interface AppOwner extends Owner, Typed<"AppOwner"> {
|
|
|
219
275
|
readonly mnemonic: Mnemonic;
|
|
220
276
|
}
|
|
221
277
|
|
|
222
|
-
/**
|
|
278
|
+
/**
|
|
279
|
+
* Creates an {@link AppOwner} from an {@link OwnerSecret}.
|
|
280
|
+
*
|
|
281
|
+
* @group Variants
|
|
282
|
+
*/
|
|
223
283
|
export const createAppOwner = (secret: OwnerSecret): AppOwner => ({
|
|
224
284
|
...createOwner(secret),
|
|
225
285
|
type: "AppOwner",
|
|
226
286
|
mnemonic: ownerSecretToMnemonic(secret),
|
|
227
287
|
});
|
|
228
288
|
|
|
229
|
-
/**
|
|
289
|
+
/**
|
|
290
|
+
* Deterministic {@link AppOwner} for tests.
|
|
291
|
+
*
|
|
292
|
+
* @group Testing
|
|
293
|
+
*/
|
|
230
294
|
export const testAppOwner = /*#__PURE__*/ createAppOwner(testOwnerSecret);
|
|
231
295
|
|
|
232
296
|
/**
|
|
@@ -239,10 +303,16 @@ export const testAppOwner = /*#__PURE__*/ createAppOwner(testOwnerSecret);
|
|
|
239
303
|
* Can be created from {@link OwnerSecret} via {@link createShardOwner} or
|
|
240
304
|
* deterministically derived from {@link AppOwner} using
|
|
241
305
|
* {@link deriveShardOwner}.
|
|
306
|
+
*
|
|
307
|
+
* @group Variants
|
|
242
308
|
*/
|
|
243
309
|
export interface ShardOwner extends Owner, Typed<"ShardOwner"> {}
|
|
244
310
|
|
|
245
|
-
/**
|
|
311
|
+
/**
|
|
312
|
+
* Creates a {@link ShardOwner} from an {@link OwnerSecret}.
|
|
313
|
+
*
|
|
314
|
+
* @group Variants
|
|
315
|
+
*/
|
|
246
316
|
export const createShardOwner = (secret: OwnerSecret): ShardOwner => ({
|
|
247
317
|
...createOwner(secret),
|
|
248
318
|
type: "ShardOwner",
|
|
@@ -265,6 +335,8 @@ export const createShardOwner = (secret: OwnerSecret): ShardOwner => ({
|
|
|
265
335
|
* - Use paths like `["shard", 1]` for versioned data lifecycle
|
|
266
336
|
* - Use paths like `["project", "MyApp", 1]` for named partitions with versions
|
|
267
337
|
* - Each device can derive the same owners and set up initial structure
|
|
338
|
+
*
|
|
339
|
+
* @group Variants
|
|
268
340
|
*/
|
|
269
341
|
export const deriveShardOwner = (
|
|
270
342
|
owner: AppOwner,
|
|
@@ -278,7 +350,11 @@ export const deriveShardOwner = (
|
|
|
278
350
|
};
|
|
279
351
|
};
|
|
280
352
|
|
|
281
|
-
/**
|
|
353
|
+
/**
|
|
354
|
+
* An {@link Owner} for collaborative data with write access.
|
|
355
|
+
*
|
|
356
|
+
* @group Variants
|
|
357
|
+
*/
|
|
282
358
|
export interface SharedOwner extends Owner, Typed<"SharedOwner"> {}
|
|
283
359
|
|
|
284
360
|
/**
|
|
@@ -287,6 +363,8 @@ export interface SharedOwner extends Owner, Typed<"SharedOwner"> {}
|
|
|
287
363
|
*
|
|
288
364
|
* Use {@link createSharedReadonlyOwner} to create a read-only version for
|
|
289
365
|
* sharing.
|
|
366
|
+
*
|
|
367
|
+
* @group Variants
|
|
290
368
|
*/
|
|
291
369
|
export const createSharedOwner = (secret: OwnerSecret): SharedOwner => ({
|
|
292
370
|
...createOwner(secret),
|
|
@@ -297,11 +375,17 @@ export const createSharedOwner = (secret: OwnerSecret): SharedOwner => ({
|
|
|
297
375
|
* Read-only version of a {@link SharedOwner} for data sharing. Contains only the
|
|
298
376
|
* {@link OwnerId} and {@link EncryptionKey} needed for others to read the shared
|
|
299
377
|
* data without write access.
|
|
378
|
+
*
|
|
379
|
+
* @group Variants
|
|
300
380
|
*/
|
|
301
381
|
export interface SharedReadonlyOwner
|
|
302
382
|
extends ReadonlyOwner, Typed<"SharedReadonlyOwner"> {}
|
|
303
383
|
|
|
304
|
-
/**
|
|
384
|
+
/**
|
|
385
|
+
* Creates a {@link SharedReadonlyOwner} from a {@link SharedOwner}.
|
|
386
|
+
*
|
|
387
|
+
* @group Variants
|
|
388
|
+
*/
|
|
305
389
|
export const createSharedReadonlyOwner = (
|
|
306
390
|
sharedOwner: SharedOwner,
|
|
307
391
|
): SharedReadonlyOwner => ({
|
|
@@ -314,6 +398,8 @@ export const createSharedReadonlyOwner = (
|
|
|
314
398
|
* Transport configuration for connecting to relays.
|
|
315
399
|
*
|
|
316
400
|
* Currently only WebSocket, in the future Bluetooth, LocalNetwork, etc.
|
|
401
|
+
*
|
|
402
|
+
* @group Transport
|
|
317
403
|
*/
|
|
318
404
|
export type OwnerTransport = OwnerWebSocketTransport;
|
|
319
405
|
|
|
@@ -343,6 +429,7 @@ export type OwnerTransport = OwnerWebSocketTransport;
|
|
|
343
429
|
*
|
|
344
430
|
* @see {@link createOwnerWebSocketTransport}
|
|
345
431
|
* @see {@link parseOwnerIdFromOwnerWebSocketTransportUrl}
|
|
432
|
+
* @group Transport
|
|
346
433
|
*/
|
|
347
434
|
export interface OwnerWebSocketTransport extends Typed<"WebSocket"> {
|
|
348
435
|
readonly url: string;
|
|
@@ -392,6 +479,8 @@ export interface OwnerWebSocketTransport extends Typed<"WebSocket"> {
|
|
|
392
479
|
* url: `wss://relay.evolu.dev?ownerId=${appOwner.id}`,
|
|
393
480
|
* });
|
|
394
481
|
* ```
|
|
482
|
+
*
|
|
483
|
+
* @group Transport
|
|
395
484
|
*/
|
|
396
485
|
export const createOwnerWebSocketTransport = (config: {
|
|
397
486
|
readonly url: string;
|
|
@@ -431,42 +520,45 @@ export const createOwnerWebSocketTransport = (config: {
|
|
|
431
520
|
* parseOwnerIdFromOwnerWebSocketTransportUrl("/sync?ownerId=invalid"),
|
|
432
521
|
* ).toBeNull();
|
|
433
522
|
* ```
|
|
523
|
+
*
|
|
524
|
+
* @group Transport
|
|
434
525
|
*/
|
|
435
526
|
export const parseOwnerIdFromOwnerWebSocketTransportUrl = (
|
|
436
527
|
url: string,
|
|
437
528
|
): OwnerId | null => getOrNull(OwnerId.fromUnknown(url.split("=")[1]));
|
|
438
529
|
|
|
439
|
-
/**
|
|
530
|
+
/**
|
|
531
|
+
* Common interface implemented by all owner domain errors.
|
|
532
|
+
*
|
|
533
|
+
* @group Core
|
|
534
|
+
*/
|
|
440
535
|
export interface OwnerError {
|
|
441
536
|
readonly ownerId: OwnerId;
|
|
442
537
|
}
|
|
443
538
|
|
|
444
539
|
/**
|
|
445
|
-
*
|
|
540
|
+
* Storage usage and timestamp bounds for an {@link Owner}.
|
|
446
541
|
*
|
|
447
|
-
*
|
|
542
|
+
* Storage and relay implementations use this metadata for quota enforcement and
|
|
543
|
+
* timestamp insertion strategies.
|
|
448
544
|
*
|
|
449
|
-
*
|
|
450
|
-
*
|
|
451
|
-
* - Add transferredBytes for billing and monitoring network usage.
|
|
545
|
+
* @group Core
|
|
452
546
|
*/
|
|
453
547
|
export interface OwnerUsage {
|
|
454
|
-
/**
|
|
548
|
+
/** Binary identifier of the {@link Owner} this usage belongs to. */
|
|
455
549
|
readonly ownerId: OwnerIdBytes;
|
|
456
550
|
|
|
457
551
|
/**
|
|
458
552
|
* Total logical data bytes stored.
|
|
459
553
|
*
|
|
460
|
-
* Measures
|
|
461
|
-
*
|
|
462
|
-
*
|
|
554
|
+
* Measures only {@link EncryptedDbChange} data and excludes {@link Storage}
|
|
555
|
+
* implementation overhead such as indexes and skip-list columns. This makes
|
|
556
|
+
* the measurement consistent across storage implementations and suitable for:
|
|
463
557
|
*
|
|
464
558
|
* - **Predictable measurement** - same data = same byte count across all
|
|
465
559
|
* instances
|
|
466
|
-
* - **Quota enforcement** -
|
|
467
|
-
*
|
|
468
|
-
* - **Overhead tracking** - actual Storage size can be compared against this to
|
|
469
|
-
* monitor efficiency
|
|
560
|
+
* - **Quota enforcement** - limits independent of storage implementation
|
|
561
|
+
* - **Overhead tracking** - comparison with actual storage size
|
|
470
562
|
*/
|
|
471
563
|
readonly storedBytes: NonNegativeInt;
|
|
472
564
|
|
|
@@ -510,6 +602,8 @@ export interface OwnerUsage {
|
|
|
510
602
|
*
|
|
511
603
|
* DeviceAppOwner Evolu instance is secure only when its data stays on the
|
|
512
604
|
* device.
|
|
605
|
+
*
|
|
606
|
+
* @group Variants
|
|
513
607
|
*/
|
|
514
608
|
export interface DeviceAppOwner extends AppOwner {
|
|
515
609
|
readonly source: "ExpoSecureStore" | "WebAuthnPrf" | "ElectronSafeStorage";
|