cojson 0.6.6 → 0.7.0-alpha.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/.eslintrc.cjs +1 -0
- package/.turbo/turbo-build.log +35 -0
- package/CHANGELOG.md +6 -0
- package/dist/coValue.js.map +1 -1
- package/dist/coValueCore.js.map +1 -1
- package/dist/coValues/account.js +5 -5
- package/dist/coValues/account.js.map +1 -1
- package/dist/coValues/coList.js +39 -58
- package/dist/coValues/coList.js.map +1 -1
- package/dist/coValues/coMap.js +20 -61
- package/dist/coValues/coMap.js.map +1 -1
- package/dist/coValues/coStream.js +14 -64
- package/dist/coValues/coStream.js.map +1 -1
- package/dist/coValues/group.js +57 -59
- package/dist/coValues/group.js.map +1 -1
- package/dist/coreToCoValue.js +17 -12
- package/dist/coreToCoValue.js.map +1 -1
- package/dist/index.js +8 -8
- package/dist/index.js.map +1 -1
- package/dist/localNode.js +54 -38
- package/dist/localNode.js.map +1 -1
- package/dist/permissions.js +2 -2
- package/dist/permissions.js.map +1 -1
- package/dist/sync.js +3 -3
- package/dist/sync.js.map +1 -1
- package/dist/tests/testUtils.js +6 -11
- package/dist/tests/testUtils.js.map +1 -1
- package/dist/typeUtils/expectGroup.js +2 -2
- package/dist/typeUtils/expectGroup.js.map +1 -1
- package/dist/typeUtils/isCoValue.js +8 -8
- package/dist/typeUtils/isCoValue.js.map +1 -1
- package/package.json +52 -53
- package/src/coValue.ts +21 -21
- package/src/coValueCore.ts +8 -8
- package/src/coValues/account.ts +14 -26
- package/src/coValues/coList.ts +58 -97
- package/src/coValues/coMap.ts +27 -129
- package/src/coValues/coStream.ts +31 -137
- package/src/coValues/group.ts +52 -46
- package/src/coreToCoValue.ts +16 -12
- package/src/index.ts +27 -36
- package/src/jsonValue.ts +1 -1
- package/src/localNode.ts +88 -75
- package/src/media.ts +4 -4
- package/src/permissions.ts +2 -2
- package/src/sync.ts +3 -3
- package/src/tests/account.test.ts +12 -12
- package/src/tests/coValue.test.ts +149 -182
- package/src/tests/coValueCore.test.ts +8 -3
- package/src/tests/crypto.test.ts +7 -0
- package/src/tests/group.test.ts +13 -6
- package/src/tests/permissions.test.ts +648 -840
- package/src/tests/sync.test.ts +44 -68
- package/src/tests/testUtils.ts +6 -11
- package/src/typeUtils/expectGroup.ts +4 -4
- package/src/typeUtils/isCoValue.ts +11 -11
package/src/localNode.ts
CHANGED
|
@@ -16,25 +16,25 @@ import {
|
|
|
16
16
|
} from "./coValueCore.js";
|
|
17
17
|
import {
|
|
18
18
|
InviteSecret,
|
|
19
|
-
|
|
19
|
+
RawGroup,
|
|
20
20
|
secretSeedFromInviteSecret,
|
|
21
21
|
} from "./coValues/group.js";
|
|
22
22
|
import { Peer, PeerID, SyncManager } from "./sync.js";
|
|
23
23
|
import { AgentID, RawCoID, SessionID, isAgentID } from "./ids.js";
|
|
24
24
|
import { CoID } from "./coValue.js";
|
|
25
25
|
import {
|
|
26
|
-
|
|
26
|
+
RawAccount,
|
|
27
27
|
AccountMeta,
|
|
28
28
|
accountHeaderForInitialAgentSecret,
|
|
29
29
|
ControlledAccountOrAgent,
|
|
30
|
-
|
|
30
|
+
RawControlledAccount,
|
|
31
31
|
ControlledAgent,
|
|
32
32
|
AccountID,
|
|
33
33
|
Profile,
|
|
34
|
-
|
|
34
|
+
RawAccountMigration,
|
|
35
35
|
} from "./coValues/account.js";
|
|
36
|
-
import {
|
|
37
|
-
import {
|
|
36
|
+
import { RawCoMap } from "./coValues/coMap.js";
|
|
37
|
+
import { RawCoValue } from "./index.js";
|
|
38
38
|
import { expectGroup } from "./typeUtils/expectGroup.js";
|
|
39
39
|
|
|
40
40
|
/** A `LocalNode` represents a local view of a set of loaded `CoValue`s, from the perspective of a particular account (or primitive cryptographic agent).
|
|
@@ -69,8 +69,6 @@ export class LocalNode {
|
|
|
69
69
|
|
|
70
70
|
/** @category 2. Node Creation */
|
|
71
71
|
static async withNewlyCreatedAccount<
|
|
72
|
-
P extends Profile = Profile,
|
|
73
|
-
R extends CoMap = CoMap,
|
|
74
72
|
Meta extends AccountMeta = AccountMeta
|
|
75
73
|
>({
|
|
76
74
|
name,
|
|
@@ -80,7 +78,7 @@ export class LocalNode {
|
|
|
80
78
|
}: {
|
|
81
79
|
name: string;
|
|
82
80
|
peersToLoadFrom?: Peer[];
|
|
83
|
-
migration?:
|
|
81
|
+
migration?: RawAccountMigration<Meta>;
|
|
84
82
|
initialAgentSecret?: AgentSecret;
|
|
85
83
|
}): Promise<{
|
|
86
84
|
node: LocalNode;
|
|
@@ -102,7 +100,7 @@ export class LocalNode {
|
|
|
102
100
|
);
|
|
103
101
|
|
|
104
102
|
const accountOnNodeWithAccount =
|
|
105
|
-
nodeWithAccount.account as
|
|
103
|
+
nodeWithAccount.account as RawControlledAccount<Meta>;
|
|
106
104
|
|
|
107
105
|
const profile = nodeWithAccount.expectProfileLoaded(
|
|
108
106
|
accountOnNodeWithAccount.id,
|
|
@@ -116,19 +114,30 @@ export class LocalNode {
|
|
|
116
114
|
}
|
|
117
115
|
|
|
118
116
|
if (migration) {
|
|
119
|
-
await migration(accountOnNodeWithAccount, profile
|
|
117
|
+
await migration(accountOnNodeWithAccount, profile, nodeWithAccount);
|
|
120
118
|
}
|
|
121
119
|
|
|
122
|
-
|
|
120
|
+
const controlledAccount = new RawControlledAccount(
|
|
123
121
|
accountOnNodeWithAccount.core,
|
|
124
122
|
accountOnNodeWithAccount.agentSecret
|
|
125
123
|
);
|
|
126
124
|
|
|
125
|
+
nodeWithAccount.account = controlledAccount
|
|
126
|
+
nodeWithAccount.coValues[controlledAccount.id] = {
|
|
127
|
+
state: "loaded",
|
|
128
|
+
coValue: controlledAccount.core,
|
|
129
|
+
};
|
|
130
|
+
controlledAccount.core._cachedContent = undefined;
|
|
131
|
+
|
|
127
132
|
// we shouldn't need this, but it fixes account data not syncing for new accounts
|
|
128
133
|
function syncAllCoValuesAfterCreateAccount() {
|
|
129
|
-
for (const coValueEntry of Object.values(
|
|
134
|
+
for (const coValueEntry of Object.values(
|
|
135
|
+
nodeWithAccount.coValues
|
|
136
|
+
)) {
|
|
130
137
|
if (coValueEntry.state === "loaded") {
|
|
131
|
-
void nodeWithAccount.syncManager.syncCoValue(
|
|
138
|
+
void nodeWithAccount.syncManager.syncCoValue(
|
|
139
|
+
coValueEntry.coValue
|
|
140
|
+
);
|
|
132
141
|
}
|
|
133
142
|
}
|
|
134
143
|
}
|
|
@@ -146,11 +155,7 @@ export class LocalNode {
|
|
|
146
155
|
}
|
|
147
156
|
|
|
148
157
|
/** @category 2. Node Creation */
|
|
149
|
-
static async withLoadedAccount<
|
|
150
|
-
P extends Profile = Profile,
|
|
151
|
-
R extends CoMap = CoMap,
|
|
152
|
-
Meta extends AccountMeta = AccountMeta
|
|
153
|
-
>({
|
|
158
|
+
static async withLoadedAccount<Meta extends AccountMeta = AccountMeta>({
|
|
154
159
|
accountID,
|
|
155
160
|
accountSecret,
|
|
156
161
|
sessionID,
|
|
@@ -161,7 +166,7 @@ export class LocalNode {
|
|
|
161
166
|
accountSecret: AgentSecret;
|
|
162
167
|
sessionID: SessionID;
|
|
163
168
|
peersToLoadFrom: Peer[];
|
|
164
|
-
migration?:
|
|
169
|
+
migration?: RawAccountMigration<Meta>;
|
|
165
170
|
}): Promise<LocalNode> {
|
|
166
171
|
const loadingNode = new LocalNode(
|
|
167
172
|
new ControlledAgent(accountSecret),
|
|
@@ -180,7 +185,7 @@ export class LocalNode {
|
|
|
180
185
|
throw new Error("Account unavailable from all peers");
|
|
181
186
|
}
|
|
182
187
|
|
|
183
|
-
const controlledAccount = new
|
|
188
|
+
const controlledAccount = new RawControlledAccount(
|
|
184
189
|
account.core,
|
|
185
190
|
accountSecret
|
|
186
191
|
);
|
|
@@ -198,6 +203,7 @@ export class LocalNode {
|
|
|
198
203
|
state: "loaded",
|
|
199
204
|
coValue: controlledAccount.core,
|
|
200
205
|
};
|
|
206
|
+
controlledAccount.core._cachedContent = undefined;
|
|
201
207
|
|
|
202
208
|
const profileID = account.get("profile");
|
|
203
209
|
if (!profileID) {
|
|
@@ -205,13 +211,17 @@ export class LocalNode {
|
|
|
205
211
|
}
|
|
206
212
|
const profile = await node.load(profileID);
|
|
207
213
|
|
|
214
|
+
if (profile === "unavailable") {
|
|
215
|
+
throw new Error("Profile unavailable from all peers");
|
|
216
|
+
}
|
|
217
|
+
|
|
208
218
|
if (migration) {
|
|
209
219
|
await migration(
|
|
210
|
-
controlledAccount as
|
|
211
|
-
profile
|
|
220
|
+
controlledAccount as RawControlledAccount<Meta>,
|
|
221
|
+
profile,
|
|
212
222
|
node
|
|
213
223
|
);
|
|
214
|
-
node.account = new
|
|
224
|
+
node.account = new RawControlledAccount(
|
|
215
225
|
controlledAccount.core,
|
|
216
226
|
controlledAccount.agentSecret
|
|
217
227
|
);
|
|
@@ -275,7 +285,7 @@ export class LocalNode {
|
|
|
275
285
|
*
|
|
276
286
|
* @category 3. Low-level
|
|
277
287
|
*/
|
|
278
|
-
async load<T extends
|
|
288
|
+
async load<T extends RawCoValue>(
|
|
279
289
|
id: CoID<T>,
|
|
280
290
|
onProgress?: (progress: number) => void
|
|
281
291
|
): Promise<T | "unavailable"> {
|
|
@@ -288,8 +298,19 @@ export class LocalNode {
|
|
|
288
298
|
return core.getCurrentContent() as T;
|
|
289
299
|
}
|
|
290
300
|
|
|
301
|
+
getLoaded<T extends RawCoValue>(id: CoID<T>): T | undefined {
|
|
302
|
+
const entry = this.coValues[id];
|
|
303
|
+
if (!entry) {
|
|
304
|
+
return undefined;
|
|
305
|
+
}
|
|
306
|
+
if (entry.state === "loaded") {
|
|
307
|
+
return entry.coValue.getCurrentContent() as T;
|
|
308
|
+
}
|
|
309
|
+
return undefined;
|
|
310
|
+
}
|
|
311
|
+
|
|
291
312
|
/** @category 3. Low-level */
|
|
292
|
-
subscribe<T extends
|
|
313
|
+
subscribe<T extends RawCoValue>(
|
|
293
314
|
id: CoID<T>,
|
|
294
315
|
callback: (update: T | "unavailable") => void
|
|
295
316
|
): () => void {
|
|
@@ -321,7 +342,7 @@ export class LocalNode {
|
|
|
321
342
|
}
|
|
322
343
|
|
|
323
344
|
/** @deprecated Use Account.acceptInvite instead */
|
|
324
|
-
async acceptInvite<T extends
|
|
345
|
+
async acceptInvite<T extends RawCoValue>(
|
|
325
346
|
groupOrOwnedValueID: CoID<T>,
|
|
326
347
|
inviteSecret: InviteSecret
|
|
327
348
|
): Promise<void> {
|
|
@@ -335,7 +356,7 @@ export class LocalNode {
|
|
|
335
356
|
|
|
336
357
|
if (groupOrOwnedValue.core.header.ruleset.type === "ownedByGroup") {
|
|
337
358
|
return this.acceptInvite(
|
|
338
|
-
groupOrOwnedValue.core.header.ruleset.group as CoID<
|
|
359
|
+
groupOrOwnedValue.core.header.ruleset.group as CoID<RawGroup>,
|
|
339
360
|
inviteSecret
|
|
340
361
|
);
|
|
341
362
|
} else if (groupOrOwnedValue.core.header.ruleset.type !== "group") {
|
|
@@ -447,7 +468,7 @@ export class LocalNode {
|
|
|
447
468
|
createAccount(
|
|
448
469
|
name: string,
|
|
449
470
|
agentSecret = newRandomAgentSecret()
|
|
450
|
-
):
|
|
471
|
+
): RawControlledAccount {
|
|
451
472
|
const accountAgentID = getAgentID(agentSecret);
|
|
452
473
|
let account = expectGroup(
|
|
453
474
|
this.createCoValue(accountHeaderForInitialAgentSecret(agentSecret))
|
|
@@ -458,29 +479,23 @@ export class LocalNode {
|
|
|
458
479
|
.getCurrentContent()
|
|
459
480
|
);
|
|
460
481
|
|
|
461
|
-
account
|
|
462
|
-
editable.set(accountAgentID, "admin", "trusting");
|
|
482
|
+
account.set(accountAgentID, "admin", "trusting");
|
|
463
483
|
|
|
464
|
-
|
|
484
|
+
const readKey = newRandomKeySecret();
|
|
465
485
|
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
486
|
+
const sealed = seal({
|
|
487
|
+
message: readKey.secret,
|
|
488
|
+
from: getAgentSealerSecret(agentSecret),
|
|
489
|
+
to: getAgentSealerID(accountAgentID),
|
|
490
|
+
nOnceMaterial: {
|
|
491
|
+
in: account.id,
|
|
492
|
+
tx: account.core.nextTransactionID(),
|
|
493
|
+
},
|
|
494
|
+
});
|
|
475
495
|
|
|
476
|
-
|
|
477
|
-
`${readKey.id}_for_${accountAgentID}`,
|
|
478
|
-
sealed,
|
|
479
|
-
"trusting"
|
|
480
|
-
);
|
|
496
|
+
account.set(`${readKey.id}_for_${accountAgentID}`, sealed, "trusting");
|
|
481
497
|
|
|
482
|
-
|
|
483
|
-
});
|
|
498
|
+
account.set("readKey", readKey.id, "trusting");
|
|
484
499
|
|
|
485
500
|
const profile = account.createMap<Profile>(
|
|
486
501
|
{ name },
|
|
@@ -490,7 +505,7 @@ export class LocalNode {
|
|
|
490
505
|
"trusting"
|
|
491
506
|
);
|
|
492
507
|
|
|
493
|
-
account
|
|
508
|
+
account.set("profile", profile.id, "trusting");
|
|
494
509
|
|
|
495
510
|
const accountOnThisNode = this.expectCoValueLoaded(account.id);
|
|
496
511
|
|
|
@@ -503,7 +518,7 @@ export class LocalNode {
|
|
|
503
518
|
profileOnThisNode._sessionLogs = new Map(profile.core.sessionLogs);
|
|
504
519
|
profileOnThisNode._cachedContent = undefined;
|
|
505
520
|
|
|
506
|
-
return new
|
|
521
|
+
return new RawControlledAccount(accountOnThisNode, agentSecret);
|
|
507
522
|
}
|
|
508
523
|
|
|
509
524
|
/** @internal */
|
|
@@ -531,7 +546,7 @@ export class LocalNode {
|
|
|
531
546
|
);
|
|
532
547
|
}
|
|
533
548
|
|
|
534
|
-
return new
|
|
549
|
+
return new RawAccount(coValue).currentAgentID();
|
|
535
550
|
}
|
|
536
551
|
|
|
537
552
|
async resolveAccountAgentAsync(
|
|
@@ -566,13 +581,13 @@ export class LocalNode {
|
|
|
566
581
|
);
|
|
567
582
|
}
|
|
568
583
|
|
|
569
|
-
return new
|
|
584
|
+
return new RawAccount(coValue).currentAgentID();
|
|
570
585
|
}
|
|
571
586
|
|
|
572
587
|
/**
|
|
573
588
|
* @deprecated use Account.createGroup() instead
|
|
574
589
|
*/
|
|
575
|
-
createGroup():
|
|
590
|
+
createGroup(): RawGroup {
|
|
576
591
|
const groupCoValue = this.createCoValue({
|
|
577
592
|
type: "comap",
|
|
578
593
|
ruleset: { type: "group", initialAdmin: this.account.id },
|
|
@@ -582,27 +597,25 @@ export class LocalNode {
|
|
|
582
597
|
|
|
583
598
|
let group = expectGroup(groupCoValue.getCurrentContent());
|
|
584
599
|
|
|
585
|
-
group
|
|
586
|
-
editable.set(this.account.id, "admin", "trusting");
|
|
587
|
-
|
|
588
|
-
const readKey = newRandomKeySecret();
|
|
589
|
-
|
|
590
|
-
editable.set(
|
|
591
|
-
`${readKey.id}_for_${this.account.id}`,
|
|
592
|
-
seal({
|
|
593
|
-
message: readKey.secret,
|
|
594
|
-
from: this.account.currentSealerSecret(),
|
|
595
|
-
to: this.account.currentSealerID(),
|
|
596
|
-
nOnceMaterial: {
|
|
597
|
-
in: groupCoValue.id,
|
|
598
|
-
tx: groupCoValue.nextTransactionID(),
|
|
599
|
-
},
|
|
600
|
-
}),
|
|
601
|
-
"trusting"
|
|
602
|
-
);
|
|
600
|
+
group.set(this.account.id, "admin", "trusting");
|
|
603
601
|
|
|
604
|
-
|
|
605
|
-
|
|
602
|
+
const readKey = newRandomKeySecret();
|
|
603
|
+
|
|
604
|
+
group.set(
|
|
605
|
+
`${readKey.id}_for_${this.account.id}`,
|
|
606
|
+
seal({
|
|
607
|
+
message: readKey.secret,
|
|
608
|
+
from: this.account.currentSealerSecret(),
|
|
609
|
+
to: this.account.currentSealerID(),
|
|
610
|
+
nOnceMaterial: {
|
|
611
|
+
in: groupCoValue.id,
|
|
612
|
+
tx: groupCoValue.nextTransactionID(),
|
|
613
|
+
},
|
|
614
|
+
}),
|
|
615
|
+
"trusting"
|
|
616
|
+
);
|
|
617
|
+
|
|
618
|
+
group.set("readKey", readKey.id, "trusting");
|
|
606
619
|
|
|
607
620
|
return group;
|
|
608
621
|
}
|
|
@@ -649,9 +662,9 @@ export class LocalNode {
|
|
|
649
662
|
}
|
|
650
663
|
}
|
|
651
664
|
|
|
652
|
-
if (account instanceof
|
|
665
|
+
if (account instanceof RawControlledAccount) {
|
|
653
666
|
// To make sure that when we edit the account, we're modifying the correct sessions
|
|
654
|
-
const accountInNode = new
|
|
667
|
+
const accountInNode = new RawControlledAccount(
|
|
655
668
|
newNode.expectCoValueLoaded(account.id),
|
|
656
669
|
account.agentSecret
|
|
657
670
|
);
|
package/src/media.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { RawCoMap } from './coValues/coMap.js'
|
|
2
|
+
import { RawBinaryCoStream } from './coValues/coStream.js'
|
|
3
3
|
|
|
4
|
-
export type ImageDefinition =
|
|
4
|
+
export type ImageDefinition = RawCoMap<{
|
|
5
5
|
originalSize: [number, number];
|
|
6
6
|
placeholderDataURL?: string;
|
|
7
|
-
[res: `${number}x${number}`]:
|
|
7
|
+
[res: `${number}x${number}`]: RawBinaryCoStream["id"];
|
|
8
8
|
}>;
|
package/src/permissions.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { KeyID } from "./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 {
|
|
8
|
+
import { RawAccount, AccountID, Profile } 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";
|
|
@@ -248,7 +248,7 @@ export function determineValidTransactions(
|
|
|
248
248
|
const groupAtTime = groupContent.atTime(tx.madeAt);
|
|
249
249
|
const effectiveTransactor =
|
|
250
250
|
transactor === groupContent.id &&
|
|
251
|
-
groupAtTime instanceof
|
|
251
|
+
groupAtTime instanceof RawAccount
|
|
252
252
|
? groupAtTime.currentAgentID()
|
|
253
253
|
: transactor;
|
|
254
254
|
const transactorRoleAtTxTime =
|
package/src/sync.ts
CHANGED
|
@@ -690,9 +690,9 @@ export class SyncManager {
|
|
|
690
690
|
const done = new Promise<void>((resolve) => {
|
|
691
691
|
setTimeout(async () => {
|
|
692
692
|
delete this.requestedSyncs[coValue.id];
|
|
693
|
-
if (entry.nRequestsThisTick >= 2) {
|
|
694
|
-
|
|
695
|
-
}
|
|
693
|
+
// if (entry.nRequestsThisTick >= 2) {
|
|
694
|
+
// console.log("Syncing", coValue.id, "for", entry.nRequestsThisTick, "requests");
|
|
695
|
+
// }
|
|
696
696
|
await this.actuallySyncCoValue(coValue);
|
|
697
697
|
resolve();
|
|
698
698
|
}, 0);
|
|
@@ -1,8 +1,15 @@
|
|
|
1
|
+
import { expect, test, beforeEach } from "vitest";
|
|
1
2
|
import { newRandomSessionID } from "../coValueCore.js";
|
|
2
3
|
import { cojsonReady } from "../index.js";
|
|
3
4
|
import { LocalNode } from "../localNode.js";
|
|
4
5
|
import { connectedPeers } from "../streamUtils.js";
|
|
5
6
|
|
|
7
|
+
import { webcrypto } from "node:crypto";
|
|
8
|
+
if (!("crypto" in globalThis)) {
|
|
9
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
10
|
+
(globalThis as any).crypto = webcrypto;
|
|
11
|
+
}
|
|
12
|
+
|
|
6
13
|
beforeEach(async () => {
|
|
7
14
|
await cojsonReady;
|
|
8
15
|
});
|
|
@@ -29,14 +36,9 @@ test("A node with an account can create groups and and objects within them", asy
|
|
|
29
36
|
const group = await node.createGroup();
|
|
30
37
|
expect(group).not.toBeNull();
|
|
31
38
|
|
|
32
|
-
|
|
33
|
-
map
|
|
34
|
-
edit.set("foo", "bar", "private");
|
|
35
|
-
expect(edit.get("foo")).toEqual("bar");
|
|
36
|
-
});
|
|
37
|
-
|
|
39
|
+
const map = group.createMap();
|
|
40
|
+
map.set("foo", "bar", "private");
|
|
38
41
|
expect(map.get("foo")).toEqual("bar");
|
|
39
|
-
|
|
40
42
|
expect(map.lastEditAt("foo")?.by).toEqual(accountID);
|
|
41
43
|
});
|
|
42
44
|
|
|
@@ -47,11 +49,9 @@ test("Can create account with one node, and then load it on another", async () =
|
|
|
47
49
|
const group = await node.createGroup();
|
|
48
50
|
expect(group).not.toBeNull();
|
|
49
51
|
|
|
50
|
-
|
|
51
|
-
map
|
|
52
|
-
|
|
53
|
-
expect(edit.get("foo")).toEqual("bar");
|
|
54
|
-
});
|
|
52
|
+
const map = group.createMap();
|
|
53
|
+
map.set("foo", "bar", "private");
|
|
54
|
+
expect(map.get("foo")).toEqual("bar");
|
|
55
55
|
|
|
56
56
|
const [node1asPeer, node2asPeer] = connectedPeers("node1", "node2", {
|
|
57
57
|
trace: true,
|