cojson 0.1.6 → 0.1.8
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/account.d.ts +2 -5
- package/dist/account.js.map +1 -1
- package/dist/coValue.d.ts +5 -5
- package/dist/coValue.js +4 -4
- package/dist/coValue.js.map +1 -1
- package/dist/contentTypes/coList.d.ts +6 -2
- package/dist/contentTypes/coList.js +15 -1
- package/dist/contentTypes/coList.js.map +1 -1
- package/dist/contentTypes/coMap.d.ts +3 -1
- package/dist/contentTypes/coMap.js +4 -1
- package/dist/contentTypes/coMap.js.map +1 -1
- package/dist/group.d.ts +7 -8
- package/dist/group.js +15 -2
- package/dist/group.js.map +1 -1
- package/dist/ids.d.ts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/node.d.ts +4 -26
- package/dist/node.js +15 -6
- package/dist/node.js.map +1 -1
- package/dist/permissions.d.ts +4 -4
- package/dist/permissions.js.map +1 -1
- package/package.json +2 -2
- package/src/account.test.ts +1 -1
- package/src/account.ts +2 -6
- package/src/coValue.test.ts +7 -7
- package/src/coValue.ts +8 -9
- package/src/contentTypes/coList.ts +28 -2
- package/src/contentTypes/coMap.ts +6 -1
- package/src/group.ts +26 -10
- package/src/ids.ts +2 -2
- package/src/index.ts +2 -1
- package/src/node.ts +19 -9
- package/src/permissions.test.ts +2 -2
- package/src/permissions.ts +6 -6
- package/src/sync.test.ts +27 -27
- package/tsconfig.json +1 -0
package/src/node.ts
CHANGED
|
@@ -23,7 +23,6 @@ import { CoID, ContentType } from "./contentType.js";
|
|
|
23
23
|
import {
|
|
24
24
|
Account,
|
|
25
25
|
AccountMeta,
|
|
26
|
-
AccountIDOrAgentID,
|
|
27
26
|
accountHeaderForInitialAgentSecret,
|
|
28
27
|
GeneralizedControlledAccount,
|
|
29
28
|
ControlledAccount,
|
|
@@ -36,17 +35,19 @@ import {
|
|
|
36
35
|
import { CoMap } from "./index.js";
|
|
37
36
|
|
|
38
37
|
export class LocalNode {
|
|
38
|
+
/** @internal */
|
|
39
39
|
coValues: { [key: RawCoID]: CoValueState } = {};
|
|
40
|
+
/** @internal */
|
|
40
41
|
account: GeneralizedControlledAccount;
|
|
41
|
-
|
|
42
|
+
currentSessionID: SessionID;
|
|
42
43
|
sync = new SyncManager(this);
|
|
43
44
|
|
|
44
45
|
constructor(
|
|
45
46
|
account: GeneralizedControlledAccount,
|
|
46
|
-
|
|
47
|
+
currentSessionID: SessionID
|
|
47
48
|
) {
|
|
48
49
|
this.account = account;
|
|
49
|
-
this.
|
|
50
|
+
this.currentSessionID = currentSessionID;
|
|
50
51
|
}
|
|
51
52
|
|
|
52
53
|
static withNewlyCreatedAccount(
|
|
@@ -75,7 +76,7 @@ export class LocalNode {
|
|
|
75
76
|
node: nodeWithAccount,
|
|
76
77
|
accountID: account.id,
|
|
77
78
|
accountSecret: account.agentSecret,
|
|
78
|
-
sessionID: nodeWithAccount.
|
|
79
|
+
sessionID: nodeWithAccount.currentSessionID,
|
|
79
80
|
};
|
|
80
81
|
}
|
|
81
82
|
|
|
@@ -109,6 +110,7 @@ export class LocalNode {
|
|
|
109
110
|
return node;
|
|
110
111
|
}
|
|
111
112
|
|
|
113
|
+
/** @internal */
|
|
112
114
|
createCoValue(header: CoValueHeader): CoValue {
|
|
113
115
|
const coValue = new CoValue(header, this);
|
|
114
116
|
this.coValues[coValue.id] = { state: "loaded", coValue: coValue };
|
|
@@ -118,6 +120,7 @@ export class LocalNode {
|
|
|
118
120
|
return coValue;
|
|
119
121
|
}
|
|
120
122
|
|
|
123
|
+
/** @internal */
|
|
121
124
|
loadCoValue(id: RawCoID): Promise<CoValue> {
|
|
122
125
|
let entry = this.coValues[id];
|
|
123
126
|
if (!entry) {
|
|
@@ -210,7 +213,7 @@ export class LocalNode {
|
|
|
210
213
|
newRandomSessionID(inviteAgentID)
|
|
211
214
|
);
|
|
212
215
|
|
|
213
|
-
groupAsInvite.
|
|
216
|
+
groupAsInvite.addMemberInternal(
|
|
214
217
|
this.account.id,
|
|
215
218
|
inviteRole === "adminInvite"
|
|
216
219
|
? "admin"
|
|
@@ -227,6 +230,7 @@ export class LocalNode {
|
|
|
227
230
|
}
|
|
228
231
|
}
|
|
229
232
|
|
|
233
|
+
/** @internal */
|
|
230
234
|
expectCoValueLoaded(id: RawCoID, expectation?: string): CoValue {
|
|
231
235
|
const entry = this.coValues[id];
|
|
232
236
|
if (!entry) {
|
|
@@ -244,6 +248,7 @@ export class LocalNode {
|
|
|
244
248
|
return entry.coValue;
|
|
245
249
|
}
|
|
246
250
|
|
|
251
|
+
/** @internal */
|
|
247
252
|
expectProfileLoaded(id: AccountID, expectation?: string): Profile {
|
|
248
253
|
const account = this.expectCoValueLoaded(id, expectation);
|
|
249
254
|
const profileID = expectGroupContent(account.getCurrentContent()).get(
|
|
@@ -262,6 +267,7 @@ export class LocalNode {
|
|
|
262
267
|
).getCurrentContent() as Profile;
|
|
263
268
|
}
|
|
264
269
|
|
|
270
|
+
/** @internal */
|
|
265
271
|
createAccount(
|
|
266
272
|
name: string,
|
|
267
273
|
agentSecret = newRandomAgentSecret()
|
|
@@ -326,7 +332,8 @@ export class LocalNode {
|
|
|
326
332
|
return controlledAccount;
|
|
327
333
|
}
|
|
328
334
|
|
|
329
|
-
|
|
335
|
+
/** @internal */
|
|
336
|
+
resolveAccountAgent(id: AccountID | AgentID, expectation?: string): AgentID {
|
|
330
337
|
if (isAgentID(id)) {
|
|
331
338
|
return id;
|
|
332
339
|
}
|
|
@@ -388,11 +395,12 @@ export class LocalNode {
|
|
|
388
395
|
return new Group(groupContent, this);
|
|
389
396
|
}
|
|
390
397
|
|
|
398
|
+
/** @internal */
|
|
391
399
|
testWithDifferentAccount(
|
|
392
400
|
account: GeneralizedControlledAccount,
|
|
393
|
-
|
|
401
|
+
currentSessionID: SessionID
|
|
394
402
|
): LocalNode {
|
|
395
|
-
const newNode = new LocalNode(account,
|
|
403
|
+
const newNode = new LocalNode(account, currentSessionID);
|
|
396
404
|
|
|
397
405
|
const coValuesToCopy = Object.entries(this.coValues);
|
|
398
406
|
|
|
@@ -429,6 +437,7 @@ export class LocalNode {
|
|
|
429
437
|
}
|
|
430
438
|
}
|
|
431
439
|
|
|
440
|
+
/** @internal */
|
|
432
441
|
type CoValueState =
|
|
433
442
|
| {
|
|
434
443
|
state: "loading";
|
|
@@ -437,6 +446,7 @@ type CoValueState =
|
|
|
437
446
|
}
|
|
438
447
|
| { state: "loaded"; coValue: CoValue };
|
|
439
448
|
|
|
449
|
+
/** @internal */
|
|
440
450
|
export function newLoadingState(): CoValueState {
|
|
441
451
|
let resolve: (coValue: CoValue) => void;
|
|
442
452
|
|
package/src/permissions.test.ts
CHANGED
|
@@ -108,7 +108,7 @@ test("Admins can't demote other admins in a group (high level)", () => {
|
|
|
108
108
|
newRandomSessionID(otherAdmin.id)
|
|
109
109
|
);
|
|
110
110
|
|
|
111
|
-
expect(() => groupAsOtherAdmin.
|
|
111
|
+
expect(() => groupAsOtherAdmin.addMemberInternal(admin.id, "writer")).toThrow(
|
|
112
112
|
"Failed to set role"
|
|
113
113
|
);
|
|
114
114
|
|
|
@@ -1378,7 +1378,7 @@ test("Admins can create an adminInvite, which can add an admin (high-level)", as
|
|
|
1378
1378
|
groupAsInvitedAdmin.groupMap.coValue.getCurrentReadKey().secret
|
|
1379
1379
|
).toBeDefined();
|
|
1380
1380
|
|
|
1381
|
-
groupAsInvitedAdmin.
|
|
1381
|
+
groupAsInvitedAdmin.addMemberInternal(thirdAdminID, "admin");
|
|
1382
1382
|
|
|
1383
1383
|
expect(groupAsInvitedAdmin.groupMap.get(thirdAdminID)).toEqual("admin");
|
|
1384
1384
|
});
|
package/src/permissions.ts
CHANGED
|
@@ -10,14 +10,14 @@ import {
|
|
|
10
10
|
TrustingTransaction,
|
|
11
11
|
accountOrAgentIDfromSessionID,
|
|
12
12
|
} from "./coValue.js";
|
|
13
|
-
import { RawCoID, SessionID, TransactionID } from "./ids.js";
|
|
13
|
+
import { AgentID, RawCoID, SessionID, TransactionID } from "./ids.js";
|
|
14
14
|
import {
|
|
15
|
-
|
|
15
|
+
AccountID,
|
|
16
16
|
Profile,
|
|
17
17
|
} from "./account.js";
|
|
18
18
|
|
|
19
19
|
export type PermissionsDef =
|
|
20
|
-
| { type: "group"; initialAdmin:
|
|
20
|
+
| { type: "group"; initialAdmin: AccountID | AgentID }
|
|
21
21
|
| { type: "ownedByGroup"; group: RawCoID }
|
|
22
22
|
| { type: "unsafeAllowAll" };
|
|
23
23
|
|
|
@@ -63,7 +63,7 @@ export function determineValidTransactions(
|
|
|
63
63
|
throw new Error("Group must have initialAdmin");
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
const memberState: { [agent:
|
|
66
|
+
const memberState: { [agent: AccountID | AgentID]: Role } = {};
|
|
67
67
|
|
|
68
68
|
const validTransactions: { txID: TransactionID; tx: Transaction }[] =
|
|
69
69
|
[];
|
|
@@ -77,7 +77,7 @@ export function determineValidTransactions(
|
|
|
77
77
|
const transactor = accountOrAgentIDfromSessionID(sessionID);
|
|
78
78
|
|
|
79
79
|
const change = tx.changes[0] as
|
|
80
|
-
| MapOpPayload<
|
|
80
|
+
| MapOpPayload<AccountID | AgentID, Role>
|
|
81
81
|
| MapOpPayload<"readKey", JsonValue>
|
|
82
82
|
| MapOpPayload<"profile", CoID<Profile>>;
|
|
83
83
|
if (tx.changes.length !== 1) {
|
|
@@ -248,7 +248,7 @@ export function isKeyForKeyField(
|
|
|
248
248
|
|
|
249
249
|
export function isKeyForAccountField(
|
|
250
250
|
field: string
|
|
251
|
-
): field is `${KeyID}_for_${
|
|
251
|
+
): field is `${KeyID}_for_${AccountID | AgentID}` {
|
|
252
252
|
return (
|
|
253
253
|
field.startsWith("key_") &&
|
|
254
254
|
(field.includes("_for_sealer") || field.includes("_for_co"))
|
package/src/sync.test.ts
CHANGED
|
@@ -77,12 +77,12 @@ test("Node replies with initial tx and header to empty subscribe", async () => {
|
|
|
77
77
|
uniqueness: map.coValue.header.uniqueness,
|
|
78
78
|
},
|
|
79
79
|
new: {
|
|
80
|
-
[node.
|
|
80
|
+
[node.currentSessionID]: {
|
|
81
81
|
after: 0,
|
|
82
82
|
newTransactions: [
|
|
83
83
|
{
|
|
84
84
|
privacy: "trusting" as const,
|
|
85
|
-
madeAt: map.coValue.sessions[node.
|
|
85
|
+
madeAt: map.coValue.sessions[node.currentSessionID]!
|
|
86
86
|
.transactions[0]!.madeAt,
|
|
87
87
|
changes: [
|
|
88
88
|
{
|
|
@@ -94,7 +94,7 @@ test("Node replies with initial tx and header to empty subscribe", async () => {
|
|
|
94
94
|
},
|
|
95
95
|
],
|
|
96
96
|
lastSignature:
|
|
97
|
-
map.coValue.sessions[node.
|
|
97
|
+
map.coValue.sessions[node.currentSessionID]!.lastSignature!,
|
|
98
98
|
},
|
|
99
99
|
},
|
|
100
100
|
} satisfies SyncMessage);
|
|
@@ -130,7 +130,7 @@ test("Node replies with only new tx to subscribe with some known state", async (
|
|
|
130
130
|
id: map.coValue.id,
|
|
131
131
|
header: true,
|
|
132
132
|
sessions: {
|
|
133
|
-
[node.
|
|
133
|
+
[node.currentSessionID]: 1,
|
|
134
134
|
},
|
|
135
135
|
});
|
|
136
136
|
|
|
@@ -155,12 +155,12 @@ test("Node replies with only new tx to subscribe with some known state", async (
|
|
|
155
155
|
id: map.coValue.id,
|
|
156
156
|
header: undefined,
|
|
157
157
|
new: {
|
|
158
|
-
[node.
|
|
158
|
+
[node.currentSessionID]: {
|
|
159
159
|
after: 1,
|
|
160
160
|
newTransactions: [
|
|
161
161
|
{
|
|
162
162
|
privacy: "trusting" as const,
|
|
163
|
-
madeAt: map.coValue.sessions[node.
|
|
163
|
+
madeAt: map.coValue.sessions[node.currentSessionID]!
|
|
164
164
|
.transactions[1]!.madeAt,
|
|
165
165
|
changes: [
|
|
166
166
|
{
|
|
@@ -172,7 +172,7 @@ test("Node replies with only new tx to subscribe with some known state", async (
|
|
|
172
172
|
},
|
|
173
173
|
],
|
|
174
174
|
lastSignature:
|
|
175
|
-
map.coValue.sessions[node.
|
|
175
|
+
map.coValue.sessions[node.currentSessionID]!.lastSignature!,
|
|
176
176
|
},
|
|
177
177
|
},
|
|
178
178
|
} satisfies SyncMessage);
|
|
@@ -207,7 +207,7 @@ test("After subscribing, node sends own known state and new txs to peer", async
|
|
|
207
207
|
id: map.coValue.id,
|
|
208
208
|
header: false,
|
|
209
209
|
sessions: {
|
|
210
|
-
[node.
|
|
210
|
+
[node.currentSessionID]: 0,
|
|
211
211
|
},
|
|
212
212
|
});
|
|
213
213
|
|
|
@@ -244,12 +244,12 @@ test("After subscribing, node sends own known state and new txs to peer", async
|
|
|
244
244
|
action: "content",
|
|
245
245
|
id: map.coValue.id,
|
|
246
246
|
new: {
|
|
247
|
-
[node.
|
|
247
|
+
[node.currentSessionID]: {
|
|
248
248
|
after: 0,
|
|
249
249
|
newTransactions: [
|
|
250
250
|
{
|
|
251
251
|
privacy: "trusting" as const,
|
|
252
|
-
madeAt: map.coValue.sessions[node.
|
|
252
|
+
madeAt: map.coValue.sessions[node.currentSessionID]!
|
|
253
253
|
.transactions[0]!.madeAt,
|
|
254
254
|
changes: [
|
|
255
255
|
{
|
|
@@ -261,7 +261,7 @@ test("After subscribing, node sends own known state and new txs to peer", async
|
|
|
261
261
|
},
|
|
262
262
|
],
|
|
263
263
|
lastSignature:
|
|
264
|
-
map.coValue.sessions[node.
|
|
264
|
+
map.coValue.sessions[node.currentSessionID]!.lastSignature!,
|
|
265
265
|
},
|
|
266
266
|
},
|
|
267
267
|
} satisfies SyncMessage);
|
|
@@ -276,12 +276,12 @@ test("After subscribing, node sends own known state and new txs to peer", async
|
|
|
276
276
|
action: "content",
|
|
277
277
|
id: map.coValue.id,
|
|
278
278
|
new: {
|
|
279
|
-
[node.
|
|
279
|
+
[node.currentSessionID]: {
|
|
280
280
|
after: 1,
|
|
281
281
|
newTransactions: [
|
|
282
282
|
{
|
|
283
283
|
privacy: "trusting" as const,
|
|
284
|
-
madeAt: map.coValue.sessions[node.
|
|
284
|
+
madeAt: map.coValue.sessions[node.currentSessionID]!
|
|
285
285
|
.transactions[1]!.madeAt,
|
|
286
286
|
changes: [
|
|
287
287
|
{
|
|
@@ -293,7 +293,7 @@ test("After subscribing, node sends own known state and new txs to peer", async
|
|
|
293
293
|
},
|
|
294
294
|
],
|
|
295
295
|
lastSignature:
|
|
296
|
-
map.coValue.sessions[node.
|
|
296
|
+
map.coValue.sessions[node.currentSessionID]!.lastSignature!,
|
|
297
297
|
},
|
|
298
298
|
},
|
|
299
299
|
} satisfies SyncMessage);
|
|
@@ -332,7 +332,7 @@ test("Client replies with known new content to tellKnownState from server", asyn
|
|
|
332
332
|
id: map.coValue.id,
|
|
333
333
|
header: false,
|
|
334
334
|
sessions: {
|
|
335
|
-
[node.
|
|
335
|
+
[node.currentSessionID]: 0,
|
|
336
336
|
},
|
|
337
337
|
});
|
|
338
338
|
|
|
@@ -355,12 +355,12 @@ test("Client replies with known new content to tellKnownState from server", asyn
|
|
|
355
355
|
id: map.coValue.id,
|
|
356
356
|
header: map.coValue.header,
|
|
357
357
|
new: {
|
|
358
|
-
[node.
|
|
358
|
+
[node.currentSessionID]: {
|
|
359
359
|
after: 0,
|
|
360
360
|
newTransactions: [
|
|
361
361
|
{
|
|
362
362
|
privacy: "trusting" as const,
|
|
363
|
-
madeAt: map.coValue.sessions[node.
|
|
363
|
+
madeAt: map.coValue.sessions[node.currentSessionID]!
|
|
364
364
|
.transactions[0]!.madeAt,
|
|
365
365
|
changes: [
|
|
366
366
|
{
|
|
@@ -372,7 +372,7 @@ test("Client replies with known new content to tellKnownState from server", asyn
|
|
|
372
372
|
},
|
|
373
373
|
],
|
|
374
374
|
lastSignature:
|
|
375
|
-
map.coValue.sessions[node.
|
|
375
|
+
map.coValue.sessions[node.currentSessionID]!.lastSignature!,
|
|
376
376
|
},
|
|
377
377
|
},
|
|
378
378
|
} satisfies SyncMessage);
|
|
@@ -403,7 +403,7 @@ test("No matter the optimistic known state, node respects invalid known state me
|
|
|
403
403
|
id: map.coValue.id,
|
|
404
404
|
header: false,
|
|
405
405
|
sessions: {
|
|
406
|
-
[node.
|
|
406
|
+
[node.currentSessionID]: 0,
|
|
407
407
|
},
|
|
408
408
|
});
|
|
409
409
|
|
|
@@ -447,7 +447,7 @@ test("No matter the optimistic known state, node respects invalid known state me
|
|
|
447
447
|
id: map.coValue.id,
|
|
448
448
|
header: true,
|
|
449
449
|
sessions: {
|
|
450
|
-
[node.
|
|
450
|
+
[node.currentSessionID]: 1,
|
|
451
451
|
},
|
|
452
452
|
} satisfies SyncMessage);
|
|
453
453
|
|
|
@@ -458,12 +458,12 @@ test("No matter the optimistic known state, node respects invalid known state me
|
|
|
458
458
|
id: map.coValue.id,
|
|
459
459
|
header: undefined,
|
|
460
460
|
new: {
|
|
461
|
-
[node.
|
|
461
|
+
[node.currentSessionID]: {
|
|
462
462
|
after: 1,
|
|
463
463
|
newTransactions: [
|
|
464
464
|
{
|
|
465
465
|
privacy: "trusting" as const,
|
|
466
|
-
madeAt: map.coValue.sessions[node.
|
|
466
|
+
madeAt: map.coValue.sessions[node.currentSessionID]!
|
|
467
467
|
.transactions[1]!.madeAt,
|
|
468
468
|
changes: [
|
|
469
469
|
{
|
|
@@ -475,7 +475,7 @@ test("No matter the optimistic known state, node respects invalid known state me
|
|
|
475
475
|
},
|
|
476
476
|
],
|
|
477
477
|
lastSignature:
|
|
478
|
-
map.coValue.sessions[node.
|
|
478
|
+
map.coValue.sessions[node.currentSessionID]!.lastSignature!,
|
|
479
479
|
},
|
|
480
480
|
},
|
|
481
481
|
} satisfies SyncMessage);
|
|
@@ -561,12 +561,12 @@ test("If we add a server peer, all updates to all coValues are sent to it, even
|
|
|
561
561
|
id: map.coValue.id,
|
|
562
562
|
header: map.coValue.header,
|
|
563
563
|
new: {
|
|
564
|
-
[node.
|
|
564
|
+
[node.currentSessionID]: {
|
|
565
565
|
after: 0,
|
|
566
566
|
newTransactions: [
|
|
567
567
|
{
|
|
568
568
|
privacy: "trusting" as const,
|
|
569
|
-
madeAt: map.coValue.sessions[node.
|
|
569
|
+
madeAt: map.coValue.sessions[node.currentSessionID]!
|
|
570
570
|
.transactions[0]!.madeAt,
|
|
571
571
|
changes: [
|
|
572
572
|
{
|
|
@@ -578,7 +578,7 @@ test("If we add a server peer, all updates to all coValues are sent to it, even
|
|
|
578
578
|
},
|
|
579
579
|
],
|
|
580
580
|
lastSignature:
|
|
581
|
-
map.coValue.sessions[node.
|
|
581
|
+
map.coValue.sessions[node.currentSessionID]!.lastSignature!,
|
|
582
582
|
},
|
|
583
583
|
},
|
|
584
584
|
} satisfies SyncMessage);
|
|
@@ -697,7 +697,7 @@ test("When receiving a subscribe with a known state that is ahead of our own, pe
|
|
|
697
697
|
id: map.coValue.id,
|
|
698
698
|
header: true,
|
|
699
699
|
sessions: {
|
|
700
|
-
[node.
|
|
700
|
+
[node.currentSessionID]: 1,
|
|
701
701
|
},
|
|
702
702
|
});
|
|
703
703
|
|