cojson 0.7.35 → 0.8.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/.turbo/turbo-build.log +2 -7
- package/.turbo/turbo-lint.log +4 -0
- package/CHANGELOG.md +7 -0
- package/dist/PeerState.js +13 -5
- package/dist/PeerState.js.map +1 -1
- package/dist/coValueCore.js +0 -6
- package/dist/coValueCore.js.map +1 -1
- package/dist/coValues/account.js +2 -3
- package/dist/coValues/account.js.map +1 -1
- package/dist/coValues/coStream.js.map +1 -1
- package/dist/coValues/group.js +8 -8
- package/dist/coValues/group.js.map +1 -1
- package/dist/crypto/crypto.js +3 -0
- package/dist/crypto/crypto.js.map +1 -1
- package/dist/index.js +1 -2
- package/dist/index.js.map +1 -1
- package/dist/localNode.js +9 -9
- package/dist/localNode.js.map +1 -1
- package/dist/permissions.js.map +1 -1
- package/dist/tests/account.test.js +1 -2
- package/dist/tests/account.test.js.map +1 -1
- package/dist/tests/permissions.test.js +41 -42
- package/dist/tests/permissions.test.js.map +1 -1
- package/dist/tests/sync.test.js +4 -5
- package/dist/tests/sync.test.js.map +1 -1
- package/dist/tests/testUtils.js +1 -2
- package/dist/tests/testUtils.js.map +1 -1
- package/dist/typeUtils/accountOrAgentIDfromSessionID.js.map +1 -1
- package/dist/typeUtils/isAccountID.js.map +1 -1
- package/package.json +1 -1
- package/src/PeerState.ts +18 -7
- package/src/coValueCore.ts +7 -15
- package/src/coValues/account.ts +5 -6
- package/src/coValues/coList.ts +4 -4
- package/src/coValues/coMap.ts +3 -3
- package/src/coValues/coStream.ts +8 -8
- package/src/coValues/group.ts +15 -11
- package/src/crypto/crypto.ts +5 -0
- package/src/ids.ts +2 -2
- package/src/index.ts +4 -4
- package/src/localNode.ts +18 -18
- package/src/permissions.ts +5 -5
- package/src/tests/account.test.ts +1 -2
- package/src/tests/permissions.test.ts +41 -42
- package/src/tests/sync.test.ts +8 -8
- package/src/tests/testUtils.ts +1 -2
- package/src/typeUtils/accountOrAgentIDfromSessionID.ts +3 -3
- package/src/typeUtils/isAccountID.ts +2 -2
package/src/coValueCore.ts
CHANGED
|
@@ -10,7 +10,6 @@ import {
|
|
|
10
10
|
SignerID,
|
|
11
11
|
} from "./crypto/crypto.js";
|
|
12
12
|
import { JsonObject, JsonValue } from "./jsonValue.js";
|
|
13
|
-
import { base58 } from "@scure/base";
|
|
14
13
|
import {
|
|
15
14
|
PermissionsDef as RulesetDef,
|
|
16
15
|
determineValidTransactions,
|
|
@@ -19,8 +18,8 @@ import {
|
|
|
19
18
|
import { RawGroup } from "./coValues/group.js";
|
|
20
19
|
import { LocalNode, ResolveAccountAgentError } from "./localNode.js";
|
|
21
20
|
import { CoValueKnownState, NewContentMessage } from "./sync.js";
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
21
|
+
import { RawCoID, SessionID, TransactionID } from "./ids.js";
|
|
22
|
+
import { RawAccountID, ControlledAccountOrAgent } from "./coValues/account.js";
|
|
24
23
|
import { Stringified, parseJSON, stableStringify } from "./jsonStringify.js";
|
|
25
24
|
import { coreToCoValue } from "./coreToCoValue.js";
|
|
26
25
|
import { expectGroup } from "./typeUtils/expectGroup.js";
|
|
@@ -42,9 +41,9 @@ export type CoValueHeader = {
|
|
|
42
41
|
type: AnyRawCoValue["type"];
|
|
43
42
|
ruleset: RulesetDef;
|
|
44
43
|
meta: JsonObject | null;
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
44
|
+
} & CoValueUniqueness;
|
|
45
|
+
|
|
46
|
+
export type CoValueUniqueness = {uniqueness: JsonValue, createdAt?: `2${string}` | null}
|
|
48
47
|
|
|
49
48
|
export function idforHeader(
|
|
50
49
|
header: CoValueHeader,
|
|
@@ -54,13 +53,6 @@ export function idforHeader(
|
|
|
54
53
|
return `co_z${hash.slice("shortHash_z".length)}`;
|
|
55
54
|
}
|
|
56
55
|
|
|
57
|
-
export function newRandomSessionID(accountID: AccountID | AgentID): SessionID {
|
|
58
|
-
return `${accountID}_session_z${base58.encode(
|
|
59
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
60
|
-
(globalThis as any).crypto.getRandomValues(new Uint8Array(8)),
|
|
61
|
-
)}`;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
56
|
type SessionLog = {
|
|
65
57
|
transactions: Transaction[];
|
|
66
58
|
lastHash?: Hash;
|
|
@@ -993,7 +985,7 @@ export class CoValueCore {
|
|
|
993
985
|
return this.header.ruleset.type === "group"
|
|
994
986
|
? expectGroup(this.getCurrentContent())
|
|
995
987
|
.keys()
|
|
996
|
-
.filter((k): k is
|
|
988
|
+
.filter((k): k is RawAccountID => k.startsWith("co_"))
|
|
997
989
|
: this.header.ruleset.type === "ownedByGroup"
|
|
998
990
|
? [
|
|
999
991
|
this.header.ruleset.group,
|
|
@@ -1005,7 +997,7 @@ export class CoValueCore {
|
|
|
1005
997
|
),
|
|
1006
998
|
)
|
|
1007
999
|
.filter(
|
|
1008
|
-
(session): session is
|
|
1000
|
+
(session): session is RawAccountID =>
|
|
1009
1001
|
isAccountID(session) && session !== this.id,
|
|
1010
1002
|
),
|
|
1011
1003
|
),
|
package/src/coValues/account.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CoValueCore, CoValueHeader } from "../coValueCore.js";
|
|
1
|
+
import { CoValueCore, CoValueHeader, CoValueUniqueness } from "../coValueCore.js";
|
|
2
2
|
import { CoID, RawCoValue } from "../coValue.js";
|
|
3
3
|
import {
|
|
4
4
|
AgentSecret,
|
|
@@ -63,7 +63,7 @@ export class RawAccount<
|
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
export interface ControlledAccountOrAgent {
|
|
66
|
-
id:
|
|
66
|
+
id: RawAccountID | AgentID;
|
|
67
67
|
agentSecret: AgentSecret;
|
|
68
68
|
|
|
69
69
|
currentAgentID: () => Result<AgentID, InvalidAccountAgentIDError>;
|
|
@@ -92,8 +92,8 @@ export class RawControlledAccount<Meta extends AccountMeta = AccountMeta>
|
|
|
92
92
|
* Creates a new group (with the current account as the group's first admin).
|
|
93
93
|
* @category 1. High-level
|
|
94
94
|
*/
|
|
95
|
-
createGroup() {
|
|
96
|
-
return this.core.node.createGroup();
|
|
95
|
+
createGroup(uniqueness: CoValueUniqueness = this.core.crypto.createdNowUnique()) {
|
|
96
|
+
return this.core.node.createGroup(uniqueness);
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
async acceptInvite<T extends RawCoValue>(
|
|
@@ -133,7 +133,6 @@ export class RawControlledAccount<Meta extends AccountMeta = AccountMeta>
|
|
|
133
133
|
}
|
|
134
134
|
}
|
|
135
135
|
|
|
136
|
-
/** @hidden */
|
|
137
136
|
export class ControlledAgent implements ControlledAccountOrAgent {
|
|
138
137
|
constructor(
|
|
139
138
|
public agentSecret: AgentSecret,
|
|
@@ -170,7 +169,7 @@ export class ControlledAgent implements ControlledAccountOrAgent {
|
|
|
170
169
|
}
|
|
171
170
|
|
|
172
171
|
export type AccountMeta = { type: "account" };
|
|
173
|
-
export type
|
|
172
|
+
export type RawAccountID = CoID<RawAccount>;
|
|
174
173
|
|
|
175
174
|
export type ProfileShape = {
|
|
176
175
|
name: string;
|
package/src/coValues/coList.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { isCoValue } from "../typeUtils/isCoValue.js";
|
|
|
4
4
|
import { CoValueCore } from "../coValueCore.js";
|
|
5
5
|
import { accountOrAgentIDfromSessionID } from "../typeUtils/accountOrAgentIDfromSessionID.js";
|
|
6
6
|
import { AgentID, SessionID, TransactionID } from "../ids.js";
|
|
7
|
-
import {
|
|
7
|
+
import { RawAccountID } from "./account.js";
|
|
8
8
|
import { RawGroup } from "./group.js";
|
|
9
9
|
|
|
10
10
|
type OpID = TransactionID & { changeIdx: number };
|
|
@@ -325,7 +325,7 @@ export class RawCoListView<
|
|
|
325
325
|
/** @category 5. Edit history */
|
|
326
326
|
editAt(idx: number):
|
|
327
327
|
| {
|
|
328
|
-
by:
|
|
328
|
+
by: RawAccountID | AgentID;
|
|
329
329
|
tx: TransactionID;
|
|
330
330
|
at: Date;
|
|
331
331
|
value: Item;
|
|
@@ -351,13 +351,13 @@ export class RawCoListView<
|
|
|
351
351
|
|
|
352
352
|
/** @category 5. Edit history */
|
|
353
353
|
deletionEdits(): {
|
|
354
|
-
by:
|
|
354
|
+
by: RawAccountID | AgentID;
|
|
355
355
|
tx: TransactionID;
|
|
356
356
|
at: Date;
|
|
357
357
|
// TODO: add indices that are now before and after the deleted item
|
|
358
358
|
}[] {
|
|
359
359
|
const edits: {
|
|
360
|
-
by:
|
|
360
|
+
by: RawAccountID | AgentID;
|
|
361
361
|
tx: TransactionID;
|
|
362
362
|
at: Date;
|
|
363
363
|
}[] = [];
|
package/src/coValues/coMap.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { CoID, RawCoValue } from "../coValue.js";
|
|
|
4
4
|
import { isCoValue } from "../typeUtils/isCoValue.js";
|
|
5
5
|
import { CoValueCore } from "../coValueCore.js";
|
|
6
6
|
import { accountOrAgentIDfromSessionID } from "../typeUtils/accountOrAgentIDfromSessionID.js";
|
|
7
|
-
import {
|
|
7
|
+
import { RawAccountID } from "./account.js";
|
|
8
8
|
import type { RawGroup } from "./group.js";
|
|
9
9
|
|
|
10
10
|
type MapOp<K extends string, V extends JsonValue | undefined> = {
|
|
@@ -196,7 +196,7 @@ export class RawCoMapView<
|
|
|
196
196
|
n: number,
|
|
197
197
|
):
|
|
198
198
|
| {
|
|
199
|
-
by:
|
|
199
|
+
by: RawAccountID | AgentID;
|
|
200
200
|
tx: TransactionID;
|
|
201
201
|
at: Date;
|
|
202
202
|
value?: Shape[K];
|
|
@@ -226,7 +226,7 @@ export class RawCoMapView<
|
|
|
226
226
|
key: K,
|
|
227
227
|
):
|
|
228
228
|
| {
|
|
229
|
-
by:
|
|
229
|
+
by: RawAccountID | AgentID;
|
|
230
230
|
tx: TransactionID;
|
|
231
231
|
at: Date;
|
|
232
232
|
value?: Shape[K];
|
package/src/coValues/coStream.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { accountOrAgentIDfromSessionID } from "../typeUtils/accountOrAgentIDfrom
|
|
|
7
7
|
import { RawGroup } from "./group.js";
|
|
8
8
|
import { AgentID, SessionID, TransactionID } from "../ids.js";
|
|
9
9
|
import { base64URLtoBytes, bytesToBase64url } from "../base64url.js";
|
|
10
|
-
import {
|
|
10
|
+
import { RawAccountID } from "./account.js";
|
|
11
11
|
|
|
12
12
|
export type BinaryStreamInfo = {
|
|
13
13
|
mimeType: string;
|
|
@@ -116,7 +116,7 @@ export class RawCoStreamView<
|
|
|
116
116
|
return Object.keys(this.items) as SessionID[];
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
-
accounts(): Set<
|
|
119
|
+
accounts(): Set<RawAccountID> {
|
|
120
120
|
return new Set(
|
|
121
121
|
this.sessions()
|
|
122
122
|
.map(accountOrAgentIDfromSessionID)
|
|
@@ -129,7 +129,7 @@ export class RawCoStreamView<
|
|
|
129
129
|
n: number,
|
|
130
130
|
):
|
|
131
131
|
| {
|
|
132
|
-
by:
|
|
132
|
+
by: RawAccountID | AgentID;
|
|
133
133
|
tx: TransactionID;
|
|
134
134
|
at: Date;
|
|
135
135
|
value: Item;
|
|
@@ -151,7 +151,7 @@ export class RawCoStreamView<
|
|
|
151
151
|
|
|
152
152
|
lastItemIn(sessionID: SessionID):
|
|
153
153
|
| {
|
|
154
|
-
by:
|
|
154
|
+
by: RawAccountID | AgentID;
|
|
155
155
|
tx: TransactionID;
|
|
156
156
|
at: Date;
|
|
157
157
|
value: Item;
|
|
@@ -175,9 +175,9 @@ export class RawCoStreamView<
|
|
|
175
175
|
}
|
|
176
176
|
}
|
|
177
177
|
|
|
178
|
-
lastItemBy(account:
|
|
178
|
+
lastItemBy(account: RawAccountID | AgentID):
|
|
179
179
|
| {
|
|
180
|
-
by:
|
|
180
|
+
by: RawAccountID | AgentID;
|
|
181
181
|
tx: TransactionID;
|
|
182
182
|
at: Date;
|
|
183
183
|
value: Item;
|
|
@@ -185,7 +185,7 @@ export class RawCoStreamView<
|
|
|
185
185
|
| undefined {
|
|
186
186
|
let latestItem:
|
|
187
187
|
| {
|
|
188
|
-
by:
|
|
188
|
+
by: RawAccountID | AgentID;
|
|
189
189
|
tx: TransactionID;
|
|
190
190
|
at: Date;
|
|
191
191
|
value: Item;
|
|
@@ -210,7 +210,7 @@ export class RawCoStreamView<
|
|
|
210
210
|
return latestItem;
|
|
211
211
|
}
|
|
212
212
|
|
|
213
|
-
*itemsBy(account:
|
|
213
|
+
*itemsBy(account: RawAccountID | AgentID) {
|
|
214
214
|
// TODO: this can be made more lazy without a huge collect and sort
|
|
215
215
|
const items = [
|
|
216
216
|
...Object.keys(this.items).flatMap((sessionID) =>
|
package/src/coValues/group.ts
CHANGED
|
@@ -5,9 +5,10 @@ import { JsonObject } from "../jsonValue.js";
|
|
|
5
5
|
import { RawBinaryCoStream, RawCoStream } from "./coStream.js";
|
|
6
6
|
import { Encrypted, KeyID, KeySecret, Sealed } from "../crypto/crypto.js";
|
|
7
7
|
import { AgentID, isAgentID } from "../ids.js";
|
|
8
|
-
import { RawAccount,
|
|
8
|
+
import { RawAccount, RawAccountID, ControlledAccountOrAgent } from "./account.js";
|
|
9
9
|
import { Role } from "../permissions.js";
|
|
10
10
|
import { base58 } from "@scure/base";
|
|
11
|
+
import { CoValueUniqueness } from "../coValueCore.js";
|
|
11
12
|
|
|
12
13
|
export const EVERYONE = "everyone" as const;
|
|
13
14
|
export type Everyone = "everyone";
|
|
@@ -15,10 +16,10 @@ export type Everyone = "everyone";
|
|
|
15
16
|
export type GroupShape = {
|
|
16
17
|
profile: CoID<RawCoMap> | null;
|
|
17
18
|
root: CoID<RawCoMap> | null;
|
|
18
|
-
[key:
|
|
19
|
+
[key: RawAccountID | AgentID]: Role;
|
|
19
20
|
[EVERYONE]?: Role;
|
|
20
21
|
readKey?: KeyID;
|
|
21
|
-
[revelationFor: `${KeyID}_for_${
|
|
22
|
+
[revelationFor: `${KeyID}_for_${RawAccountID | AgentID}`]: Sealed<KeySecret>;
|
|
22
23
|
[revelationFor: `${KeyID}_for_${Everyone}`]: KeySecret;
|
|
23
24
|
[oldKeyForNewKey: `${KeyID}_for_${KeyID}`]: Encrypted<
|
|
24
25
|
KeySecret,
|
|
@@ -55,12 +56,12 @@ export class RawGroup<
|
|
|
55
56
|
*
|
|
56
57
|
* @category 1. Role reading
|
|
57
58
|
*/
|
|
58
|
-
roleOf(accountID:
|
|
59
|
+
roleOf(accountID: RawAccountID): Role | undefined {
|
|
59
60
|
return this.roleOfInternal(accountID);
|
|
60
61
|
}
|
|
61
62
|
|
|
62
63
|
/** @internal */
|
|
63
|
-
roleOfInternal(accountID:
|
|
64
|
+
roleOfInternal(accountID: RawAccountID | AgentID): Role | undefined {
|
|
64
65
|
return this.get(accountID);
|
|
65
66
|
}
|
|
66
67
|
|
|
@@ -156,7 +157,7 @@ export class RawGroup<
|
|
|
156
157
|
} else {
|
|
157
158
|
return false;
|
|
158
159
|
}
|
|
159
|
-
}) as (
|
|
160
|
+
}) as (RawAccountID | AgentID)[];
|
|
160
161
|
|
|
161
162
|
const maybeCurrentReadKey = this.core.getCurrentReadKey();
|
|
162
163
|
|
|
@@ -255,6 +256,7 @@ export class RawGroup<
|
|
|
255
256
|
init?: M["_shape"],
|
|
256
257
|
meta?: M["headerMeta"],
|
|
257
258
|
initPrivacy: "trusting" | "private" = "private",
|
|
259
|
+
uniqueness: CoValueUniqueness = this.core.crypto.createdNowUnique()
|
|
258
260
|
): M {
|
|
259
261
|
const map = this.core.node
|
|
260
262
|
.createCoValue({
|
|
@@ -264,7 +266,7 @@ export class RawGroup<
|
|
|
264
266
|
group: this.id,
|
|
265
267
|
},
|
|
266
268
|
meta: meta || null,
|
|
267
|
-
...
|
|
269
|
+
...uniqueness
|
|
268
270
|
})
|
|
269
271
|
.getCurrentContent() as M;
|
|
270
272
|
|
|
@@ -287,6 +289,7 @@ export class RawGroup<
|
|
|
287
289
|
init?: L["_item"][],
|
|
288
290
|
meta?: L["headerMeta"],
|
|
289
291
|
initPrivacy: "trusting" | "private" = "private",
|
|
292
|
+
uniqueness: CoValueUniqueness = this.core.crypto.createdNowUnique()
|
|
290
293
|
): L {
|
|
291
294
|
const list = this.core.node
|
|
292
295
|
.createCoValue({
|
|
@@ -296,7 +299,7 @@ export class RawGroup<
|
|
|
296
299
|
group: this.id,
|
|
297
300
|
},
|
|
298
301
|
meta: meta || null,
|
|
299
|
-
...
|
|
302
|
+
...uniqueness
|
|
300
303
|
})
|
|
301
304
|
.getCurrentContent() as L;
|
|
302
305
|
|
|
@@ -310,7 +313,7 @@ export class RawGroup<
|
|
|
310
313
|
}
|
|
311
314
|
|
|
312
315
|
/** @category 3. Value creation */
|
|
313
|
-
createStream<C extends RawCoStream>(meta?: C["headerMeta"]): C {
|
|
316
|
+
createStream<C extends RawCoStream>(meta?: C["headerMeta"], uniqueness: CoValueUniqueness = this.core.crypto.createdNowUnique()): C {
|
|
314
317
|
return this.core.node
|
|
315
318
|
.createCoValue({
|
|
316
319
|
type: "costream",
|
|
@@ -319,7 +322,7 @@ export class RawGroup<
|
|
|
319
322
|
group: this.id,
|
|
320
323
|
},
|
|
321
324
|
meta: meta || null,
|
|
322
|
-
...
|
|
325
|
+
...uniqueness
|
|
323
326
|
})
|
|
324
327
|
.getCurrentContent() as C;
|
|
325
328
|
}
|
|
@@ -327,6 +330,7 @@ export class RawGroup<
|
|
|
327
330
|
/** @category 3. Value creation */
|
|
328
331
|
createBinaryStream<C extends RawBinaryCoStream>(
|
|
329
332
|
meta: C["headerMeta"] = { type: "binary" },
|
|
333
|
+
uniqueness: CoValueUniqueness = this.core.crypto.createdNowUnique()
|
|
330
334
|
): C {
|
|
331
335
|
return this.core.node
|
|
332
336
|
.createCoValue({
|
|
@@ -336,7 +340,7 @@ export class RawGroup<
|
|
|
336
340
|
group: this.id,
|
|
337
341
|
},
|
|
338
342
|
meta: meta,
|
|
339
|
-
...
|
|
343
|
+
...uniqueness
|
|
340
344
|
})
|
|
341
345
|
.getCurrentContent() as C;
|
|
342
346
|
}
|
package/src/crypto/crypto.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { JsonValue } from "../jsonValue.js";
|
|
|
2
2
|
import { base58 } from "@scure/base";
|
|
3
3
|
import { AgentID, RawCoID, TransactionID } from "../ids.js";
|
|
4
4
|
import { Stringified, parseJSON, stableStringify } from "../jsonStringify.js";
|
|
5
|
+
import { RawAccountID, SessionID } from "../index.js";
|
|
5
6
|
|
|
6
7
|
export type SignerSecret = `signerSecret_z${string}`;
|
|
7
8
|
export type SignerID = `signer_z${string}`;
|
|
@@ -290,6 +291,10 @@ export abstract class CryptoProvider<Blake3State = any> {
|
|
|
290
291
|
}),
|
|
291
292
|
)}`;
|
|
292
293
|
}
|
|
294
|
+
|
|
295
|
+
newRandomSessionID(accountID: RawAccountID | AgentID): SessionID {
|
|
296
|
+
return `${accountID}_session_z${base58.encode(this.randomBytes(8))}`;
|
|
297
|
+
}
|
|
293
298
|
}
|
|
294
299
|
|
|
295
300
|
export type Hash = `hash_z${string}`;
|
package/src/ids.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { RawAccountID } from "./coValues/account.js";
|
|
2
2
|
import { base58 } from "@scure/base";
|
|
3
3
|
import { shortHashLength } from "./crypto/crypto.js";
|
|
4
4
|
|
|
@@ -28,4 +28,4 @@ export function isAgentID(id: string): id is AgentID {
|
|
|
28
28
|
);
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
export type SessionID = `${
|
|
31
|
+
export type SessionID = `${RawAccountID | AgentID}_session_z${string}`;
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CoValueCore,
|
|
3
|
-
|
|
3
|
+
type CoValueUniqueness,
|
|
4
4
|
MAX_RECOMMENDED_TX_SIZE,
|
|
5
5
|
idforHeader,
|
|
6
6
|
} from "./coValueCore.js";
|
|
@@ -50,7 +50,7 @@ import type {
|
|
|
50
50
|
import { DisconnectedError, PingTimeoutError } from "./sync.js";
|
|
51
51
|
import type { AgentSecret } from "./crypto/crypto.js";
|
|
52
52
|
import type {
|
|
53
|
-
|
|
53
|
+
RawAccountID,
|
|
54
54
|
AccountMeta,
|
|
55
55
|
RawAccountMigration,
|
|
56
56
|
} from "./coValues/account.js";
|
|
@@ -65,7 +65,6 @@ import { getPriorityFromHeader } from "./priority.js";
|
|
|
65
65
|
|
|
66
66
|
/** @hidden */
|
|
67
67
|
export const cojsonInternals = {
|
|
68
|
-
newRandomSessionID,
|
|
69
68
|
connectedPeers,
|
|
70
69
|
rawCoIDtoBytes,
|
|
71
70
|
rawCoIDfromBytes,
|
|
@@ -98,7 +97,7 @@ export {
|
|
|
98
97
|
CoID,
|
|
99
98
|
AnyRawCoValue,
|
|
100
99
|
RawAccount,
|
|
101
|
-
|
|
100
|
+
RawAccountID,
|
|
102
101
|
AccountMeta,
|
|
103
102
|
RawAccountMigration,
|
|
104
103
|
RawProfile as Profile,
|
|
@@ -132,6 +131,7 @@ export type {
|
|
|
132
131
|
OutgoingSyncQueue,
|
|
133
132
|
DisconnectedError,
|
|
134
133
|
PingTimeoutError,
|
|
134
|
+
CoValueUniqueness
|
|
135
135
|
};
|
|
136
136
|
|
|
137
137
|
// eslint-disable-next-line @typescript-eslint/no-namespace
|
package/src/localNode.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { AgentSecret, CryptoProvider } from "./crypto/crypto.js";
|
|
|
2
2
|
import {
|
|
3
3
|
CoValueCore,
|
|
4
4
|
CoValueHeader,
|
|
5
|
-
|
|
5
|
+
CoValueUniqueness,
|
|
6
6
|
} from "./coValueCore.js";
|
|
7
7
|
import {
|
|
8
8
|
InviteSecret,
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
ControlledAccountOrAgent,
|
|
20
20
|
RawControlledAccount,
|
|
21
21
|
ControlledAgent,
|
|
22
|
-
|
|
22
|
+
RawAccountID,
|
|
23
23
|
RawProfile,
|
|
24
24
|
RawAccountMigration,
|
|
25
25
|
InvalidAccountAgentIDError,
|
|
@@ -81,14 +81,14 @@ export class LocalNode {
|
|
|
81
81
|
initialAgentSecret?: AgentSecret;
|
|
82
82
|
}): Promise<{
|
|
83
83
|
node: LocalNode;
|
|
84
|
-
accountID:
|
|
84
|
+
accountID: RawAccountID;
|
|
85
85
|
accountSecret: AgentSecret;
|
|
86
86
|
sessionID: SessionID;
|
|
87
87
|
}> {
|
|
88
88
|
const throwawayAgent = crypto.newRandomAgentSecret();
|
|
89
89
|
const setupNode = new LocalNode(
|
|
90
90
|
new ControlledAgent(throwawayAgent, crypto),
|
|
91
|
-
newRandomSessionID(crypto.getAgentID(throwawayAgent)),
|
|
91
|
+
crypto.newRandomSessionID(crypto.getAgentID(throwawayAgent)),
|
|
92
92
|
crypto,
|
|
93
93
|
);
|
|
94
94
|
|
|
@@ -96,7 +96,7 @@ export class LocalNode {
|
|
|
96
96
|
|
|
97
97
|
const nodeWithAccount = account.core.node.testWithDifferentAccount(
|
|
98
98
|
account,
|
|
99
|
-
newRandomSessionID(account.id),
|
|
99
|
+
crypto.newRandomSessionID(account.id),
|
|
100
100
|
);
|
|
101
101
|
|
|
102
102
|
const accountOnNodeWithAccount =
|
|
@@ -173,7 +173,7 @@ export class LocalNode {
|
|
|
173
173
|
crypto,
|
|
174
174
|
migration,
|
|
175
175
|
}: {
|
|
176
|
-
accountID:
|
|
176
|
+
accountID: RawAccountID;
|
|
177
177
|
accountSecret: AgentSecret;
|
|
178
178
|
sessionID: SessionID | undefined;
|
|
179
179
|
peersToLoadFrom: Peer[];
|
|
@@ -182,7 +182,7 @@ export class LocalNode {
|
|
|
182
182
|
}): Promise<LocalNode> {
|
|
183
183
|
const loadingNode = new LocalNode(
|
|
184
184
|
new ControlledAgent(accountSecret, crypto),
|
|
185
|
-
newRandomSessionID(accountID),
|
|
185
|
+
crypto.newRandomSessionID(accountID),
|
|
186
186
|
crypto,
|
|
187
187
|
);
|
|
188
188
|
|
|
@@ -206,7 +206,7 @@ export class LocalNode {
|
|
|
206
206
|
// since this is all synchronous, we can just swap out nodes for the SyncManager
|
|
207
207
|
const node = loadingNode.testWithDifferentAccount(
|
|
208
208
|
controlledAccount,
|
|
209
|
-
sessionID || newRandomSessionID(accountID),
|
|
209
|
+
sessionID || crypto.newRandomSessionID(accountID),
|
|
210
210
|
);
|
|
211
211
|
node.syncManager = loadingNode.syncManager;
|
|
212
212
|
node.syncManager.local = node;
|
|
@@ -429,7 +429,7 @@ export class LocalNode {
|
|
|
429
429
|
group.core
|
|
430
430
|
.testWithDifferentAccount(
|
|
431
431
|
new ControlledAgent(inviteAgentSecret, this.crypto),
|
|
432
|
-
newRandomSessionID(inviteAgentID),
|
|
432
|
+
this.crypto.newRandomSessionID(inviteAgentID),
|
|
433
433
|
)
|
|
434
434
|
.getCurrentContent(),
|
|
435
435
|
);
|
|
@@ -470,7 +470,7 @@ export class LocalNode {
|
|
|
470
470
|
}
|
|
471
471
|
|
|
472
472
|
/** @internal */
|
|
473
|
-
expectProfileLoaded(id:
|
|
473
|
+
expectProfileLoaded(id: RawAccountID, expectation?: string): RawProfile {
|
|
474
474
|
const account = this.expectCoValueLoaded(id, expectation);
|
|
475
475
|
const profileID = expectGroup(account.getCurrentContent()).get(
|
|
476
476
|
"profile",
|
|
@@ -499,7 +499,7 @@ export class LocalNode {
|
|
|
499
499
|
)
|
|
500
500
|
.testWithDifferentAccount(
|
|
501
501
|
new ControlledAgent(agentSecret, this.crypto),
|
|
502
|
-
newRandomSessionID(accountAgentID),
|
|
502
|
+
this.crypto.newRandomSessionID(accountAgentID),
|
|
503
503
|
)
|
|
504
504
|
.getCurrentContent(),
|
|
505
505
|
);
|
|
@@ -533,7 +533,7 @@ export class LocalNode {
|
|
|
533
533
|
|
|
534
534
|
/** @internal */
|
|
535
535
|
resolveAccountAgent(
|
|
536
|
-
id:
|
|
536
|
+
id: RawAccountID | AgentID,
|
|
537
537
|
expectation?: string,
|
|
538
538
|
): Result<AgentID, ResolveAccountAgentError> {
|
|
539
539
|
if (isAgentID(id)) {
|
|
@@ -560,7 +560,7 @@ export class LocalNode {
|
|
|
560
560
|
}
|
|
561
561
|
|
|
562
562
|
resolveAccountAgentAsync(
|
|
563
|
-
id:
|
|
563
|
+
id: RawAccountID | AgentID,
|
|
564
564
|
expectation?: string,
|
|
565
565
|
): ResultAsync<AgentID, ResolveAccountAgentError> {
|
|
566
566
|
if (isAgentID(id)) {
|
|
@@ -606,12 +606,12 @@ export class LocalNode {
|
|
|
606
606
|
/**
|
|
607
607
|
* @deprecated use Account.createGroup() instead
|
|
608
608
|
*/
|
|
609
|
-
createGroup(): RawGroup {
|
|
609
|
+
createGroup(uniqueness: CoValueUniqueness = this.crypto.createdNowUnique()): RawGroup {
|
|
610
610
|
const groupCoValue = this.createCoValue({
|
|
611
611
|
type: "comap",
|
|
612
612
|
ruleset: { type: "group", initialAdmin: this.account.id },
|
|
613
613
|
meta: null,
|
|
614
|
-
...
|
|
614
|
+
...uniqueness
|
|
615
615
|
});
|
|
616
616
|
|
|
617
617
|
const group = expectGroup(groupCoValue.getCurrentContent());
|
|
@@ -731,19 +731,19 @@ export type LoadCoValueCoreError = {
|
|
|
731
731
|
type: "ErrorLoadingCoValueCore";
|
|
732
732
|
error: unknown;
|
|
733
733
|
expectation?: string;
|
|
734
|
-
id:
|
|
734
|
+
id: RawAccountID;
|
|
735
735
|
};
|
|
736
736
|
|
|
737
737
|
export type AccountUnavailableFromAllPeersError = {
|
|
738
738
|
type: "AccountUnavailableFromAllPeers";
|
|
739
739
|
expectation?: string;
|
|
740
|
-
id:
|
|
740
|
+
id: RawAccountID;
|
|
741
741
|
};
|
|
742
742
|
|
|
743
743
|
export type UnexpectedlyNotAccountError = {
|
|
744
744
|
type: "UnexpectedlyNotAccount";
|
|
745
745
|
expectation?: string;
|
|
746
|
-
id:
|
|
746
|
+
id: RawAccountID;
|
|
747
747
|
};
|
|
748
748
|
|
|
749
749
|
export type ResolveAccountAgentError =
|
package/src/permissions.ts
CHANGED
|
@@ -5,13 +5,13 @@ import { KeyID } from "./crypto/crypto.js";
|
|
|
5
5
|
import { CoValueCore, Transaction } from "./coValueCore.js";
|
|
6
6
|
import { accountOrAgentIDfromSessionID } from "./typeUtils/accountOrAgentIDfromSessionID.js";
|
|
7
7
|
import { AgentID, RawCoID, SessionID, TransactionID } from "./ids.js";
|
|
8
|
-
import { RawAccount,
|
|
8
|
+
import { RawAccount, RawAccountID, RawProfile } from "./coValues/account.js";
|
|
9
9
|
import { parseJSON } from "./jsonStringify.js";
|
|
10
10
|
import { EVERYONE, Everyone } from "./coValues/group.js";
|
|
11
11
|
import { expectGroup } from "./typeUtils/expectGroup.js";
|
|
12
12
|
|
|
13
13
|
export type PermissionsDef =
|
|
14
|
-
| { type: "group"; initialAdmin:
|
|
14
|
+
| { type: "group"; initialAdmin: RawAccountID | AgentID }
|
|
15
15
|
| { type: "ownedByGroup"; group: RawCoID }
|
|
16
16
|
| { type: "unsafeAllowAll" };
|
|
17
17
|
|
|
@@ -53,7 +53,7 @@ export function determineValidTransactions(
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
const memberState: {
|
|
56
|
-
[agent:
|
|
56
|
+
[agent: RawAccountID | AgentID]: Role;
|
|
57
57
|
[EVERYONE]?: Role;
|
|
58
58
|
} = {};
|
|
59
59
|
|
|
@@ -99,7 +99,7 @@ export function determineValidTransactions(
|
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
const change = changes[0] as
|
|
102
|
-
| MapOpPayload<
|
|
102
|
+
| MapOpPayload<RawAccountID | AgentID | Everyone, Role>
|
|
103
103
|
| MapOpPayload<"readKey", JsonValue>
|
|
104
104
|
| MapOpPayload<"profile", CoID<RawProfile>>;
|
|
105
105
|
if (changes.length !== 1) {
|
|
@@ -303,7 +303,7 @@ export function isKeyForKeyField(co: string): co is `${KeyID}_for_${KeyID}` {
|
|
|
303
303
|
|
|
304
304
|
export function isKeyForAccountField(
|
|
305
305
|
co: string,
|
|
306
|
-
): co is `${KeyID}_for_${
|
|
306
|
+
): co is `${KeyID}_for_${RawAccountID | AgentID}` {
|
|
307
307
|
return (
|
|
308
308
|
(co.startsWith("key_") &&
|
|
309
309
|
(co.includes("_for_sealer") || co.includes("_for_co"))) ||
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { expect, test } from "vitest";
|
|
2
|
-
import { newRandomSessionID } from "../coValueCore.js";
|
|
3
2
|
import { LocalNode } from "../localNode.js";
|
|
4
3
|
import { connectedPeers } from "../streamUtils.js";
|
|
5
4
|
import { WasmCrypto } from "../crypto/WasmCrypto.js";
|
|
@@ -65,7 +64,7 @@ test("Can create account with one node, and then load it on another", async () =
|
|
|
65
64
|
const node2 = await LocalNode.withLoadedAccount({
|
|
66
65
|
accountID,
|
|
67
66
|
accountSecret,
|
|
68
|
-
sessionID: newRandomSessionID(accountID),
|
|
67
|
+
sessionID: Crypto.newRandomSessionID(accountID),
|
|
69
68
|
peersToLoadFrom: [node1asPeer],
|
|
70
69
|
crypto: Crypto,
|
|
71
70
|
});
|